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;
}
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);