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) };