Bug 1530937 part 17 - Remove now unused VMFunction code. r=nbp

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan de Mooij 2019-03-12 14:47:50 +00:00
Родитель aac57cc8b5
Коммит e0b761d01f
13 изменённых файлов: 146 добавлений и 329 удалений

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

@ -1773,13 +1773,6 @@ bool DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame,
return true; return true;
} }
typedef bool (*DoTypeUpdateFallbackFn)(JSContext*, BaselineFrame*,
ICUpdatedStub*, HandleValue,
HandleValue);
const VMFunction DoTypeUpdateFallbackInfo =
FunctionInfo<DoTypeUpdateFallbackFn>(DoTypeUpdateFallback,
"DoTypeUpdateFallback", NonTailCall);
bool ICTypeUpdate_Fallback::Compiler::generateStubCode(MacroAssembler& masm) { bool ICTypeUpdate_Fallback::Compiler::generateStubCode(MacroAssembler& masm) {
// Just store false into R1.scratchReg() and return. // Just store false into R1.scratchReg() and return.
masm.move32(Imm32(0), R1.scratchReg()); masm.move32(Imm32(0), R1.scratchReg());

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

@ -1490,8 +1490,6 @@ class ICTypeMonitor_AnyValue : public ICStub {
// TypeUpdate // TypeUpdate
extern const VMFunction DoTypeUpdateFallbackInfo;
// The TypeUpdate fallback is not a regular fallback, since it just // The TypeUpdate fallback is not a regular fallback, since it just
// forwards to a different entry point in the main fallback stub. // forwards to a different entry point in the main fallback stub.
class ICTypeUpdate_Fallback : public ICStub { class ICTypeUpdate_Fallback : public ICStub {

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

@ -165,7 +165,6 @@ JitRuntime::JitRuntime()
debugTrapHandler_(nullptr), debugTrapHandler_(nullptr),
baselineDebugModeOSRHandler_(nullptr), baselineDebugModeOSRHandler_(nullptr),
trampolineCode_(nullptr), trampolineCode_(nullptr),
functionWrappers_(nullptr),
jitcodeGlobalTable_(nullptr), jitcodeGlobalTable_(nullptr),
#ifdef DEBUG #ifdef DEBUG
ionBailAfter_(0), ionBailAfter_(0),
@ -179,8 +178,6 @@ JitRuntime::~JitRuntime() {
MOZ_ASSERT(ionLazyLinkListSize_ == 0); MOZ_ASSERT(ionLazyLinkListSize_ == 0);
MOZ_ASSERT(ionLazyLinkList_.ref().isEmpty()); MOZ_ASSERT(ionLazyLinkList_.ref().isEmpty());
js_delete(functionWrappers_.ref());
// By this point, the jitcode global table should be empty. // By this point, the jitcode global table should be empty.
MOZ_ASSERT_IF(jitcodeGlobalTable_, jitcodeGlobalTable_->empty()); MOZ_ASSERT_IF(jitcodeGlobalTable_, jitcodeGlobalTable_->empty());
js_delete(jitcodeGlobalTable_.ref()); js_delete(jitcodeGlobalTable_.ref());
@ -201,11 +198,6 @@ bool JitRuntime::initialize(JSContext* cx) {
JitContext jctx(cx, nullptr); JitContext jctx(cx, nullptr);
functionWrappers_ = cx->new_<VMWrapperMap>(cx);
if (!functionWrappers_) {
return false;
}
StackMacroAssembler masm; StackMacroAssembler masm;
Label bailoutTail; Label bailoutTail;
@ -290,22 +282,6 @@ bool JitRuntime::initialize(JSContext* cx) {
return false; return false;
} }
// TODO(bug 1530937): remove this after converting all VM functions.
for (VMFunction* fun = VMFunction::functions; fun; fun = fun->next) {
if (functionWrappers_->has(fun)) {
// Duplicate VMFunction definition. See VMFunction::hash.
continue;
}
JitSpew(JitSpew_Codegen, "# VM function wrapper (%s)", fun->name());
uint32_t offset;
if (!generateVMWrapper(cx, masm, *fun, fun->wrapped, &offset)) {
return false;
}
if (!functionWrappers_->putNew(fun, offset)) {
return false;
}
}
JitSpew(JitSpew_Codegen, "# Emitting profiler exit frame tail stub"); JitSpew(JitSpew_Codegen, "# Emitting profiler exit frame tail stub");
Label profilerExitTail; Label profilerExitTail;
generateProfilerExitFrameTailStub(masm, &profilerExitTail); generateProfilerExitFrameTailStub(masm, &profilerExitTail);
@ -634,16 +610,6 @@ uint32_t JitRuntime::getBailoutTableSize(
return bailoutTables_.ref()[frameClass.classId()].size; return bailoutTables_.ref()[frameClass.classId()].size;
} }
TrampolinePtr JitRuntime::getVMWrapper(const VMFunction& f) const {
MOZ_ASSERT(functionWrappers_);
MOZ_ASSERT(trampolineCode_);
JitRuntime::VMWrapperMap::Ptr p =
functionWrappers_->readonlyThreadsafeLookup(&f);
MOZ_ASSERT(p);
return trampolineCode(p->value());
}
void JitCodeHeader::init(JitCode* jitCode) { void JitCodeHeader::init(JitCode* jitCode) {
// As long as JitCode isn't moveable, we can avoid tracing this and // As long as JitCode isn't moveable, we can avoid tracing this and
// mutating executable data. // mutating executable data.

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

@ -1033,12 +1033,12 @@ static void TraceJitExitFrameCopiedArguments(JSTracer* trc,
doubleArgs -= f->doubleByRefArgs() * sizeof(double); doubleArgs -= f->doubleByRefArgs() * sizeof(double);
for (uint32_t explicitArg = 0; explicitArg < f->explicitArgs; explicitArg++) { for (uint32_t explicitArg = 0; explicitArg < f->explicitArgs; explicitArg++) {
if (f->argProperties(explicitArg) == VMFunction::DoubleByRef) { if (f->argProperties(explicitArg) == VMFunctionData::DoubleByRef) {
// Arguments with double size can only have RootValue type. // Arguments with double size can only have RootValue type.
if (f->argRootType(explicitArg) == VMFunction::RootValue) { if (f->argRootType(explicitArg) == VMFunctionData::RootValue) {
TraceRoot(trc, reinterpret_cast<Value*>(doubleArgs), "ion-vm-args"); TraceRoot(trc, reinterpret_cast<Value*>(doubleArgs), "ion-vm-args");
} else { } else {
MOZ_ASSERT(f->argRootType(explicitArg) == VMFunction::RootNone); MOZ_ASSERT(f->argRootType(explicitArg) == VMFunctionData::RootNone);
} }
doubleArgs += sizeof(double); doubleArgs += sizeof(double);
} }
@ -1136,9 +1136,9 @@ static void TraceJitExitFrame(JSTracer* trc, const JSJitFrameIter& frame) {
uint8_t* argBase = frame.exitFrame()->argBase(); uint8_t* argBase = frame.exitFrame()->argBase();
for (uint32_t explicitArg = 0; explicitArg < f->explicitArgs; explicitArg++) { for (uint32_t explicitArg = 0; explicitArg < f->explicitArgs; explicitArg++) {
switch (f->argRootType(explicitArg)) { switch (f->argRootType(explicitArg)) {
case VMFunction::RootNone: case VMFunctionData::RootNone:
break; break;
case VMFunction::RootObject: { case VMFunctionData::RootObject: {
// Sometimes we can bake in HandleObjects to nullptr. // Sometimes we can bake in HandleObjects to nullptr.
JSObject** pobj = reinterpret_cast<JSObject**>(argBase); JSObject** pobj = reinterpret_cast<JSObject**>(argBase);
if (*pobj) { if (*pobj) {
@ -1146,31 +1146,31 @@ static void TraceJitExitFrame(JSTracer* trc, const JSJitFrameIter& frame) {
} }
break; break;
} }
case VMFunction::RootString: case VMFunctionData::RootString:
TraceRoot(trc, reinterpret_cast<JSString**>(argBase), "ion-vm-args"); TraceRoot(trc, reinterpret_cast<JSString**>(argBase), "ion-vm-args");
break; break;
case VMFunction::RootFunction: case VMFunctionData::RootFunction:
TraceRoot(trc, reinterpret_cast<JSFunction**>(argBase), "ion-vm-args"); TraceRoot(trc, reinterpret_cast<JSFunction**>(argBase), "ion-vm-args");
break; break;
case VMFunction::RootValue: case VMFunctionData::RootValue:
TraceRoot(trc, reinterpret_cast<Value*>(argBase), "ion-vm-args"); TraceRoot(trc, reinterpret_cast<Value*>(argBase), "ion-vm-args");
break; break;
case VMFunction::RootId: case VMFunctionData::RootId:
TraceRoot(trc, reinterpret_cast<jsid*>(argBase), "ion-vm-args"); TraceRoot(trc, reinterpret_cast<jsid*>(argBase), "ion-vm-args");
break; break;
case VMFunction::RootCell: case VMFunctionData::RootCell:
TraceGenericPointerRoot(trc, reinterpret_cast<gc::Cell**>(argBase), TraceGenericPointerRoot(trc, reinterpret_cast<gc::Cell**>(argBase),
"ion-vm-args"); "ion-vm-args");
break; break;
} }
switch (f->argProperties(explicitArg)) { switch (f->argProperties(explicitArg)) {
case VMFunction::WordByValue: case VMFunctionData::WordByValue:
case VMFunction::WordByRef: case VMFunctionData::WordByRef:
argBase += sizeof(void*); argBase += sizeof(void*);
break; break;
case VMFunction::DoubleByValue: case VMFunctionData::DoubleByValue:
case VMFunction::DoubleByRef: case VMFunctionData::DoubleByRef:
argBase += 2 * sizeof(void*); argBase += 2 * sizeof(void*);
break; break;
} }
@ -1178,24 +1178,24 @@ static void TraceJitExitFrame(JSTracer* trc, const JSJitFrameIter& frame) {
if (f->outParam == Type_Handle) { if (f->outParam == Type_Handle) {
switch (f->outParamRootType) { switch (f->outParamRootType) {
case VMFunction::RootNone: case VMFunctionData::RootNone:
MOZ_CRASH("Handle outparam must have root type"); MOZ_CRASH("Handle outparam must have root type");
case VMFunction::RootObject: case VMFunctionData::RootObject:
TraceRoot(trc, footer->outParam<JSObject*>(), "ion-vm-out"); TraceRoot(trc, footer->outParam<JSObject*>(), "ion-vm-out");
break; break;
case VMFunction::RootString: case VMFunctionData::RootString:
TraceRoot(trc, footer->outParam<JSString*>(), "ion-vm-out"); TraceRoot(trc, footer->outParam<JSString*>(), "ion-vm-out");
break; break;
case VMFunction::RootFunction: case VMFunctionData::RootFunction:
TraceRoot(trc, footer->outParam<JSFunction*>(), "ion-vm-out"); TraceRoot(trc, footer->outParam<JSFunction*>(), "ion-vm-out");
break; break;
case VMFunction::RootValue: case VMFunctionData::RootValue:
TraceRoot(trc, footer->outParam<Value>(), "ion-vm-outvp"); TraceRoot(trc, footer->outParam<Value>(), "ion-vm-outvp");
break; break;
case VMFunction::RootId: case VMFunctionData::RootId:
TraceRoot(trc, footer->outParam<jsid>(), "ion-vm-outvp"); TraceRoot(trc, footer->outParam<jsid>(), "ion-vm-outvp");
break; break;
case VMFunction::RootCell: case VMFunctionData::RootCell:
TraceGenericPointerRoot(trc, footer->outParam<gc::Cell*>(), TraceGenericPointerRoot(trc, footer->outParam<gc::Cell*>(),
"ion-vm-out"); "ion-vm-out");
break; break;

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

@ -2995,38 +2995,38 @@ void MacroAssembler::PushValue(const Address& addr) {
framePushed_ += sizeof(Value); framePushed_ += sizeof(Value);
} }
void MacroAssembler::PushEmptyRooted(VMFunction::RootType rootType) { void MacroAssembler::PushEmptyRooted(VMFunctionData::RootType rootType) {
switch (rootType) { switch (rootType) {
case VMFunction::RootNone: case VMFunctionData::RootNone:
MOZ_CRASH("Handle must have root type"); MOZ_CRASH("Handle must have root type");
case VMFunction::RootObject: case VMFunctionData::RootObject:
case VMFunction::RootString: case VMFunctionData::RootString:
case VMFunction::RootFunction: case VMFunctionData::RootFunction:
case VMFunction::RootCell: case VMFunctionData::RootCell:
Push(ImmPtr(nullptr)); Push(ImmPtr(nullptr));
break; break;
case VMFunction::RootValue: case VMFunctionData::RootValue:
Push(UndefinedValue()); Push(UndefinedValue());
break; break;
case VMFunction::RootId: case VMFunctionData::RootId:
Push(ImmWord(JSID_BITS(JSID_VOID))); Push(ImmWord(JSID_BITS(JSID_VOID)));
break; break;
} }
} }
void MacroAssembler::popRooted(VMFunction::RootType rootType, Register cellReg, void MacroAssembler::popRooted(VMFunctionData::RootType rootType,
const ValueOperand& valueReg) { Register cellReg, const ValueOperand& valueReg) {
switch (rootType) { switch (rootType) {
case VMFunction::RootNone: case VMFunctionData::RootNone:
MOZ_CRASH("Handle must have root type"); MOZ_CRASH("Handle must have root type");
case VMFunction::RootObject: case VMFunctionData::RootObject:
case VMFunction::RootString: case VMFunctionData::RootString:
case VMFunction::RootFunction: case VMFunctionData::RootFunction:
case VMFunction::RootCell: case VMFunctionData::RootCell:
case VMFunction::RootId: case VMFunctionData::RootId:
Pop(cellReg); Pop(cellReg);
break; break;
case VMFunction::RootValue: case VMFunctionData::RootValue:
Pop(valueReg); Pop(valueReg);
break; break;
} }

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

@ -387,7 +387,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
void Push(const Value& val); void Push(const Value& val);
void Push(JSValueType type, Register reg); void Push(JSValueType type, Register reg);
void PushValue(const Address& addr); void PushValue(const Address& addr);
void PushEmptyRooted(VMFunction::RootType rootType); void PushEmptyRooted(VMFunctionData::RootType rootType);
inline CodeOffset PushWithPatch(ImmWord word); inline CodeOffset PushWithPatch(ImmWord word);
inline CodeOffset PushWithPatch(ImmPtr imm); inline CodeOffset PushWithPatch(ImmPtr imm);
@ -397,7 +397,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
void Pop(const ValueOperand& val) PER_SHARED_ARCH; void Pop(const ValueOperand& val) PER_SHARED_ARCH;
void PopFlags() DEFINED_ON(x86_shared); void PopFlags() DEFINED_ON(x86_shared);
void PopStackPtr() DEFINED_ON(arm, mips_shared, x86_shared); void PopStackPtr() DEFINED_ON(arm, mips_shared, x86_shared);
void popRooted(VMFunction::RootType rootType, Register cellReg, void popRooted(VMFunctionData::RootType rootType, Register cellReg,
const ValueOperand& valueReg); const ValueOperand& valueReg);
// Move the stack pointer based on the requested amount. // Move the stack pointer based on the requested amount.

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

@ -118,6 +118,7 @@ namespace jit {
_(GlobalNameConflictsCheckFromIon, js::jit::GlobalNameConflictsCheckFromIon) \ _(GlobalNameConflictsCheckFromIon, js::jit::GlobalNameConflictsCheckFromIon) \
_(GreaterThan, js::jit::GreaterThan) \ _(GreaterThan, js::jit::GreaterThan) \
_(GreaterThanOrEqual, js::jit::GreaterThanOrEqual) \ _(GreaterThanOrEqual, js::jit::GreaterThanOrEqual) \
_(HandleDebugTrap, js::jit::HandleDebugTrap) \
_(HomeObjectSuperBase, js::HomeObjectSuperBase) \ _(HomeObjectSuperBase, js::HomeObjectSuperBase) \
_(ImplicitThisOperation, js::ImplicitThisOperation) \ _(ImplicitThisOperation, js::ImplicitThisOperation) \
_(ImportMetaOperation, js::ImportMetaOperation) \ _(ImportMetaOperation, js::ImportMetaOperation) \

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

@ -67,12 +67,11 @@ struct VMFunctionDataHelper<R (*)(JSContext*, Args...)>
static constexpr uint64_t argumentRootTypes() { static constexpr uint64_t argumentRootTypes() {
return BitMask<TypeToRootType, uint64_t, 3, Args...>::result; return BitMask<TypeToRootType, uint64_t, 3, Args...>::result;
} }
constexpr explicit VMFunctionDataHelper( constexpr explicit VMFunctionDataHelper(const char* name)
const char* name, PopValues extraValuesToPop = PopValues(0))
: VMFunctionData(name, explicitArgs(), argumentProperties(), : VMFunctionData(name, explicitArgs(), argumentProperties(),
argumentPassedInFloatRegs(), argumentRootTypes(), argumentPassedInFloatRegs(), argumentRootTypes(),
outParam(), outParamRootType(), returnType(), outParam(), outParamRootType(), returnType(),
extraValuesToPop.numValues, NonTailCall) {} /* extraValuesToPop = */ 0, NonTailCall) {}
constexpr explicit VMFunctionDataHelper(const char* name, constexpr explicit VMFunctionDataHelper(const char* name,
MaybeTailCall expectTailCall, MaybeTailCall expectTailCall,
PopValues extraValuesToPop) PopValues extraValuesToPop)
@ -187,10 +186,6 @@ bool JitRuntime::generateVMWrappers(JSContext* cx, MacroAssembler& masm) {
return true; return true;
} }
// Statics are initialized to null.
/* static */
VMFunction* VMFunction::functions;
AutoDetectInvalidation::AutoDetectInvalidation(JSContext* cx, AutoDetectInvalidation::AutoDetectInvalidation(JSContext* cx,
MutableHandleValue rval) MutableHandleValue rval)
: cx_(cx), : cx_(cx),

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

@ -56,8 +56,6 @@ enum MaybeTailCall : bool { TailCall, NonTailCall };
// [SMDOC] JIT-to-C++ Function Calls. (callVM) // [SMDOC] JIT-to-C++ Function Calls. (callVM)
// //
// TODO(bug 1530937): update this comment after converting all VM functions.
//
// Sometimes it is easier to reuse C++ code by calling VM's functions. Calling a // Sometimes it is easier to reuse C++ code by calling VM's functions. Calling a
// function from the VM can be achieved with the use of callWithABI but this is // function from the VM can be achieved with the use of callWithABI but this is
// discouraged when the called functions might trigger exceptions and/or // discouraged when the called functions might trigger exceptions and/or
@ -65,15 +63,15 @@ enum MaybeTailCall : bool { TailCall, NonTailCall };
// callVM are interfaces provided to handle the exception handling and register // callVM are interfaces provided to handle the exception handling and register
// the stack end (JITActivation) such that walking the stack is made possible. // the stack end (JITActivation) such that walking the stack is made possible.
// //
// A VMFunction is a structure which contains the necessary information needed // VMFunctionData is a structure which contains the necessary information needed
// for generating a trampoline function to make a call (with generateVMWrapper) // for generating a trampoline function to make a call (with generateVMWrapper)
// and to root the arguments of the function (in TraceJitExitFrame). VMFunctions // and to root the arguments of the function (in TraceJitExitFrame).
// are created with the FunctionInfo template, which infers the fields of the // VMFunctionData is created with the VMFunctionDataHelper template, which
// VMFunction from the function signature. The rooting and trampoline code is // infers the VMFunctionData fields from the function signature. The rooting and
// therefore determined by the arguments of a function and their locations in // trampoline code is therefore determined by the arguments of a function and
// the signature of a function. // their locations in the signature of a function.
// //
// VMFunction all expect a JSContext* as first argument. This argument is // VM functions all expect a JSContext* as first argument. This argument is
// implicitly provided by the trampoline code (in generateVMWrapper) and used // implicitly provided by the trampoline code (in generateVMWrapper) and used
// for creating new objects or reporting errors. If your function does not make // for creating new objects or reporting errors. If your function does not make
// use of a JSContext* argument, then you might probably use a callWithABI // use of a JSContext* argument, then you might probably use a callWithABI
@ -90,9 +88,9 @@ enum MaybeTailCall : bool { TailCall, NonTailCall };
// JIT Code usage: // JIT Code usage:
// //
// Different JIT compilers in SpiderMonkey have their own implementations of // Different JIT compilers in SpiderMonkey have their own implementations of
// callVM to consume VMFunctions. However, the general shape of them is that // callVM to call VM functions. However, the general shape of them is that
// arguments that don't include the JIT Context or trailing out-param are pushed // arguments (excluding the JSContext or trailing out-param) are pushed on to
// on to the stack from right to left (rightmost argument is pushed first). // the stack from right to left (rightmost argument is pushed first).
// //
// Regardless of return value protocol being used (final outParam, or return // Regardless of return value protocol being used (final outParam, or return
// value) the generated trampolines ensure the return value ends up in // value) the generated trampolines ensure the return value ends up in
@ -110,18 +108,19 @@ enum MaybeTailCall : bool { TailCall, NonTailCall };
// //
// This function returns true on success, and z is the outparam return value. // This function returns true on success, and z is the outparam return value.
// //
// A VMFunction for this can be created using FunctionInfo. The typical pattern // A VM function wrapper for this can be created by adding an entry to
// used is: // VM_FUNCTION_LIST in VMFunctionList-inl.h:
// //
// typedef bool (*FooFn)(JSContext*, HandleObject, HandleId, // _(Foo, js::Foo)
// MutableHandleValue);
// const VMFunction FooInfo = FunctionInfo<FooFn>(Foo, "Foo");
// //
// In the compiler code the call would then be issued like this: // In the compiler code the call would then be issued like this:
// //
// masm.Push(id); // masm.Push(id);
// masm.Push(obj); // masm.Push(obj);
// if (!callVM(FooInfo)) { //
// using Fn = bool (*)(JSContext*, HandleObject, HandleId,
// MutableHandleValue);
// if (!callVM<Fn, js::Foo>()) {
// return false; // return false;
// } // }
// //
@ -318,86 +317,7 @@ struct VMFunctionData {
returnType == Type_Object); returnType == Type_Object);
} }
// Note: clang-tidy suggests using |= auto| here but that generates extra constexpr VMFunctionData(const VMFunctionData& o) = default;
// static initializers for old-style VMFunction definitions with Clang. We can
// do this after bug 1530937 converts all of them.
constexpr VMFunctionData(const VMFunctionData& o)
:
#if defined(JS_JITSPEW) || defined(JS_TRACE_LOGGING)
name_(o.name_),
#endif
argumentRootTypes(o.argumentRootTypes),
argumentProperties(o.argumentProperties),
argumentPassedInFloatRegs(o.argumentPassedInFloatRegs),
explicitArgs(o.explicitArgs),
outParamRootType(o.outParamRootType),
outParam(o.outParam),
returnType(o.returnType),
extraValuesToPop(o.extraValuesToPop),
expectTailCall(o.expectTailCall) {
}
};
// TODO(bug 1530937): remove VMFunction and FunctionInfo after converting all VM
// functions to the new design.
struct VMFunction : public VMFunctionData {
// Address of the C function.
void* wrapped;
// Global linked list of all VMFunctions.
static VMFunction* functions;
VMFunction* next;
constexpr VMFunction(void* wrapped, const char* name, uint32_t explicitArgs,
uint32_t argumentProperties,
uint32_t argumentPassedInFloatRegs,
uint64_t argRootTypes, DataType outParam,
RootType outParamRootType, DataType returnType,
uint8_t extraValuesToPop = 0,
MaybeTailCall expectTailCall = NonTailCall)
: VMFunctionData(name, explicitArgs, argumentProperties,
argumentPassedInFloatRegs, argRootTypes, outParam,
outParamRootType, returnType, extraValuesToPop,
expectTailCall),
wrapped(wrapped),
next(nullptr) {}
VMFunction(const VMFunction& o)
: VMFunctionData(o), wrapped(o.wrapped), next(functions) {
// Add this to the global list of VMFunctions.
functions = this;
}
typedef const VMFunction* Lookup;
static HashNumber hash(const VMFunction* f) {
// The hash is based on the wrapped function, not the VMFunction*, to
// avoid generating duplicate wrapper code.
HashNumber hash = 0;
hash = mozilla::AddToHash(hash, f->wrapped);
hash = mozilla::AddToHash(hash, f->expectTailCall);
return hash;
}
static bool match(const VMFunction* f1, const VMFunction* f2) {
if (f1->wrapped != f2->wrapped ||
f1->expectTailCall != f2->expectTailCall) {
return false;
}
// If this starts failing, add extraValuesToPop to the if-statement and
// hash() method above.
MOZ_ASSERT(f1->extraValuesToPop == f2->extraValuesToPop);
MOZ_ASSERT(strcmp(f1->name_, f2->name_) == 0);
MOZ_ASSERT(f1->explicitArgs == f2->explicitArgs);
MOZ_ASSERT(f1->argumentProperties == f2->argumentProperties);
MOZ_ASSERT(f1->argumentPassedInFloatRegs == f2->argumentPassedInFloatRegs);
MOZ_ASSERT(f1->outParam == f2->outParam);
MOZ_ASSERT(f1->returnType == f2->returnType);
MOZ_ASSERT(f1->argumentRootTypes == f2->argumentRootTypes);
MOZ_ASSERT(f1->outParamRootType == f2->outParamRootType);
return true;
}
}; };
template <class> template <class>
@ -544,113 +464,115 @@ struct TypeToDataType<HandleId> {
template <class T> template <class T>
struct TypeToArgProperties { struct TypeToArgProperties {
static const uint32_t result = static const uint32_t result =
(sizeof(T) <= sizeof(void*) ? VMFunction::Word : VMFunction::Double); (sizeof(T) <= sizeof(void*) ? VMFunctionData::Word
: VMFunctionData::Double);
}; };
template <> template <>
struct TypeToArgProperties<const Value&> { struct TypeToArgProperties<const Value&> {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<Value>::result | VMFunction::ByRef; TypeToArgProperties<Value>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<HandleObject> { struct TypeToArgProperties<HandleObject> {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<JSObject*>::result | VMFunction::ByRef; TypeToArgProperties<JSObject*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<HandleString> { struct TypeToArgProperties<HandleString> {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<JSString*>::result | VMFunction::ByRef; TypeToArgProperties<JSString*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<HandlePropertyName> { struct TypeToArgProperties<HandlePropertyName> {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<PropertyName*>::result | VMFunction::ByRef; TypeToArgProperties<PropertyName*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<HandleFunction> { struct TypeToArgProperties<HandleFunction> {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<JSFunction*>::result | VMFunction::ByRef; TypeToArgProperties<JSFunction*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<Handle<NativeObject*> > { struct TypeToArgProperties<Handle<NativeObject*> > {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<NativeObject*>::result | VMFunction::ByRef; TypeToArgProperties<NativeObject*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<Handle<InlineTypedObject*> > { struct TypeToArgProperties<Handle<InlineTypedObject*> > {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<InlineTypedObject*>::result | VMFunction::ByRef; TypeToArgProperties<InlineTypedObject*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<Handle<ArrayObject*> > { struct TypeToArgProperties<Handle<ArrayObject*> > {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<ArrayObject*>::result | VMFunction::ByRef; TypeToArgProperties<ArrayObject*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<Handle<AbstractGeneratorObject*> > { struct TypeToArgProperties<Handle<AbstractGeneratorObject*> > {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<AbstractGeneratorObject*>::result | VMFunction::ByRef; TypeToArgProperties<AbstractGeneratorObject*>::result |
VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<Handle<AsyncFunctionGeneratorObject*> > { struct TypeToArgProperties<Handle<AsyncFunctionGeneratorObject*> > {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<AsyncFunctionGeneratorObject*>::result | TypeToArgProperties<AsyncFunctionGeneratorObject*>::result |
VMFunction::ByRef; VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<Handle<PlainObject*> > { struct TypeToArgProperties<Handle<PlainObject*> > {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<PlainObject*>::result | VMFunction::ByRef; TypeToArgProperties<PlainObject*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<Handle<RegExpObject*> > { struct TypeToArgProperties<Handle<RegExpObject*> > {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<RegExpObject*>::result | VMFunction::ByRef; TypeToArgProperties<RegExpObject*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<Handle<WithScope*> > { struct TypeToArgProperties<Handle<WithScope*> > {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<WithScope*>::result | VMFunction::ByRef; TypeToArgProperties<WithScope*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<Handle<LexicalScope*> > { struct TypeToArgProperties<Handle<LexicalScope*> > {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<LexicalScope*>::result | VMFunction::ByRef; TypeToArgProperties<LexicalScope*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<Handle<Scope*> > { struct TypeToArgProperties<Handle<Scope*> > {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<Scope*>::result | VMFunction::ByRef; TypeToArgProperties<Scope*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<HandleScript> { struct TypeToArgProperties<HandleScript> {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<JSScript*>::result | VMFunction::ByRef; TypeToArgProperties<JSScript*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<HandleValue> { struct TypeToArgProperties<HandleValue> {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<Value>::result | VMFunction::ByRef; TypeToArgProperties<Value>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<MutableHandleValue> { struct TypeToArgProperties<MutableHandleValue> {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<Value>::result | VMFunction::ByRef; TypeToArgProperties<Value>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<HandleId> { struct TypeToArgProperties<HandleId> {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<jsid>::result | VMFunction::ByRef; TypeToArgProperties<jsid>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<HandleShape> { struct TypeToArgProperties<HandleShape> {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<Shape*>::result | VMFunction::ByRef; TypeToArgProperties<Shape*>::result | VMFunctionData::ByRef;
}; };
template <> template <>
struct TypeToArgProperties<HandleObjectGroup> { struct TypeToArgProperties<HandleObjectGroup> {
static const uint32_t result = static const uint32_t result =
TypeToArgProperties<ObjectGroup*>::result | VMFunction::ByRef; TypeToArgProperties<ObjectGroup*>::result | VMFunctionData::ByRef;
}; };
// Convert argument type to whether or not it should be passed in a float // Convert argument type to whether or not it should be passed in a float
@ -667,87 +589,87 @@ struct TypeToPassInFloatReg<double> {
// Convert argument types to root types used by the gc, see MarkJitExitFrame. // Convert argument types to root types used by the gc, see MarkJitExitFrame.
template <class T> template <class T>
struct TypeToRootType { struct TypeToRootType {
static const uint32_t result = VMFunction::RootNone; static const uint32_t result = VMFunctionData::RootNone;
}; };
template <> template <>
struct TypeToRootType<HandleObject> { struct TypeToRootType<HandleObject> {
static const uint32_t result = VMFunction::RootObject; static const uint32_t result = VMFunctionData::RootObject;
}; };
template <> template <>
struct TypeToRootType<HandleString> { struct TypeToRootType<HandleString> {
static const uint32_t result = VMFunction::RootString; static const uint32_t result = VMFunctionData::RootString;
}; };
template <> template <>
struct TypeToRootType<HandlePropertyName> { struct TypeToRootType<HandlePropertyName> {
static const uint32_t result = VMFunction::RootString; static const uint32_t result = VMFunctionData::RootString;
}; };
template <> template <>
struct TypeToRootType<HandleFunction> { struct TypeToRootType<HandleFunction> {
static const uint32_t result = VMFunction::RootFunction; static const uint32_t result = VMFunctionData::RootFunction;
}; };
template <> template <>
struct TypeToRootType<HandleValue> { struct TypeToRootType<HandleValue> {
static const uint32_t result = VMFunction::RootValue; static const uint32_t result = VMFunctionData::RootValue;
}; };
template <> template <>
struct TypeToRootType<MutableHandleValue> { struct TypeToRootType<MutableHandleValue> {
static const uint32_t result = VMFunction::RootValue; static const uint32_t result = VMFunctionData::RootValue;
}; };
template <> template <>
struct TypeToRootType<HandleId> { struct TypeToRootType<HandleId> {
static const uint32_t result = VMFunction::RootId; static const uint32_t result = VMFunctionData::RootId;
}; };
template <> template <>
struct TypeToRootType<HandleShape> { struct TypeToRootType<HandleShape> {
static const uint32_t result = VMFunction::RootCell; static const uint32_t result = VMFunctionData::RootCell;
}; };
template <> template <>
struct TypeToRootType<HandleObjectGroup> { struct TypeToRootType<HandleObjectGroup> {
static const uint32_t result = VMFunction::RootCell; static const uint32_t result = VMFunctionData::RootCell;
}; };
template <> template <>
struct TypeToRootType<HandleScript> { struct TypeToRootType<HandleScript> {
static const uint32_t result = VMFunction::RootCell; static const uint32_t result = VMFunctionData::RootCell;
}; };
template <> template <>
struct TypeToRootType<Handle<NativeObject*> > { struct TypeToRootType<Handle<NativeObject*> > {
static const uint32_t result = VMFunction::RootObject; static const uint32_t result = VMFunctionData::RootObject;
}; };
template <> template <>
struct TypeToRootType<Handle<InlineTypedObject*> > { struct TypeToRootType<Handle<InlineTypedObject*> > {
static const uint32_t result = VMFunction::RootObject; static const uint32_t result = VMFunctionData::RootObject;
}; };
template <> template <>
struct TypeToRootType<Handle<ArrayObject*> > { struct TypeToRootType<Handle<ArrayObject*> > {
static const uint32_t result = VMFunction::RootObject; static const uint32_t result = VMFunctionData::RootObject;
}; };
template <> template <>
struct TypeToRootType<Handle<AbstractGeneratorObject*> > { struct TypeToRootType<Handle<AbstractGeneratorObject*> > {
static const uint32_t result = VMFunction::RootObject; static const uint32_t result = VMFunctionData::RootObject;
}; };
template <> template <>
struct TypeToRootType<Handle<AsyncFunctionGeneratorObject*> > { struct TypeToRootType<Handle<AsyncFunctionGeneratorObject*> > {
static const uint32_t result = VMFunction::RootObject; static const uint32_t result = VMFunctionData::RootObject;
}; };
template <> template <>
struct TypeToRootType<Handle<PlainObject*> > { struct TypeToRootType<Handle<PlainObject*> > {
static const uint32_t result = VMFunction::RootObject; static const uint32_t result = VMFunctionData::RootObject;
}; };
template <> template <>
struct TypeToRootType<Handle<RegExpObject*> > { struct TypeToRootType<Handle<RegExpObject*> > {
static const uint32_t result = VMFunction::RootObject; static const uint32_t result = VMFunctionData::RootObject;
}; };
template <> template <>
struct TypeToRootType<Handle<LexicalScope*> > { struct TypeToRootType<Handle<LexicalScope*> > {
static const uint32_t result = VMFunction::RootCell; static const uint32_t result = VMFunctionData::RootCell;
}; };
template <> template <>
struct TypeToRootType<Handle<WithScope*> > { struct TypeToRootType<Handle<WithScope*> > {
static const uint32_t result = VMFunction::RootCell; static const uint32_t result = VMFunctionData::RootCell;
}; };
template <> template <>
struct TypeToRootType<Handle<Scope*> > { struct TypeToRootType<Handle<Scope*> > {
static const uint32_t result = VMFunction::RootCell; static const uint32_t result = VMFunctionData::RootCell;
}; };
template <class T> template <class T>
struct TypeToRootType<Handle<T> > { struct TypeToRootType<Handle<T> > {
@ -797,19 +719,19 @@ struct OutParamToDataType<MutableHandleString> {
template <class> template <class>
struct OutParamToRootType { struct OutParamToRootType {
static const VMFunction::RootType result = VMFunction::RootNone; static const VMFunctionData::RootType result = VMFunctionData::RootNone;
}; };
template <> template <>
struct OutParamToRootType<MutableHandleValue> { struct OutParamToRootType<MutableHandleValue> {
static const VMFunction::RootType result = VMFunction::RootValue; static const VMFunctionData::RootType result = VMFunctionData::RootValue;
}; };
template <> template <>
struct OutParamToRootType<MutableHandleObject> { struct OutParamToRootType<MutableHandleObject> {
static const VMFunction::RootType result = VMFunction::RootObject; static const VMFunctionData::RootType result = VMFunctionData::RootObject;
}; };
template <> template <>
struct OutParamToRootType<MutableHandleString> { struct OutParamToRootType<MutableHandleString> {
static const VMFunction::RootType result = VMFunction::RootString; static const VMFunctionData::RootType result = VMFunctionData::RootString;
}; };
// Extract the last element of a list of types. // Extract the last element of a list of types.
@ -862,52 +784,6 @@ struct BitMask<Each, ResultType, Shift, HeadType, TailTypes...> {
(BitMask<Each, ResultType, Shift, TailTypes...>::result << Shift); (BitMask<Each, ResultType, Shift, TailTypes...>::result << Shift);
}; };
// Extract VMFunction properties based on the signature of the function. The
// properties are used to generate the logic for calling the VM function, and
// also for marking the stack during GCs.
template <typename... Args>
struct FunctionInfo;
template <class R, typename... Args>
struct FunctionInfo<R (*)(JSContext*, Args...)> : public VMFunction {
using pf = R (*)(JSContext*, Args...);
static DataType returnType() { return TypeToDataType<R>::result; }
static DataType outParam() {
return OutParamToDataType<typename LastArg<Args...>::Type>::result;
}
static RootType outParamRootType() {
return OutParamToRootType<typename LastArg<Args...>::Type>::result;
}
static size_t NbArgs() { return LastArg<Args...>::nbArgs; }
static size_t explicitArgs() {
return NbArgs() - (outParam() != Type_Void ? 1 : 0);
}
static uint32_t argumentProperties() {
return BitMask<TypeToArgProperties, uint32_t, 2, Args...>::result;
}
static uint32_t argumentPassedInFloatRegs() {
return BitMask<TypeToPassInFloatReg, uint32_t, 2, Args...>::result;
}
static uint64_t argumentRootTypes() {
return BitMask<TypeToRootType, uint64_t, 3, Args...>::result;
}
explicit FunctionInfo(pf fun, const char* name,
PopValues extraValuesToPop = PopValues(0))
: VMFunction(JS_FUNC_TO_DATA_PTR(void*, fun), name, explicitArgs(),
argumentProperties(), argumentPassedInFloatRegs(),
argumentRootTypes(), outParam(), outParamRootType(),
returnType(), extraValuesToPop.numValues, NonTailCall) {
}
explicit FunctionInfo(pf fun, const char* name, MaybeTailCall expectTailCall,
PopValues extraValuesToPop = PopValues(0))
: VMFunction(JS_FUNC_TO_DATA_PTR(void*, fun), name, explicitArgs(),
argumentProperties(), argumentPassedInFloatRegs(),
argumentRootTypes(), outParam(), outParamRootType(),
returnType(), extraValuesToPop.numValues, expectTailCall) {
}
};
class AutoDetectInvalidation { class AutoDetectInvalidation {
JSContext* cx_; JSContext* cx_;
IonScript* ionScript_; IonScript* ionScript_;

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

@ -18,6 +18,7 @@
#include "jit/MacroAssembler-inl.h" #include "jit/MacroAssembler-inl.h"
#include "jit/SharedICHelpers-inl.h" #include "jit/SharedICHelpers-inl.h"
#include "jit/VMFunctionList-inl.h"
using namespace js; using namespace js;
using namespace js::jit; using namespace js::jit;
@ -706,8 +707,6 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm, bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
const VMFunctionData& f, void* nativeFun, const VMFunctionData& f, void* nativeFun,
uint32_t* wrapperOffset) { uint32_t* wrapperOffset) {
MOZ_ASSERT(functionWrappers_);
*wrapperOffset = startTrampolineCode(masm); *wrapperOffset = startTrampolineCode(masm);
AllocatableGeneralRegisterSet regs(Register::Codes::WrapperMask); AllocatableGeneralRegisterSet regs(Register::Codes::WrapperMask);
@ -794,24 +793,24 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
// Copy any arguments. // Copy any arguments.
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) { for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
switch (f.argProperties(explicitArg)) { switch (f.argProperties(explicitArg)) {
case VMFunction::WordByValue: case VMFunctionData::WordByValue:
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL); masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL);
argDisp += sizeof(void*); argDisp += sizeof(void*);
break; break;
case VMFunction::DoubleByValue: case VMFunctionData::DoubleByValue:
// Values should be passed by reference, not by value, so we assert // Values should be passed by reference, not by value, so we assert
// that the argument is a double-precision float. // that the argument is a double-precision float.
MOZ_ASSERT(f.argPassedInFloatReg(explicitArg)); MOZ_ASSERT(f.argPassedInFloatReg(explicitArg));
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::DOUBLE); masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::DOUBLE);
argDisp += sizeof(double); argDisp += sizeof(double);
break; break;
case VMFunction::WordByRef: case VMFunctionData::WordByRef:
masm.passABIArg( masm.passABIArg(
MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS), MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
MoveOp::GENERAL); MoveOp::GENERAL);
argDisp += sizeof(void*); argDisp += sizeof(void*);
break; break;
case VMFunction::DoubleByRef: case VMFunctionData::DoubleByRef:
masm.passABIArg( masm.passABIArg(
MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS), MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
MoveOp::GENERAL); MoveOp::GENERAL);
@ -949,10 +948,6 @@ uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
return offset; return offset;
} }
typedef bool (*HandleDebugTrapFn)(JSContext*, BaselineFrame*, uint8_t*, bool*);
static const VMFunction HandleDebugTrapInfo =
FunctionInfo<HandleDebugTrapFn>(HandleDebugTrap, "HandleDebugTrap");
JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) { JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
StackMacroAssembler masm; StackMacroAssembler masm;
@ -969,8 +964,10 @@ JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
masm.movePtr(ImmPtr(nullptr), ICStubReg); masm.movePtr(ImmPtr(nullptr), ICStubReg);
EmitBaselineEnterStubFrame(masm, scratch2); EmitBaselineEnterStubFrame(masm, scratch2);
TrampolinePtr code = using Fn = bool (*)(JSContext*, BaselineFrame*, uint8_t*, bool*);
cx->runtime()->jitRuntime()->getVMWrapper(HandleDebugTrapInfo); VMFunctionId id = VMFunctionToId<Fn, jit::HandleDebugTrap>::id;
TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(id);
masm.push(lr); masm.push(lr);
masm.push(scratch1); masm.push(scratch1);
EmitBaselineCallVM(code, masm); EmitBaselineCallVM(code, masm);

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

@ -16,6 +16,7 @@
#include "jit/MacroAssembler-inl.h" #include "jit/MacroAssembler-inl.h"
#include "jit/SharedICHelpers-inl.h" #include "jit/SharedICHelpers-inl.h"
#include "jit/VMFunctionList-inl.h"
using namespace js; using namespace js;
using namespace js::jit; using namespace js::jit;
@ -535,8 +536,6 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm, bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
const VMFunctionData& f, void* nativeFun, const VMFunctionData& f, void* nativeFun,
uint32_t* wrapperOffset) { uint32_t* wrapperOffset) {
MOZ_ASSERT(functionWrappers_);
*wrapperOffset = startTrampolineCode(masm); *wrapperOffset = startTrampolineCode(masm);
// Avoid conflicts with argument registers while discarding the result after // Avoid conflicts with argument registers while discarding the result after
@ -629,22 +628,22 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
// Copy arguments. // Copy arguments.
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) { for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
switch (f.argProperties(explicitArg)) { switch (f.argProperties(explicitArg)) {
case VMFunction::WordByValue: case VMFunctionData::WordByValue:
masm.passABIArg(MoveOperand(argsBase, argDisp), masm.passABIArg(MoveOperand(argsBase, argDisp),
(f.argPassedInFloatReg(explicitArg) ? MoveOp::DOUBLE (f.argPassedInFloatReg(explicitArg) ? MoveOp::DOUBLE
: MoveOp::GENERAL)); : MoveOp::GENERAL));
argDisp += sizeof(void*); argDisp += sizeof(void*);
break; break;
case VMFunction::WordByRef: case VMFunctionData::WordByRef:
masm.passABIArg( masm.passABIArg(
MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS), MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
MoveOp::GENERAL); MoveOp::GENERAL);
argDisp += sizeof(void*); argDisp += sizeof(void*);
break; break;
case VMFunction::DoubleByValue: case VMFunctionData::DoubleByValue:
case VMFunction::DoubleByRef: case VMFunctionData::DoubleByRef:
MOZ_CRASH("NYI: AArch64 callVM should not be used with 128bit values."); MOZ_CRASH("NYI: AArch64 callVM should not be used with 128bit values.");
} }
} }
@ -787,10 +786,6 @@ uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
return offset; return offset;
} }
typedef bool (*HandleDebugTrapFn)(JSContext*, BaselineFrame*, uint8_t*, bool*);
static const VMFunction HandleDebugTrapInfo =
FunctionInfo<HandleDebugTrapFn>(HandleDebugTrap, "HandleDebugTrap");
JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) { JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
StackMacroAssembler masm(cx); StackMacroAssembler masm(cx);
#ifndef JS_USE_LINK_REGISTER #ifndef JS_USE_LINK_REGISTER
@ -812,8 +807,10 @@ JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
masm.movePtr(ImmPtr(nullptr), ICStubReg); masm.movePtr(ImmPtr(nullptr), ICStubReg);
EmitBaselineEnterStubFrame(masm, scratch2); EmitBaselineEnterStubFrame(masm, scratch2);
TrampolinePtr code = using Fn = bool (*)(JSContext*, BaselineFrame*, uint8_t*, bool*);
cx->runtime()->jitRuntime()->getVMWrapper(HandleDebugTrapInfo); VMFunctionId id = VMFunctionToId<Fn, jit::HandleDebugTrap>::id;
TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(id);
masm.asVIXL().Push(vixl::lr, ARMRegister(scratch1, 64)); masm.asVIXL().Push(vixl::lr, ARMRegister(scratch1, 64));
EmitBaselineCallVM(code, masm); EmitBaselineCallVM(code, masm);

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

@ -17,6 +17,7 @@
#include "jit/MacroAssembler-inl.h" #include "jit/MacroAssembler-inl.h"
#include "jit/SharedICHelpers-inl.h" #include "jit/SharedICHelpers-inl.h"
#include "jit/VMFunctionList-inl.h"
using namespace js; using namespace js;
using namespace js::jit; using namespace js::jit;
@ -593,8 +594,6 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm, bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
const VMFunctionData& f, void* nativeFun, const VMFunctionData& f, void* nativeFun,
uint32_t* wrapperOffset) { uint32_t* wrapperOffset) {
MOZ_ASSERT(functionWrappers_);
*wrapperOffset = startTrampolineCode(masm); *wrapperOffset = startTrampolineCode(masm);
// Avoid conflicts with argument registers while discarding the result after // Avoid conflicts with argument registers while discarding the result after
@ -678,7 +677,7 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
// Copy arguments. // Copy arguments.
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) { for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
switch (f.argProperties(explicitArg)) { switch (f.argProperties(explicitArg)) {
case VMFunction::WordByValue: case VMFunctionData::WordByValue:
if (f.argPassedInFloatReg(explicitArg)) { if (f.argPassedInFloatReg(explicitArg)) {
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::DOUBLE); masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::DOUBLE);
} else { } else {
@ -686,14 +685,14 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
} }
argDisp += sizeof(void*); argDisp += sizeof(void*);
break; break;
case VMFunction::WordByRef: case VMFunctionData::WordByRef:
masm.passABIArg( masm.passABIArg(
MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS), MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
MoveOp::GENERAL); MoveOp::GENERAL);
argDisp += sizeof(void*); argDisp += sizeof(void*);
break; break;
case VMFunction::DoubleByValue: case VMFunctionData::DoubleByValue:
case VMFunction::DoubleByRef: case VMFunctionData::DoubleByRef:
MOZ_CRASH("NYI: x64 callVM should not be used with 128bits values."); MOZ_CRASH("NYI: x64 callVM should not be used with 128bits values.");
} }
} }
@ -821,10 +820,6 @@ uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
return offset; return offset;
} }
typedef bool (*HandleDebugTrapFn)(JSContext*, BaselineFrame*, uint8_t*, bool*);
static const VMFunction HandleDebugTrapInfo =
FunctionInfo<HandleDebugTrapFn>(HandleDebugTrap, "HandleDebugTrap");
JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) { JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
StackMacroAssembler masm; StackMacroAssembler masm;
#ifndef JS_USE_LINK_REGISTER #ifndef JS_USE_LINK_REGISTER
@ -850,8 +845,10 @@ JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
masm.movePtr(ImmPtr(nullptr), ICStubReg); masm.movePtr(ImmPtr(nullptr), ICStubReg);
EmitBaselineEnterStubFrame(masm, scratch3); EmitBaselineEnterStubFrame(masm, scratch3);
TrampolinePtr code = using Fn = bool (*)(JSContext*, BaselineFrame*, uint8_t*, bool*);
cx->runtime()->jitRuntime()->getVMWrapper(HandleDebugTrapInfo); VMFunctionId id = VMFunctionToId<Fn, jit::HandleDebugTrap>::id;
TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(id);
masm.push(scratch1); masm.push(scratch1);
masm.push(scratch2); masm.push(scratch2);
EmitBaselineCallVM(code, masm); EmitBaselineCallVM(code, masm);

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

@ -22,6 +22,7 @@
#include "jit/MacroAssembler-inl.h" #include "jit/MacroAssembler-inl.h"
#include "jit/SharedICHelpers-inl.h" #include "jit/SharedICHelpers-inl.h"
#include "jit/VMFunctionList-inl.h"
#include "vm/JSScript-inl.h" #include "vm/JSScript-inl.h"
using mozilla::IsPowerOfTwo; using mozilla::IsPowerOfTwo;
@ -610,8 +611,6 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm, bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
const VMFunctionData& f, void* nativeFun, const VMFunctionData& f, void* nativeFun,
uint32_t* wrapperOffset) { uint32_t* wrapperOffset) {
MOZ_ASSERT(functionWrappers_);
*wrapperOffset = startTrampolineCode(masm); *wrapperOffset = startTrampolineCode(masm);
// Avoid conflicts with argument registers while discarding the result after // Avoid conflicts with argument registers while discarding the result after
@ -688,11 +687,11 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
// Copy arguments. // Copy arguments.
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) { for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
switch (f.argProperties(explicitArg)) { switch (f.argProperties(explicitArg)) {
case VMFunction::WordByValue: case VMFunctionData::WordByValue:
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL); masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL);
argDisp += sizeof(void*); argDisp += sizeof(void*);
break; break;
case VMFunction::DoubleByValue: case VMFunctionData::DoubleByValue:
// We don't pass doubles in float registers on x86, so no need // We don't pass doubles in float registers on x86, so no need
// to check for argPassedInFloatReg. // to check for argPassedInFloatReg.
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL); masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL);
@ -700,13 +699,13 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL); masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL);
argDisp += sizeof(void*); argDisp += sizeof(void*);
break; break;
case VMFunction::WordByRef: case VMFunctionData::WordByRef:
masm.passABIArg( masm.passABIArg(
MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS), MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
MoveOp::GENERAL); MoveOp::GENERAL);
argDisp += sizeof(void*); argDisp += sizeof(void*);
break; break;
case VMFunction::DoubleByRef: case VMFunctionData::DoubleByRef:
masm.passABIArg( masm.passABIArg(
MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS), MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
MoveOp::GENERAL); MoveOp::GENERAL);
@ -840,10 +839,6 @@ uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
return offset; return offset;
} }
typedef bool (*HandleDebugTrapFn)(JSContext*, BaselineFrame*, uint8_t*, bool*);
static const VMFunction HandleDebugTrapInfo =
FunctionInfo<HandleDebugTrapFn>(HandleDebugTrap, "HandleDebugTrap");
JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) { JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
StackMacroAssembler masm; StackMacroAssembler masm;
#ifndef JS_USE_LINK_REGISTER #ifndef JS_USE_LINK_REGISTER
@ -869,8 +864,10 @@ JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
masm.movePtr(ImmPtr(nullptr), ICStubReg); masm.movePtr(ImmPtr(nullptr), ICStubReg);
EmitBaselineEnterStubFrame(masm, scratch3); EmitBaselineEnterStubFrame(masm, scratch3);
TrampolinePtr code = using Fn = bool (*)(JSContext*, BaselineFrame*, uint8_t*, bool*);
cx->runtime()->jitRuntime()->getVMWrapper(HandleDebugTrapInfo); VMFunctionId id = VMFunctionToId<Fn, jit::HandleDebugTrap>::id;
TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(id);
masm.push(scratch1); masm.push(scratch1);
masm.push(scratch2); masm.push(scratch2);
EmitBaselineCallVM(code, masm); EmitBaselineCallVM(code, masm);