[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

ggaren at apple.com ggaren at apple.com
Thu Apr 8 01:09:58 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit d81680899d5a994011afd0168c736ae049ce4359
Author: ggaren at apple.com <ggaren at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Jan 15 20:48:52 2010 +0000

    2010-01-14  Geoffrey Garen  <ggaren at apple.com>
    
            Reviewed by Oliver Hunt.
    
            REGRESISON: Google maps buttons not working properly
            https://bugs.webkit.org/show_bug.cgi?id=31871
    
            REGRESSION(r52948): JavaScript exceptions thrown on Google Maps when
            getting directions for a second time
            https://bugs.webkit.org/show_bug.cgi?id=33446
    
            SunSpider and v8 report no change.
    
            * interpreter/Interpreter.cpp:
            (JSC::Interpreter::tryCacheGetByID): Update our cached offset in case
            flattening the dictionary changed any of its offsets.
    
            * jit/JITStubs.cpp:
            (JSC::JITThunks::tryCacheGetByID):
            (JSC::DEFINE_STUB_FUNCTION):
            * runtime/Operations.h:
            (JSC::normalizePrototypeChain): ditto
    2010-01-15  Geoffrey Garen  <ggaren at apple.com>
    
            Reviewed by Oliver Hunt.
    
            REGRESISON: Google maps buttons not working properly
            https://bugs.webkit.org/show_bug.cgi?id=31871
    
            REGRESSION(r52948): JavaScript exceptions thrown on Google Maps when
            getting directions for a second time
            https://bugs.webkit.org/show_bug.cgi?id=33446
    
            Added a test for these bugs.
    
            * fast/js/pic/undictionary-expected.txt: Added.
            * fast/js/pic/undictionary.html: Added.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53341 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 1ae2804..b1486b3 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,26 @@
+2010-01-14  Geoffrey Garen  <ggaren at apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        REGRESISON: Google maps buttons not working properly
+        https://bugs.webkit.org/show_bug.cgi?id=31871
+
+        REGRESSION(r52948): JavaScript exceptions thrown on Google Maps when
+        getting directions for a second time
+        https://bugs.webkit.org/show_bug.cgi?id=33446
+        
+        SunSpider and v8 report no change.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::tryCacheGetByID): Update our cached offset in case
+        flattening the dictionary changed any of its offsets.
+
+        * jit/JITStubs.cpp:
+        (JSC::JITThunks::tryCacheGetByID):
+        (JSC::DEFINE_STUB_FUNCTION):
+        * runtime/Operations.h:
+        (JSC::normalizePrototypeChain): ditto
+
 2010-01-14  Gavin Barraclough  <barraclough at apple.com>
 
         Reviewed by Oliver Hunt.
diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp
index b8e7517..fe9665e 100644
--- a/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/JavaScriptCore/interpreter/Interpreter.cpp
@@ -1044,23 +1044,27 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
         ASSERT(slot.slotBase().isObject());
 
         JSObject* baseObject = asObject(slot.slotBase());
+        size_t offset = slot.cachedOffset();
 
         // Since we're accessing a prototype in a loop, it's a good bet that it
         // should not be treated as a dictionary.
-        if (baseObject->structure()->isDictionary())
+        if (baseObject->structure()->isDictionary()) {
             baseObject->flattenDictionaryObject();
+            offset = baseObject->structure()->get(propertyName);
+        }
 
         ASSERT(!baseObject->structure()->isUncacheableDictionary());
 
         vPC[0] = getOpcode(op_get_by_id_proto);
         vPC[5] = baseObject->structure();
-        vPC[6] = slot.cachedOffset();
+        vPC[6] = offset;
 
         codeBlock->refStructures(vPC);
         return;
     }
 
-    size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase());
+    size_t offset = slot.cachedOffset();
+    size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
     if (!count) {
         vPC[0] = getOpcode(op_get_by_id_generic);
         return;
@@ -1070,7 +1074,7 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
     vPC[4] = structure;
     vPC[5] = structure->prototypeChain(callFrame);
     vPC[6] = count;
-    vPC[7] = slot.cachedOffset();
+    vPC[7] = offset;
     codeBlock->refStructures(vPC);
 }
 
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index b79dc84..bcab628 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -889,21 +889,25 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
         ASSERT(slot.slotBase().isObject());
 
         JSObject* slotBaseObject = asObject(slot.slotBase());
