Title: [183548] trunk/Source/_javascript_Core
Revision
183548
Author
fpi...@apple.com
Date
2015-04-29 08:55:54 -0700 (Wed, 29 Apr 2015)

Log Message

TypeOf should return SpecStringIdent and the DFG should know this
https://bugs.webkit.org/show_bug.cgi?id=144376

Reviewed by Andreas Kling.
        
Make TypeOf return atomic strings. That's a simple change in SmallStrings.
        
Make the DFG know this and use it for optimization. This makes Switch(TypeOf) a bit less
bad.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::setType):
* dfg/DFGAbstractValue.h:
(JSC::DFG::AbstractValue::setType):
* dfg/DFGInPlaceAbstractState.cpp:
(JSC::DFG::InPlaceAbstractState::initialize):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* runtime/SmallStrings.cpp:
(JSC::SmallStrings::initialize):
* tests/stress/switch-typeof-indirect.js: Added.
(bar):
(foo):
(test):
* tests/stress/switch-typeof-slightly-indirect.js: Added.
(foo):
(test):
* tests/stress/switch-typeof.js: Added.
(foo):
(test):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (183547 => 183548)


--- trunk/Source/_javascript_Core/ChangeLog	2015-04-29 15:49:43 UTC (rev 183547)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-04-29 15:55:54 UTC (rev 183548)
@@ -1,3 +1,38 @@
+2015-04-28  Filip Pizlo  <fpi...@apple.com>
+
+        TypeOf should return SpecStringIdent and the DFG should know this
+        https://bugs.webkit.org/show_bug.cgi?id=144376
+
+        Reviewed by Andreas Kling.
+        
+        Make TypeOf return atomic strings. That's a simple change in SmallStrings.
+        
+        Make the DFG know this and use it for optimization. This makes Switch(TypeOf) a bit less
+        bad.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::setType):
+        * dfg/DFGAbstractValue.h:
+        (JSC::DFG::AbstractValue::setType):
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::initialize):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * runtime/SmallStrings.cpp:
+        (JSC::SmallStrings::initialize):
+        * tests/stress/switch-typeof-indirect.js: Added.
+        (bar):
+        (foo):
+        (test):
+        * tests/stress/switch-typeof-slightly-indirect.js: Added.
+        (foo):
+        (test):
+        * tests/stress/switch-typeof.js: Added.
+        (foo):
+        (test):
+
 2015-04-29  Joseph Pecoraro  <pecor...@apple.com>
 
         REGRESSION(181868): Windows Live SkyDrive cannot open an excel file

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (183547 => 183548)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2015-04-29 15:49:43 UTC (rev 183547)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2015-04-29 15:55:54 UTC (rev 183548)
@@ -347,7 +347,7 @@
             setConstant(node, jsDoubleNumber(child.asNumber()));
             break;
         }
-        forNode(node).setType(forNode(node->child1()).m_type);
+        forNode(node).setType(m_graph, forNode(node->child1()).m_type);
         forNode(node).fixTypeForRepresentation(node);
         break;
     }
@@ -370,7 +370,7 @@
             break;
         }
         
-        forNode(node).setType(forNode(node->child1()).m_type & ~SpecDoubleImpureNaN);
+        forNode(node).setType(m_graph, forNode(node->child1()).m_type & ~SpecDoubleImpureNaN);
         forNode(node).fixTypeForRepresentation(node);
         break;
     }
@@ -378,7 +378,7 @@
     case ValueAdd: {
         ASSERT(node->binaryUseKind() == UntypedUse);
         clobberWorld(node->origin.semantic, clobberLimit);
-        forNode(node).setType(SpecString | SpecBytecodeNumber);
+        forNode(node).setType(m_graph, SpecString | SpecBytecodeNumber);
         break;
     }
         
@@ -910,7 +910,7 @@
             break;
         }
 
-        forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
+        forNode(node).setType(m_graph, SpecStringIdent);
         break;
     }
             
@@ -1009,7 +1009,7 @@
         break;
         
     case StringFromCharCode:
-        forNode(node).setType(SpecString);
+        forNode(node).setType(m_graph, SpecString);
         break;
 
     case StringCharAt:
@@ -1268,7 +1268,7 @@
         
         clobberWorld(node->origin.semantic, clobberLimit);
         
-        forNode(node).setType((SpecHeapTop & ~SpecCell) | SpecString | SpecCellOther);
+        forNode(node).setType(m_graph, (SpecHeapTop & ~SpecCell) | SpecString | SpecCellOther);
         break;
     }
         
@@ -1315,7 +1315,7 @@
         break;
 
     case NewArrayWithSize:
-        forNode(node).setType(SpecArray);
+        forNode(node).setType(m_graph, SpecArray);
         break;
         
     case NewTypedArray:
