Title: [179865] trunk/Source/_javascript_Core
Revision
179865
Author
[email protected]
Date
2015-02-09 23:40:53 -0800 (Mon, 09 Feb 2015)

Log Message

JSC's Type Profiler doesn't profile the type of the looping variable in ForOf/ForIn loops
https://bugs.webkit.org/show_bug.cgi?id=141241

Reviewed by Filip Pizlo.

Type information is now recorded for ForIn and ForOf statements. 
It was an oversight to not have these statements profiled before.

* bytecompiler/NodesCodegen.cpp:
(JSC::ForInNode::emitLoopHeader):
(JSC::ForOfNode::emitBytecode):
* tests/typeProfiler/loop.js: Added.
(testForIn):
(testForOf):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (179864 => 179865)


--- trunk/Source/_javascript_Core/ChangeLog	2015-02-10 07:09:31 UTC (rev 179864)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-02-10 07:40:53 UTC (rev 179865)
@@ -1,3 +1,20 @@
+2015-02-09  Saam Barati  <[email protected]>
+
+        JSC's Type Profiler doesn't profile the type of the looping variable in ForOf/ForIn loops
+        https://bugs.webkit.org/show_bug.cgi?id=141241
+
+        Reviewed by Filip Pizlo.
+
+        Type information is now recorded for ForIn and ForOf statements. 
+        It was an oversight to not have these statements profiled before.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForInNode::emitLoopHeader):
+        (JSC::ForOfNode::emitBytecode):
+        * tests/typeProfiler/loop.js: Added.
+        (testForIn):
+        (testForOf):
+
 2015-02-09  Filip Pizlo  <[email protected]>
 
         DFG::StackLayoutPhase should always set the scopeRegister to VirtualRegister() because the DFG doesn't do anything to make its value valid

Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (179864 => 179865)


--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2015-02-10 07:09:31 UTC (rev 179864)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2015-02-10 07:40:53 UTC (rev 179865)
@@ -2027,7 +2027,11 @@
             RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident, resolveScopeInfo);
             generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
             generator.emitPutToScope(scope, ident, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
+            if (generator.vm()->typeProfiler())
+                generator.emitProfileType(propertyName, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
         }
+        if (generator.vm()->typeProfiler())
+            generator.emitTypeProfilerExpressionInfo(m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
         return;
     }
     if (m_lexpr->isDotAccessorNode()) {
@@ -2036,6 +2040,10 @@
         RegisterID* base = generator.emitNode(assignNode->base());
         generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
         generator.emitPutById(base, ident, propertyName);
+        if (generator.vm()->typeProfiler()) {
+            generator.emitProfileType(propertyName, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+            generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
+        }
         return;
     }
     if (m_lexpr->isBracketAccessorNode()) {
@@ -2044,6 +2052,10 @@
         RegisterID* subscript = generator.emitNode(assignNode->subscript());
         generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
         generator.emitPutByVal(base.get(), subscript, propertyName);
+        if (generator.vm()->typeProfiler()) {
+            generator.emitProfileType(propertyName, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+            generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
+        }
         return;
     }
 
@@ -2063,6 +2075,8 @@
             return;
         }
         generator.emitMove(local.get(), propertyName);
+        if (generator.vm()->typeProfiler())
+            generator.emitTypeProfilerExpressionInfo(m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
         return;
     }
 
@@ -2235,7 +2249,11 @@
                 RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident, resolveScopeInfo);
                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
                 generator.emitPutToScope(scope, ident, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
+                if (generator.vm()->typeProfiler())
+                    generator.emitProfileType(value, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
             }
+            if (generator.vm()->typeProfiler())
+                generator.emitTypeProfilerExpressionInfo(m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
         } else if (m_lexpr->isDotAccessorNode()) {
             DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
             const Identifier& ident = assignNode->identifier();
@@ -2243,6 +2261,10 @@
             
             generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
             generator.emitPutById(base.get(), ident, value);
+            if (generator.vm()->typeProfiler()) {
+                generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+                generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
+            }
         } else if (m_lexpr->isBracketAccessorNode()) {
             BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
             RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
@@ -2250,6 +2272,10 @@
             
             generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
             generator.emitPutByVal(base.get(), subscript, value);
+            if (generator.vm()->typeProfiler()) {
+                generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
+                generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
+            }
         } else {
             ASSERT(m_lexpr->isDeconstructionNode());
             DeconstructingAssignmentNode* assignNode = static_cast<DeconstructingAssignmentNode*>(m_lexpr);

Added: trunk/Source/_javascript_Core/tests/typeProfiler/loop.js (0 => 179865)


--- trunk/Source/_javascript_Core/tests/typeProfiler/loop.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/typeProfiler/loop.js	2015-02-10 07:40:53 UTC (rev 179865)
@@ -0,0 +1,37 @@
+load("./driver/driver.js");
+
+function testForIn(x) {
+    // FIXME: add support for the following statement types: "for (var arg of expr)" and "for (var arg in expr)"
+    // https://bugs.webkit.org/show_bug.cgi?id=141241
+     
+    for (arg2 in x)
+        x; 
+
+    for ({x: arg3} in x) 
+        x;
+}
+
+function testForOf(x) {
+    for (arg2 of x)
+        x; 
+
+    for ({x: arg3} of x) 
+        x;
+}
+
+testForIn([1])
+var types = findTypeForExpression(testForIn, "arg2"); 
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.String) !== -1, "Primitive type names should contain 'String'");
+types = findTypeForExpression(testForIn, "arg3");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Undefined) !== -1, "Primitive type names should contain 'Undefined'"); 
+
+testForOf([1])
+types = findTypeForExpression(testForOf, "arg2"); 
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Integer) !== -1, "Primitive type names should contain 'Integer'");
+types = findTypeForExpression(testForOf, "arg3");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Undefined) !== -1, "Primitive type names should contain 'Undefined'"); 
+testForOf([{x:29}])
+types = findTypeForExpression(testForOf, "arg2");
+assert(types.instructionTypeSet.structures[0].fields.indexOf("x") !== -1, "variable 'arg1' should have field 'x'");
+types = findTypeForExpression(testForOf, "arg3");
+assert(types.instructionTypeSet.primitiveTypeNames.indexOf(T.Integer) !== -1, "Primitive type names should contain 'Integer'"); 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to