-
+        size_t offset = slot.cachedOffset();
+        
         // Since we're accessing a prototype in a loop, it's a good bet that it
         // should not be treated as a dictionary.
-        if (slotBaseObject->structure()->isDictionary())
+        if (slotBaseObject->structure()->isDictionary()) {
             slotBaseObject->flattenDictionaryObject();
+            offset = slotBaseObject->structure()->get(propertyName);
+        }
         
         stubInfo->initGetByIdProto(structure, slotBaseObject->structure());
 
         ASSERT(!structure->isDictionary());
         ASSERT(!slotBaseObject->structure()->isDictionary());
-        JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), slot.cachedOffset(), returnAddress);
+        JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), offset, returnAddress);
         return;
     }
 
-    size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase());
+    size_t offset = slot.cachedOffset();
+    size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
     if (!count) {
         stubInfo->accessType = access_get_by_id_generic;
         return;
@@ -911,7 +915,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
 
     StructureChain* prototypeChain = structure->prototypeChain(callFrame);
     stubInfo->initGetByIdChain(structure, prototypeChain);
-    JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, slot.cachedOffset(), returnAddress);
+    JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, offset, returnAddress);
 }
 
 #endif // ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
@@ -1436,10 +1440,11 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
     STUB_INIT_STACK_FRAME(stackFrame);
 
     CallFrame* callFrame = stackFrame.callFrame;
+    const Identifier& propertyName = stackFrame.args[1].identifier();
 
     JSValue baseValue = stackFrame.args[0].jsValue();
     PropertySlot slot(baseValue);
-    JSValue result = baseValue.get(callFrame, stackFrame.args[1].identifier(), slot);
+    JSValue result = baseValue.get(callFrame, propertyName, slot);
 
     CHECK_FOR_EXCEPTION();
 
@@ -1454,6 +1459,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
 
     ASSERT(slot.slotBase().isObject());
     JSObject* slotBaseObject = asObject(slot.slotBase());
+    
+    size_t offset = slot.cachedOffset();
 
     if (slot.slotBase() == baseValue)
         ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
@@ -1461,23 +1468,25 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
         ASSERT(!asCell(baseValue)->structure()->isDictionary());
         // Since we're accessing a prototype in a loop, it's a good bet that it
         // should not be treated as a dictionary.
-        if (slotBaseObject->structure()->isDictionary())
+        if (slotBaseObject->structure()->isDictionary()) {
             slotBaseObject->flattenDictionaryObject();
+            offset = slotBaseObject->structure()->get(propertyName);
+        }
 
         int listIndex;
         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
 
-        JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), slot.cachedOffset());
+        JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), offset);
 
         if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
             ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
-    } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase())) {
+    } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset)) {
         ASSERT(!asCell(baseValue)->structure()->isDictionary());
         int listIndex;
         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
 
         StructureChain* protoChain = structure->prototypeChain(callFrame);
-        JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, slot.cachedOffset());
+        JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, offset);
 
         if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
             ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
diff --git a/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h
index a5718d3..8b1c82b 100644
--- a/JavaScriptCore/runtime/Operations.h
+++ b/JavaScriptCore/runtime/Operations.h
@@ -339,7 +339,7 @@ namespace JSC {
         return jsAddSlowCase(callFrame, v1, v2);
     }
 
