Skip to content

Commit f55e9e6

Browse files
committed
Bug 1703469: Use operand for callee in scripted setters r=jandem
Differential Revision: https://phabricator.services.mozilla.com/D251754
1 parent f4f5b7d commit f55e9e6

File tree

8 files changed

+77
-63
lines changed

8 files changed

+77
-63
lines changed

js/src/jit/BaselineCacheIRCompiler.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,10 +1649,9 @@ bool BaselineCacheIRCompiler::emitCallNativeSetter(
16491649
}
16501650

16511651
bool BaselineCacheIRCompiler::emitCallScriptedSetterShared(
1652-
ObjOperandId receiverId, uint32_t setterOffset, ValOperandId rhsId,
1652+
ObjOperandId receiverId, ObjOperandId calleeId, ValOperandId rhsId,
16531653
bool sameRealm, uint32_t nargsAndFlagsOffset,
16541654
Maybe<uint32_t> icScriptOffset) {
1655-
AutoScratchRegister callee(allocator, masm);
16561655
AutoScratchRegister scratch(allocator, masm);
16571656
#if defined(JS_CODEGEN_X86)
16581657
Register code = scratch;
@@ -1661,14 +1660,11 @@ bool BaselineCacheIRCompiler::emitCallScriptedSetterShared(
16611660
#endif
16621661

16631662
Register receiver = allocator.useRegister(masm, receiverId);
1664-
Address setterAddr(stubAddress(setterOffset));
1663+
Register callee = allocator.useRegister(masm, calleeId);
16651664
ValueOperand val = allocator.useValueRegister(masm, rhsId);
16661665

16671666
bool isInlined = icScriptOffset.isSome();
16681667

1669-
// First, load the callee.
1670-
masm.loadPtr(setterAddr, callee);
1671-
16721668
if (isInlined) {
16731669
// If we are calling a trial-inlined setter, guard that the
16741670
// target has a BaselineScript.
@@ -1750,20 +1746,20 @@ bool BaselineCacheIRCompiler::emitCallScriptedSetterShared(
17501746
}
17511747

17521748
bool BaselineCacheIRCompiler::emitCallScriptedSetter(
1753-
ObjOperandId receiverId, uint32_t setterOffset, ValOperandId rhsId,
1749+
ObjOperandId receiverId, ObjOperandId calleeId, ValOperandId rhsId,
17541750
bool sameRealm, uint32_t nargsAndFlagsOffset) {
17551751
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
17561752
Maybe<uint32_t> icScriptOffset = mozilla::Nothing();
1757-
return emitCallScriptedSetterShared(receiverId, setterOffset, rhsId,
1753+
return emitCallScriptedSetterShared(receiverId, calleeId, rhsId,
17581754
sameRealm, nargsAndFlagsOffset,
17591755
icScriptOffset);
17601756
}
17611757

17621758
bool BaselineCacheIRCompiler::emitCallInlinedSetter(
1763-
ObjOperandId receiverId, uint32_t setterOffset, ValOperandId rhsId,
1759+
ObjOperandId receiverId, ObjOperandId calleeId, ValOperandId rhsId,
17641760
uint32_t icScriptOffset, bool sameRealm, uint32_t nargsAndFlagsOffset) {
17651761
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
1766-
return emitCallScriptedSetterShared(receiverId, setterOffset, rhsId,
1762+
return emitCallScriptedSetterShared(receiverId, calleeId, rhsId,
17671763
sameRealm, nargsAndFlagsOffset,
17681764
mozilla::Some(icScriptOffset));
17691765
}

js/src/jit/BaselineCacheIRCompiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class MOZ_RAII BaselineCacheIRCompiler : public CacheIRCompiler {
122122
uint32_t nargsAndFlagsOffset,
123123
mozilla::Maybe<uint32_t> icScriptOffset);
124124
bool emitCallScriptedSetterShared(ObjOperandId receiverId,
125-
uint32_t setterOffset, ValOperandId rhsId,
125+
ObjOperandId calleeId, ValOperandId rhsId,
126126
bool sameRealm,
127127
uint32_t nargsAndFlagsOffset,
128128
mozilla::Maybe<uint32_t> icScriptOffset);

js/src/jit/CacheIROps.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,7 +1921,7 @@
19211921
custom_writer: true
19221922
args:
19231923
receiver: ObjId
1924-
setter: ObjectField
1924+
callee: ObjId
19251925
rhs: ValId
19261926
sameRealm: BoolImm
19271927
nargsAndFlags: RawInt32Field
@@ -1933,7 +1933,7 @@
19331933
custom_writer: true
19341934
args:
19351935
receiver: ObjId
1936-
setter: ObjectField
1936+
callee: ObjId
19371937
rhs: ValId
19381938
icScript: RawPointerField
19391939
sameRealm: BoolImm

js/src/jit/CacheIRWriter.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -654,15 +654,17 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter {
654654
ValOperandId rhs, bool sameRealm) {
655655
MOZ_ASSERT(setter->hasJitEntry());
656656
uint32_t nargsAndFlags = setter->flagsAndArgCountRaw();
657-
callScriptedSetter_(receiver, setter, rhs, sameRealm, nargsAndFlags);
657+
ObjOperandId callee = getterSetterCalleeOperand(setter);
658+
callScriptedSetter_(receiver, callee, rhs, sameRealm, nargsAndFlags);
658659
trialInliningState_ = TrialInliningState::Candidate;
659660
}
660661

661-
void callInlinedSetter(ObjOperandId receiver, JSFunction* setter,
662-
ValOperandId rhs, ICScript* icScript, bool sameRealm) {
662+
void callInlinedSetter(ObjOperandId receiver, ObjOperandId callee,
663+
JSFunction* setter, ValOperandId rhs,
664+
ICScript* icScript, bool sameRealm) {
663665
MOZ_ASSERT(setter->hasJitEntry());
664666
uint32_t nargsAndFlags = setter->flagsAndArgCountRaw();
665-
callInlinedSetter_(receiver, setter, rhs, icScript, sameRealm,
667+
callInlinedSetter_(receiver, callee, rhs, icScript, sameRealm,
666668
nargsAndFlags);
667669
trialInliningState_ = TrialInliningState::Inlined;
668670
}

js/src/jit/IonCacheIRCompiler.cpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,18 +1672,19 @@ bool IonCacheIRCompiler::emitCallNativeSetter(ObjOperandId receiverId,
16721672
}
16731673

16741674
bool IonCacheIRCompiler::emitCallScriptedSetter(ObjOperandId receiverId,
1675-
uint32_t setterOffset,
1675+
ObjOperandId calleeId,
16761676
ValOperandId rhsId,
16771677
bool sameRealm,
16781678
uint32_t nargsAndFlagsOffset) {
16791679
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
16801680
AutoSaveLiveRegisters save(*this);
16811681

16821682
Register receiver = allocator.useRegister(masm, receiverId);
1683-
JSFunction* target = &objectStubField(setterOffset)->as<JSFunction>();
1683+
Register callee = allocator.useRegister(masm, calleeId);
16841684
ConstantOrRegister val = allocator.useConstantOrRegister(masm, rhsId);
16851685

1686-
MOZ_ASSERT(sameRealm == (cx_->realm() == target->realm()));
1686+
int32_t nargsAndFlags = int32StubField(nargsAndFlagsOffset);
1687+
size_t nargs = nargsAndFlags >> JSFunction::ArgCountShift;
16871688

16881689
AutoScratchRegister scratch(allocator, masm);
16891690

@@ -1696,36 +1697,33 @@ bool IonCacheIRCompiler::emitCallScriptedSetter(ObjOperandId receiverId,
16961697
// The JitFrameLayout pushed below will be aligned to JitStackAlignment,
16971698
// so we just have to make sure the stack is aligned after we push the
16981699
// |this| + argument Values.
1699-
size_t numArgs = std::max<size_t>(1, target->nargs());
1700-
uint32_t argSize = (numArgs + 1) * sizeof(Value);
1700+
size_t numPushedArgs = std::max<size_t>(1, nargs);
1701+
uint32_t argSize = (numPushedArgs + 1) * sizeof(Value);
17011702
uint32_t padding =
17021703
ComputeByteAlignment(masm.framePushed() + argSize, JitStackAlignment);
17031704
MOZ_ASSERT(padding % sizeof(uintptr_t) == 0);
17041705
MOZ_ASSERT(padding < JitStackAlignment);
17051706
masm.reserveStack(padding);
17061707

1707-
for (size_t i = 1; i < target->nargs(); i++) {
1708+
for (size_t i = 1; i < nargs; i++) {
17081709
masm.Push(UndefinedValue());
17091710
}
17101711
masm.Push(val);
17111712
masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(receiver)));
17121713

17131714
if (!sameRealm) {
1714-
masm.switchToRealm(target->realm(), scratch);
1715+
masm.switchToObjectRealm(callee, scratch);
17151716
}
17161717

1717-
masm.movePtr(ImmGCPtr(target), scratch);
1718-
1719-
masm.Push(scratch);
1718+
masm.Push(callee);
17201719
masm.PushFrameDescriptorForJitCall(FrameType::IonICCall, /* argc = */ 1);
17211720

17221721
// Check stack alignment. Add 2 * sizeof(uintptr_t) for the return address and
17231722
// frame pointer pushed by the call/callee.
17241723
MOZ_ASSERT(
17251724
((masm.framePushed() + 2 * sizeof(uintptr_t)) % JitStackAlignment) == 0);
17261725

1727-
MOZ_ASSERT(target->hasJitEntry());
1728-
masm.loadJitCodeRaw(scratch, scratch);
1726+
masm.loadJitCodeRaw(callee, scratch);
17291727
masm.callJit(scratch);
17301728

17311729
if (!sameRealm) {
@@ -1739,7 +1737,7 @@ bool IonCacheIRCompiler::emitCallScriptedSetter(ObjOperandId receiverId,
17391737
}
17401738

17411739
bool IonCacheIRCompiler::emitCallInlinedSetter(
1742-
ObjOperandId receiverId, uint32_t setterOffset, ValOperandId rhsId,
1740+
ObjOperandId receiverId, ObjOperandId calleeId, ValOperandId rhsId,
17431741
uint32_t icScriptOffset, bool sameRealm, uint32_t nargsAndFlagsOffset) {
17441742
MOZ_CRASH("Trial inlining not supported in Ion");
17451743
}

js/src/jit/TrialInlining.cpp

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,9 @@ Maybe<InlinableSetterData> FindInlinableSetterData(ICCacheIRStub* stub) {
383383
const CacheIRStubInfo* stubInfo = stub->stubInfo();
384384
const uint8_t* stubData = stub->stubDataStart();
385385

386+
ObjOperandId maybeCalleeOperand;
387+
uintptr_t maybeRawCallee = 0;
388+
386389
CacheIRReader reader(stubInfo);
387390
while (reader.more()) {
388391
const uint8_t* opStart = reader.currentPosition();
@@ -393,40 +396,51 @@ Maybe<InlinableSetterData> FindInlinableSetterData(ICCacheIRStub* stub) {
393396
mozilla::DebugOnly<const uint8_t*> argStart = reader.currentPosition();
394397

395398
switch (op) {
399+
case CacheOp::LoadObject: {
400+
// If we load a constant object, remember it in case it's the callee.
401+
maybeCalleeOperand = reader.objOperandId();
402+
uint32_t maybeCalleeOffset = reader.stubOffset();
403+
maybeRawCallee = stubInfo->getStubRawWord(stubData, maybeCalleeOffset);
404+
break;
405+
}
396406
case CacheOp::CallScriptedSetter: {
397-
data.emplace();
398-
data->receiverOperand = reader.objOperandId();
399-
400-
uint32_t setterOffset = reader.stubOffset();
401-
uintptr_t rawTarget = stubInfo->getStubRawWord(stubData, setterOffset);
402-
data->target = reinterpret_cast<JSFunction*>(rawTarget);
403-
404-
data->rhsOperand = reader.valOperandId();
405-
data->sameRealm = reader.readBool();
407+
ObjOperandId receiverOperand = reader.objOperandId();
408+
ObjOperandId calleeOperand = reader.objOperandId();
409+
ValOperandId rhsOperand = reader.valOperandId();
410+
bool sameRealm = reader.readBool();
406411
(void)reader.stubOffset(); // nargsAndFlags
407412

408-
data->endOfSharedPrefix = opStart;
413+
if (maybeCalleeOperand == calleeOperand) {
414+
data.emplace();
415+
data->target = reinterpret_cast<JSFunction*>(maybeRawCallee);
416+
data->receiverOperand = receiverOperand;
417+
data->calleeOperand = calleeOperand;
418+
data->rhsOperand = rhsOperand;
419+
data->sameRealm = sameRealm;
420+
data->endOfSharedPrefix = opStart;
421+
}
409422
break;
410423
}
411424
case CacheOp::CallInlinedSetter: {
412-
data.emplace();
413-
data->receiverOperand = reader.objOperandId();
414-
415-
uint32_t setterOffset = reader.stubOffset();
416-
uintptr_t rawTarget = stubInfo->getStubRawWord(stubData, setterOffset);
417-
data->target = reinterpret_cast<JSFunction*>(rawTarget);
418-
419-
data->rhsOperand = reader.valOperandId();
420-
425+
ObjOperandId receiverOperand = reader.objOperandId();
426+
ObjOperandId calleeOperand = reader.objOperandId();
427+
ValOperandId rhsOperand = reader.valOperandId();
421428
uint32_t icScriptOffset = reader.stubOffset();
422429
uintptr_t rawICScript =
423430
stubInfo->getStubRawWord(stubData, icScriptOffset);
424-
data->icScript = reinterpret_cast<ICScript*>(rawICScript);
425-
426-
data->sameRealm = reader.readBool();
431+
bool sameRealm = reader.readBool();
427432
(void)reader.stubOffset(); // nargsAndFlags
428433

429-
data->endOfSharedPrefix = opStart;
434+
if (maybeCalleeOperand == calleeOperand) {
435+
data.emplace();
436+
data->target = reinterpret_cast<JSFunction*>(maybeRawCallee);
437+
data->receiverOperand = receiverOperand;
438+
data->calleeOperand = calleeOperand;
439+
data->rhsOperand = rhsOperand;
440+
data->icScript = reinterpret_cast<ICScript*>(rawICScript);
441+
data->sameRealm = sameRealm;
442+
data->endOfSharedPrefix = opStart;
443+
}
430444
break;
431445
}
432446
default:
@@ -886,8 +900,9 @@ bool TrialInliner::maybeInlineSetter(ICEntry& entry, ICFallbackStub* fallback,
886900
ValOperandId rhsValId(writer.setInputOperandId(1));
887901
cloneSharedPrefix(stub, data->endOfSharedPrefix, writer);
888902

889-
writer.callInlinedSetter(data->receiverOperand, data->target,
890-
data->rhsOperand, newICScript, data->sameRealm);
903+
writer.callInlinedSetter(data->receiverOperand, data->calleeOperand,
904+
data->target, data->rhsOperand, newICScript,
905+
data->sameRealm);
891906
writer.returnFromIC();
892907

893908
return replaceICStub(entry, fallback, writer, kind);

js/src/jit/TrialInlining.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ class InlinableGetterData : public InlinableOpData {
133133
class InlinableSetterData : public InlinableOpData {
134134
public:
135135
ObjOperandId receiverOperand;
136+
ObjOperandId calleeOperand;
136137
ValOperandId rhsOperand;
137138
bool sameRealm = false;
138139
};

js/src/jit/WarpCacheIRTranspiler.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ class MOZ_RAII WarpCacheIRTranspiler : public WarpBuilderShared {
305305
MDefinition* getter, bool sameRealm,
306306
uint32_t nargsAndFlagsOffset);
307307
[[nodiscard]] bool emitCallSetter(CallKind kind, ObjOperandId receiverId,
308-
uint32_t setterOffset, ValOperandId rhsId,
308+
MDefinition* setter, ValOperandId rhsId,
309309
bool sameRealm,
310310
uint32_t nargsAndFlagsOffset);
311311

@@ -6688,11 +6688,10 @@ bool WarpCacheIRTranspiler::emitCallNativeGetterResult(
66886688

66896689
bool WarpCacheIRTranspiler::emitCallSetter(CallKind kind,
66906690
ObjOperandId receiverId,
6691-
uint32_t setterOffset,
6691+
MDefinition* setter,
66926692
ValOperandId rhsId, bool sameRealm,
66936693
uint32_t nargsAndFlagsOffset) {
66946694
MDefinition* receiver = getOperand(receiverId);
6695-
MDefinition* setter = objectStubField(setterOffset);
66966695
MDefinition* rhs = getOperand(rhsId);
66976696
if (kind == CallKind::Scripted && callInfo_ && callInfo_->isInlined()) {
66986697
// We are transpiling to generate the correct guards. We also update the
@@ -6733,16 +6732,18 @@ bool WarpCacheIRTranspiler::emitCallSetter(CallKind kind,
67336732
}
67346733

67356734
bool WarpCacheIRTranspiler::emitCallScriptedSetter(
6736-
ObjOperandId receiverId, uint32_t setterOffset, ValOperandId rhsId,
6735+
ObjOperandId receiverId, ObjOperandId calleeId, ValOperandId rhsId,
67376736
bool sameRealm, uint32_t nargsAndFlagsOffset) {
6738-
return emitCallSetter(CallKind::Scripted, receiverId, setterOffset, rhsId,
6737+
MDefinition* setter = getOperand(calleeId);
6738+
return emitCallSetter(CallKind::Scripted, receiverId, setter, rhsId,
67396739
sameRealm, nargsAndFlagsOffset);
67406740
}
67416741

67426742
bool WarpCacheIRTranspiler::emitCallInlinedSetter(
6743-
ObjOperandId receiverId, uint32_t setterOffset, ValOperandId rhsId,
6743+
ObjOperandId receiverId, ObjOperandId calleeId, ValOperandId rhsId,
67446744
uint32_t icScriptOffset, bool sameRealm, uint32_t nargsAndFlagsOffset) {
6745-
return emitCallSetter(CallKind::Scripted, receiverId, setterOffset, rhsId,
6745+
MDefinition* setter = getOperand(calleeId);
6746+
return emitCallSetter(CallKind::Scripted, receiverId, setter, rhsId,
67466747
sameRealm, nargsAndFlagsOffset);
67476748
}
67486749

@@ -6751,7 +6752,8 @@ bool WarpCacheIRTranspiler::emitCallNativeSetter(ObjOperandId receiverId,
67516752
ValOperandId rhsId,
67526753
bool sameRealm,
67536754
uint32_t nargsAndFlagsOffset) {
6754-
return emitCallSetter(CallKind::Native, receiverId, setterOffset, rhsId,
6755+
MDefinition* setter = objectStubField(setterOffset);
6756+
return emitCallSetter(CallKind::Native, receiverId, setter, rhsId,
67556757
sameRealm, nargsAndFlagsOffset);
67566758
}
67576759

0 commit comments

Comments
 (0)