Title: [259638] trunk
Revision
259638
Author
ysuz...@apple.com
Date
2020-04-07 09:04:57 -0700 (Tue, 07 Apr 2020)

Log Message

[JSC] Inlined IC should get right JSGlobalObject
https://bugs.webkit.org/show_bug.cgi?id=210092

Reviewed by Tadeu Zagallo.

JSTests:

* stress/getter-setter-globalobject-in-ic.js: Added.
(shouldBe):
(valueFunc):
(accessorFunc):
(valueTest):
(accessorTest):

Source/_javascript_Core:

In DFG / FTL, CodeBlock in AccessCase is the DFG / FTL CodeBlock which includes all the inlined CodeBlocks.
If inlining happens with CodeBlock which has different JSGlobalObject, CodeBlock->globalObject() is different
to the actual lexical JSGlobalObject of the IC. So basically, we should not rely on codeBlock->globalObject() in IC.

This patch passes the correct lexical JSGlobalObject to IC to use. We do not retain this JSGlobalObject.
Since this is lexical JSGlobalObject of that IC, the owner CodeBlock of this IC should already retain it (even if this
JSGlobalObject is one of inlined CodeBlock since the owner CodeBlock retains inlined lower-tier CodeBlocks).

* bytecode/AccessCase.cpp:
(JSC::AccessCase::generateImpl):
* bytecode/PolymorphicAccess.cpp:
(JSC::PolymorphicAccess::regenerate):
* bytecode/PolymorphicAccess.h:
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::addAccessCase):
* bytecode/StructureStubInfo.h:
* jit/Repatch.cpp:
(JSC::tryCacheGetBy):
(JSC::tryCacheArrayGetByVal):
(JSC::tryCachePutByID):
(JSC::tryCacheDeleteBy):
(JSC::tryCacheInByID):
(JSC::tryCacheInstanceOf):
* tools/JSDollarVM.cpp:

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (259637 => 259638)


--- trunk/JSTests/ChangeLog	2020-04-07 16:00:52 UTC (rev 259637)
+++ trunk/JSTests/ChangeLog	2020-04-07 16:04:57 UTC (rev 259638)
@@ -1,5 +1,19 @@
 2020-04-07  Yusuke Suzuki  <ysuz...@apple.com>
 
+        [JSC] Inlined IC should get right JSGlobalObject
+        https://bugs.webkit.org/show_bug.cgi?id=210092
+
+        Reviewed by Tadeu Zagallo.
+
+        * stress/getter-setter-globalobject-in-ic.js: Added.
+        (shouldBe):
+        (valueFunc):
+        (accessorFunc):
+        (valueTest):
+        (accessorTest):
+
+2020-04-07  Yusuke Suzuki  <ysuz...@apple.com>
+
         [JSC] $.evalScript should check exception when accessing "global"
         https://bugs.webkit.org/show_bug.cgi?id=210114
         <rdar://problem/61388482>

Added: trunk/JSTests/stress/getter-setter-globalobject-in-ic.js (0 => 259638)


--- trunk/JSTests/stress/getter-setter-globalobject-in-ic.js	                        (rev 0)
+++ trunk/JSTests/stress/getter-setter-globalobject-in-ic.js	2020-04-07 16:04:57 UTC (rev 259638)
@@ -0,0 +1,39 @@
+var custom = $vm.createCustomTestGetterSetter();
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var valueFunc = runString(`
+var custom = $vm.createCustomTestGetterSetter();
+function valueFunc() {
+    return custom.customValueGlobalObject;
+}`).valueFunc;
+
+var accessorFunc = runString(`
+var custom = $vm.createCustomTestGetterSetter();
+function accessorFunc() {
+    return custom.customAccessorGlobalObject;
+}`).accessorFunc;
+
+shouldBe(this.custom !== valueFunc().custom, true);
+shouldBe(this.custom !== accessorFunc().custom, true);
+shouldBe(this.custom, custom.customValueGlobalObject.custom);
+shouldBe(this.custom, custom.customAccessorGlobalObject.custom);
+
+function valueTest()
+{
+    return valueFunc();
+}
+noInline(valueTest);
+
+function accessorTest()
+{
+    return accessorFunc();
+}
+noInline(accessorTest);
+
+for (var i = 0; i < 1e3; ++i)
+    shouldBe(this.custom !== valueTest().custom, true);
+for (var i = 0; i < 1e3; ++i)
+    shouldBe(this.custom !== accessorTest().custom, true);