-    inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase)
+    inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, size_t& slotOffset)
     {
         JSCell* cell = asCell(base);
         size_t count = 0;
@@ -357,8 +357,11 @@ namespace JSC {
 
             // Since we're accessing a prototype in a loop, it's a good bet that it
             // should not be treated as a dictionary.
-            if (cell->structure()->isDictionary())
+            if (cell->structure()->isDictionary()) {
                 asObject(cell)->flattenDictionaryObject();
+                if (slotBase == cell)
+                    slotOffset = cell->structure()->get(propertyName); 
+            }
 
             ++count;
         }
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index d568d24..0f069b8 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,19 @@
+2010-01-15  Geoffrey Garen  <ggaren at apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        REGRESISON: Google maps buttons not working properly
+        https://bugs.webkit.org/show_bug.cgi?id=31871
+
+        REGRESSION(r52948): JavaScript exceptions thrown on Google Maps when
+        getting directions for a second time
+        https://bugs.webkit.org/show_bug.cgi?id=33446
+        
+        Added a test for these bugs.
+
+        * fast/js/pic/undictionary-expected.txt: Added.
+        * fast/js/pic/undictionary.html: Added.
+
 2010-01-15  Ojan Vafai  <ojan at chromium.org>
 
         Reviewed by Eric Seidel.
diff --git a/LayoutTests/fast/js/pic/undictionary-expected.txt b/LayoutTests/fast/js/pic/undictionary-expected.txt
new file mode 100644
index 0000000..42375b5
--- /dev/null
+++ b/LayoutTests/fast/js/pic/undictionary-expected.txt
@@ -0,0 +1,15 @@
+This page tests for a caching error when transitioning prototypes away from being dictionaries. If the test passes, you'll see a series of PASS messages below.
+
+PASS: getB(o) should be b and is.
+PASS: getB(o) should be b and is.
+PASS: getB(o) should be b and is.
+PASS: getB(o2) should be b and is.
+PASS: getB(o2) should be b and is.
+PASS: getB(o2) should be b and is.
+PASS: getB(o) should be b and is.
+PASS: getB(o) should be b and is.
+PASS: getB(o) should be b and is.
+PASS: getB(o2) should be b and is.
+PASS: getB(o2) should be b and is.
+PASS: getB(o2) should be b and is.
+
diff --git a/LayoutTests/fast/js/pic/undictionary.html b/LayoutTests/fast/js/pic/undictionary.html
new file mode 100644
index 0000000..8d6f91c
--- /dev/null
+++ b/LayoutTests/fast/js/pic/undictionary.html
@@ -0,0 +1,96 @@
+<p>
+This page tests for a caching error when transitioning prototypes away from being dictionaries.
+If the test passes, you'll see a series of PASS messages below.
+</p>
+
+<pre id="console"></pre>
+
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function log(s)
+{
+    if (this.document)
+        document.getElementById("console").appendChild(document.createTextNode(s + "\n"));
+    else
+        print(s + "\n");
+}
+
+function shouldBe(aDescription, a, b)
+{
+    if (a === b) {
+        log("PASS: " + aDescription + " should be " + b + " and is.");
+    } else {
+        log("FAIL: " + aDescription + " should be " + b + " but instead is " + a + ".");
+    }
+}
+
+// Prototype tests
+(function () {
+    function getB(o)
+    {
+        return o.b;
+    }
+
+    var o = {
+        __proto__ : {
+            a: "a",
+            b: "b"
+        }
+    };
+
+    delete o.__proto__.a;
+    o.__proto__.c = "c"; // if o.__proto__ un-dictionaries itself, .c will overwrite the deleted .b slot.
+    for (var i = 0; i < 3; ++i)
+        shouldBe("getB(o)", getB(o), "b");
+        
+    var o2 = {
+        __proto__ : {
+            a2: "a2",
+            b: "b"
+        }
+    };
+
+    delete o2.__proto__.a2;
+    o2.__proto__.c2 = "c2"; // if o2.__proto__ un-dictionaries itself, .c2 will overwrite the deleted .b slot.
+    for (var i = 0; i < 3; ++i)
+        shouldBe("getB(o2)", getB(o2), "b");
+})();
+
+// Prototype chain tests
+(function () {
+    function getB(o)
+    {
+        return o.b;
+    }
+
+    var o = {
+        __proto__ : {
+            __proto__ : {
+                a: "a",
+                b: "b"
+            }
+        }
+    };
+
+    delete o.__proto__.__proto__.a;
+    o.__proto__.__proto__.c = "c"; // if o.__proto__.__proto__ un-dictionaries itself, .c will overwrite the deleted .b slot.
+    for (var i = 0; i < 3; ++i)
+        shouldBe("getB(o)", getB(o), "b");
+
+    var o2 = {
+        __proto__ : {
+            __proto__ : {
+                a2: "a",
+                b: "b"
+            }
+        }
+    };
+
+    delete o2.__proto__.__proto__.a2;
+    o2.__proto__.__proto__.c = "c"; // if o2.__proto__.__proto__ un-dictionaries itself, .c will overwrite the deleted .b slot.
+    for (var i = 0; i < 3; ++i)
+        shouldBe("getB(o2)", getB(o2), "b");
+})();
+</script>

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list