[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.18-1-697-g2f78b87
ggaren at apple.com
ggaren at apple.com
Wed Jan 20 22:26:02 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit 4cb86a23aad1f52c758d2df82d523fca77429791
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