Modified: trunk/Source/_javascript_Core/ChangeLog (259637 => 259638)


--- trunk/Source/_javascript_Core/ChangeLog	2020-04-07 16:00:52 UTC (rev 259637)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-04-07 16:04:57 UTC (rev 259638)
@@ -1,5 +1,37 @@
 2020-04-07  Yusuke Suzuki  <ysuz...@apple.com>
 
+        [JSC] Inlined IC should get right JSGlobalObject
+        https://bugs.webkit.org/show_bug.cgi?id=210092
+
+        Reviewed by Tadeu Zagallo.
+
+        In DFG / FTL, CodeBlock in AccessCase is the DFG / FTL CodeBlock which includes all the inlined CodeBlocks.
+        If inlining happens with CodeBlock which has different JSGlobalObject, CodeBlock->globalObject() is different
+        to the actual lexical JSGlobalObject of the IC. So basically, we should not rely on codeBlock->globalObject() in IC.
+
+        This patch passes the correct lexical JSGlobalObject to IC to use. We do not retain this JSGlobalObject.
+        Since this is lexical JSGlobalObject of that IC, the owner CodeBlock of this IC should already retain it (even if this
+        JSGlobalObject is one of inlined CodeBlock since the owner CodeBlock retains inlined lower-tier CodeBlocks).
+
+        * bytecode/AccessCase.cpp:
+        (JSC::AccessCase::generateImpl):
+        * bytecode/PolymorphicAccess.cpp:
+        (JSC::PolymorphicAccess::regenerate):
+        * bytecode/PolymorphicAccess.h:
+        * bytecode/StructureStubInfo.cpp:
+        (JSC::StructureStubInfo::addAccessCase):
+        * bytecode/StructureStubInfo.h:
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetBy):
+        (JSC::tryCacheArrayGetByVal):
+        (JSC::tryCachePutByID):
+        (JSC::tryCacheDeleteBy):
+        (JSC::tryCacheInByID):
+        (JSC::tryCacheInstanceOf):
+        * tools/JSDollarVM.cpp:
+
+2020-04-07  Yusuke Suzuki  <ysuz...@apple.com>
+
         [JSC] $.evalScript should check exception when accessing "global"
         https://bugs.webkit.org/show_bug.cgi?id=210114
         <rdar://problem/61388482>

Modified: trunk/Source/_javascript_Core/bytecode/AccessCase.cpp (259637 => 259638)


--- trunk/Source/_javascript_Core/bytecode/AccessCase.cpp	2020-04-07 16:00:52 UTC (rev 259637)
+++ trunk/Source/_javascript_Core/bytecode/AccessCase.cpp	2020-04-07 16:04:57 UTC (rev 259638)
@@ -1367,6 +1367,7 @@
     CCallHelpers& jit = *state.jit;
     VM& vm = state.m_vm;
     CodeBlock* codeBlock = jit.codeBlock();
+    JSGlobalObject* globalObject = state.m_globalObject;
     StructureStubInfo& stubInfo = *state.stubInfo;
     JSValueRegs valueRegs = state.valueRegs;
     GPRReg baseGPR = state.baseGPR;
@@ -1657,8 +1658,6 @@
                 jit.setupResults(valueRegs);
             done.append(jit.jump());
 
-            // FIXME: Revisit JSGlobalObject.
-            // https://bugs.webkit.org/show_bug.cgi?id=203204
             slowCase.link(&jit);
             jit.move(loadedValueGPR, GPRInfo::regT0);
 #if USE(JSVALUE32_64)
