diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 3f860b6fcc17..ed3b0f8162b8 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -63,6 +63,7 @@ #include "jit/shared/CodeGenerator-shared-inl.h" #include "jit/shared/Lowering-shared-inl.h" #include "jit/TemplateObject-inl.h" +#include "jit/VMFunctionList-inl.h" #include "vm/Interpreter-inl.h" #include "vm/JSScript-inl.h" @@ -279,8 +280,9 @@ static void StoreAllLiveRegs(MacroAssembler& masm, LiveRegisterSet liveRegs) { // Before doing any call to Cpp, you should ensure that volatile // registers are evicted by the register allocator. -void CodeGenerator::callVM(const VMFunction& fun, LInstruction* ins, - const Register* dynStack) { +void CodeGenerator::callVMInternal(const VMFunctionData& fun, + TrampolinePtr code, LInstruction* ins, + const Register* dynStack) { #ifdef DEBUG if (ins->mirRaw()) { MOZ_ASSERT(ins->mirRaw()->isInstruction()); @@ -297,9 +299,6 @@ void CodeGenerator::callVM(const VMFunction& fun, LInstruction* ins, pushedArgs_ = 0; #endif - // Get the wrapper of the VM function. - TrampolinePtr wrapper = gen->jitRuntime()->getVMWrapper(fun); - #ifdef CHECK_OSIPOINT_REGISTERS if (shouldVerifyOsiPointRegs(ins->safepoint())) { StoreAllLiveRegs(masm, ins->safepoint()->liveRegs()); @@ -322,7 +321,7 @@ void CodeGenerator::callVM(const VMFunction& fun, LInstruction* ins, // when returning from the call. Failures are handled with exceptions based // on the return value of the C functions. To guard the outcome of the // returned value, use another LIR instruction. - uint32_t callOffset = masm.callJit(wrapper); + uint32_t callOffset = masm.callJit(code); markSafepointAt(callOffset, ins); // Remove rest of the frame left on the stack. We remove the return address @@ -335,6 +334,24 @@ void CodeGenerator::callVM(const VMFunction& fun, LInstruction* ins, // ... frame ... } +void CodeGenerator::callVMInternal(VMFunctionId id, LInstruction* ins, + const Register* dynStack) { + TrampolinePtr code = gen->jitRuntime()->getVMWrapper(id); + callVMInternal(GetVMFunction(id), code, ins, dynStack); +} + +void CodeGenerator::callVM(const VMFunction& fun, LInstruction* ins, + const Register* dynStack) { + TrampolinePtr code = gen->jitRuntime()->getVMWrapper(fun); + callVMInternal(fun, code, ins, dynStack); +} + +template +void CodeGenerator::callVM(LInstruction* ins, const Register* dynStack) { + VMFunctionId id = VMFunctionToId::id; + callVMInternal(id, ins, dynStack); +} + // ArgSeq store arguments for OutOfLineCallVM. // // OutOfLineCallVM are created with "oolCallVM" function. The third argument of @@ -3418,39 +3435,29 @@ void CodeGenerator::visitUnaryCache(LUnaryCache* lir) { addIC(lir, allocateIC(ic)); } -typedef JSFunction* (*MakeDefaultConstructorFn)(JSContext*, HandleScript, - jsbytecode*, HandleObject); -static const VMFunction MakeDefaultConstructorInfo = - FunctionInfo(js::MakeDefaultConstructor, - "MakeDefaultConstructor"); - void CodeGenerator::visitClassConstructor(LClassConstructor* lir) { pushArg(ImmPtr(nullptr)); pushArg(ImmPtr(lir->mir()->pc())); pushArg(ImmGCPtr(current->mir()->info().script())); - callVM(MakeDefaultConstructorInfo, lir); -} -typedef JSObject* (*GetOrCreateModuleMetaObjectFn)(JSContext*, HandleObject); -static const VMFunction GetOrCreateModuleMetaObjectInfo = - FunctionInfo(js::GetOrCreateModuleMetaObject, - "GetOrCreateModuleMetaObject"); + using Fn = + JSFunction* (*)(JSContext*, HandleScript, jsbytecode*, HandleObject); + callVM(lir); +} void CodeGenerator::visitModuleMetadata(LModuleMetadata* lir) { pushArg(ImmPtr(lir->mir()->module())); - callVM(GetOrCreateModuleMetaObjectInfo, lir); -} -typedef JSObject* (*StartDynamicModuleImportFn)(JSContext*, HandleScript, - HandleValue); -static const VMFunction StartDynamicModuleImportInfo = - FunctionInfo(js::StartDynamicModuleImport, - "StartDynamicModuleImport"); + using Fn = JSObject* (*)(JSContext*, HandleObject); + callVM(lir); +} void CodeGenerator::visitDynamicImport(LDynamicImport* lir) { pushArg(ToValue(lir, LDynamicImport::SpecifierIndex)); pushArg(ImmGCPtr(current->mir()->info().script())); - callVM(StartDynamicModuleImportInfo, lir); + + using Fn = JSObject* (*)(JSContext*, HandleScript, HandleValue); + callVM(lir); } typedef JSObject* (*LambdaFn)(JSContext*, HandleFunction, HandleObject); @@ -3460,7 +3467,9 @@ static const VMFunction LambdaInfo = void CodeGenerator::visitLambdaForSingleton(LLambdaForSingleton* lir) { pushArg(ToRegister(lir->environmentChain())); pushArg(ImmGCPtr(lir->mir()->info().funUnsafe())); - callVM(LambdaInfo, lir); + + using Fn = JSObject* (*)(JSContext*, HandleFunction, HandleObject); + callVM(lir); } void CodeGenerator::visitLambda(LLambda* lir) { @@ -3611,17 +3620,14 @@ void CodeGenerator::emitLambdaInit(Register output, Register envChain, Address(output, JSFunction::offsetOfAtom())); } -typedef bool (*SetFunNameFn)(JSContext*, HandleFunction, HandleValue, - FunctionPrefixKind); -static const VMFunction SetFunNameInfo = - FunctionInfo(js::SetFunctionName, "SetFunName"); - void CodeGenerator::visitSetFunName(LSetFunName* lir) { pushArg(Imm32(lir->mir()->prefixKind())); pushArg(ToValue(lir, LSetFunName::NameValue)); pushArg(ToRegister(lir->fun())); - callVM(SetFunNameInfo, lir); + using Fn = + bool (*)(JSContext*, HandleFunction, HandleValue, FunctionPrefixKind); + callVM(lir); } void CodeGenerator::visitOsiPoint(LOsiPoint* lir) { @@ -5903,10 +5909,6 @@ void CodeGenerator::visitCheckOverRecursed(LCheckOverRecursed* lir) { masm.bind(ool->rejoin()); } -typedef bool (*DefVarFn)(JSContext*, HandleObject, HandleScript, jsbytecode*); -static const VMFunction DefVarInfo = - FunctionInfo(DefVarOperation, "DefVarOperation"); - void CodeGenerator::visitDefVar(LDefVar* lir) { Register envChain = ToRegister(lir->environmentChain()); @@ -5917,14 +5919,10 @@ void CodeGenerator::visitDefVar(LDefVar* lir) { pushArg(ImmGCPtr(script)); // JSScript* pushArg(envChain); // JSObject* - callVM(DefVarInfo, lir); + using Fn = bool (*)(JSContext*, HandleObject, HandleScript, jsbytecode*); + callVM(lir); } -typedef bool (*DefLexicalFn)(JSContext*, HandleObject, HandleScript, - jsbytecode*); -static const VMFunction DefLexicalInfo = - FunctionInfo(DefLexicalOperation, "DefLexicalOperation"); - void CodeGenerator::visitDefLexical(LDefLexical* lir) { Register envChain = ToRegister(lir->environmentChain()); @@ -5935,14 +5933,10 @@ void CodeGenerator::visitDefLexical(LDefLexical* lir) { pushArg(ImmGCPtr(script)); // JSScript* pushArg(envChain); // JSObject* - callVM(DefLexicalInfo, lir); + using Fn = bool (*)(JSContext*, HandleObject, HandleScript, jsbytecode*); + callVM(lir); } -typedef bool (*DefFunOperationFn)(JSContext*, HandleScript, HandleObject, - HandleFunction); -static const VMFunction DefFunOperationInfo = - FunctionInfo(DefFunOperation, "DefFunOperation"); - void CodeGenerator::visitDefFun(LDefFun* lir) { Register envChain = ToRegister(lir->environmentChain()); @@ -5951,7 +5945,8 @@ void CodeGenerator::visitDefFun(LDefFun* lir) { pushArg(envChain); pushArg(ImmGCPtr(current->mir()->info().script())); - callVM(DefFunOperationInfo, lir); + using Fn = bool (*)(JSContext*, HandleScript, HandleObject, HandleFunction); + callVM(lir); } typedef bool (*CheckOverRecursedFn)(JSContext*); @@ -7165,12 +7160,6 @@ void CodeGenerator::visitInitElem(LInitElem* lir) { callVM(InitElemInfo, lir); } -typedef bool (*InitElemGetterSetterFn)(JSContext*, jsbytecode*, HandleObject, - HandleValue, HandleObject); -static const VMFunction InitElemGetterSetterInfo = - FunctionInfo(InitElemGetterSetterOperation, - "InitElemGetterSetterOperation"); - void CodeGenerator::visitInitElemGetterSetter(LInitElemGetterSetter* lir) { Register obj = ToRegister(lir->object()); Register value = ToRegister(lir->value()); @@ -7180,29 +7169,21 @@ void CodeGenerator::visitInitElemGetterSetter(LInitElemGetterSetter* lir) { pushArg(obj); pushArg(ImmPtr(lir->mir()->resumePoint()->pc())); - callVM(InitElemGetterSetterInfo, lir); + using Fn = bool (*)(JSContext*, jsbytecode*, HandleObject, HandleValue, + HandleObject); + callVM(lir); } -typedef bool (*MutatePrototypeFn)(JSContext* cx, HandlePlainObject obj, - HandleValue value); -static const VMFunction MutatePrototypeInfo = - FunctionInfo(MutatePrototype, "MutatePrototype"); - void CodeGenerator::visitMutateProto(LMutateProto* lir) { Register objReg = ToRegister(lir->getObject()); pushArg(ToValue(lir, LMutateProto::ValueIndex)); pushArg(objReg); - callVM(MutatePrototypeInfo, lir); + using Fn = bool (*)(JSContext * cx, HandlePlainObject obj, HandleValue value); + callVM(lir); } -typedef bool (*InitPropGetterSetterFn)(JSContext*, jsbytecode*, HandleObject, - HandlePropertyName, HandleObject); -static const VMFunction InitPropGetterSetterInfo = - FunctionInfo(InitPropGetterSetterOperation, - "InitPropGetterSetterOperation"); - void CodeGenerator::visitInitPropGetterSetter(LInitPropGetterSetter* lir) { Register obj = ToRegister(lir->object()); Register value = ToRegister(lir->value()); @@ -7212,7 +7193,9 @@ void CodeGenerator::visitInitPropGetterSetter(LInitPropGetterSetter* lir) { pushArg(obj); pushArg(ImmPtr(lir->mir()->resumePoint()->pc())); - callVM(InitPropGetterSetterInfo, lir); + using Fn = bool (*)(JSContext*, jsbytecode*, HandleObject, HandlePropertyName, + HandleObject); + callVM(lir); } typedef bool (*CreateThisFn)(JSContext* cx, HandleObject callee, @@ -7441,15 +7424,13 @@ void CodeGenerator::visitComputeThis(LComputeThis* lir) { masm.bind(ool->rejoin()); } -typedef bool (*ImplicitThisFn)(JSContext*, HandleObject, HandlePropertyName, - MutableHandleValue); -static const VMFunction ImplicitThisInfo = FunctionInfo( - ImplicitThisOperation, "ImplicitThisOperation"); - void CodeGenerator::visitImplicitThis(LImplicitThis* lir) { pushArg(ImmGCPtr(lir->mir()->name())); pushArg(ToRegister(lir->env())); - callVM(ImplicitThisInfo, lir); + + using Fn = bool (*)(JSContext*, HandleObject, HandlePropertyName, + MutableHandleValue); + callVM(lir); } void CodeGenerator::visitArrowNewTarget(LArrowNewTarget* lir) { @@ -11502,13 +11483,11 @@ void CodeGenerator::visitOutOfLineUnboxFloatingPoint( masm.jump(ool->rejoin()); } -typedef JSObject* (*BindVarFn)(JSContext*, JSObject*); -static const VMFunction BindVarInfo = - FunctionInfo(BindVarOperation, "BindVarOperation"); - void CodeGenerator::visitCallBindVar(LCallBindVar* lir) { pushArg(ToRegister(lir->environmentChain())); - callVM(BindVarInfo, lir); + + using Fn = JSObject* (*)(JSContext*, JSObject*); + callVM(lir); } typedef bool (*GetPropertyFn)(JSContext*, HandleValue, HandlePropertyName, @@ -11911,13 +11890,11 @@ void CodeGenerator::visitSetPropertyCache(LSetPropertyCache* ins) { ins->mir()->needsTypeBarrier(), ins->mir()->guardHoles()); } -typedef bool (*ThrowFn)(JSContext*, HandleValue); -static const VMFunction ThrowInfoCodeGen = - FunctionInfo(js::ThrowOperation, "ThrowOperation"); - void CodeGenerator::visitThrow(LThrow* lir) { pushArg(ToValue(lir, LThrow::Value)); - callVM(ThrowInfoCodeGen, lir); + + using Fn = bool (*)(JSContext*, HandleValue); + callVM(lir); } typedef bool (*BitNotFn)(JSContext*, MutableHandleValue, MutableHandleValue); @@ -12168,14 +12145,12 @@ void CodeGenerator::visitOutOfLineTypeOfV(OutOfLineTypeOfV* ool) { masm.jump(ool->rejoin()); } -typedef JSObject* (*ToAsyncIterFn)(JSContext*, HandleObject, HandleValue); -static const VMFunction ToAsyncIterInfo = - FunctionInfo(js::CreateAsyncFromSyncIterator, "ToAsyncIter"); - void CodeGenerator::visitToAsyncIter(LToAsyncIter* lir) { pushArg(ToValue(lir, LToAsyncIter::NextMethodIndex)); pushArg(ToRegister(lir->iterator())); - callVM(ToAsyncIterInfo, lir); + + using Fn = JSObject* (*)(JSContext*, HandleObject, HandleValue); + callVM(lir); } typedef bool (*ToIdFn)(JSContext*, HandleValue, MutableHandleValue); @@ -13897,15 +13872,12 @@ void CodeGenerator::visitLexicalCheck(LLexicalCheck* ins) { bailoutFrom(&bail, ins->snapshot()); } -typedef bool (*ThrowRuntimeLexicalErrorFn)(JSContext*, unsigned); -static const VMFunction ThrowRuntimeLexicalErrorInfo = - FunctionInfo(ThrowRuntimeLexicalError, - "ThrowRuntimeLexicalError"); - void CodeGenerator::visitThrowRuntimeLexicalError( LThrowRuntimeLexicalError* ins) { pushArg(Imm32(ins->mir()->errorNumber())); - callVM(ThrowRuntimeLexicalErrorInfo, ins); + + using Fn = bool (*)(JSContext*, unsigned); + callVM(ins); } typedef bool (*GlobalNameConflictsCheckFromIonFn)(JSContext*, HandleScript); @@ -14004,11 +13976,6 @@ void CodeGenerator::visitCheckIsObj(LCheckIsObj* ins) { masm.bind(ool->rejoin()); } -typedef bool (*ThrowObjCoercibleFn)(JSContext*, HandleValue); -static const VMFunction ThrowObjectCoercibleInfo = - FunctionInfo(ThrowObjectCoercible, - "ThrowObjectCoercible"); - void CodeGenerator::visitCheckObjCoercible(LCheckObjCoercible* ins) { ValueOperand checkValue = ToValue(ins, LCheckObjCoercible::CheckValue); Label fail, done; @@ -14016,18 +13983,16 @@ void CodeGenerator::visitCheckObjCoercible(LCheckObjCoercible* ins) { masm.branchTestUndefined(Assembler::NotEqual, checkValue, &done); masm.bind(&fail); pushArg(checkValue); - callVM(ThrowObjectCoercibleInfo, ins); + using Fn = bool (*)(JSContext*, HandleValue); + callVM(ins); masm.bind(&done); } -typedef bool (*CheckSelfHostedFn)(JSContext*, HandleValue); -static const VMFunction CheckSelfHostedInfo = FunctionInfo( - js::Debug_CheckSelfHosted, "Debug_CheckSelfHosted"); - void CodeGenerator::visitDebugCheckSelfHosted(LDebugCheckSelfHosted* ins) { ValueOperand checkValue = ToValue(ins, LDebugCheckSelfHosted::CheckValue); pushArg(checkValue); - callVM(CheckSelfHostedInfo, ins); + using Fn = bool (*)(JSContext*, HandleValue); + callVM(ins); } void CodeGenerator::visitRandom(LRandom* ins) { diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index af63a4863010..db044baa9789 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -76,9 +76,17 @@ class CodeGenerator final : public CodeGeneratorSpecific { void verifyOsiPointRegs(LSafepoint* safepoint); #endif - void callVM(const VMFunction& f, LInstruction* ins, + void callVMInternal(const VMFunctionData& fun, TrampolinePtr code, + LInstruction* ins, const Register* dynStack); + void callVMInternal(VMFunctionId id, LInstruction* ins, + const Register* dynStack); + + void callVM(const VMFunction& fun, LInstruction* ins, const Register* dynStack = nullptr); + template + void callVM(LInstruction* ins, const Register* dynStack = nullptr); + template inline OutOfLineCode* oolCallVM(const VMFunction& fun, LInstruction* ins, const ArgSeq& args, const StoreOutputTo& out);