Title: [172401] trunk/Source/_javascript_Core
Revision
172401
Author
mhahnenb...@apple.com
Date
2014-08-11 11:59:44 -0700 (Mon, 11 Aug 2014)

Log Message

for-in optimization should also make sure the base matches the object being iterated
https://bugs.webkit.org/show_bug.cgi?id=135782

Reviewed by Geoffrey Garen.

If we access a different base object with the same index, we shouldn't try to randomly
load from that object's backing store.

* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitGetByVal):
(JSC::BytecodeGenerator::pushIndexedForInScope):
(JSC::BytecodeGenerator::pushStructureForInScope):
* bytecompiler/BytecodeGenerator.h:
(JSC::ForInContext::ForInContext):
(JSC::ForInContext::base):
(JSC::StructureForInContext::StructureForInContext):
(JSC::IndexedForInContext::IndexedForInContext):
* bytecompiler/NodesCodegen.cpp:
(JSC::ForInNode::emitMultiLoopBytecode):
* tests/stress/for-in-tests.js:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (172400 => 172401)


--- trunk/Source/_javascript_Core/ChangeLog	2014-08-11 18:47:34 UTC (rev 172400)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-08-11 18:59:44 UTC (rev 172401)
@@ -1,3 +1,26 @@
+2014-08-11  Mark Hahnenberg  <mhahnenb...@apple.com>
+
+        for-in optimization should also make sure the base matches the object being iterated
+        https://bugs.webkit.org/show_bug.cgi?id=135782
+
+        Reviewed by Geoffrey Garen.
+
+        If we access a different base object with the same index, we shouldn't try to randomly 
+        load from that object's backing store.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitGetByVal):
+        (JSC::BytecodeGenerator::pushIndexedForInScope):
+        (JSC::BytecodeGenerator::pushStructureForInScope):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::ForInContext::ForInContext):
+        (JSC::ForInContext::base):
+        (JSC::StructureForInContext::StructureForInContext):
+        (JSC::IndexedForInContext::IndexedForInContext):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ForInNode::emitMultiLoopBytecode):
+        * tests/stress/for-in-tests.js:
+
 2014-08-11  Brent Fulgham  <bfulg...@apple.com>
 
         [Win] Unreviewed gardening.

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (172400 => 172401)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2014-08-11 18:47:34 UTC (rev 172400)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2014-08-11 18:59:44 UTC (rev 172401)
@@ -1445,6 +1445,9 @@
 {
     for (size_t i = m_forInContextStack.size(); i > 0; i--) {
         ForInContext* context = m_forInContextStack[i - 1].get();
+        if (context->base() != base)
+            continue;
+
         if (context->local() != property)
             continue;
 
@@ -2620,11 +2623,11 @@
     return dst;
 }
 
-void BytecodeGenerator::pushIndexedForInScope(RegisterID* localRegister, RegisterID* indexRegister)
+void BytecodeGenerator::pushIndexedForInScope(RegisterID* baseRegister, RegisterID* localRegister, RegisterID* indexRegister)
 {
     if (!localRegister)
         return;
-    m_forInContextStack.append(std::make_unique<IndexedForInContext>(localRegister, indexRegister));
+    m_forInContextStack.append(std::make_unique<IndexedForInContext>(baseRegister, localRegister, indexRegister));
 }
 
 void BytecodeGenerator::popIndexedForInScope(RegisterID* localRegister)
@@ -2634,11 +2637,11 @@
     m_forInContextStack.removeLast();
 }
 
-void BytecodeGenerator::pushStructureForInScope(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister)
+void BytecodeGenerator::pushStructureForInScope(RegisterID* baseRegister, RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister)
 {
     if (!localRegister)
         return;
-    m_forInContextStack.append(std::make_unique<StructureForInContext>(localRegister, indexRegister, propertyRegister, enumeratorRegister));
+    m_forInContextStack.append(std::make_unique<StructureForInContext>(baseRegister, localRegister, indexRegister, propertyRegister, enumeratorRegister));
 }
 
 void BytecodeGenerator::popStructureForInScope(RegisterID* localRegister)

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (172400 => 172401)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2014-08-11 18:47:34 UTC (rev 172400)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2014-08-11 18:59:44 UTC (rev 172401)
@@ -99,8 +99,9 @@
 
     class ForInContext {
     public:
-        ForInContext(RegisterID* localRegister)
-            : m_localRegister(localRegister)
+        ForInContext(RegisterID* baseRegister, RegisterID* localRegister)
+            : m_baseRegister(baseRegister)
+            , m_localRegister(localRegister)
             , m_isValid(true)
         {
         }
@@ -118,17 +119,19 @@
         };
         virtual ForInContextType type() const = 0;
 