@@ -1666,7 +1665,7 @@
             jit.move(CCallHelpers::TrustedImm32(JSValue::CellTag), GPRInfo::regT1);
 #endif
             jit.move(CCallHelpers::TrustedImmPtr(access.callLinkInfo()), GPRInfo::regT2);
-            jit.move(CCallHelpers::TrustedImmPtr(state.m_globalObject), GPRInfo::regT3);
+            jit.move(CCallHelpers::TrustedImmPtr(globalObject), GPRInfo::regT3);
             slowPathCall = jit.nearCall();
             if (m_type == Getter)
                 jit.setupResults(valueRegs);
@@ -1710,17 +1709,17 @@
             // FIXME: Remove this differences in custom values and custom accessors.
             // https://bugs.webkit.org/show_bug.cgi?id=158014
             GPRReg baseForCustom = m_type == CustomValueGetter || m_type == CustomValueSetter ? baseForAccessGPR : baseForCustomGetGPR; 
-            // FIXME: Revisit JSGlobalObject.
-            // https://bugs.webkit.org/show_bug.cgi?id=203204
+            // We do not need to keep globalObject alive since the owner CodeBlock (even if JSGlobalObject* is one of CodeBlock that is inlined and held by DFG CodeBlock)
+            // must keep it alive.
             if (m_type == CustomValueGetter || m_type == CustomAccessorGetter) {
                 RELEASE_ASSERT(m_identifier);
                 jit.setupArguments<PropertySlot::GetValueFunc>(
-                    CCallHelpers::TrustedImmPtr(codeBlock->globalObject()),
+                    CCallHelpers::TrustedImmPtr(globalObject),
                     CCallHelpers::CellValue(baseForCustom),
                     CCallHelpers::TrustedImmPtr(uid()));
             } else {
                 jit.setupArguments<PutPropertySlot::PutValueFunc>(
-                    CCallHelpers::TrustedImmPtr(codeBlock->globalObject()),
+                    CCallHelpers::TrustedImmPtr(globalObject),
                     CCallHelpers::CellValue(baseForCustom),
                     valueRegs);
             }

Modified: trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp (259637 => 259638)


--- trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp	2020-04-07 16:00:52 UTC (rev 259637)
+++ trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp	2020-04-07 16:04:57 UTC (rev 259638)
@@ -388,7 +388,7 @@
 }
 
 AccessGenerationResult PolymorphicAccess::regenerate(
-    const GCSafeConcurrentJSLocker& locker, VM& vm, CodeBlock* codeBlock, StructureStubInfo& stubInfo)
+    const GCSafeConcurrentJSLocker& locker, VM& vm, JSGlobalObject* globalObject, CodeBlock* codeBlock, StructureStubInfo& stubInfo)
 {
     SuperSamplerScope superSamplerScope(false);
     
@@ -395,7 +395,7 @@
     if (PolymorphicAccessInternal::verbose)
         dataLog("Regenerate with m_list: ", listDump(m_list), "\n");
 
-    AccessGenerationState state(vm, codeBlock->globalObject());
+    AccessGenerationState state(vm, globalObject);
 
     state.access = this;
     state.stubInfo = &stubInfo;

Modified: trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.h (259637 => 259638)


--- trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.h	2020-04-07 16:00:52 UTC (rev 259637)
+++ trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.h	2020-04-07 16:04:57 UTC (rev 259638)
@@ -144,7 +144,7 @@
     AccessGenerationResult addCase(
         const GCSafeConcurrentJSLocker&, VM&, CodeBlock*, StructureStubInfo&, std::unique_ptr<AccessCase>);
     
-    AccessGenerationResult regenerate(const GCSafeConcurrentJSLocker&, VM&, CodeBlock*, StructureStubInfo&);
+    AccessGenerationResult regenerate(const GCSafeConcurrentJSLocker&, VM&, JSGlobalObject*, CodeBlock*, StructureStubInfo&);
     
     bool isEmpty() const { return m_list.isEmpty(); }
     unsigned size() const { return m_list.size(); }

Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp (259637 => 259638)


--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp	2020-04-07 16:00:52 UTC (rev 259637)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp	2020-04-07 16:04:57 UTC (rev 259638)
@@ -140,7 +140,7 @@
 }
 
 AccessGenerationResult StructureStubInfo::addAccessCase(
-    const GCSafeConcurrentJSLocker& locker, CodeBlock* codeBlock, CacheableIdentifier ident, std::unique_ptr<AccessCase> accessCase)
+    const GCSafeConcurrentJSLocker& locker, JSGlobalObject* globalObject, CodeBlock* codeBlock, CacheableIdentifier ident, std::unique_ptr<AccessCase> accessCase)
 {
     checkConsistency();
 
@@ -219,7 +219,7 @@
         // PolymorphicAccess.
         clearBufferedStructures();
         
-        result = u.stub->regenerate(locker, vm, codeBlock, *this);
+        result = u.stub->regenerate(locker, vm, globalObject, codeBlock, *this);
         
         if (StructureStubInfoInternal::verbose)
             dataLog("Regeneration result: ", result, "\n");

Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h (259637 => 259638)


--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h	2020-04-07 16:00:52 UTC (rev 259637)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h	2020-04-07 16:04:57 UTC (rev 259638)
@@ -83,7 +83,7 @@
     void initPutByIdReplace(CodeBlock*, Structure* baseObjectStructure, PropertyOffset, CacheableIdentifier);
     void initInByIdSelf(CodeBlock*, Structure* baseObjectStructure, PropertyOffset, CacheableIdentifier);
 
-    AccessGenerationResult addAccessCase(const GCSafeConcurrentJSLocker&, CodeBlock*, CacheableIdentifier, std::unique_ptr<AccessCase>);
+    AccessGenerationResult addAccessCase(const GCSafeConcurrentJSLocker&, JSGlobalObject*, CodeBlock*, CacheableIdentifier, std::unique_ptr<AccessCase>);
 
     void reset(CodeBlock*);
 

Modified: trunk/Source/_javascript_Core/jit/Repatch.cpp (259637 => 259638)


--- trunk/Source/_javascript_Core/jit/Repatch.cpp	2020-04-07 16:00:52 UTC (rev 259637)
+++ trunk/Source/_javascript_Core/jit/Repatch.cpp	2020-04-07 16:04:57 UTC (rev 259638)
@@ -396,7 +396,7 @@
 
         LOG_IC((ICEvent::GetByAddAccessCase, baseValue.classInfoOrNull(vm), Identifier::fromUid(vm, propertyName.uid()), slot.slotBase() == baseValue));
 
-        result = stubInfo.addAccessCase(locker, codeBlock, propertyName, WTFMove(newCase));
+        result = stubInfo.addAccessCase(locker, globalObject, codeBlock, propertyName, WTFMove(newCase));
 
         if (result.generatedSomeCode()) {
             LOG_IC((ICEvent::GetByReplaceWithJump, baseValue.classInfoOrNull(vm), Identifier::fromUid(vm, propertyName.uid()), slot.slotBase() == baseValue));
@@ -495,7 +495,7 @@
             }
         }
 