@@ -1354,7 +1354,7 @@
 
     case CreateThis: {
         // FIXME: We can fold this to NewObject if the incoming callee is a constant.
-        forNode(node).setType(SpecFinalObject);
+        forNode(node).setType(m_graph, SpecFinalObject);
         break;
     }
         
@@ -1402,7 +1402,7 @@
         break;
         
     case CreateClonedArguments:
-        forNode(node).setType(SpecObjectOther);
+        forNode(node).setType(m_graph, SpecObjectOther);
         break;
         
     case NewFunction:
@@ -1420,7 +1420,7 @@
                 break;
             }
         }
-        forNode(node).setType(SpecFunction);
+        forNode(node).setType(m_graph, SpecFunction);
         break;
         
     case GetArgumentCount:
@@ -1437,7 +1437,7 @@
             }
         }
         
-        forNode(node).setType(SpecObject);
+        forNode(node).setType(m_graph, SpecObject);
         break;
     }
         
@@ -1451,7 +1451,7 @@
             }
         }
         
-        forNode(node).setType(SpecObject);
+        forNode(node).setType(m_graph, SpecObject);
         break;
     }
         
@@ -1462,7 +1462,7 @@
                 break;
             }
         }
-        forNode(node).setType(SpecObjectOther);
+        forNode(node).setType(m_graph, SpecObjectOther);
         break;
 
     case SkipScope: {
@@ -1471,7 +1471,7 @@
             setConstant(node, *m_graph.freeze(JSValue(jsCast<JSScope*>(child.asCell())->next())));
             break;
         }
-        forNode(node).setType(SpecObjectOther);
+        forNode(node).setType(m_graph, SpecObjectOther);
         break;
     }
 
@@ -1874,7 +1874,7 @@
                 break;
             }
         }
-        forNode(node).setType(SpecCellOther);
+        forNode(node).setType(m_graph, SpecCellOther);
         break;
     }
     
@@ -1997,19 +1997,19 @@
         break;
     }
     case GetPropertyEnumerator: {
-        forNode(node).setType(SpecCell);
+        forNode(node).setType(m_graph, SpecCell);
         break;
     }
     case GetEnumeratorStructurePname: {
-        forNode(node).setType(SpecString | SpecOther);
+        forNode(node).setType(m_graph, SpecString | SpecOther);
         break;
     }
     case GetEnumeratorGenericPname: {
-        forNode(node).setType(SpecString | SpecOther);
+        forNode(node).setType(m_graph, SpecString | SpecOther);
         break;
     }
     case ToIndexString: {
-        forNode(node).setType(SpecString);
+        forNode(node).setType(m_graph, SpecString);
         break;
     }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp (183547 => 183548)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp	2015-04-29 15:49:43 UTC (rev 183547)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp	2015-04-29 15:55:54 UTC (rev 183548)
@@ -118,6 +118,24 @@
     assertIsRegistered(graph);
 }
 
