зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
aac57cc8b5
Коммит
e0b761d01f
|
@ -1773,13 +1773,6 @@ bool DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame,
|
|||
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) {
|
||||
// Just store false into R1.scratchReg() and return.
|
||||
masm.move32(Imm32(0), R1.scratchReg());
|
||||
|
|
|
@ -1490,8 +1490,6 @@ class ICTypeMonitor_AnyValue : public ICStub {
|
|||
|
||||
// TypeUpdate
|
||||
|
||||
extern const VMFunction DoTypeUpdateFallbackInfo;
|
||||
|
||||
// The TypeUpdate fallback is not a regular fallback, since it just
|
||||
// forwards to a different entry point in the main fallback stub.
|
||||
class ICTypeUpdate_Fallback : public ICStub {
|
||||
|
|
|
@ -165,7 +165,6 @@ JitRuntime::JitRuntime()
|
|||
debugTrapHandler_(nullptr),
|
||||
baselineDebugModeOSRHandler_(nullptr),
|
||||
trampolineCode_(nullptr),
|
||||
functionWrappers_(nullptr),
|
||||
jitcodeGlobalTable_(nullptr),
|
||||
#ifdef DEBUG
|
||||
ionBailAfter_(0),
|
||||
|
@ -179,8 +178,6 @@ JitRuntime::~JitRuntime() {
|
|||
MOZ_ASSERT(ionLazyLinkListSize_ == 0);
|
||||
MOZ_ASSERT(ionLazyLinkList_.ref().isEmpty());
|
||||
|
||||
js_delete(functionWrappers_.ref());
|
||||
|
||||
// By this point, the jitcode global table should be empty.
|
||||
MOZ_ASSERT_IF(jitcodeGlobalTable_, jitcodeGlobalTable_->empty());
|
||||
js_delete(jitcodeGlobalTable_.ref());
|
||||
|
@ -201,11 +198,6 @@ bool JitRuntime::initialize(JSContext* cx) {
|
|||
|
||||
JitContext jctx(cx, nullptr);
|
||||
|
||||
functionWrappers_ = cx->new_<VMWrapperMap>(cx);
|
||||
if (!functionWrappers_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
StackMacroAssembler masm;
|
||||
|
||||
Label bailoutTail;
|
||||
|
@ -290,22 +282,6 @@ bool JitRuntime::initialize(JSContext* cx) {
|
|||
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");
|
||||
Label profilerExitTail;
|
||||
generateProfilerExitFrameTailStub(masm, &profilerExitTail);
|
||||
|
@ -634,16 +610,6 @@ uint32_t JitRuntime::getBailoutTableSize(
|
|||
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) {
|
||||
// As long as JitCode isn't moveable, we can avoid tracing this and
|
||||
// mutating executable data.
|
||||
|
|
|
@ -1033,12 +1033,12 @@ static void TraceJitExitFrameCopiedArguments(JSTracer* trc,
|
|||
doubleArgs -= f->doubleByRefArgs() * sizeof(double);
|
||||
|
||||
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.
|
||||
if (f->argRootType(explicitArg) == VMFunction::RootValue) {
|
||||
if (f->argRootType(explicitArg) == VMFunctionData::RootValue) {
|
||||
TraceRoot(trc, reinterpret_cast<Value*>(doubleArgs), "ion-vm-args");
|
||||
} else {
|
||||
MOZ_ASSERT(f->argRootType(explicitArg) == VMFunction::RootNone);
|
||||
MOZ_ASSERT(f->argRootType(explicitArg) == VMFunctionData::RootNone);
|
||||
}
|
||||
doubleArgs += sizeof(double);
|
||||
}
|
||||
|
@ -1136,9 +1136,9 @@ static void TraceJitExitFrame(JSTracer* trc, const JSJitFrameIter& frame) {
|
|||
uint8_t* argBase = frame.exitFrame()->argBase();
|
||||
for (uint32_t explicitArg = 0; explicitArg < f->explicitArgs; explicitArg++) {
|
||||
switch (f->argRootType(explicitArg)) {
|
||||
case VMFunction::RootNone:
|
||||
case VMFunctionData::RootNone:
|
||||
break;
|
||||
case VMFunction::RootObject: {
|
||||
case VMFunctionData::RootObject: {
|
||||
// Sometimes we can bake in HandleObjects to nullptr.
|
||||
JSObject** pobj = reinterpret_cast<JSObject**>(argBase);
|
||||
if (*pobj) {
|
||||
|
@ -1146,31 +1146,31 @@ static void TraceJitExitFrame(JSTracer* trc, const JSJitFrameIter& frame) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case VMFunction::RootString:
|
||||
case VMFunctionData::RootString:
|
||||
TraceRoot(trc, reinterpret_cast<JSString**>(argBase), "ion-vm-args");
|
||||
break;
|
||||
case VMFunction::RootFunction:
|
||||
case VMFunctionData::RootFunction:
|
||||
TraceRoot(trc, reinterpret_cast<JSFunction**>(argBase), "ion-vm-args");
|
||||
break;
|
||||
case VMFunction::RootValue:
|
||||
case VMFunctionData::RootValue:
|
||||
TraceRoot(trc, reinterpret_cast<Value*>(argBase), "ion-vm-args");
|
||||
break;
|
||||
case VMFunction::RootId:
|
||||
case VMFunctionData::RootId:
|
||||
TraceRoot(trc, reinterpret_cast<jsid*>(argBase), "ion-vm-args");
|
||||
break;
|
||||
case VMFunction::RootCell:
|
||||
case VMFunctionData::RootCell:
|
||||
TraceGenericPointerRoot(trc, reinterpret_cast<gc::Cell**>(argBase),
|
||||
"ion-vm-args");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (f->argProperties(explicitArg)) {
|
||||
case VMFunction::WordByValue:
|
||||
case VMFunction::WordByRef:
|
||||
case VMFunctionData::WordByValue:
|
||||
case VMFunctionData::WordByRef:
|
||||
argBase += sizeof(void*);
|
||||
break;
|
||||
case VMFunction::DoubleByValue:
|
||||
case VMFunction::DoubleByRef:
|
||||
case VMFunctionData::DoubleByValue:
|
||||
case VMFunctionData::DoubleByRef:
|
||||
argBase += 2 * sizeof(void*);
|
||||
break;
|
||||
}
|
||||
|
@ -1178,24 +1178,24 @@ static void TraceJitExitFrame(JSTracer* trc, const JSJitFrameIter& frame) {
|
|||
|
||||
if (f->outParam == Type_Handle) {
|
||||
switch (f->outParamRootType) {
|
||||
case VMFunction::RootNone:
|
||||
case VMFunctionData::RootNone:
|
||||
MOZ_CRASH("Handle outparam must have root type");
|
||||
case VMFunction::RootObject:
|
||||
case VMFunctionData::RootObject:
|
||||
TraceRoot(trc, footer->outParam<JSObject*>(), "ion-vm-out");
|
||||
break;
|
||||
case VMFunction::RootString:
|
||||
case VMFunctionData::RootString:
|
||||
TraceRoot(trc, footer->outParam<JSString*>(), "ion-vm-out");
|
||||
break;
|
||||
case VMFunction::RootFunction:
|
||||
case VMFunctionData::RootFunction:
|
||||
TraceRoot(trc, footer->outParam<JSFunction*>(), "ion-vm-out");
|
||||
break;
|
||||
case VMFunction::RootValue:
|
||||
case VMFunctionData::RootValue:
|
||||
TraceRoot(trc, footer->outParam<Value>(), "ion-vm-outvp");
|
||||
break;
|
||||
case VMFunction::RootId:
|
||||
case VMFunctionData::RootId:
|
||||
TraceRoot(trc, footer->outParam<jsid>(), "ion-vm-outvp");
|
||||
break;
|
||||
case VMFunction::RootCell:
|
||||
case VMFunctionData::RootCell:
|
||||
TraceGenericPointerRoot(trc, footer->outParam<gc::Cell*>(),
|
||||
"ion-vm-out");
|
||||
break;
|
||||
|
|
|
@ -2995,38 +2995,38 @@ void MacroAssembler::PushValue(const Address& addr) {
|
|||
framePushed_ += sizeof(Value);
|
||||
}
|
||||
|
||||
void MacroAssembler::PushEmptyRooted(VMFunction::RootType rootType) {
|
||||
void MacroAssembler::PushEmptyRooted(VMFunctionData::RootType rootType) {
|
||||
switch (rootType) {
|
||||
case VMFunction::RootNone:
|
||||
case VMFunctionData::RootNone:
|
||||
MOZ_CRASH("Handle must have root type");
|
||||
case VMFunction::RootObject:
|
||||
case VMFunction::RootString:
|
||||
case VMFunction::RootFunction:
|
||||
case VMFunction::RootCell:
|
||||
case VMFunctionData::RootObject:
|
||||
case VMFunctionData::RootString:
|
||||
case VMFunctionData::RootFunction:
|
||||
case VMFunctionData::RootCell:
|
||||
Push(ImmPtr(nullptr));
|
||||
break;
|
||||
case VMFunction::RootValue:
|
||||
case VMFunctionData::RootValue:
|
||||
Push(UndefinedValue());
|
||||
break;
|
||||
case VMFunction::RootId:
|
||||
case VMFunctionData::RootId:
|
||||
Push(ImmWord(JSID_BITS(JSID_VOID)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::popRooted(VMFunction::RootType rootType, Register cellReg,
|
||||
const ValueOperand& valueReg) {
|
||||
void MacroAssembler::popRooted(VMFunctionData::RootType rootType,
|
||||
Register cellReg, const ValueOperand& valueReg) {
|
||||
switch (rootType) {
|
||||
case VMFunction::RootNone:
|
||||
case VMFunctionData::RootNone:
|
||||
MOZ_CRASH("Handle must have root type");
|
||||
case VMFunction::RootObject:
|
||||
case VMFunction::RootString:
|
||||
case VMFunction::RootFunction:
|
||||
case VMFunction::RootCell:
|
||||
case VMFunction::RootId:
|
||||
case VMFunctionData::RootObject:
|
||||
case VMFunctionData::RootString:
|
||||
case VMFunctionData::RootFunction:
|
||||
case VMFunctionData::RootCell:
|
||||
case VMFunctionData::RootId:
|
||||
Pop(cellReg);
|
||||
break;
|
||||
case VMFunction::RootValue:
|
||||
case VMFunctionData::RootValue:
|
||||
Pop(valueReg);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -387,7 +387,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
|
|||
void Push(const Value& val);
|
||||
void Push(JSValueType type, Register reg);
|
||||
void PushValue(const Address& addr);
|
||||
void PushEmptyRooted(VMFunction::RootType rootType);
|
||||
void PushEmptyRooted(VMFunctionData::RootType rootType);
|
||||
inline CodeOffset PushWithPatch(ImmWord word);
|
||||
inline CodeOffset PushWithPatch(ImmPtr imm);
|
||||
|
||||
|
@ -397,7 +397,7 @@ class MacroAssembler : public MacroAssemblerSpecific {
|
|||
void Pop(const ValueOperand& val) PER_SHARED_ARCH;
|
||||
void PopFlags() DEFINED_ON(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);
|
||||
|
||||
// Move the stack pointer based on the requested amount.
|
||||
|
|
|
@ -118,6 +118,7 @@ namespace jit {
|
|||
_(GlobalNameConflictsCheckFromIon, js::jit::GlobalNameConflictsCheckFromIon) \
|
||||
_(GreaterThan, js::jit::GreaterThan) \
|
||||
_(GreaterThanOrEqual, js::jit::GreaterThanOrEqual) \
|
||||
_(HandleDebugTrap, js::jit::HandleDebugTrap) \
|
||||
_(HomeObjectSuperBase, js::HomeObjectSuperBase) \
|
||||
_(ImplicitThisOperation, js::ImplicitThisOperation) \
|
||||
_(ImportMetaOperation, js::ImportMetaOperation) \
|
||||
|
|
|
@ -67,12 +67,11 @@ struct VMFunctionDataHelper<R (*)(JSContext*, Args...)>
|
|||
static constexpr uint64_t argumentRootTypes() {
|
||||
return BitMask<TypeToRootType, uint64_t, 3, Args...>::result;
|
||||
}
|
||||
constexpr explicit VMFunctionDataHelper(
|
||||
const char* name, PopValues extraValuesToPop = PopValues(0))
|
||||
constexpr explicit VMFunctionDataHelper(const char* name)
|
||||
: VMFunctionData(name, explicitArgs(), argumentProperties(),
|
||||
argumentPassedInFloatRegs(), argumentRootTypes(),
|
||||
outParam(), outParamRootType(), returnType(),
|
||||
extraValuesToPop.numValues, NonTailCall) {}
|
||||
/* extraValuesToPop = */ 0, NonTailCall) {}
|
||||
constexpr explicit VMFunctionDataHelper(const char* name,
|
||||
MaybeTailCall expectTailCall,
|
||||
PopValues extraValuesToPop)
|
||||
|
@ -187,10 +186,6 @@ bool JitRuntime::generateVMWrappers(JSContext* cx, MacroAssembler& masm) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Statics are initialized to null.
|
||||
/* static */
|
||||
VMFunction* VMFunction::functions;
|
||||
|
||||
AutoDetectInvalidation::AutoDetectInvalidation(JSContext* cx,
|
||||
MutableHandleValue rval)
|
||||
: cx_(cx),
|
||||
|
|
|
@ -56,8 +56,6 @@ enum MaybeTailCall : bool { TailCall, NonTailCall };
|
|||
|
||||
// [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
|
||||
// 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
|
||||
|
@ -65,15 +63,15 @@ enum MaybeTailCall : bool { TailCall, NonTailCall };
|
|||
// callVM are interfaces provided to handle the exception handling and register
|
||||
// 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)
|
||||
// and to root the arguments of the function (in TraceJitExitFrame). VMFunctions
|
||||
// are created with the FunctionInfo template, which infers the fields of the
|
||||
// VMFunction from the function signature. The rooting and trampoline code is
|
||||
// therefore determined by the arguments of a function and their locations in
|
||||
// the signature of a function.
|
||||
// and to root the arguments of the function (in TraceJitExitFrame).
|
||||
// VMFunctionData is created with the VMFunctionDataHelper template, which
|
||||
// infers the VMFunctionData fields from the function signature. The rooting and
|
||||
// trampoline code is therefore determined by the arguments of a function and
|
||||
// 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
|
||||
// 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
|
||||
|
@ -90,9 +88,9 @@ enum MaybeTailCall : bool { TailCall, NonTailCall };
|
|||
// JIT Code usage:
|
||||
//
|
||||
// Different JIT compilers in SpiderMonkey have their own implementations of
|
||||
// callVM to consume VMFunctions. However, the general shape of them is that
|
||||
// arguments that don't include the JIT Context or trailing out-param are pushed
|
||||
// on to the stack from right to left (rightmost argument is pushed first).
|
||||
// callVM to call VM functions. However, the general shape of them is that
|
||||
// arguments (excluding the JSContext or trailing out-param) are pushed on to
|
||||
// the stack from right to left (rightmost argument is pushed first).
|
||||
//
|
||||
// Regardless of return value protocol being used (final outParam, or return
|
||||
// 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.
|
||||
//
|
||||
// A VMFunction for this can be created using FunctionInfo. The typical pattern
|
||||
// used is:
|
||||
// A VM function wrapper for this can be created by adding an entry to
|
||||
// VM_FUNCTION_LIST in VMFunctionList-inl.h:
|
||||
//
|
||||
// typedef bool (*FooFn)(JSContext*, HandleObject, HandleId,
|
||||
// MutableHandleValue);
|
||||
// const VMFunction FooInfo = FunctionInfo<FooFn>(Foo, "Foo");
|
||||
// _(Foo, js::Foo)
|
||||
//
|
||||
// In the compiler code the call would then be issued like this:
|
||||
//
|
||||
// masm.Push(id);
|
||||
// masm.Push(obj);
|
||||
// if (!callVM(FooInfo)) {
|
||||
//
|
||||
// using Fn = bool (*)(JSContext*, HandleObject, HandleId,
|
||||
// MutableHandleValue);
|
||||
// if (!callVM<Fn, js::Foo>()) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
|
@ -318,86 +317,7 @@ struct VMFunctionData {
|
|||
returnType == Type_Object);
|
||||
}
|
||||
|
||||
// Note: clang-tidy suggests using |= auto| here but that generates extra
|
||||
// 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;
|
||||
}
|
||||
constexpr VMFunctionData(const VMFunctionData& o) = default;
|
||||
};
|
||||
|
||||
template <class>
|
||||
|
@ -544,113 +464,115 @@ struct TypeToDataType<HandleId> {
|
|||
template <class T>
|
||||
struct TypeToArgProperties {
|
||||
static const uint32_t result =
|
||||
(sizeof(T) <= sizeof(void*) ? VMFunction::Word : VMFunction::Double);
|
||||
(sizeof(T) <= sizeof(void*) ? VMFunctionData::Word
|
||||
: VMFunctionData::Double);
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<const Value&> {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<Value>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<Value>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<HandleObject> {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<JSObject*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<JSObject*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<HandleString> {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<JSString*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<JSString*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<HandlePropertyName> {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<PropertyName*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<PropertyName*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<HandleFunction> {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<JSFunction*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<JSFunction*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<Handle<NativeObject*> > {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<NativeObject*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<NativeObject*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<Handle<InlineTypedObject*> > {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<InlineTypedObject*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<InlineTypedObject*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<Handle<ArrayObject*> > {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<ArrayObject*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<ArrayObject*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<Handle<AbstractGeneratorObject*> > {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<AbstractGeneratorObject*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<AbstractGeneratorObject*>::result |
|
||||
VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<Handle<AsyncFunctionGeneratorObject*> > {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<AsyncFunctionGeneratorObject*>::result |
|
||||
VMFunction::ByRef;
|
||||
VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<Handle<PlainObject*> > {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<PlainObject*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<PlainObject*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<Handle<RegExpObject*> > {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<RegExpObject*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<RegExpObject*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<Handle<WithScope*> > {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<WithScope*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<WithScope*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<Handle<LexicalScope*> > {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<LexicalScope*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<LexicalScope*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<Handle<Scope*> > {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<Scope*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<Scope*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<HandleScript> {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<JSScript*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<JSScript*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<HandleValue> {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<Value>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<Value>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<MutableHandleValue> {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<Value>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<Value>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<HandleId> {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<jsid>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<jsid>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<HandleShape> {
|
||||
static const uint32_t result =
|
||||
TypeToArgProperties<Shape*>::result | VMFunction::ByRef;
|
||||
TypeToArgProperties<Shape*>::result | VMFunctionData::ByRef;
|
||||
};
|
||||
template <>
|
||||
struct TypeToArgProperties<HandleObjectGroup> {
|
||||
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
|
||||
|
@ -667,87 +589,87 @@ struct TypeToPassInFloatReg<double> {
|
|||
// Convert argument types to root types used by the gc, see MarkJitExitFrame.
|
||||
template <class T>
|
||||
struct TypeToRootType {
|
||||
static const uint32_t result = VMFunction::RootNone;
|
||||
static const uint32_t result = VMFunctionData::RootNone;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<HandleObject> {
|
||||
static const uint32_t result = VMFunction::RootObject;
|
||||
static const uint32_t result = VMFunctionData::RootObject;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<HandleString> {
|
||||
static const uint32_t result = VMFunction::RootString;
|
||||
static const uint32_t result = VMFunctionData::RootString;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<HandlePropertyName> {
|
||||
static const uint32_t result = VMFunction::RootString;
|
||||
static const uint32_t result = VMFunctionData::RootString;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<HandleFunction> {
|
||||
static const uint32_t result = VMFunction::RootFunction;
|
||||
static const uint32_t result = VMFunctionData::RootFunction;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<HandleValue> {
|
||||
static const uint32_t result = VMFunction::RootValue;
|
||||
static const uint32_t result = VMFunctionData::RootValue;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<MutableHandleValue> {
|
||||
static const uint32_t result = VMFunction::RootValue;
|
||||
static const uint32_t result = VMFunctionData::RootValue;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<HandleId> {
|
||||
static const uint32_t result = VMFunction::RootId;
|
||||
static const uint32_t result = VMFunctionData::RootId;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<HandleShape> {
|
||||
static const uint32_t result = VMFunction::RootCell;
|
||||
static const uint32_t result = VMFunctionData::RootCell;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<HandleObjectGroup> {
|
||||
static const uint32_t result = VMFunction::RootCell;
|
||||
static const uint32_t result = VMFunctionData::RootCell;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<HandleScript> {
|
||||
static const uint32_t result = VMFunction::RootCell;
|
||||
static const uint32_t result = VMFunctionData::RootCell;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<Handle<NativeObject*> > {
|
||||
static const uint32_t result = VMFunction::RootObject;
|
||||
static const uint32_t result = VMFunctionData::RootObject;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<Handle<InlineTypedObject*> > {
|
||||
static const uint32_t result = VMFunction::RootObject;
|
||||
static const uint32_t result = VMFunctionData::RootObject;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<Handle<ArrayObject*> > {
|
||||
static const uint32_t result = VMFunction::RootObject;
|
||||
static const uint32_t result = VMFunctionData::RootObject;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<Handle<AbstractGeneratorObject*> > {
|
||||
static const uint32_t result = VMFunction::RootObject;
|
||||
static const uint32_t result = VMFunctionData::RootObject;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<Handle<AsyncFunctionGeneratorObject*> > {
|
||||
static const uint32_t result = VMFunction::RootObject;
|
||||
static const uint32_t result = VMFunctionData::RootObject;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<Handle<PlainObject*> > {
|
||||
static const uint32_t result = VMFunction::RootObject;
|
||||
static const uint32_t result = VMFunctionData::RootObject;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<Handle<RegExpObject*> > {
|
||||
static const uint32_t result = VMFunction::RootObject;
|
||||
static const uint32_t result = VMFunctionData::RootObject;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<Handle<LexicalScope*> > {
|
||||
static const uint32_t result = VMFunction::RootCell;
|
||||
static const uint32_t result = VMFunctionData::RootCell;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<Handle<WithScope*> > {
|
||||
static const uint32_t result = VMFunction::RootCell;
|
||||
static const uint32_t result = VMFunctionData::RootCell;
|
||||
};
|
||||
template <>
|
||||
struct TypeToRootType<Handle<Scope*> > {
|
||||
static const uint32_t result = VMFunction::RootCell;
|
||||
static const uint32_t result = VMFunctionData::RootCell;
|
||||
};
|
||||
template <class T>
|
||||
struct TypeToRootType<Handle<T> > {
|
||||
|
@ -797,19 +719,19 @@ struct OutParamToDataType<MutableHandleString> {
|
|||
|
||||
template <class>
|
||||
struct OutParamToRootType {
|
||||
static const VMFunction::RootType result = VMFunction::RootNone;
|
||||
static const VMFunctionData::RootType result = VMFunctionData::RootNone;
|
||||
};
|
||||
template <>
|
||||
struct OutParamToRootType<MutableHandleValue> {
|
||||
static const VMFunction::RootType result = VMFunction::RootValue;
|
||||
static const VMFunctionData::RootType result = VMFunctionData::RootValue;
|
||||
};
|
||||
template <>
|
||||
struct OutParamToRootType<MutableHandleObject> {
|
||||
static const VMFunction::RootType result = VMFunction::RootObject;
|
||||
static const VMFunctionData::RootType result = VMFunctionData::RootObject;
|
||||
};
|
||||
template <>
|
||||
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.
|
||||
|
@ -862,52 +784,6 @@ struct BitMask<Each, ResultType, Shift, HeadType, TailTypes...> {
|
|||
(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 {
|
||||
JSContext* cx_;
|
||||
IonScript* ionScript_;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "jit/MacroAssembler-inl.h"
|
||||
#include "jit/SharedICHelpers-inl.h"
|
||||
#include "jit/VMFunctionList-inl.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
@ -706,8 +707,6 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
|
|||
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
||||
const VMFunctionData& f, void* nativeFun,
|
||||
uint32_t* wrapperOffset) {
|
||||
MOZ_ASSERT(functionWrappers_);
|
||||
|
||||
*wrapperOffset = startTrampolineCode(masm);
|
||||
|
||||
AllocatableGeneralRegisterSet regs(Register::Codes::WrapperMask);
|
||||
|
@ -794,24 +793,24 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
|||
// Copy any arguments.
|
||||
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
|
||||
switch (f.argProperties(explicitArg)) {
|
||||
case VMFunction::WordByValue:
|
||||
case VMFunctionData::WordByValue:
|
||||
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL);
|
||||
argDisp += sizeof(void*);
|
||||
break;
|
||||
case VMFunction::DoubleByValue:
|
||||
case VMFunctionData::DoubleByValue:
|
||||
// Values should be passed by reference, not by value, so we assert
|
||||
// that the argument is a double-precision float.
|
||||
MOZ_ASSERT(f.argPassedInFloatReg(explicitArg));
|
||||
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::DOUBLE);
|
||||
argDisp += sizeof(double);
|
||||
break;
|
||||
case VMFunction::WordByRef:
|
||||
case VMFunctionData::WordByRef:
|
||||
masm.passABIArg(
|
||||
MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
|
||||
MoveOp::GENERAL);
|
||||
argDisp += sizeof(void*);
|
||||
break;
|
||||
case VMFunction::DoubleByRef:
|
||||
case VMFunctionData::DoubleByRef:
|
||||
masm.passABIArg(
|
||||
MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
|
||||
MoveOp::GENERAL);
|
||||
|
@ -949,10 +948,6 @@ uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
|
|||
return offset;
|
||||
}
|
||||
|
||||
typedef bool (*HandleDebugTrapFn)(JSContext*, BaselineFrame*, uint8_t*, bool*);
|
||||
static const VMFunction HandleDebugTrapInfo =
|
||||
FunctionInfo<HandleDebugTrapFn>(HandleDebugTrap, "HandleDebugTrap");
|
||||
|
||||
JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
|
||||
StackMacroAssembler masm;
|
||||
|
||||
|
@ -969,8 +964,10 @@ JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
|
|||
masm.movePtr(ImmPtr(nullptr), ICStubReg);
|
||||
EmitBaselineEnterStubFrame(masm, scratch2);
|
||||
|
||||
TrampolinePtr code =
|
||||
cx->runtime()->jitRuntime()->getVMWrapper(HandleDebugTrapInfo);
|
||||
using Fn = bool (*)(JSContext*, BaselineFrame*, uint8_t*, bool*);
|
||||
VMFunctionId id = VMFunctionToId<Fn, jit::HandleDebugTrap>::id;
|
||||
TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(id);
|
||||
|
||||
masm.push(lr);
|
||||
masm.push(scratch1);
|
||||
EmitBaselineCallVM(code, masm);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "jit/MacroAssembler-inl.h"
|
||||
#include "jit/SharedICHelpers-inl.h"
|
||||
#include "jit/VMFunctionList-inl.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
@ -535,8 +536,6 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
|
|||
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
||||
const VMFunctionData& f, void* nativeFun,
|
||||
uint32_t* wrapperOffset) {
|
||||
MOZ_ASSERT(functionWrappers_);
|
||||
|
||||
*wrapperOffset = startTrampolineCode(masm);
|
||||
|
||||
// Avoid conflicts with argument registers while discarding the result after
|
||||
|
@ -629,22 +628,22 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
|||
// Copy arguments.
|
||||
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
|
||||
switch (f.argProperties(explicitArg)) {
|
||||
case VMFunction::WordByValue:
|
||||
case VMFunctionData::WordByValue:
|
||||
masm.passABIArg(MoveOperand(argsBase, argDisp),
|
||||
(f.argPassedInFloatReg(explicitArg) ? MoveOp::DOUBLE
|
||||
: MoveOp::GENERAL));
|
||||
argDisp += sizeof(void*);
|
||||
break;
|
||||
|
||||
case VMFunction::WordByRef:
|
||||
case VMFunctionData::WordByRef:
|
||||
masm.passABIArg(
|
||||
MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
|
||||
MoveOp::GENERAL);
|
||||
argDisp += sizeof(void*);
|
||||
break;
|
||||
|
||||
case VMFunction::DoubleByValue:
|
||||
case VMFunction::DoubleByRef:
|
||||
case VMFunctionData::DoubleByValue:
|
||||
case VMFunctionData::DoubleByRef:
|
||||
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;
|
||||
}
|
||||
|
||||
typedef bool (*HandleDebugTrapFn)(JSContext*, BaselineFrame*, uint8_t*, bool*);
|
||||
static const VMFunction HandleDebugTrapInfo =
|
||||
FunctionInfo<HandleDebugTrapFn>(HandleDebugTrap, "HandleDebugTrap");
|
||||
|
||||
JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
|
||||
StackMacroAssembler masm(cx);
|
||||
#ifndef JS_USE_LINK_REGISTER
|
||||
|
@ -812,8 +807,10 @@ JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
|
|||
masm.movePtr(ImmPtr(nullptr), ICStubReg);
|
||||
EmitBaselineEnterStubFrame(masm, scratch2);
|
||||
|
||||
TrampolinePtr code =
|
||||
cx->runtime()->jitRuntime()->getVMWrapper(HandleDebugTrapInfo);
|
||||
using Fn = bool (*)(JSContext*, BaselineFrame*, uint8_t*, bool*);
|
||||
VMFunctionId id = VMFunctionToId<Fn, jit::HandleDebugTrap>::id;
|
||||
TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(id);
|
||||
|
||||
masm.asVIXL().Push(vixl::lr, ARMRegister(scratch1, 64));
|
||||
EmitBaselineCallVM(code, masm);
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "jit/MacroAssembler-inl.h"
|
||||
#include "jit/SharedICHelpers-inl.h"
|
||||
#include "jit/VMFunctionList-inl.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
@ -593,8 +594,6 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
|
|||
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
||||
const VMFunctionData& f, void* nativeFun,
|
||||
uint32_t* wrapperOffset) {
|
||||
MOZ_ASSERT(functionWrappers_);
|
||||
|
||||
*wrapperOffset = startTrampolineCode(masm);
|
||||
|
||||
// Avoid conflicts with argument registers while discarding the result after
|
||||
|
@ -678,7 +677,7 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
|||
// Copy arguments.
|
||||
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
|
||||
switch (f.argProperties(explicitArg)) {
|
||||
case VMFunction::WordByValue:
|
||||
case VMFunctionData::WordByValue:
|
||||
if (f.argPassedInFloatReg(explicitArg)) {
|
||||
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::DOUBLE);
|
||||
} else {
|
||||
|
@ -686,14 +685,14 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
|||
}
|
||||
argDisp += sizeof(void*);
|
||||
break;
|
||||
case VMFunction::WordByRef:
|
||||
case VMFunctionData::WordByRef:
|
||||
masm.passABIArg(
|
||||
MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
|
||||
MoveOp::GENERAL);
|
||||
argDisp += sizeof(void*);
|
||||
break;
|
||||
case VMFunction::DoubleByValue:
|
||||
case VMFunction::DoubleByRef:
|
||||
case VMFunctionData::DoubleByValue:
|
||||
case VMFunctionData::DoubleByRef:
|
||||
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;
|
||||
}
|
||||
|
||||
typedef bool (*HandleDebugTrapFn)(JSContext*, BaselineFrame*, uint8_t*, bool*);
|
||||
static const VMFunction HandleDebugTrapInfo =
|
||||
FunctionInfo<HandleDebugTrapFn>(HandleDebugTrap, "HandleDebugTrap");
|
||||
|
||||
JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
|
||||
StackMacroAssembler masm;
|
||||
#ifndef JS_USE_LINK_REGISTER
|
||||
|
@ -850,8 +845,10 @@ JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
|
|||
masm.movePtr(ImmPtr(nullptr), ICStubReg);
|
||||
EmitBaselineEnterStubFrame(masm, scratch3);
|
||||
|
||||
TrampolinePtr code =
|
||||
cx->runtime()->jitRuntime()->getVMWrapper(HandleDebugTrapInfo);
|
||||
using Fn = bool (*)(JSContext*, BaselineFrame*, uint8_t*, bool*);
|
||||
VMFunctionId id = VMFunctionToId<Fn, jit::HandleDebugTrap>::id;
|
||||
TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(id);
|
||||
|
||||
masm.push(scratch1);
|
||||
masm.push(scratch2);
|
||||
EmitBaselineCallVM(code, masm);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "jit/MacroAssembler-inl.h"
|
||||
#include "jit/SharedICHelpers-inl.h"
|
||||
#include "jit/VMFunctionList-inl.h"
|
||||
#include "vm/JSScript-inl.h"
|
||||
|
||||
using mozilla::IsPowerOfTwo;
|
||||
|
@ -610,8 +611,6 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
|
|||
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
||||
const VMFunctionData& f, void* nativeFun,
|
||||
uint32_t* wrapperOffset) {
|
||||
MOZ_ASSERT(functionWrappers_);
|
||||
|
||||
*wrapperOffset = startTrampolineCode(masm);
|
||||
|
||||
// Avoid conflicts with argument registers while discarding the result after
|
||||
|
@ -688,11 +687,11 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
|||
// Copy arguments.
|
||||
for (uint32_t explicitArg = 0; explicitArg < f.explicitArgs; explicitArg++) {
|
||||
switch (f.argProperties(explicitArg)) {
|
||||
case VMFunction::WordByValue:
|
||||
case VMFunctionData::WordByValue:
|
||||
masm.passABIArg(MoveOperand(argsBase, argDisp), MoveOp::GENERAL);
|
||||
argDisp += sizeof(void*);
|
||||
break;
|
||||
case VMFunction::DoubleByValue:
|
||||
case VMFunctionData::DoubleByValue:
|
||||
// We don't pass doubles in float registers on x86, so no need
|
||||
// to check for argPassedInFloatReg.
|
||||
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);
|
||||
argDisp += sizeof(void*);
|
||||
break;
|
||||
case VMFunction::WordByRef:
|
||||
case VMFunctionData::WordByRef:
|
||||
masm.passABIArg(
|
||||
MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
|
||||
MoveOp::GENERAL);
|
||||
argDisp += sizeof(void*);
|
||||
break;
|
||||
case VMFunction::DoubleByRef:
|
||||
case VMFunctionData::DoubleByRef:
|
||||
masm.passABIArg(
|
||||
MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
|
||||
MoveOp::GENERAL);
|
||||
|
@ -840,10 +839,6 @@ uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
|
|||
return offset;
|
||||
}
|
||||
|
||||
typedef bool (*HandleDebugTrapFn)(JSContext*, BaselineFrame*, uint8_t*, bool*);
|
||||
static const VMFunction HandleDebugTrapInfo =
|
||||
FunctionInfo<HandleDebugTrapFn>(HandleDebugTrap, "HandleDebugTrap");
|
||||
|
||||
JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
|
||||
StackMacroAssembler masm;
|
||||
#ifndef JS_USE_LINK_REGISTER
|
||||
|
@ -869,8 +864,10 @@ JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx) {
|
|||
masm.movePtr(ImmPtr(nullptr), ICStubReg);
|
||||
EmitBaselineEnterStubFrame(masm, scratch3);
|
||||
|
||||
TrampolinePtr code =
|
||||
cx->runtime()->jitRuntime()->getVMWrapper(HandleDebugTrapInfo);
|
||||
using Fn = bool (*)(JSContext*, BaselineFrame*, uint8_t*, bool*);
|
||||
VMFunctionId id = VMFunctionToId<Fn, jit::HandleDebugTrap>::id;
|
||||
TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(id);
|
||||
|
||||
masm.push(scratch1);
|
||||
masm.push(scratch2);
|
||||
EmitBaselineCallVM(code, masm);
|
||||
|
|
Загрузка…
Ссылка в новой задаче