-        result = stubInfo.addAccessCase(locker, codeBlock, nullptr, AccessCase::create(vm, codeBlock, accessType, nullptr));
+        result = stubInfo.addAccessCase(locker, globalObject, codeBlock, nullptr, AccessCase::create(vm, codeBlock, accessType, nullptr));
 
         if (result.generatedSomeCode()) {
             LOG_IC((ICEvent::GetByReplaceWithJump, baseValue.classInfoOrNull(vm), Identifier()));
@@ -714,7 +714,7 @@
 
         LOG_IC((ICEvent::PutByIdAddAccessCase, oldStructure->classInfo(), ident, slot.base() == baseValue));
         
-        result = stubInfo.addAccessCase(locker, codeBlock, propertyName, WTFMove(newCase));
+        result = stubInfo.addAccessCase(locker, globalObject, codeBlock, propertyName, WTFMove(newCase));
 
         if (result.generatedSomeCode()) {
             LOG_IC((ICEvent::PutByIdReplaceWithJump, oldStructure->classInfo(), ident, slot.base() == baseValue));
@@ -778,7 +778,7 @@
                 newCase = AccessCase::create(vm, codeBlock, AccessCase::DeleteMiss, propertyName, invalidOffset, oldStructure, { }, nullptr);
         }
 
-        result = stubInfo.addAccessCase(locker, codeBlock, propertyName, WTFMove(newCase));
+        result = stubInfo.addAccessCase(locker, globalObject, codeBlock, propertyName, WTFMove(newCase));
 
         if (result.generatedSomeCode()) {
             RELEASE_ASSERT(result.code());
@@ -896,7 +896,7 @@
         std::unique_ptr<AccessCase> newCase = AccessCase::create(
             vm, codeBlock, wasFound ? AccessCase::InHit : AccessCase::InMiss, propertyName, wasFound ? slot.cachedOffset() : invalidOffset, structure, conditionSet, WTFMove(prototypeAccessChain));
 
-        result = stubInfo.addAccessCase(locker, codeBlock, propertyName, WTFMove(newCase));
+        result = stubInfo.addAccessCase(locker, globalObject, codeBlock, propertyName, WTFMove(newCase));
 
         if (result.generatedSomeCode()) {
             LOG_IC((ICEvent::InReplaceWithJump, structure->classInfo(), ident, slot.slotBase() == base));
@@ -964,7 +964,7 @@
         
         LOG_IC((ICEvent::InstanceOfAddAccessCase, structure->classInfo(), Identifier()));
         
-        result = stubInfo.addAccessCase(locker, codeBlock, nullptr, WTFMove(newCase));
+        result = stubInfo.addAccessCase(locker, globalObject, codeBlock, nullptr, WTFMove(newCase));
         
         if (result.generatedSomeCode()) {
             LOG_IC((ICEvent::InstanceOfReplaceWithJump, structure->classInfo(), Identifier()));

Modified: trunk/Source/_javascript_Core/tools/JSDollarVM.cpp (259637 => 259638)


--- trunk/Source/_javascript_Core/tools/JSDollarVM.cpp	2020-04-07 16:00:52 UTC (rev 259637)
+++ trunk/Source/_javascript_Core/tools/JSDollarVM.cpp	2020-04-07 16:04:57 UTC (rev 259638)
@@ -1344,6 +1344,16 @@
     return slotValue;
 }
 
+static EncodedJSValue customGetAccessorGlobalObject(JSGlobalObject* globalObject, EncodedJSValue, PropertyName)
+{
+    return JSValue::encode(globalObject);
+}
+
+static EncodedJSValue customGetValueGlobalObject(JSGlobalObject* globalObject, EncodedJSValue, PropertyName)
+{
+    return JSValue::encode(globalObject);
+}
+
 static bool customSetAccessor(JSGlobalObject* globalObject, EncodedJSValue thisObject, EncodedJSValue encodedValue)
 {
     DollarVMAssertScope assertScope;
@@ -1383,6 +1393,11 @@
         CustomGetterSetter::create(vm, customGetValue, customSetValue), 0);
     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customAccessor"),
         CustomGetterSetter::create(vm, customGetAccessor, customSetAccessor), static_cast<unsigned>(PropertyAttribute::CustomAccessor));
+    putDirectCustomAccessor(vm, Identifier::fromString(vm, "customValueGlobalObject"),
+        CustomGetterSetter::create(vm, customGetValueGlobalObject, nullptr), 0);
+    putDirectCustomAccessor(vm, Identifier::fromString(vm, "customAccessorGlobalObject"),
+        CustomGetterSetter::create(vm, customGetAccessorGlobalObject, nullptr), static_cast<unsigned>(PropertyAttribute::CustomAccessor));
+
 }
 
 const ClassInfo Element::s_info = { "Element", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Element) };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to