Bug 1530937 part 16 - Convert tailCallVMs. r=tcampbell

Tail calls have their own list/array/enum to improve type safety.

Differential Revision: https://phabricator.services.mozilla.com/D23112

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan de Mooij 2019-03-12 14:06:22 +00:00
Родитель 38175a1f96
Коммит c89f4b00ab
8 изменённых файлов: 366 добавлений и 279 удалений

Просмотреть файл

@ -40,7 +40,6 @@ class MOZ_RAII BaselineCacheIRCompiler : public CacheIRCompiler {
BaselineCacheIRStubKind kind_;
void callVMInternal(MacroAssembler& masm, VMFunctionId id);
void tailCallVM(MacroAssembler& masm, const VMFunction& fun);
template <typename Fn, Fn fn>
void callVM(MacroAssembler& masm) {
@ -48,6 +47,14 @@ class MOZ_RAII BaselineCacheIRCompiler : public CacheIRCompiler {
callVMInternal(masm, id);
}
void tailCallVMInternal(MacroAssembler& masm, TailCallVMFunctionId id);
template <typename Fn, Fn fn>
void tailCallVM(MacroAssembler& masm) {
TailCallVMFunctionId id = TailCallVMFunctionToId<Fn, fn>::id;
tailCallVMInternal(masm, id);
}
MOZ_MUST_USE bool callTypeUpdateIC(Register obj, ValueOperand val,
Register scratch,
LiveGeneralRegisterSet saveRegs);
@ -158,11 +165,12 @@ void BaselineCacheIRCompiler::callVMInternal(MacroAssembler& masm,
EmitBaselineCallVM(code, masm);
}
void BaselineCacheIRCompiler::tailCallVM(MacroAssembler& masm,
const VMFunction& fun) {
void BaselineCacheIRCompiler::tailCallVMInternal(MacroAssembler& masm,
TailCallVMFunctionId id) {
MOZ_ASSERT(!inStubFrame_);
TrampolinePtr code = cx_->runtime()->jitRuntime()->getVMWrapper(fun);
TrampolinePtr code = cx_->runtime()->jitRuntime()->getVMWrapper(id);
const VMFunctionData& fun = GetVMFunction(id);
MOZ_ASSERT(fun.expectTailCall == TailCall);
size_t argSize = fun.explicitStackSlots() * sizeof(void*);
@ -2414,7 +2422,8 @@ bool BaselineCacheIRCompiler::emitCallStringObjectConcatResult() {
masm.pushValue(rhs);
masm.pushValue(lhs);
tailCallVM(masm, DoConcatStringObjectInfo);
using Fn = bool (*)(JSContext*, HandleValue, HandleValue, MutableHandleValue);
tailCallVM<Fn, DoConcatStringObject>(masm);
return true;
}

Просмотреть файл

@ -5302,13 +5302,6 @@ bool BaselineCodeGen<Handler>::emit_JSOP_FINALYIELDRVAL() {
return emitReturn();
}
typedef bool (*GeneratorThrowFn)(JSContext*, BaselineFrame*,
Handle<AbstractGeneratorObject*>, HandleValue,
uint32_t);
static const VMFunction GeneratorThrowOrReturnInfo =
FunctionInfo<GeneratorThrowFn>(jit::GeneratorThrowOrReturn,
"GeneratorThrowOrReturn", TailCall);
template <>
bool BaselineCompilerCodeGen::emit_JSOP_RESUME() {
auto resumeKind = AbstractGeneratorObject::getResumeKind(handler.pc());
@ -5518,8 +5511,13 @@ bool BaselineCompilerCodeGen::emit_JSOP_RESUME() {
pushArg(genObj);
pushArg(scratch2);
const VMFunction& fun = GeneratorThrowOrReturnInfo;
TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(fun);
using Fn =
bool (*)(JSContext*, BaselineFrame*, Handle<AbstractGeneratorObject*>,
HandleValue, uint32_t);
TailCallVMFunctionId id =
TailCallVMFunctionToId<Fn, jit::GeneratorThrowOrReturn>::id;
TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(id);
const VMFunctionData& fun = GetVMFunction(id);
// Create and push the frame descriptor.
masm.subStackPtrFrom(scratch1);

Просмотреть файл

@ -1100,8 +1100,10 @@ JitCode* ICStubCompiler::getStubCode() {
return newStubCode;
}
bool ICStubCompiler::tailCallVM(const VMFunction& fun, MacroAssembler& masm) {
TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(fun);
bool ICStubCompiler::tailCallVMInternal(MacroAssembler& masm,
TailCallVMFunctionId id) {
TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(id);
const VMFunctionData& fun = GetVMFunction(id);
MOZ_ASSERT(fun.expectTailCall == TailCall);
uint32_t argSize = fun.explicitStackSlots() * sizeof(void*);
EmitBaselineTailCallVM(code, masm, argSize);
@ -1124,6 +1126,12 @@ bool ICStubCompiler::callVM(MacroAssembler& masm) {
return callVMInternal(masm, id);
}
template <typename Fn, Fn fn>
bool ICStubCompiler::tailCallVM(MacroAssembler& masm) {
TailCallVMFunctionId id = TailCallVMFunctionToId<Fn, fn>::id;
return tailCallVMInternal(masm, id);
}
void ICStubCompiler::enterStubFrame(MacroAssembler& masm, Register scratch) {
EmitBaselineEnterStubFrame(masm, scratch);
#ifdef DEBUG
@ -1366,9 +1374,9 @@ bool ICTypeMonitor_Fallback::addMonitorStubForValue(JSContext* cx,
return true;
}
static bool DoTypeMonitorFallback(JSContext* cx, BaselineFrame* frame,
ICTypeMonitor_Fallback* stub,
HandleValue value, MutableHandleValue res) {
bool DoTypeMonitorFallback(JSContext* cx, BaselineFrame* frame,
ICTypeMonitor_Fallback* stub, HandleValue value,
MutableHandleValue res) {
JSScript* script = frame->script();
jsbytecode* pc = stub->icEntry()->pc(script);
TypeFallbackICSpew(cx, stub, "TypeMonitor");
@ -1420,13 +1428,6 @@ static bool DoTypeMonitorFallback(JSContext* cx, BaselineFrame* frame,
return stub->addMonitorStubForValue(cx, frame, types, value);
}
typedef bool (*DoTypeMonitorFallbackFn)(JSContext*, BaselineFrame*,
ICTypeMonitor_Fallback*, HandleValue,
MutableHandleValue);
static const VMFunction DoTypeMonitorFallbackInfo =
FunctionInfo<DoTypeMonitorFallbackFn>(DoTypeMonitorFallback,
"DoTypeMonitorFallback", TailCall);
bool ICTypeMonitor_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
MOZ_ASSERT(R0 == JSReturnOperand);
@ -1437,7 +1438,9 @@ bool ICTypeMonitor_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
masm.pushBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
return tailCallVM(DoTypeMonitorFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICTypeMonitor_Fallback*,
HandleValue, MutableHandleValue);
return tailCallVM<Fn, DoTypeMonitorFallback>(masm);
}
bool ICTypeMonitor_PrimitiveSet::Compiler::generateStubCode(
@ -1886,9 +1889,9 @@ bool ICTypeUpdate_AnyValue::Compiler::generateStubCode(MacroAssembler& masm) {
// ToBool_Fallback
//
static bool DoToBoolFallback(JSContext* cx, BaselineFrame* frame,
ICToBool_Fallback* stub, HandleValue arg,
MutableHandleValue ret) {
bool DoToBoolFallback(JSContext* cx, BaselineFrame* frame,
ICToBool_Fallback* stub, HandleValue arg,
MutableHandleValue ret) {
stub->incrementEnteredCount();
FallbackICSpew(cx, stub, "ToBool");
@ -1903,11 +1906,6 @@ static bool DoToBoolFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*pf)(JSContext*, BaselineFrame*, ICToBool_Fallback*, HandleValue,
MutableHandleValue);
static const VMFunction fun =
FunctionInfo<pf>(DoToBoolFallback, "DoToBoolFallback", TailCall);
bool ICToBool_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
MOZ_ASSERT(R0 == JSReturnOperand);
@ -1919,7 +1917,9 @@ bool ICToBool_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(fun, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICToBool_Fallback*,
HandleValue, MutableHandleValue);
return tailCallVM<Fn, DoToBoolFallback>(masm);
}
static void StripPreliminaryObjectStubs(JSContext* cx, ICFallbackStub* stub) {
@ -1950,9 +1950,9 @@ static void StripPreliminaryObjectStubs(JSContext* cx, ICFallbackStub* stub) {
// GetElem_Fallback
//
static bool DoGetElemFallback(JSContext* cx, BaselineFrame* frame,
ICGetElem_Fallback* stub, HandleValue lhs,
HandleValue rhs, MutableHandleValue res) {
bool DoGetElemFallback(JSContext* cx, BaselineFrame* frame,
ICGetElem_Fallback* stub, HandleValue lhs,
HandleValue rhs, MutableHandleValue res) {
stub->incrementEnteredCount();
RootedScript script(cx, frame->script());
@ -2042,10 +2042,10 @@ static bool DoGetElemFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
static bool DoGetElemSuperFallback(JSContext* cx, BaselineFrame* frame,
ICGetElem_Fallback* stub, HandleValue lhs,
HandleValue rhs, HandleValue receiver,
MutableHandleValue res) {
bool DoGetElemSuperFallback(JSContext* cx, BaselineFrame* frame,
ICGetElem_Fallback* stub, HandleValue lhs,
HandleValue rhs, HandleValue receiver,
MutableHandleValue res) {
stub->incrementEnteredCount();
RootedScript script(cx, frame->script());
@ -2120,22 +2120,6 @@ static bool DoGetElemSuperFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoGetElemFallbackFn)(JSContext*, BaselineFrame*,
ICGetElem_Fallback*, HandleValue,
HandleValue, MutableHandleValue);
static const VMFunction DoGetElemFallbackInfo =
FunctionInfo<DoGetElemFallbackFn>(DoGetElemFallback, "DoGetElemFallback",
TailCall, PopValues(2));
typedef bool (*DoGetElemSuperFallbackFn)(JSContext*, BaselineFrame*,
ICGetElem_Fallback*, HandleValue,
HandleValue, HandleValue,
MutableHandleValue);
static const VMFunction DoGetElemSuperFallbackInfo =
FunctionInfo<DoGetElemSuperFallbackFn>(DoGetElemSuperFallback,
"DoGetElemSuperFallback", TailCall,
PopValues(3));
bool ICGetElem_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
MOZ_ASSERT(R0 == JSReturnOperand);
@ -2159,7 +2143,10 @@ bool ICGetElem_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
masm.pushBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
if (!tailCallVM(DoGetElemSuperFallbackInfo, masm)) {
using Fn =
bool (*)(JSContext*, BaselineFrame*, ICGetElem_Fallback*, HandleValue,
HandleValue, HandleValue, MutableHandleValue);
if (!tailCallVM<Fn, DoGetElemSuperFallback>(masm)) {
return false;
}
} else {
@ -2173,7 +2160,9 @@ bool ICGetElem_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
masm.pushBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
if (!tailCallVM(DoGetElemFallbackInfo, masm)) {
using Fn = bool (*)(JSContext*, BaselineFrame*, ICGetElem_Fallback*,
HandleValue, HandleValue, MutableHandleValue);
if (!tailCallVM<Fn, DoGetElemFallback>(masm)) {
return false;
}
}
@ -2216,10 +2205,9 @@ static void SetUpdateStubData(ICCacheIR_Updated* stub,
}
}
static bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame,
ICSetElem_Fallback* stub, Value* stack,
HandleValue objv, HandleValue index,
HandleValue rhs) {
bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame,
ICSetElem_Fallback* stub, Value* stack, HandleValue objv,
HandleValue index, HandleValue rhs) {
stub->incrementEnteredCount();
RootedScript script(cx, frame->script());
@ -2360,13 +2348,6 @@ static bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoSetElemFallbackFn)(JSContext*, BaselineFrame*,
ICSetElem_Fallback*, Value*, HandleValue,
HandleValue, HandleValue);
static const VMFunction DoSetElemFallbackInfo =
FunctionInfo<DoSetElemFallbackFn>(DoSetElemFallback, "DoSetElemFallback",
TailCall, PopValues(2));
bool ICSetElem_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
MOZ_ASSERT(R0 == JSReturnOperand);
@ -2399,7 +2380,9 @@ bool ICSetElem_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoSetElemFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICSetElem_Fallback*, Value*,
HandleValue, HandleValue, HandleValue);
return tailCallVM<Fn, DoSetElemFallback>(masm);
}
void ICScript::noteHasDenseAdd(uint32_t pcOffset) {
@ -2499,9 +2482,9 @@ template void StoreToTypedArray(JSContext* cx, MacroAssembler& masm,
// In_Fallback
//
static bool DoInFallback(JSContext* cx, BaselineFrame* frame,
ICIn_Fallback* stub, HandleValue key,
HandleValue objValue, MutableHandleValue res) {
bool DoInFallback(JSContext* cx, BaselineFrame* frame, ICIn_Fallback* stub,
HandleValue key, HandleValue objValue,
MutableHandleValue res) {
stub->incrementEnteredCount();
FallbackICSpew(cx, stub, "In");
@ -2525,11 +2508,6 @@ static bool DoInFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoInFallbackFn)(JSContext*, BaselineFrame*, ICIn_Fallback*,
HandleValue, HandleValue, MutableHandleValue);
static const VMFunction DoInFallbackInfo = FunctionInfo<DoInFallbackFn>(
DoInFallback, "DoInFallback", TailCall, PopValues(2));
bool ICIn_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
EmitRestoreTailCallReg(masm);
@ -2543,16 +2521,18 @@ bool ICIn_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoInFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICIn_Fallback*, HandleValue,
HandleValue, MutableHandleValue);
return tailCallVM<Fn, DoInFallback>(masm);
}
//
// HasOwn_Fallback
//
static bool DoHasOwnFallback(JSContext* cx, BaselineFrame* frame,
ICHasOwn_Fallback* stub, HandleValue keyValue,
HandleValue objValue, MutableHandleValue res) {
bool DoHasOwnFallback(JSContext* cx, BaselineFrame* frame,
ICHasOwn_Fallback* stub, HandleValue keyValue,
HandleValue objValue, MutableHandleValue res) {
stub->incrementEnteredCount();
FallbackICSpew(cx, stub, "HasOwn");
@ -2570,12 +2550,6 @@ static bool DoHasOwnFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoHasOwnFallbackFn)(JSContext*, BaselineFrame*,
ICHasOwn_Fallback*, HandleValue, HandleValue,
MutableHandleValue);
static const VMFunction DoHasOwnFallbackInfo = FunctionInfo<DoHasOwnFallbackFn>(
DoHasOwnFallback, "DoHasOwnFallback", TailCall, PopValues(2));
bool ICHasOwn_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
EmitRestoreTailCallReg(masm);
@ -2589,16 +2563,18 @@ bool ICHasOwn_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoHasOwnFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICHasOwn_Fallback*,
HandleValue, HandleValue, MutableHandleValue);
return tailCallVM<Fn, DoHasOwnFallback>(masm);
}
//
// GetName_Fallback
//
static bool DoGetNameFallback(JSContext* cx, BaselineFrame* frame,
ICGetName_Fallback* stub, HandleObject envChain,
MutableHandleValue res) {
bool DoGetNameFallback(JSContext* cx, BaselineFrame* frame,
ICGetName_Fallback* stub, HandleObject envChain,
MutableHandleValue res) {
stub->incrementEnteredCount();
RootedScript script(cx, frame->script());
@ -2637,13 +2613,6 @@ static bool DoGetNameFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoGetNameFallbackFn)(JSContext*, BaselineFrame*,
ICGetName_Fallback*, HandleObject,
MutableHandleValue);
static const VMFunction DoGetNameFallbackInfo =
FunctionInfo<DoGetNameFallbackFn>(DoGetNameFallback, "DoGetNameFallback",
TailCall);
bool ICGetName_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
MOZ_ASSERT(R0 == JSReturnOperand);
@ -2653,16 +2622,18 @@ bool ICGetName_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoGetNameFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICGetName_Fallback*,
HandleObject, MutableHandleValue);
return tailCallVM<Fn, DoGetNameFallback>(masm);
}
//
// BindName_Fallback
//
static bool DoBindNameFallback(JSContext* cx, BaselineFrame* frame,
ICBindName_Fallback* stub, HandleObject envChain,
MutableHandleValue res) {
bool DoBindNameFallback(JSContext* cx, BaselineFrame* frame,
ICBindName_Fallback* stub, HandleObject envChain,
MutableHandleValue res) {
stub->incrementEnteredCount();
jsbytecode* pc = stub->icEntry()->pc(frame->script());
@ -2686,13 +2657,6 @@ static bool DoBindNameFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoBindNameFallbackFn)(JSContext*, BaselineFrame*,
ICBindName_Fallback*, HandleObject,
MutableHandleValue);
static const VMFunction DoBindNameFallbackInfo =
FunctionInfo<DoBindNameFallbackFn>(DoBindNameFallback, "DoBindNameFallback",
TailCall);
bool ICBindName_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
MOZ_ASSERT(R0 == JSReturnOperand);
@ -2702,16 +2666,18 @@ bool ICBindName_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoBindNameFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICBindName_Fallback*,
HandleObject, MutableHandleValue);
return tailCallVM<Fn, DoBindNameFallback>(masm);
}
//
// GetIntrinsic_Fallback
//
static bool DoGetIntrinsicFallback(JSContext* cx, BaselineFrame* frame,
ICGetIntrinsic_Fallback* stub,
MutableHandleValue res) {
bool DoGetIntrinsicFallback(JSContext* cx, BaselineFrame* frame,
ICGetIntrinsic_Fallback* stub,
MutableHandleValue res) {
stub->incrementEnteredCount();
RootedScript script(cx, frame->script());
@ -2737,20 +2703,15 @@ static bool DoGetIntrinsicFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoGetIntrinsicFallbackFn)(JSContext*, BaselineFrame*,
ICGetIntrinsic_Fallback*,
MutableHandleValue);
static const VMFunction DoGetIntrinsicFallbackInfo =
FunctionInfo<DoGetIntrinsicFallbackFn>(DoGetIntrinsicFallback,
"DoGetIntrinsicFallback", TailCall);
bool ICGetIntrinsic_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
EmitRestoreTailCallReg(masm);
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoGetIntrinsicFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICGetIntrinsic_Fallback*,
MutableHandleValue);
return tailCallVM<Fn, DoGetIntrinsicFallback>(masm);
}
//
@ -2790,9 +2751,9 @@ static bool ComputeGetPropResult(JSContext* cx, BaselineFrame* frame, JSOp op,
return true;
}
static bool DoGetPropFallback(JSContext* cx, BaselineFrame* frame,
ICGetProp_Fallback* stub, MutableHandleValue val,
MutableHandleValue res) {
bool DoGetPropFallback(JSContext* cx, BaselineFrame* frame,
ICGetProp_Fallback* stub, MutableHandleValue val,
MutableHandleValue res) {
stub->incrementEnteredCount();
RootedScript script(cx, frame->script());
@ -2853,10 +2814,9 @@ static bool DoGetPropFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
static bool DoGetPropSuperFallback(JSContext* cx, BaselineFrame* frame,
ICGetProp_Fallback* stub,
HandleValue receiver, MutableHandleValue val,
MutableHandleValue res) {
bool DoGetPropSuperFallback(JSContext* cx, BaselineFrame* frame,
ICGetProp_Fallback* stub, HandleValue receiver,
MutableHandleValue val, MutableHandleValue res) {
stub->incrementEnteredCount();
RootedScript script(cx, frame->script());
@ -2918,21 +2878,6 @@ static bool DoGetPropSuperFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoGetPropFallbackFn)(JSContext*, BaselineFrame*,
ICGetProp_Fallback*, MutableHandleValue,
MutableHandleValue);
static const VMFunction DoGetPropFallbackInfo =
FunctionInfo<DoGetPropFallbackFn>(DoGetPropFallback, "DoGetPropFallback",
TailCall, PopValues(1));
typedef bool (*DoGetPropSuperFallbackFn)(JSContext*, BaselineFrame*,
ICGetProp_Fallback*, HandleValue,
MutableHandleValue,
MutableHandleValue);
static const VMFunction DoGetPropSuperFallbackInfo =
FunctionInfo<DoGetPropSuperFallbackFn>(DoGetPropSuperFallback,
"DoGetPropSuperFallback", TailCall);
bool ICGetProp_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
MOZ_ASSERT(R0 == JSReturnOperand);
@ -2946,7 +2891,9 @@ bool ICGetProp_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
masm.pushBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
if (!tailCallVM(DoGetPropSuperFallbackInfo, masm)) {
using Fn = bool (*)(JSContext*, BaselineFrame*, ICGetProp_Fallback*,
HandleValue, MutableHandleValue, MutableHandleValue);
if (!tailCallVM<Fn, DoGetPropSuperFallback>(masm)) {
return false;
}
} else {
@ -2958,7 +2905,9 @@ bool ICGetProp_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
masm.pushBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
if (!tailCallVM(DoGetPropFallbackInfo, masm)) {
using Fn = bool (*)(JSContext*, BaselineFrame*, ICGetProp_Fallback*,
MutableHandleValue, MutableHandleValue);
if (!tailCallVM<Fn, DoGetPropFallback>(masm)) {
return false;
}
}
@ -2997,9 +2946,9 @@ void ICGetProp_Fallback::Compiler::postGenerateStubCode(MacroAssembler& masm,
// SetProp_Fallback
//
static bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame,
ICSetProp_Fallback* stub, Value* stack,
HandleValue lhs, HandleValue rhs) {
bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame,
ICSetProp_Fallback* stub, Value* stack, HandleValue lhs,
HandleValue rhs) {
stub->incrementEnteredCount();
RootedScript script(cx, frame->script());
@ -3145,13 +3094,6 @@ static bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoSetPropFallbackFn)(JSContext*, BaselineFrame*,
ICSetProp_Fallback*, Value*, HandleValue,
HandleValue);
static const VMFunction DoSetPropFallbackInfo =
FunctionInfo<DoSetPropFallbackFn>(DoSetPropFallback, "DoSetPropFallback",
TailCall, PopValues(1));
bool ICSetProp_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
MOZ_ASSERT(R0 == JSReturnOperand);
@ -3176,7 +3118,9 @@ bool ICSetProp_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
if (!tailCallVM(DoSetPropFallbackInfo, masm)) {
using Fn = bool (*)(JSContext*, BaselineFrame*, ICSetProp_Fallback*, Value*,
HandleValue, HandleValue);
if (!tailCallVM<Fn, DoSetPropFallback>(masm)) {
return false;
}
@ -5334,9 +5278,9 @@ bool ICCall_ScriptedFunCall::Compiler::generateStubCode(MacroAssembler& masm) {
// GetIterator_Fallback
//
static bool DoGetIteratorFallback(JSContext* cx, BaselineFrame* frame,
ICGetIterator_Fallback* stub,
HandleValue value, MutableHandleValue res) {
bool DoGetIteratorFallback(JSContext* cx, BaselineFrame* frame,
ICGetIterator_Fallback* stub, HandleValue value,
MutableHandleValue res) {
stub->incrementEnteredCount();
FallbackICSpew(cx, stub, "GetIterator");
@ -5352,13 +5296,6 @@ static bool DoGetIteratorFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoGetIteratorFallbackFn)(JSContext*, BaselineFrame*,
ICGetIterator_Fallback*, HandleValue,
MutableHandleValue);
static const VMFunction DoGetIteratorFallbackInfo =
FunctionInfo<DoGetIteratorFallbackFn>(
DoGetIteratorFallback, "DoGetIteratorFallback", TailCall, PopValues(1));
bool ICGetIterator_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
EmitRestoreTailCallReg(masm);
@ -5369,16 +5306,18 @@ bool ICGetIterator_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoGetIteratorFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICGetIterator_Fallback*,
HandleValue, MutableHandleValue);
return tailCallVM<Fn, DoGetIteratorFallback>(masm);
}
//
// InstanceOf_Fallback
//
static bool DoInstanceOfFallback(JSContext* cx, BaselineFrame* frame,
ICInstanceOf_Fallback* stub, HandleValue lhs,
HandleValue rhs, MutableHandleValue res) {
bool DoInstanceOfFallback(JSContext* cx, BaselineFrame* frame,
ICInstanceOf_Fallback* stub, HandleValue lhs,
HandleValue rhs, MutableHandleValue res) {
stub->incrementEnteredCount();
FallbackICSpew(cx, stub, "InstanceOf");
@ -5415,13 +5354,6 @@ static bool DoInstanceOfFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoInstanceOfFallbackFn)(JSContext*, BaselineFrame*,
ICInstanceOf_Fallback*, HandleValue,
HandleValue, MutableHandleValue);
static const VMFunction DoInstanceOfFallbackInfo =
FunctionInfo<DoInstanceOfFallbackFn>(
DoInstanceOfFallback, "DoInstanceOfFallback", TailCall, PopValues(2));
bool ICInstanceOf_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
EmitRestoreTailCallReg(masm);
@ -5434,16 +5366,18 @@ bool ICInstanceOf_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoInstanceOfFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICInstanceOf_Fallback*,
HandleValue, HandleValue, MutableHandleValue);
return tailCallVM<Fn, DoInstanceOfFallback>(masm);
}
//
// TypeOf_Fallback
//
static bool DoTypeOfFallback(JSContext* cx, BaselineFrame* frame,
ICTypeOf_Fallback* stub, HandleValue val,
MutableHandleValue res) {
bool DoTypeOfFallback(JSContext* cx, BaselineFrame* frame,
ICTypeOf_Fallback* stub, HandleValue val,
MutableHandleValue res) {
stub->incrementEnteredCount();
FallbackICSpew(cx, stub, "TypeOf");
@ -5456,12 +5390,6 @@ static bool DoTypeOfFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoTypeOfFallbackFn)(JSContext*, BaselineFrame* frame,
ICTypeOf_Fallback*, HandleValue,
MutableHandleValue);
static const VMFunction DoTypeOfFallbackInfo = FunctionInfo<DoTypeOfFallbackFn>(
DoTypeOfFallback, "DoTypeOfFallback", TailCall);
bool ICTypeOf_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
EmitRestoreTailCallReg(masm);
@ -5469,7 +5397,9 @@ bool ICTypeOf_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoTypeOfFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICTypeOf_Fallback*,
HandleValue, MutableHandleValue);
return tailCallVM<Fn, DoTypeOfFallback>(masm);
}
ICTypeMonitor_SingleObject::ICTypeMonitor_SingleObject(JitCode* stubCode,
@ -5532,8 +5462,8 @@ ICCall_ClassHook::ICCall_ClassHook(JitCode* stubCode, ICStub* firstMonitorStub,
// Rest_Fallback
//
static bool DoRestFallback(JSContext* cx, BaselineFrame* frame,
ICRest_Fallback* stub, MutableHandleValue res) {
bool DoRestFallback(JSContext* cx, BaselineFrame* frame, ICRest_Fallback* stub,
MutableHandleValue res) {
unsigned numFormals = frame->numFormalArgs() - 1;
unsigned numActuals = frame->numActualArgs();
unsigned numRest = numActuals > numFormals ? numActuals - numFormals : 0;
@ -5549,27 +5479,24 @@ static bool DoRestFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoRestFallbackFn)(JSContext*, BaselineFrame*, ICRest_Fallback*,
MutableHandleValue);
static const VMFunction DoRestFallbackInfo =
FunctionInfo<DoRestFallbackFn>(DoRestFallback, "DoRestFallback", TailCall);
bool ICRest_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
EmitRestoreTailCallReg(masm);
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoRestFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICRest_Fallback*,
MutableHandleValue);
return tailCallVM<Fn, DoRestFallback>(masm);
}
//
// UnaryArith_Fallback
//
static bool DoUnaryArithFallback(JSContext* cx, BaselineFrame* frame,
ICUnaryArith_Fallback* stub, HandleValue val,
MutableHandleValue res) {
bool DoUnaryArithFallback(JSContext* cx, BaselineFrame* frame,
ICUnaryArith_Fallback* stub, HandleValue val,
MutableHandleValue res) {
stub->incrementEnteredCount();
RootedScript script(cx, frame->script());
@ -5619,13 +5546,6 @@ static bool DoUnaryArithFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoUnaryArithFallbackFn)(JSContext*, BaselineFrame*,
ICUnaryArith_Fallback*, HandleValue,
MutableHandleValue);
static const VMFunction DoUnaryArithFallbackInfo =
FunctionInfo<DoUnaryArithFallbackFn>(
DoUnaryArithFallback, "DoUnaryArithFallback", TailCall, PopValues(1));
bool ICUnaryArith_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
MOZ_ASSERT(R0 == JSReturnOperand);
@ -5640,16 +5560,18 @@ bool ICUnaryArith_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoUnaryArithFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICUnaryArith_Fallback*,
HandleValue, MutableHandleValue);
return tailCallVM<Fn, DoUnaryArithFallback>(masm);
}
//
// BinaryArith_Fallback
//
static bool DoBinaryArithFallback(JSContext* cx, BaselineFrame* frame,
ICBinaryArith_Fallback* stub, HandleValue lhs,
HandleValue rhs, MutableHandleValue ret) {
bool DoBinaryArithFallback(JSContext* cx, BaselineFrame* frame,
ICBinaryArith_Fallback* stub, HandleValue lhs,
HandleValue rhs, MutableHandleValue ret) {
stub->incrementEnteredCount();
RootedScript script(cx, frame->script());
@ -5748,13 +5670,6 @@ static bool DoBinaryArithFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoBinaryArithFallbackFn)(JSContext*, BaselineFrame*,
ICBinaryArith_Fallback*, HandleValue,
HandleValue, MutableHandleValue);
static const VMFunction DoBinaryArithFallbackInfo =
FunctionInfo<DoBinaryArithFallbackFn>(
DoBinaryArithFallback, "DoBinaryArithFallback", TailCall, PopValues(2));
bool ICBinaryArith_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
MOZ_ASSERT(R0 == JSReturnOperand);
@ -5771,15 +5686,17 @@ bool ICBinaryArith_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoBinaryArithFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICBinaryArith_Fallback*,
HandleValue, HandleValue, MutableHandleValue);
return tailCallVM<Fn, DoBinaryArithFallback>(masm);
}
//
// Compare_Fallback
//
static bool DoCompareFallback(JSContext* cx, BaselineFrame* frame,
ICCompare_Fallback* stub, HandleValue lhs,
HandleValue rhs, MutableHandleValue ret) {
bool DoCompareFallback(JSContext* cx, BaselineFrame* frame,
ICCompare_Fallback* stub, HandleValue lhs,
HandleValue rhs, MutableHandleValue ret) {
stub->incrementEnteredCount();
RootedScript script(cx, frame->script());
@ -5849,13 +5766,6 @@ static bool DoCompareFallback(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoCompareFallbackFn)(JSContext*, BaselineFrame*,
ICCompare_Fallback*, HandleValue,
HandleValue, MutableHandleValue);
static const VMFunction DoCompareFallbackInfo =
FunctionInfo<DoCompareFallbackFn>(DoCompareFallback, "DoCompareFallback",
TailCall, PopValues(2));
bool ICCompare_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
MOZ_ASSERT(R0 == JSReturnOperand);
@ -5871,16 +5781,18 @@ bool ICCompare_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.pushValue(R0);
masm.push(ICStubReg);
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoCompareFallbackInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICCompare_Fallback*,
HandleValue, HandleValue, MutableHandleValue);
return tailCallVM<Fn, DoCompareFallback>(masm);
}
//
// NewArray_Fallback
//
static bool DoNewArray(JSContext* cx, BaselineFrame* frame,
ICNewArray_Fallback* stub, uint32_t length,
MutableHandleValue res) {
bool DoNewArray(JSContext* cx, BaselineFrame* frame, ICNewArray_Fallback* stub,
uint32_t length, MutableHandleValue res) {
stub->incrementEnteredCount();
FallbackICSpew(cx, stub, "NewArray");
@ -5914,11 +5826,6 @@ static bool DoNewArray(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoNewArrayFn)(JSContext*, BaselineFrame*, ICNewArray_Fallback*,
uint32_t, MutableHandleValue);
static const VMFunction DoNewArrayInfo =
FunctionInfo<DoNewArrayFn>(DoNewArray, "DoNewArray", TailCall);
bool ICNewArray_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
EmitRestoreTailCallReg(masm);
@ -5926,14 +5833,16 @@ bool ICNewArray_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
masm.push(ICStubReg); // stub.
masm.pushBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
return tailCallVM(DoNewArrayInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICNewArray_Fallback*,
uint32_t, MutableHandleValue);
return tailCallVM<Fn, DoNewArray>(masm);
}
//
// NewObject_Fallback
//
static bool DoNewObject(JSContext* cx, BaselineFrame* frame,
ICNewObject_Fallback* stub, MutableHandleValue res) {
bool DoNewObject(JSContext* cx, BaselineFrame* frame,
ICNewObject_Fallback* stub, MutableHandleValue res) {
stub->incrementEnteredCount();
FallbackICSpew(cx, stub, "NewObject");
@ -5972,18 +5881,15 @@ static bool DoNewObject(JSContext* cx, BaselineFrame* frame,
return true;
}
typedef bool (*DoNewObjectFn)(JSContext*, BaselineFrame*, ICNewObject_Fallback*,
MutableHandleValue);
static const VMFunction DoNewObjectInfo =
FunctionInfo<DoNewObjectFn>(DoNewObject, "DoNewObject", TailCall);
bool ICNewObject_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
EmitRestoreTailCallReg(masm);
masm.push(ICStubReg); // stub.
pushStubPayload(masm, R0.scratchReg());
return tailCallVM(DoNewObjectInfo, masm);
using Fn = bool (*)(JSContext*, BaselineFrame*, ICNewObject_Fallback*,
MutableHandleValue);
return tailCallVM<Fn, DoNewObject>(masm);
}
} // namespace jit

Просмотреть файл

@ -996,7 +996,11 @@ class ICStubCompiler {
void pushStubPayload(MacroAssembler& masm, Register scratch);
// Emits a tail call to a VMFunction wrapper.
MOZ_MUST_USE bool tailCallVM(const VMFunction& fun, MacroAssembler& masm);
MOZ_MUST_USE bool tailCallVMInternal(MacroAssembler& masm,
TailCallVMFunctionId id);
template <typename Fn, Fn fn>
MOZ_MUST_USE bool tailCallVM(MacroAssembler& masm);
// Emits a normal (non-tail) call to a VMFunction wrapper.
MOZ_MUST_USE bool callVMInternal(MacroAssembler& masm, VMFunctionId id);
@ -2738,6 +2742,95 @@ extern bool DoSpreadCallFallback(JSContext* cx, BaselineFrame* frame,
ICCall_Fallback* stub, Value* vp,
MutableHandleValue res);
extern bool DoTypeMonitorFallback(JSContext* cx, BaselineFrame* frame,
ICTypeMonitor_Fallback* stub,
HandleValue value, MutableHandleValue res);
extern bool DoToBoolFallback(JSContext* cx, BaselineFrame* frame,
ICToBool_Fallback* stub, HandleValue arg,
MutableHandleValue ret);
extern bool DoGetElemSuperFallback(JSContext* cx, BaselineFrame* frame,
ICGetElem_Fallback* stub, HandleValue lhs,
HandleValue rhs, HandleValue receiver,
MutableHandleValue res);
extern bool DoGetElemFallback(JSContext* cx, BaselineFrame* frame,
ICGetElem_Fallback* stub, HandleValue lhs,
HandleValue rhs, MutableHandleValue res);
extern bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame,
ICSetElem_Fallback* stub, Value* stack,
HandleValue objv, HandleValue index,
HandleValue rhs);
extern bool DoInFallback(JSContext* cx, BaselineFrame* frame,
ICIn_Fallback* stub, HandleValue key,
HandleValue objValue, MutableHandleValue res);
extern bool DoHasOwnFallback(JSContext* cx, BaselineFrame* frame,
ICHasOwn_Fallback* stub, HandleValue keyValue,
HandleValue objValue, MutableHandleValue res);
extern bool DoGetNameFallback(JSContext* cx, BaselineFrame* frame,
ICGetName_Fallback* stub, HandleObject envChain,
MutableHandleValue res);
extern bool DoBindNameFallback(JSContext* cx, BaselineFrame* frame,
ICBindName_Fallback* stub, HandleObject envChain,
MutableHandleValue res);
extern bool DoGetIntrinsicFallback(JSContext* cx, BaselineFrame* frame,
ICGetIntrinsic_Fallback* stub,
MutableHandleValue res);
extern bool DoGetPropFallback(JSContext* cx, BaselineFrame* frame,
ICGetProp_Fallback* stub, MutableHandleValue val,
MutableHandleValue res);
extern bool DoGetPropSuperFallback(JSContext* cx, BaselineFrame* frame,
ICGetProp_Fallback* stub,
HandleValue receiver, MutableHandleValue val,
MutableHandleValue res);
extern bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame,
ICSetProp_Fallback* stub, Value* stack,
HandleValue lhs, HandleValue rhs);
extern bool DoGetIteratorFallback(JSContext* cx, BaselineFrame* frame,
ICGetIterator_Fallback* stub,
HandleValue value, MutableHandleValue res);
extern bool DoInstanceOfFallback(JSContext* cx, BaselineFrame* frame,
ICInstanceOf_Fallback* stub, HandleValue lhs,
HandleValue rhs, MutableHandleValue res);
extern bool DoTypeOfFallback(JSContext* cx, BaselineFrame* frame,
ICTypeOf_Fallback* stub, HandleValue val,
MutableHandleValue res);
extern bool DoRestFallback(JSContext* cx, BaselineFrame* frame,
ICRest_Fallback* stub, MutableHandleValue res);
extern bool DoUnaryArithFallback(JSContext* cx, BaselineFrame* frame,
ICUnaryArith_Fallback* stub, HandleValue val,
MutableHandleValue res);
extern bool DoBinaryArithFallback(JSContext* cx, BaselineFrame* frame,
ICBinaryArith_Fallback* stub, HandleValue lhs,
HandleValue rhs, MutableHandleValue ret);
extern bool DoNewArray(JSContext* cx, BaselineFrame* frame,
ICNewArray_Fallback* stub, uint32_t length,
MutableHandleValue res);
extern bool DoNewObject(JSContext* cx, BaselineFrame* frame,
ICNewObject_Fallback* stub, MutableHandleValue res);
extern bool DoCompareFallback(JSContext* cx, BaselineFrame* frame,
ICCompare_Fallback* stub, HandleValue lhs,
HandleValue rhs, MutableHandleValue ret);
} // namespace jit
} // namespace js

Просмотреть файл

@ -29,6 +29,8 @@ namespace jit {
class FrameSizeClass;
struct VMFunctionData;
enum class TailCallVMFunctionId;
enum class VMFunctionId;
struct EnterJitData {
@ -149,6 +151,10 @@ class JitRuntime {
using VMWrapperOffsets = Vector<uint32_t, 0, SystemAllocPolicy>;
VMWrapperOffsets functionWrapperOffsets_;
// Maps TailCallVMFunctionId to the offset of the wrapper code in
// trampolineCode_.
VMWrapperOffsets tailCallFunctionWrapperOffsets_;
// Global table of jitcode native address => bytecode address mappings.
UnprotectedData<JitcodeGlobalTable*> jitcodeGlobalTable_;
@ -200,6 +206,10 @@ class JitRuntime {
bool generateVMWrapper(JSContext* cx, MacroAssembler& masm,
const VMFunctionData& f, void* nativeFun,
uint32_t* wrapperOffset);
template <typename IdT>
bool generateVMWrappers(JSContext* cx, MacroAssembler& masm,
VMWrapperOffsets& offsets);
bool generateVMWrappers(JSContext* cx, MacroAssembler& masm);
bool generateTLEventVM(MacroAssembler& masm, const VMFunctionData& f,
@ -238,10 +248,14 @@ class JitRuntime {
TrampolinePtr getVMWrapper(const VMFunction& f) const;
TrampolinePtr getVMWrapper(const VMFunctionId funId) const {
TrampolinePtr getVMWrapper(VMFunctionId funId) const {
MOZ_ASSERT(trampolineCode_);
return trampolineCode(functionWrapperOffsets_[size_t(funId)]);
}
TrampolinePtr getVMWrapper(TailCallVMFunctionId funId) const {
MOZ_ASSERT(trampolineCode_);
return trampolineCode(tailCallFunctionWrapperOffsets_[size_t(funId)]);
}
JitCode* debugTrapHandler(JSContext* cx);
JitCode* getBaselineDebugModeOSRHandler(JSContext* cx);

Просмотреть файл

@ -247,18 +247,51 @@ namespace jit {
js::UnboxedPlainObject::convertToNative) \
_(UrshValues, js::UrshValues)
// The list below is for tail calls. The third argument specifies the number of
// non-argument Values the VM wrapper should pop from the stack. This is used
// for Baseline ICs.
#define TAIL_CALL_VMFUNCTION_LIST(_) \
_(DoBinaryArithFallback, js::jit::DoBinaryArithFallback, 2) \
_(DoBindNameFallback, js::jit::DoBindNameFallback, 0) \
_(DoCompareFallback, js::jit::DoCompareFallback, 2) \
_(DoConcatStringObject, js::jit::DoConcatStringObject, 2) \
_(DoGetElemFallback, js::jit::DoGetElemFallback, 2) \
_(DoGetElemSuperFallback, js::jit::DoGetElemSuperFallback, 3) \
_(DoGetIntrinsicFallback, js::jit::DoGetIntrinsicFallback, 0) \
_(DoGetIteratorFallback, js::jit::DoGetIteratorFallback, 1) \
_(DoGetNameFallback, js::jit::DoGetNameFallback, 0) \
_(DoGetPropFallback, js::jit::DoGetPropFallback, 1) \
_(DoGetPropSuperFallback, js::jit::DoGetPropSuperFallback, 0) \
_(DoHasOwnFallback, js::jit::DoHasOwnFallback, 2) \
_(DoInFallback, js::jit::DoInFallback, 2) \
_(DoInstanceOfFallback, js::jit::DoInstanceOfFallback, 2) \
_(DoNewArray, js::jit::DoNewArray, 0) \
_(DoNewObject, js::jit::DoNewObject, 0) \
_(DoRestFallback, js::jit::DoRestFallback, 0) \
_(DoSetElemFallback, js::jit::DoSetElemFallback, 2) \
_(DoSetPropFallback, js::jit::DoSetPropFallback, 1) \
_(DoToBoolFallback, js::jit::DoToBoolFallback, 0) \
_(DoTypeMonitorFallback, js::jit::DoTypeMonitorFallback, 0) \
_(DoTypeOfFallback, js::jit::DoTypeOfFallback, 0) \
_(DoUnaryArithFallback, js::jit::DoUnaryArithFallback, 1) \
_(GeneratorThrowOrReturn, js::jit::GeneratorThrowOrReturn, 0)
#define DEF_ID(name, ...) name,
enum class VMFunctionId {
#define DEF_ID(name, fp) name,
VMFUNCTION_LIST(DEF_ID)
#undef DEF_ID
Count
};
enum class TailCallVMFunctionId { TAIL_CALL_VMFUNCTION_LIST(DEF_ID) Count };
#undef DEF_ID
// Define the VMFunctionToId template to map from signature + function to
// the VMFunctionId. This lets us verify the consumer/codegen code matches
// the C++ signature.
template <typename Function, Function fun>
struct VMFunctionToId; // Error on this line? Forgot to update VMFUNCTION_LIST?
struct VMFunctionToId; // Error here? Update VMFUNCTION_LIST?
template <typename Function, Function fun>
struct TailCallVMFunctionToId; // Error here? Update TAIL_CALL_VMFUNCTION_LIST?
// GCC warns when the signature does not have matching attributes (for example
// MOZ_MUST_USE). Squelch this warning to avoid a GCC-only footgun.
@ -277,6 +310,14 @@ struct VMFunctionToId; // Error on this line? Forgot to update VMFUNCTION_LIST?
VMFUNCTION_LIST(DEF_TEMPLATE)
#undef DEF_TEMPLATE
#define DEF_TEMPLATE(name, fp, valuesToPop) \
template <> \
struct TailCallVMFunctionToId<decltype(&(::fp)), ::fp> { \
static constexpr TailCallVMFunctionId id = TailCallVMFunctionId::name; \
};
TAIL_CALL_VMFUNCTION_LIST(DEF_TEMPLATE)
#undef DEF_TEMPLATE
#if MOZ_IS_GCC
# pragma GCC diagnostic pop
#endif

Просмотреть файл

@ -73,9 +73,9 @@ struct VMFunctionDataHelper<R (*)(JSContext*, Args...)>
argumentPassedInFloatRegs(), argumentRootTypes(),
outParam(), outParamRootType(), returnType(),
extraValuesToPop.numValues, NonTailCall) {}
constexpr explicit VMFunctionDataHelper(
const char* name, MaybeTailCall expectTailCall,
PopValues extraValuesToPop = PopValues(0))
constexpr explicit VMFunctionDataHelper(const char* name,
MaybeTailCall expectTailCall,
PopValues extraValuesToPop)
: VMFunctionData(name, explicitArgs(), argumentProperties(),
argumentPassedInFloatRegs(), argumentRootTypes(),
outParam(), outParamRootType(), returnType(),
@ -95,31 +95,51 @@ static constexpr VMFunctionData vmFunctions[] = {
VMFUNCTION_LIST(DEF_VMFUNCTION)
#undef DEF_VMFUNCTION
};
static constexpr VMFunctionData tailCallVMFunctions[] = {
#define DEF_VMFUNCTION(name, fp, valuesToPop) \
VMFunctionDataHelper<decltype(&(::fp))>(#name, TailCall, \
PopValues(valuesToPop)),
TAIL_CALL_VMFUNCTION_LIST(DEF_VMFUNCTION)
#undef DEF_VMFUNCTION
};
#if MOZ_IS_GCC
# pragma GCC diagnostic pop
#endif
// Generate array storing C++ function pointers. These pointers are not stored
// Generate arrays storing C++ function pointers. These pointers are not stored
// in VMFunctionData because there's no good way to cast them to void* in
// constexpr code. Compilers are smart enough to treat the const array below as
// constexpr.
static void* const vmFunctionTargets[] = {
#define DEF_VMFUNCTION(name, fp) (void*)(::fp),
VMFUNCTION_LIST(DEF_VMFUNCTION)
#define DEF_VMFUNCTION(name, fp, ...) (void*)(::fp),
static void* const vmFunctionTargets[] = {VMFUNCTION_LIST(DEF_VMFUNCTION)};
static void* const tailCallVMFunctionTargets[] = {
TAIL_CALL_VMFUNCTION_LIST(DEF_VMFUNCTION)};
#undef DEF_VMFUNCTION
};
const VMFunctionData& GetVMFunction(VMFunctionId id) {
return vmFunctions[size_t(id)];
}
const VMFunctionData& GetVMFunction(TailCallVMFunctionId id) {
return tailCallVMFunctions[size_t(id)];
}
bool JitRuntime::generateVMWrappers(JSContext* cx, MacroAssembler& masm) {
static void* GetVMFunctionTarget(VMFunctionId id) {
return vmFunctionTargets[size_t(id)];
}
static void* GetVMFunctionTarget(TailCallVMFunctionId id) {
return tailCallVMFunctionTargets[size_t(id)];
}
template <typename IdT>
bool JitRuntime::generateVMWrappers(JSContext* cx, MacroAssembler& masm,
VMWrapperOffsets& offsets) {
// Generate all VM function wrappers.
static constexpr size_t NumVMFunctions = size_t(VMFunctionId::Count);
static constexpr size_t NumVMFunctions = size_t(IdT::Count);
if (!functionWrapperOffsets_.reserve(NumVMFunctions)) {
if (!offsets.reserve(NumVMFunctions)) {
return false;
}
@ -128,7 +148,7 @@ bool JitRuntime::generateVMWrappers(JSContext* cx, MacroAssembler& masm) {
#endif
for (size_t i = 0; i < NumVMFunctions; i++) {
VMFunctionId id = VMFunctionId(i);
IdT id = IdT(i);
const VMFunctionData& fun = GetVMFunction(id);
#ifdef DEBUG
@ -143,12 +163,25 @@ bool JitRuntime::generateVMWrappers(JSContext* cx, MacroAssembler& masm) {
JitSpew(JitSpew_Codegen, "# VM function wrapper (%s)", fun.name());
uint32_t offset;
if (!generateVMWrapper(cx, masm, fun, vmFunctionTargets[i], &offset)) {
if (!generateVMWrapper(cx, masm, fun, GetVMFunctionTarget(id), &offset)) {
return false;
}
MOZ_ASSERT(functionWrapperOffsets_.length() == size_t(id));
functionWrapperOffsets_.infallibleAppend(offset);
MOZ_ASSERT(offsets.length() == size_t(id));
offsets.infallibleAppend(offset);
}
return true;
};
bool JitRuntime::generateVMWrappers(JSContext* cx, MacroAssembler& masm) {
if (!generateVMWrappers<VMFunctionId>(cx, masm, functionWrapperOffsets_)) {
return false;
}
if (!generateVMWrappers<TailCallVMFunctionId>(
cx, masm, tailCallFunctionWrapperOffsets_)) {
return false;
}
return true;
@ -1882,12 +1915,6 @@ bool DoConcatStringObject(JSContext* cx, HandleValue lhs, HandleValue rhs,
return true;
}
typedef bool (*DoConcatStringObjectFn)(JSContext*, HandleValue, HandleValue,
MutableHandleValue);
const VMFunction DoConcatStringObjectInfo =
FunctionInfo<DoConcatStringObjectFn>(
DoConcatStringObject, "DoConcatStringObject", TailCall, PopValues(2));
MOZ_MUST_USE bool TrySkipAwait(JSContext* cx, HandleValue val,
MutableHandleValue resolved) {
bool canSkip;

Просмотреть файл

@ -1225,12 +1225,11 @@ bool DoToNumeric(JSContext* cx, HandleValue arg, MutableHandleValue ret);
bool CopyStringSplitArray(JSContext* cx, HandleArrayObject arr,
MutableHandleValue result);
// TailCall VMFunctions
extern const VMFunction DoConcatStringObjectInfo;
enum class TailCallVMFunctionId;
enum class VMFunctionId;
extern const VMFunctionData& GetVMFunction(VMFunctionId id);
extern const VMFunctionData& GetVMFunction(TailCallVMFunctionId id);
} // namespace jit
} // namespace js