+void AbstractValue::setType(Graph& graph, SpeculatedType type)
+{
+    SpeculatedType cellType = type & SpecCell;
+    if (cellType) {
+        if (!(cellType & ~SpecString))
+            m_structure = graph.m_vm.stringStructure.get();
+        else
+            m_structure.makeTop();
+        m_arrayModes = ALL_ARRAY_MODES;
+    } else {
+        m_structure.clear();
+        m_arrayModes = 0;
+    }
+    m_type = type;
+    m_value = JSValue();
+    checkConsistency();
+}
+
 void AbstractValue::fixTypeForRepresentation(NodeFlags representation)
 {
     if (representation == NodeResultDouble) {

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h (183547 => 183548)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h	2015-04-29 15:49:43 UTC (rev 183547)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h	2015-04-29 15:55:54 UTC (rev 183548)
@@ -199,15 +199,15 @@
     void set(Graph&, Structure*);
     void set(Graph&, const StructureSet&);
     
+    // Set this value to represent the given set of types as precisely as possible.
+    void setType(Graph&, SpeculatedType);
+    
+    // As above, but only valid for non-cell types.
     void setType(SpeculatedType type)
     {
-        if (type & SpecCell) {
-            m_structure.makeTop();
-            m_arrayModes = ALL_ARRAY_MODES;
-        } else {
-            m_structure.clear();
-            m_arrayModes = 0;
-        }
+        RELEASE_ASSERT(!(type & SpecCell));
+        m_structure.clear();
+        m_arrayModes = 0;
         m_type = type;
         m_value = JSValue();
         checkConsistency();

Modified: trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp (183547 => 183548)


--- trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp	2015-04-29 15:49:43 UTC (rev 183547)
+++ trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp	2015-04-29 15:55:54 UTC (rev 183548)
@@ -118,7 +118,7 @@
             root->valuesAtHead.argument(i).setType(SpecBoolean);
             break;
         case FlushedCell:
-            root->valuesAtHead.argument(i).setType(SpecCell);
+            root->valuesAtHead.argument(i).setType(m_graph, SpecCell);
             break;
         case FlushedJSValue:
             root->valuesAtHead.argument(i).makeHeapTop();

Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (183547 => 183548)


--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2015-04-29 15:49:43 UTC (rev 183547)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2015-04-29 15:55:54 UTC (rev 183548)
@@ -379,7 +379,7 @@
         }
 
         case TypeOf: {
-            changed |= setPrediction(SpecString);
+            changed |= setPrediction(SpecStringIdent);
             break;
         }
 

Modified: trunk/Source/_javascript_Core/runtime/SmallStrings.cpp (183547 => 183548)


--- trunk/Source/_javascript_Core/runtime/SmallStrings.cpp	2015-04-29 15:49:43 UTC (rev 183547)
+++ trunk/Source/_javascript_Core/runtime/SmallStrings.cpp	2015-04-29 15:55:54 UTC (rev 183548)
@@ -130,7 +130,7 @@
 
 void SmallStrings::initialize(VM* vm, JSString*& string, const char* value)
 {
-    string = JSString::create(*vm, StringImpl::create(value));
+    string = JSString::create(*vm, Identifier::fromString(vm, value).impl());
     m_needsToBeVisited = true;
 }
 

Added: trunk/Source/_javascript_Core/tests/stress/switch-typeof-indirect.js (0 => 183548)


--- trunk/Source/_javascript_Core/tests/stress/switch-typeof-indirect.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/switch-typeof-indirect.js	2015-04-29 15:55:54 UTC (rev 183548)
@@ -0,0 +1,41 @@
+function bar(value) {
+    return typeof value;
+}
+noInline(bar);
+
+function foo(value) {
+    switch (bar(value)) {
+    case "undefined":
+        return 0;
+    case "object":
+        return 1;
+    case "function":
+        return 2;
+    case "boolean":
+        return 3;
+    case "number":
+        return 4;
+    case "string":
+        return 5;
+    default:
+        return 6;
+    }
+}
+
+noInline(foo);
+
+function test(value, expected) {
+    var result = foo(value);
+    if (result != expected)
+        throw "Error: bad type code for " + value + ": " + result + " (expected " + expected + ")";
+}
+
+for (var i = 0; i < 10000; ++i) {
+    test(void 0, 0);
+    test({}, 1);
+    test(function() { return 42; }, 2);
+    test(true, 3);
+    test(42, 4);
+    test(42.5, 4);
+    test("hello", 5);
+}

Added: trunk/Source/_javascript_Core/tests/stress/switch-typeof-slightly-indirect.js (0 => 183548)


--- trunk/Source/_javascript_Core/tests/stress/switch-typeof-slightly-indirect.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/switch-typeof-slightly-indirect.js	2015-04-29 15:55:54 UTC (rev 183548)
@@ -0,0 +1,39 @@
+function foo(value) {
+    var t = typeof value;
+    if (!t)
+        return -1;
+    switch (t) {
+    case "undefined":
+        return 0;
+    case "object":
+        return 1;
+    case "function":
+        return 2;
+    case "boolean":
+        return 3;
+    case "number":
+        return 4;
+    case "string":
+        return 5;
+    default:
+        return 6;
+    }
+}
+
+noInline(foo);
+
+function test(value, expected) {
+    var result = foo(value);
+    if (result != expected)
+        throw "Error: bad type code for " + value + ": " + result + " (expected " + expected + ")";
+}
+
+for (var i = 0; i < 10000; ++i) {
+    test(void 0, 0);
+    test({}, 1);
+    test(function() { return 42; }, 2);
+    test(true, 3);
+    test(42, 4);
+    test(42.5, 4);
+    test("hello", 5);
+}

Added: trunk/Source/_javascript_Core/tests/stress/switch-typeof.js (0 => 183548)


--- trunk/Source/_javascript_Core/tests/stress/switch-typeof.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/switch-typeof.js	2015-04-29 15:55:54 UTC (rev 183548)
@@ -0,0 +1,36 @@
+function foo(value) {
+    switch (typeof value) {
+    case "undefined":
+        return 0;
+    case "object":
+        return 1;
+    case "function":
+        return 2;
+    case "boolean":
+        return 3;
+    case "number":
+        return 4;
+    case "string":
+        return 5;
+    default:
+        return 6;
+    }
+}
+
+noInline(foo);
+
+function test(value, expected) {
+    var result = foo(value);
+    if (result != expected)
+        throw "Error: bad type code for " + value + ": " + result + " (expected " + expected + ")";
+}
+
+for (var i = 0; i < 10000; ++i) {
+    test(void 0, 0);
+    test({}, 1);
+    test(function() { return 42; }, 2);
+    test(true, 3);
+    test(42, 4);
+    test(42.5, 4);
+    test("hello", 5);
+}
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to