Diff
Modified: branches/safari-612-branch/JSTests/ChangeLog (285314 => 285315)
--- branches/safari-612-branch/JSTests/ChangeLog 2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/JSTests/ChangeLog 2021-11-04 21:43:02 UTC (rev 285315)
@@ -1,5 +1,59 @@
2021-11-04 Russell Epstein <[email protected]>
+ Cherry-pick r283512. rdar://problem/85034084
+
+ IntrinsicGetterAccessCase implementation of __proto__ needs to handle get_by_id_with_this
+ https://bugs.webkit.org/show_bug.cgi?id=229951
+ <rdar://problem/82787527>
+
+ Reviewed by Yusuke Suzuki.
+
+ JSTests:
+
+ * stress/run-proto-intrinsic-getter-with-this-value-in-get-by-id-with-this.js: Added.
+ (assert):
+ (main.v37):
+ (main):
+
+ Source/_javascript_Core:
+
+ The whole point of get_by_id_with_this is to have different
+ slot base values for |this| vs the slot base when invoking
+ getters. However, our intrinsic getter inlining wasn't respecting
+ this. This patch makes the __proto__ intrinsic getter do the right
+ thing. For typed array intrinsic getters, if they have different
+ |this| value vs slot base, we chose not to inline them, because
+ the type checks are not on the |this| value, so they're not guaranteed
+ to be typed arrays. We can improve upon this in the future.
+
+ * bytecode/IntrinsicGetterAccessCase.h:
+ * jit/AssemblyHelpers.cpp:
+ (JSC::AssemblyHelpers::emitLoadPrototypeWithoutCheck):
+ * jit/AssemblyHelpers.h:
+ * jit/IntrinsicEmitter.cpp:
+ (JSC::IntrinsicGetterAccessCase::canEmitIntrinsicGetter):
+ (JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter):
+ * jit/Repatch.cpp:
+ (JSC::tryCacheGetBy):
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@283512 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2021-10-04 Saam Barati <[email protected]>
+
+ IntrinsicGetterAccessCase implementation of __proto__ needs to handle get_by_id_with_this
+ https://bugs.webkit.org/show_bug.cgi?id=229951
+ <rdar://problem/82787527>
+
+ Reviewed by Yusuke Suzuki.
+
+ * stress/run-proto-intrinsic-getter-with-this-value-in-get-by-id-with-this.js: Added.
+ (assert):
+ (main.v37):
+ (main):
+
+2021-11-04 Russell Epstein <[email protected]>
+
Cherry-pick r285117. rdar://problem/84402043
JSGenericTypedArrayView<Adaptor>::set crashes if the length + objectOffset is > UINT32_MAX
Added: branches/safari-612-branch/JSTests/stress/run-proto-intrinsic-getter-with-this-value-in-get-by-id-with-this.js (0 => 285315)
--- branches/safari-612-branch/JSTests/stress/run-proto-intrinsic-getter-with-this-value-in-get-by-id-with-this.js (rev 0)
+++ branches/safari-612-branch/JSTests/stress/run-proto-intrinsic-getter-with-this-value-in-get-by-id-with-this.js 2021-11-04 21:43:02 UTC (rev 285315)
@@ -0,0 +1,25 @@
+//@ runDefault("--forcePolyProto=true", "--validateOptions=true", "--useConcurrentJIT=false", "--useConcurrentGC=false", "--thresholdForJITSoon=10", "--thresholdForJITAfterWarmUp=10", "--thresholdForOptimizeAfterWarmUp=100", "--thresholdForOptimizeAfterLongWarmUp=100", "--thresholdForOptimizeSoon=100", "--thresholdForFTLOptimizeAfterWarmUp=1000", "--thresholdForFTLOptimizeSoon=1000", "--validateBCE=true", "--useFTLJIT=true")
+
+function assert(b) {
+ if (!b)
+ throw new Error;
+}
+
+function main() {
+ let v41;
+
+ v37 = class V37 {
+ constructor() {
+ v41 = super.__proto__;
+ }
+ };
+
+ for (let v70 = 0; v70 < 100; v70++) {
+ new v37();
+ assert(v41 !== null);
+ }
+
+}
+noDFG(main);
+noFTL(main);
+main();
Modified: branches/safari-612-branch/Source/_javascript_Core/ChangeLog (285314 => 285315)
--- branches/safari-612-branch/Source/_javascript_Core/ChangeLog 2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/Source/_javascript_Core/ChangeLog 2021-11-04 21:43:02 UTC (rev 285315)
@@ -1,5 +1,73 @@
2021-11-04 Russell Epstein <[email protected]>
+ Cherry-pick r283512. rdar://problem/85034084
+
+ IntrinsicGetterAccessCase implementation of __proto__ needs to handle get_by_id_with_this
+ https://bugs.webkit.org/show_bug.cgi?id=229951
+ <rdar://problem/82787527>
+
+ Reviewed by Yusuke Suzuki.
+
+ JSTests:
+
+ * stress/run-proto-intrinsic-getter-with-this-value-in-get-by-id-with-this.js: Added.
+ (assert):
+ (main.v37):
+ (main):
+
+ Source/_javascript_Core:
+
+ The whole point of get_by_id_with_this is to have different
+ slot base values for |this| vs the slot base when invoking
+ getters. However, our intrinsic getter inlining wasn't respecting
+ this. This patch makes the __proto__ intrinsic getter do the right
+ thing. For typed array intrinsic getters, if they have different
+ |this| value vs slot base, we chose not to inline them, because
+ the type checks are not on the |this| value, so they're not guaranteed
+ to be typed arrays. We can improve upon this in the future.
+
+ * bytecode/IntrinsicGetterAccessCase.h:
+ * jit/AssemblyHelpers.cpp:
+ (JSC::AssemblyHelpers::emitLoadPrototypeWithoutCheck):
+ * jit/AssemblyHelpers.h:
+ * jit/IntrinsicEmitter.cpp:
+ (JSC::IntrinsicGetterAccessCase::canEmitIntrinsicGetter):
+ (JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter):
+ * jit/Repatch.cpp:
+ (JSC::tryCacheGetBy):
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@283512 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2021-10-04 Saam Barati <[email protected]>
+
+ IntrinsicGetterAccessCase implementation of __proto__ needs to handle get_by_id_with_this
+ https://bugs.webkit.org/show_bug.cgi?id=229951
+ <rdar://problem/82787527>
+
+ Reviewed by Yusuke Suzuki.
+
+ The whole point of get_by_id_with_this is to have different
+ slot base values for |this| vs the slot base when invoking
+ getters. However, our intrinsic getter inlining wasn't respecting
+ this. This patch makes the __proto__ intrinsic getter do the right
+ thing. For typed array intrinsic getters, if they have different
+ |this| value vs slot base, we chose not to inline them, because
+ the type checks are not on the |this| value, so they're not guaranteed
+ to be typed arrays. We can improve upon this in the future.
+
+ * bytecode/IntrinsicGetterAccessCase.h:
+ * jit/AssemblyHelpers.cpp:
+ (JSC::AssemblyHelpers::emitLoadPrototypeWithoutCheck):
+ * jit/AssemblyHelpers.h:
+ * jit/IntrinsicEmitter.cpp:
+ (JSC::IntrinsicGetterAccessCase::canEmitIntrinsicGetter):
+ (JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter):
+ * jit/Repatch.cpp:
+ (JSC::tryCacheGetBy):
+
+2021-11-04 Russell Epstein <[email protected]>
+
Cherry-pick r285149. rdar://problem/81217357
[JSC] LLIntCallee should have two replacements
Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/IntrinsicGetterAccessCase.h (285314 => 285315)
--- branches/safari-612-branch/Source/_javascript_Core/bytecode/IntrinsicGetterAccessCase.h 2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/IntrinsicGetterAccessCase.h 2021-11-04 21:43:02 UTC (rev 285315)
@@ -39,7 +39,7 @@
JSFunction* intrinsicFunction() const { return m_intrinsicFunction.get(); }
Intrinsic intrinsic() const { return m_intrinsicFunction->intrinsic(); }
- static bool canEmitIntrinsicGetter(JSFunction*, Structure*);
+ static bool canEmitIntrinsicGetter(StructureStubInfo&, JSFunction*, Structure*);
void emitIntrinsicGetter(AccessGenerationState&);
static Ref<AccessCase> create(VM&, JSCell*, CacheableIdentifier, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, JSFunction* intrinsicFunction, RefPtr<PolyProtoAccessChain>&&);
Modified: branches/safari-612-branch/Source/_javascript_Core/jit/AssemblyHelpers.cpp (285314 => 285315)
--- branches/safari-612-branch/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2021-11-04 21:43:02 UTC (rev 285315)
@@ -413,6 +413,36 @@
hasMonoProto.link(this);
}
+void AssemblyHelpers::emitLoadPrototypeWithoutCheck(VM& vm, GPRReg objectGPR, JSValueRegs resultRegs, GPRReg scratchGPR, GPRReg scratch2GPR)
+{
+ ASSERT(objectGPR != scratchGPR);
+ ASSERT(objectGPR != scratch2GPR);
+ ASSERT(resultRegs.payloadGPR() != scratchGPR);
+ ASSERT(resultRegs.payloadGPR() != scratch2GPR);
+#if USE(JSVALUE32_64)
+ ASSERT(resultRegs.tagGPR() != scratchGPR);
+ ASSERT(resultRegs.tagGPR() != scratch2GPR);
+#endif
+
+ emitLoadStructure(vm, objectGPR, scratchGPR, scratch2GPR);
+#if USE(JSVALUE64)
+ loadValue(MacroAssembler::Address(scratchGPR, Structure::prototypeOffset()), JSValueRegs(scratch2GPR));
+#else
+ load32(MacroAssembler::Address(scratchGPR, Structure::prototypeOffset() + TagOffset), scratch2GPR);
+#endif
+ auto hasMonoProto = branchIfNotEmpty(scratch2GPR);
+ loadValue(MacroAssembler::Address(objectGPR, offsetRelativeToBase(knownPolyProtoOffset)), resultRegs);
+ auto done = jump();
+ hasMonoProto.link(this);
+#if USE(JSVALUE64)
+ move(scratch2GPR, resultRegs.payloadGPR());
+#else
+ load32(MacroAssembler::Address(scratchGPR, Structure::prototypeOffset() + PayloadOffset), resultRegs.payloadGPR());
+ move(scratch2GPR, resultRegs.tagGPR());
+#endif
+ done.link(this);
+}
+
void AssemblyHelpers::makeSpaceOnStackForCCall()
{
unsigned stackOffset = WTF::roundUpToMultipleOf(stackAlignmentBytes(), maxFrameExtentForSlowPathCall);
Modified: branches/safari-612-branch/Source/_javascript_Core/jit/AssemblyHelpers.h (285314 => 285315)
--- branches/safari-612-branch/Source/_javascript_Core/jit/AssemblyHelpers.h 2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/Source/_javascript_Core/jit/AssemblyHelpers.h 2021-11-04 21:43:02 UTC (rev 285315)
@@ -1518,6 +1518,7 @@
void emitLoadStructure(VM&, RegisterID source, RegisterID dest, RegisterID scratch);
void emitLoadPrototype(VM&, GPRReg objectGPR, JSValueRegs resultRegs, GPRReg scratchGPR, JumpList& slowPath);
+ void emitLoadPrototypeWithoutCheck(VM&, GPRReg objectGPR, JSValueRegs resultRegs, GPRReg scratchGPR, GPRReg scratch2GPR);
void emitStoreStructureWithTypeInfo(TrustedImmPtr structure, RegisterID dest, RegisterID)
{
Modified: branches/safari-612-branch/Source/_javascript_Core/jit/IntrinsicEmitter.cpp (285314 => 285315)
--- branches/safari-612-branch/Source/_javascript_Core/jit/IntrinsicEmitter.cpp 2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/Source/_javascript_Core/jit/IntrinsicEmitter.cpp 2021-11-04 21:43:02 UTC (rev 285315)
@@ -46,7 +46,7 @@
typedef CCallHelpers::TrustedImm64 TrustedImm64;
typedef CCallHelpers::Imm64 Imm64;
-bool IntrinsicGetterAccessCase::canEmitIntrinsicGetter(JSFunction* getter, Structure* structure)
+bool IntrinsicGetterAccessCase::canEmitIntrinsicGetter(StructureStubInfo& stubInfo, JSFunction* getter, Structure* structure)
{
switch (getter->intrinsic()) {
@@ -53,6 +53,10 @@
case TypedArrayByteOffsetIntrinsic:
case TypedArrayByteLengthIntrinsic:
case TypedArrayLengthIntrinsic: {
+ // We aren't structure checking the this value, so we don't know it's a typed array.
+ if (stubInfo.thisValueIsInThisGPR())
+ return false;
+
TypedArrayType type = structure->classInfo()->typedArrayStorageType;
if (!isTypedView(type))
@@ -146,10 +150,34 @@
}
case UnderscoreProtoIntrinsic: {
- if (structure()->hasPolyProto())
- jit.loadValue(CCallHelpers::Address(baseGPR, offsetRelativeToBase(knownPolyProtoOffset)), valueRegs);
- else
- jit.moveValue(structure()->storedPrototype(), valueRegs);
+ StructureStubInfo& stubInfo = *state.stubInfo;
+ if (stubInfo.thisValueIsInThisGPR()) {
+ ScratchRegisterAllocator allocator(stubInfo.usedRegisters);
+ allocator.lock(state.scratchGPR);
+ allocator.lock(state.baseGPR);
+ allocator.lock(state.u.thisGPR);
+ allocator.lock(valueRegs);
+#if USE(JSVALUE32_64)
+ allocator.lock(stubInfo.baseTagGPR);
+ allocator.lock(stubInfo.v.thisTagGPR);
+#endif
+ if (stubInfo.m_stubInfoGPR != InvalidGPRReg)
+ allocator.lock(stubInfo.m_stubInfoGPR);
+ if (stubInfo.m_arrayProfileGPR != InvalidGPRReg)
+ allocator.lock(stubInfo.m_arrayProfileGPR);
+
+ GPRReg scratch2GPR = allocator.allocateScratchGPR();
+ auto preservedState = allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+
+ jit.emitLoadPrototypeWithoutCheck(state.m_vm, state.u.thisGPR, valueRegs, state.scratchGPR, scratch2GPR);
+
+ allocator.restoreReusedRegistersByPopping(jit, preservedState);
+ } else {
+ if (structure()->hasPolyProto())
+ jit.loadValue(CCallHelpers::Address(baseGPR, offsetRelativeToBase(knownPolyProtoOffset)), valueRegs);
+ else
+ jit.moveValue(structure()->storedPrototype(), valueRegs);
+ }
state.succeed();
return;
}
Modified: branches/safari-612-branch/Source/_javascript_Core/jit/Repatch.cpp (285314 => 285315)
--- branches/safari-612-branch/Source/_javascript_Core/jit/Repatch.cpp 2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/Source/_javascript_Core/jit/Repatch.cpp 2021-11-04 21:43:02 UTC (rev 285315)
@@ -404,7 +404,7 @@
RELEASE_ASSERT_NOT_REACHED();
newCase = ProxyableAccessCase::create(vm, codeBlock, type, propertyName, offset, structure, conditionSet, loadTargetFromProxy, slot.watchpointSet(), WTFMove(prototypeAccessChain));
- } else if (!loadTargetFromProxy && getter && IntrinsicGetterAccessCase::canEmitIntrinsicGetter(getter, structure))
+ } else if (!loadTargetFromProxy && getter && IntrinsicGetterAccessCase::canEmitIntrinsicGetter(stubInfo, getter, structure))
newCase = IntrinsicGetterAccessCase::create(vm, codeBlock, propertyName, slot.cachedOffset(), structure, conditionSet, getter, WTFMove(prototypeAccessChain));
else {
if (isPrivate) {