+        RegisterID* base() const { return m_baseRegister.get(); }
         RegisterID* local() const { return m_localRegister.get(); }
 
     private:
+        RefPtr<RegisterID> m_baseRegister;
         RefPtr<RegisterID> m_localRegister;
         bool m_isValid;
     };
 
     class StructureForInContext : public ForInContext {
     public:
-        StructureForInContext(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister)
-            : ForInContext(localRegister)
+        StructureForInContext(RegisterID* baseRegister, RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister)
+            : ForInContext(baseRegister, localRegister)
             , m_indexRegister(indexRegister)
             , m_propertyRegister(propertyRegister)
             , m_enumeratorRegister(enumeratorRegister)
@@ -152,8 +155,8 @@
 
     class IndexedForInContext : public ForInContext {
     public:
-        IndexedForInContext(RegisterID* localRegister, RegisterID* indexRegister)
-            : ForInContext(localRegister)
+        IndexedForInContext(RegisterID* baseRegister, RegisterID* localRegister, RegisterID* indexRegister)
+            : ForInContext(baseRegister, localRegister)
             , m_indexRegister(indexRegister)
         {
         }
@@ -525,9 +528,9 @@
         void pushFinallyContext(StatementNode* finallyBlock);
         void popFinallyContext();
 
-        void pushIndexedForInScope(RegisterID* local, RegisterID* index);
+        void pushIndexedForInScope(RegisterID* base, RegisterID* local, RegisterID* index);
         void popIndexedForInScope(RegisterID* local);
-        void pushStructureForInScope(RegisterID* local, RegisterID* index, RegisterID* property, RegisterID* enumerator);
+        void pushStructureForInScope(RegisterID* base, RegisterID* local, RegisterID* index, RegisterID* property, RegisterID* enumerator);
         void popStructureForInScope(RegisterID* local);
         void invalidateForInContextForLocal(RegisterID* local);
 

Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (172400 => 172401)


--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2014-08-11 18:47:34 UTC (rev 172400)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2014-08-11 18:59:44 UTC (rev 172401)
@@ -2044,7 +2044,7 @@
         generator.emitToIndexString(propertyName.get(), i.get());
         this->emitLoopHeader(generator, propertyName.get());
 
-        generator.pushIndexedForInScope(local.get(), i.get());
+        generator.pushIndexedForInScope(base.get(), local.get(), i.get());
         generator.emitNode(dst, m_statement);
         generator.popIndexedForInScope(local.get());
 
@@ -2078,7 +2078,7 @@
 
         this->emitLoopHeader(generator, propertyName.get());
 
-        generator.pushStructureForInScope(local.get(), i.get(), propertyName.get(), structureEnumerator.get());
+        generator.pushStructureForInScope(base.get(), local.get(), i.get(), propertyName.get(), structureEnumerator.get());
         generator.emitNode(dst, m_statement);
         generator.popStructureForInScope(local.get());
 

Modified: trunk/Source/_javascript_Core/tests/stress/for-in-tests.js (172400 => 172401)


--- trunk/Source/_javascript_Core/tests/stress/for-in-tests.js	2014-08-11 18:47:34 UTC (rev 172400)
+++ trunk/Source/_javascript_Core/tests/stress/for-in-tests.js	2014-08-11 18:59:44 UTC (rev 172401)
@@ -75,3 +75,26 @@
     }
     foo(null);
 })();
+(function() {
+    var foo = function(a, b) {
+        for (var p in a) {
+            var f1 = a[p];
+            var f2 = b[p];
+            if (f1 === f2)
+                continue;
+            a[p] = b[p];
+        }
+    };
+    noInline(foo);
+    for (var i = 0; i < 10000; ++i) {
+        var o1 = {};
+        var o2 = {};
+        o2.x = 42;
+        o2.y = 53;
+        foo(o1, o2);
+        if (o1.x !== o2.x)
+            throw new Error("bad result: " + o1.x + "!==" + o2.x);
+        if (o1.y !== o2.y)
+            throw new Error("bad result: " + o1.y + "!==" + o2.y);
+    }
+})();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to