diff options
author | Filip Pizlo <fpizlo@apple.com> | 2013-03-21 18:13:57 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-03-26 17:49:37 +0100 |
commit | 1f8a9f66cf95c3ea5a8819c87157ac00d4b1ef0c (patch) | |
tree | 1eff680108b1835a7146ea8601e499c8e163785d /Source/JavaScriptCore/jit/JITStubs.cpp | |
parent | 2e536fc35017d3f52e071da231e4fe7deddd4f88 (diff) | |
download | qtwebkit-1f8a9f66cf95c3ea5a8819c87157ac00d4b1ef0c.tar.gz |
Named lookups on HTML documents produce inconsistent results in JavaScriptCore bindings
https://bugs.webkit.org/show_bug.cgi?id=104623
Reviewed by Geoffrey Garen.
Source/JavaScriptCore:
Add the notion of objects that HasImpureGetOwnPropertySlot, and use that to inhibit prototype chain caching
in some cases. This appears to be perf-neutral on benchmarks that we track.
* dfg/DFGRepatch.cpp:
(JSC::DFG::tryCacheGetByID):
(JSC::DFG::tryBuildGetByIDProtoList):
* jit/JITStubs.cpp:
(JSC::JITThunks::tryCacheGetByID):
(JSC::DEFINE_STUB_FUNCTION):
* runtime/JSTypeInfo.h:
(JSC):
(JSC::TypeInfo::hasImpureGetOwnPropertySlot):
* runtime/Operations.h:
(JSC::normalizePrototypeChainForChainAccess):
Source/WebCore:
All DOM objects that have named getters or directly override getOwnPropertySlot are now marked as
HasImpureGetOwnPropertySlot.
Tests: fast/js/prototype-chain-caching-with-impure-get-own-property-slot-traps
fast/js/dfg-prototype-chain-caching-with-impure-get-own-property-slot-traps
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader):
LayoutTests:
* fast/js/dfg-prototype-chain-caching-with-impure-get-own-property-slot-traps-expected.txt: Added.
* fast/js/dfg-prototype-chain-caching-with-impure-get-own-property-slot-traps.html: Added.
* fast/js/prototype-chain-caching-with-impure-get-own-property-slot-traps-expected.txt: Added.
* fast/js/prototype-chain-caching-with-impure-get-own-property-slot-traps.html: Added.
* fast/js/script-tests/dfg-prototype-chain-caching-with-impure-get-own-property-slot-traps.js: Added.
(f):
* fast/js/script-tests/prototype-chain-caching-with-impure-get-own-property-slot-traps.js: Added.
(f):
Change-Id: Ie17e39f2b8139778455e28aca9428698f4dd362f
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@137700 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/jit/JITStubs.cpp')
-rw-r--r-- | Source/JavaScriptCore/jit/JITStubs.cpp | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp index f47ac08ef..fbef1fcb9 100644 --- a/Source/JavaScriptCore/jit/JITStubs.cpp +++ b/Source/JavaScriptCore/jit/JITStubs.cpp @@ -908,6 +908,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co // Uncacheable: give up. if (!slot.isCacheable()) { + stubInfo->accessType = access_get_by_id_generic; ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic)); return; } @@ -916,6 +917,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co Structure* structure = baseCell->structure(); if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) { + stubInfo->accessType = access_get_by_id_generic; ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic)); return; } @@ -934,6 +936,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co } if (structure->isDictionary()) { + stubInfo->accessType = access_get_by_id_generic; ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic)); return; } @@ -943,6 +946,12 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co JSObject* slotBaseObject = asObject(slot.slotBase()); size_t offset = slot.cachedOffset(); + + if (structure->typeInfo().hasImpureGetOwnPropertySlot()) { + stubInfo->accessType = access_get_by_id_generic; + ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic)); + return; + } // Since we're accessing a prototype in a loop, it's a good bet that it // should not be treated as a dictionary. @@ -960,9 +969,10 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co } PropertyOffset offset = slot.cachedOffset(); - size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset); + size_t count = normalizePrototypeChainForChainAccess(callFrame, baseValue, slot.slotBase(), propertyName, offset); if (count == InvalidPrototypeChain) { stubInfo->accessType = access_get_by_id_generic; + ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic)); return; } @@ -1689,6 +1699,12 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail)); else if (slot.slotBase() == baseValue.asCell()->structure()->prototypeForLookup(callFrame)) { ASSERT(!baseValue.asCell()->structure()->isDictionary()); + + if (baseValue.asCell()->structure()->typeInfo().hasImpureGetOwnPropertySlot()) { + ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail)); + return JSValue::encode(result); + } + // 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()) { @@ -1705,7 +1721,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); } } else { - size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset); + size_t count = normalizePrototypeChainForChainAccess(callFrame, baseValue, slot.slotBase(), propertyName, offset); if (count == InvalidPrototypeChain) { ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail)); return JSValue::encode(result); |