зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1675084: Ensure call node depends on guards r=jandem
Differential Revision: https://phabricator.services.mozilla.com/D95771
This commit is contained in:
Родитель
d13debb6cd
Коммит
b5623086d5
|
@ -86,10 +86,10 @@ class OperandId {
|
||||||
static const uint16_t InvalidId = UINT16_MAX;
|
static const uint16_t InvalidId = UINT16_MAX;
|
||||||
uint16_t id_;
|
uint16_t id_;
|
||||||
|
|
||||||
OperandId() : id_(InvalidId) {}
|
|
||||||
explicit OperandId(uint16_t id) : id_(id) {}
|
explicit OperandId(uint16_t id) : id_(id) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
OperandId() : id_(InvalidId) {}
|
||||||
uint16_t id() const { return id_; }
|
uint16_t id() const { return id_; }
|
||||||
bool valid() const { return id_ != InvalidId; }
|
bool valid() const { return id_ != InvalidId; }
|
||||||
};
|
};
|
||||||
|
@ -406,7 +406,8 @@ enum class ArgumentKind : uint8_t {
|
||||||
Arg0,
|
Arg0,
|
||||||
Arg1,
|
Arg1,
|
||||||
Arg2,
|
Arg2,
|
||||||
Arg3
|
Arg3,
|
||||||
|
NumKinds
|
||||||
};
|
};
|
||||||
|
|
||||||
// This function calculates the index of an argument based on the call flags.
|
// This function calculates the index of an argument based on the call flags.
|
||||||
|
|
|
@ -47,6 +47,19 @@ class MOZ_RAII WarpCacheIRTranspiler : public WarpBuilderShared {
|
||||||
|
|
||||||
CallInfo* callInfo_;
|
CallInfo* callInfo_;
|
||||||
|
|
||||||
|
// Array mapping call arguments to OperandId.
|
||||||
|
using ArgumentKindArray =
|
||||||
|
mozilla::EnumeratedArray<ArgumentKind, ArgumentKind::NumKinds, OperandId>;
|
||||||
|
ArgumentKindArray argumentOperandIds_;
|
||||||
|
|
||||||
|
void setArgumentId(ArgumentKind kind, OperandId id) {
|
||||||
|
MOZ_ASSERT(kind != ArgumentKind::Callee);
|
||||||
|
MOZ_ASSERT(!argumentOperandIds_[kind].valid());
|
||||||
|
argumentOperandIds_[kind] = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateArgumentsFromOperands();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// Used to assert that there is only one effectful instruction
|
// Used to assert that there is only one effectful instruction
|
||||||
// per stub. And that this instruction has a resume point.
|
// per stub. And that this instruction has a resume point.
|
||||||
|
@ -3430,6 +3443,46 @@ bool WarpCacheIRTranspiler::emitLoadWrapperTarget(ObjOperandId objId,
|
||||||
return defineOperand(resultId, ins);
|
return defineOperand(resultId, ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When we transpile a call, we may generate guards for some
|
||||||
|
// arguments. To make sure the call instruction depends on those
|
||||||
|
// guards, when the transpiler creates an operand for an argument, we
|
||||||
|
// register the OperandId of that argument in argumentIds_. (See
|
||||||
|
// emitLoadArgumentSlot.) Before generating the call, we update the
|
||||||
|
// CallInfo to use the appropriate value from operands_.
|
||||||
|
// Note: The callee is an explicit argument to the call op, and is
|
||||||
|
// tracked separately.
|
||||||
|
void WarpCacheIRTranspiler::updateArgumentsFromOperands() {
|
||||||
|
for (uint32_t i = 0; i < uint32_t(ArgumentKind::NumKinds); i++) {
|
||||||
|
ArgumentKind kind = ArgumentKind(i);
|
||||||
|
OperandId id = argumentOperandIds_[kind];
|
||||||
|
if (id.valid()) {
|
||||||
|
switch (kind) {
|
||||||
|
case ArgumentKind::This:
|
||||||
|
callInfo_->setThis(getOperand(id));
|
||||||
|
break;
|
||||||
|
case ArgumentKind::NewTarget:
|
||||||
|
callInfo_->setNewTarget(getOperand(id));
|
||||||
|
break;
|
||||||
|
case ArgumentKind::Arg0:
|
||||||
|
callInfo_->setArg(0, getOperand(id));
|
||||||
|
break;
|
||||||
|
case ArgumentKind::Arg1:
|
||||||
|
callInfo_->setArg(1, getOperand(id));
|
||||||
|
break;
|
||||||
|
case ArgumentKind::Arg2:
|
||||||
|
callInfo_->setArg(2, getOperand(id));
|
||||||
|
break;
|
||||||
|
case ArgumentKind::Arg3:
|
||||||
|
callInfo_->setArg(3, getOperand(id));
|
||||||
|
break;
|
||||||
|
case ArgumentKind::Callee:
|
||||||
|
case ArgumentKind::NumKinds:
|
||||||
|
MOZ_CRASH("Unexpected argument kind");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool WarpCacheIRTranspiler::emitLoadArgumentSlot(ValOperandId resultId,
|
bool WarpCacheIRTranspiler::emitLoadArgumentSlot(ValOperandId resultId,
|
||||||
uint32_t slotIndex) {
|
uint32_t slotIndex) {
|
||||||
// Reverse of GetIndexOfArgument.
|
// Reverse of GetIndexOfArgument.
|
||||||
|
@ -3442,6 +3495,7 @@ bool WarpCacheIRTranspiler::emitLoadArgumentSlot(ValOperandId resultId,
|
||||||
// NewTarget (optional)
|
// NewTarget (optional)
|
||||||
if (callInfo_->constructing()) {
|
if (callInfo_->constructing()) {
|
||||||
if (slotIndex == 0) {
|
if (slotIndex == 0) {
|
||||||
|
setArgumentId(ArgumentKind::NewTarget, resultId);
|
||||||
return defineOperand(resultId, callInfo_->getNewTarget());
|
return defineOperand(resultId, callInfo_->getNewTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3451,11 +3505,15 @@ bool WarpCacheIRTranspiler::emitLoadArgumentSlot(ValOperandId resultId,
|
||||||
// Args..
|
// Args..
|
||||||
if (slotIndex < callInfo_->argc()) {
|
if (slotIndex < callInfo_->argc()) {
|
||||||
uint32_t arg = callInfo_->argc() - 1 - slotIndex;
|
uint32_t arg = callInfo_->argc() - 1 - slotIndex;
|
||||||
|
ArgumentKind kind = ArgumentKind(uint32_t(ArgumentKind::Arg0) + arg);
|
||||||
|
MOZ_ASSERT(kind < ArgumentKind::NumKinds);
|
||||||
|
setArgumentId(kind, resultId);
|
||||||
return defineOperand(resultId, callInfo_->getArg(arg));
|
return defineOperand(resultId, callInfo_->getArg(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ThisValue
|
// ThisValue
|
||||||
if (slotIndex == callInfo_->argc()) {
|
if (slotIndex == callInfo_->argc()) {
|
||||||
|
setArgumentId(ArgumentKind::This, resultId);
|
||||||
return defineOperand(resultId, callInfo_->thisArg());
|
return defineOperand(resultId, callInfo_->thisArg());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3544,6 +3602,10 @@ bool WarpCacheIRTranspiler::updateCallInfo(MDefinition* callee,
|
||||||
// the resulting call instruction depends on these guards.
|
// the resulting call instruction depends on these guards.
|
||||||
callInfo_->setCallee(callee);
|
callInfo_->setCallee(callee);
|
||||||
|
|
||||||
|
// The transpilation may also add guards to other arguments.
|
||||||
|
// We replace those arguments in the CallInfo here.
|
||||||
|
updateArgumentsFromOperands();
|
||||||
|
|
||||||
switch (flags.getArgFormat()) {
|
switch (flags.getArgFormat()) {
|
||||||
case CallFlags::Standard:
|
case CallFlags::Standard:
|
||||||
MOZ_ASSERT(callInfo_->argFormat() == CallInfo::ArgFormat::Standard);
|
MOZ_ASSERT(callInfo_->argFormat() == CallInfo::ArgFormat::Standard);
|
||||||
|
@ -3552,7 +3614,7 @@ bool WarpCacheIRTranspiler::updateCallInfo(MDefinition* callee,
|
||||||
MOZ_ASSERT(callInfo_->argFormat() == CallInfo::ArgFormat::Array);
|
MOZ_ASSERT(callInfo_->argFormat() == CallInfo::ArgFormat::Array);
|
||||||
break;
|
break;
|
||||||
case CallFlags::FunCall:
|
case CallFlags::FunCall:
|
||||||
// Note: setCallee above already changed the callee to the target
|
// Note: We already changed the callee to the target
|
||||||
// function instead of the |call| function.
|
// function instead of the |call| function.
|
||||||
MOZ_ASSERT(!callInfo_->constructing());
|
MOZ_ASSERT(!callInfo_->constructing());
|
||||||
MOZ_ASSERT(callInfo_->argFormat() == CallInfo::ArgFormat::Standard);
|
MOZ_ASSERT(callInfo_->argFormat() == CallInfo::ArgFormat::Standard);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче