mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Decouple JSContext from Ion backend, bug 774253. r=dvander
This commit is contained in:
parent
004b0b22cc
commit
6c4d57b26e
@ -207,8 +207,7 @@ CodeGenerator::visitIntToString(LIntToString *lir)
|
||||
bool
|
||||
CodeGenerator::visitRegExp(LRegExp *lir)
|
||||
{
|
||||
GlobalObject *global = &gen->info().script()->global();
|
||||
RootedObject proto(gen->cx, global->getOrCreateRegExpPrototype(gen->cx));
|
||||
JSObject *proto = lir->mir()->getRegExpPrototype();
|
||||
|
||||
typedef JSObject *(*pf)(JSContext *, JSObject *, JSObject *);
|
||||
static const VMFunction CloneRegExpObjectInfo = FunctionInfo<pf>(CloneRegExpObject);
|
||||
@ -234,7 +233,7 @@ CodeGenerator::visitLambda(LLambda *lir)
|
||||
{
|
||||
Register scopeChain = ToRegister(lir->scopeChain());
|
||||
Register output = ToRegister(lir->output());
|
||||
RootedFunction fun(gen->cx, lir->mir()->fun());
|
||||
JSFunction *fun = lir->mir()->fun();
|
||||
|
||||
typedef JSObject *(*pf)(JSContext *, HandleFunction, HandleObject);
|
||||
static const VMFunction Info = FunctionInfo<pf>(js::Lambda);
|
||||
@ -244,23 +243,11 @@ CodeGenerator::visitLambda(LLambda *lir)
|
||||
if (!ool)
|
||||
return false;
|
||||
|
||||
JS_ASSERT(gen->cx->compartment == fun->compartment());
|
||||
JS_ASSERT(gen->compartment == fun->compartment());
|
||||
JS_ASSERT(!fun->hasSingletonType());
|
||||
|
||||
// Because of compartment-per-global and compile'n'go, the Function prototype,
|
||||
// first non-scope object on the scope chain, and global object, are all
|
||||
// invariant. We can thus use CloneFunctionObject with the global object to get
|
||||
// a bogus clone and use that as our template object.
|
||||
RootedObject parent(gen->cx, &fun->global());
|
||||
RootedFunction clone(gen->cx, CloneFunctionObject(gen->cx, fun, parent));
|
||||
if (!clone)
|
||||
return false;
|
||||
|
||||
JS_ASSERT(clone->getAllocKind() != JSFunction::ExtendedFinalizeKind);
|
||||
JS_ASSERT(clone->isInterpreted());
|
||||
|
||||
masm.newGCThing(gen->cx, output, clone, ool->entry());
|
||||
masm.initGCThing(gen->cx, output, clone);
|
||||
masm.newGCThing(output, fun, ool->entry());
|
||||
masm.initGCThing(output, fun);
|
||||
|
||||
// Initialize nargs and flags. We do this with a single uint32 to avoid
|
||||
// 16-bit writes.
|
||||
@ -276,9 +263,9 @@ CodeGenerator::visitLambda(LLambda *lir)
|
||||
|
||||
JS_STATIC_ASSERT(offsetof(JSFunction, flags) == offsetof(JSFunction, nargs) + 2);
|
||||
masm.store32(Imm32(u.word), Address(output, offsetof(JSFunction, nargs)));
|
||||
masm.storePtr(ImmGCPtr(clone->script()), Address(output, JSFunction::offsetOfNativeOrScript()));
|
||||
masm.storePtr(ImmGCPtr(fun->script()), Address(output, JSFunction::offsetOfNativeOrScript()));
|
||||
masm.storePtr(scopeChain, Address(output, JSFunction::offsetOfEnvironment()));
|
||||
masm.storePtr(ImmGCPtr(clone->atom), Address(output, offsetof(JSFunction, atom)));
|
||||
masm.storePtr(ImmGCPtr(fun->atom), Address(output, offsetof(JSFunction, atom)));
|
||||
|
||||
masm.bind(ool->rejoin());
|
||||
return true;
|
||||
@ -619,7 +606,8 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call)
|
||||
if (call->hasSingleTarget() &&
|
||||
call->getSingleTarget()->script()->ion == ION_DISABLED_SCRIPT)
|
||||
{
|
||||
emitCallInvokeFunction(call, unusedStack);
|
||||
if (!emitCallInvokeFunction(call, unusedStack))
|
||||
return false;
|
||||
|
||||
if (call->mir()->isConstructing()) {
|
||||
Label notPrimitive;
|
||||
@ -652,7 +640,7 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call)
|
||||
masm.movePtr(Address(objreg, offsetof(JSScript, ion)), objreg);
|
||||
|
||||
// Guard that the IonScript has been compiled.
|
||||
masm.branchPtr(Assembler::BelowOrEqual, objreg, ImmWord(ION_DISABLED_SCRIPT), &invoke);
|
||||
masm.branchPtr(Assembler::BelowOrEqual, objreg, ImmWord(ION_COMPILING_SCRIPT), &invoke);
|
||||
|
||||
// Nestle %esp up to the argument vector.
|
||||
masm.freeStack(unusedStack);
|
||||
@ -691,7 +679,7 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call)
|
||||
|
||||
// Hardcode the address of the argumentsRectifier code.
|
||||
IonCompartment *ion = gen->ionCompartment();
|
||||
IonCode *argumentsRectifier = ion->getArgumentsRectifier(gen->cx);
|
||||
IonCode *argumentsRectifier = ion->getArgumentsRectifier(GetIonContext()->cx);
|
||||
if (!argumentsRectifier)
|
||||
return false;
|
||||
|
||||
@ -721,7 +709,8 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call)
|
||||
|
||||
// Handle uncompiled or native functions.
|
||||
masm.bind(&invoke);
|
||||
emitCallInvokeFunction(call, unusedStack);
|
||||
if (!emitCallInvokeFunction(call, unusedStack))
|
||||
return false;
|
||||
|
||||
masm.bind(&end);
|
||||
|
||||
@ -885,7 +874,8 @@ CodeGenerator::visitApplyArgsGeneric(LApplyArgsGeneric *apply)
|
||||
(!apply->getSingleTarget()->isInterpreted() ||
|
||||
apply->getSingleTarget()->script()->ion == ION_DISABLED_SCRIPT))
|
||||
{
|
||||
emitCallInvokeFunction(apply, copyreg);
|
||||
if (!emitCallInvokeFunction(apply, copyreg))
|
||||
return false;
|
||||
emitPopArguments(apply, copyreg);
|
||||
return true;
|
||||
}
|
||||
@ -910,7 +900,7 @@ CodeGenerator::visitApplyArgsGeneric(LApplyArgsGeneric *apply)
|
||||
masm.movePtr(Address(objreg, offsetof(JSScript, ion)), objreg);
|
||||
|
||||
// Guard that the IonScript has been compiled.
|
||||
masm.branchPtr(Assembler::BelowOrEqual, objreg, ImmWord(ION_DISABLED_SCRIPT), &invoke);
|
||||
masm.branchPtr(Assembler::BelowOrEqual, objreg, ImmWord(ION_COMPILING_SCRIPT), &invoke);
|
||||
|
||||
// Call with an Ion frame or a rectifier frame.
|
||||
{
|
||||
@ -951,7 +941,7 @@ CodeGenerator::visitApplyArgsGeneric(LApplyArgsGeneric *apply)
|
||||
|
||||
// Hardcode the address of the argumentsRectifier code.
|
||||
IonCompartment *ion = gen->ionCompartment();
|
||||
IonCode *argumentsRectifier = ion->getArgumentsRectifier(gen->cx);
|
||||
IonCode *argumentsRectifier = ion->getArgumentsRectifier(GetIonContext()->cx);
|
||||
if (!argumentsRectifier)
|
||||
return false;
|
||||
|
||||
@ -982,7 +972,8 @@ CodeGenerator::visitApplyArgsGeneric(LApplyArgsGeneric *apply)
|
||||
// Handle uncompiled or native functions.
|
||||
{
|
||||
masm.bind(&invoke);
|
||||
emitCallInvokeFunction(apply, copyreg);
|
||||
if (!emitCallInvokeFunction(apply, copyreg))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Pop arguments and continue.
|
||||
@ -1068,7 +1059,7 @@ CodeGenerator::visitCheckOverRecursed(LCheckOverRecursed *lir)
|
||||
// Ion may legally place frames very close to the limit. Calling additional
|
||||
// C functions may then violate the limit without any checking.
|
||||
|
||||
JSRuntime *rt = gen->cx->runtime;
|
||||
JSRuntime *rt = gen->compartment->rt;
|
||||
Register limitReg = ToRegister(lir->limitTemp());
|
||||
|
||||
// Since Ion frames exist on the C stack, the stack limit may be
|
||||
@ -1184,7 +1175,10 @@ CodeGenerator::visitNewArrayCallVM(LNewArray *lir)
|
||||
JS_ASSERT(!lir->isCall());
|
||||
saveLive(lir);
|
||||
|
||||
pushArg(ImmGCPtr(lir->mir()->type()));
|
||||
JSObject *templateObject = lir->mir()->templateObject();
|
||||
types::TypeObject *type = templateObject->hasSingletonType() ? NULL : templateObject->type();
|
||||
|
||||
pushArg(ImmGCPtr(type));
|
||||
pushArg(Imm32(lir->mir()->count()));
|
||||
|
||||
if (!callVM(NewInitArrayInfo, lir))
|
||||
@ -1206,7 +1200,7 @@ CodeGenerator::visitNewSlots(LNewSlots *lir)
|
||||
Register temp3 = ToRegister(lir->temp3());
|
||||
Register output = ToRegister(lir->output());
|
||||
|
||||
masm.mov(ImmWord(gen->cx->runtime), temp1);
|
||||
masm.mov(ImmWord(gen->compartment->rt), temp1);
|
||||
masm.mov(Imm32(lir->mir()->nslots()), temp2);
|
||||
|
||||
masm.setupUnalignedABICall(2, temp3);
|
||||
@ -1225,7 +1219,7 @@ bool
|
||||
CodeGenerator::visitNewArray(LNewArray *lir)
|
||||
{
|
||||
Register objReg = ToRegister(lir->output());
|
||||
types::TypeObject *typeObj = lir->mir()->type();
|
||||
JSObject *templateObject = lir->mir()->templateObject();
|
||||
uint32 count = lir->mir()->count();
|
||||
|
||||
JS_ASSERT(count < JSObject::NELEMENTS_LIMIT);
|
||||
@ -1238,20 +1232,15 @@ CodeGenerator::visitNewArray(LNewArray *lir)
|
||||
// but only when data doesn't fit the available array slots.
|
||||
bool allocating = lir->mir()->isAllocating() && count > maxArraySlots;
|
||||
|
||||
if (!gen->cx->typeInferenceEnabled() || !typeObj || allocating)
|
||||
if (templateObject->hasSingletonType() || allocating)
|
||||
return visitNewArrayCallVM(lir);
|
||||
|
||||
OutOfLineNewArray *ool = new OutOfLineNewArray(lir);
|
||||
if (!addOutOfLineCode(ool))
|
||||
return false;
|
||||
|
||||
RootedObject templateObject(gen->cx, NewDenseUnallocatedArray(gen->cx, count));
|
||||
if (!templateObject)
|
||||
return false;
|
||||
templateObject->setType(typeObj);
|
||||
|
||||
masm.newGCThing(gen->cx, objReg, templateObject, ool->entry());
|
||||
masm.initGCThing(gen->cx, objReg, templateObject);
|
||||
masm.newGCThing(objReg, templateObject, ool->entry());
|
||||
masm.initGCThing(objReg, templateObject);
|
||||
|
||||
masm.bind(ool->rejoin());
|
||||
return true;
|
||||
@ -1290,14 +1279,13 @@ CodeGenerator::visitNewObjectVMCall(LNewObject *lir)
|
||||
{
|
||||
Register objReg = ToRegister(lir->output());
|
||||
|
||||
typedef JSObject *(*pf)(JSContext *, HandleObject, types::TypeObject *);
|
||||
typedef JSObject *(*pf)(JSContext *, HandleObject);
|
||||
static const VMFunction Info = FunctionInfo<pf>(NewInitObject);
|
||||
|
||||
JS_ASSERT(!lir->isCall());
|
||||
saveLive(lir);
|
||||
|
||||
pushArg(ImmGCPtr(lir->mir()->type()));
|
||||
pushArg(ImmGCPtr(lir->mir()->baseObj()));
|
||||
pushArg(ImmGCPtr(lir->mir()->templateObject()));
|
||||
if (!callVM(Info, lir))
|
||||
return false;
|
||||
|
||||
@ -1313,26 +1301,17 @@ CodeGenerator::visitNewObject(LNewObject *lir)
|
||||
{
|
||||
Register objReg = ToRegister(lir->output());
|
||||
|
||||
RootedObject baseObj(gen->cx, lir->mir()->baseObj());
|
||||
types::TypeObject *typeObj = lir->mir()->type();
|
||||
JSObject *templateObject = lir->mir()->templateObject();
|
||||
|
||||
if (!gen->cx->typeInferenceEnabled() || !typeObj ||
|
||||
!baseObj || baseObj->hasDynamicSlots())
|
||||
{
|
||||
if (templateObject->hasSingletonType() || templateObject->hasDynamicSlots())
|
||||
return visitNewObjectVMCall(lir);
|
||||
}
|
||||
|
||||
OutOfLineNewObject *ool = new OutOfLineNewObject(lir);
|
||||
if (!addOutOfLineCode(ool))
|
||||
return false;
|
||||
|
||||
RootedObject templateObject(gen->cx, CopyInitializerObject(gen->cx, baseObj));
|
||||
if (!templateObject)
|
||||
return false;
|
||||
templateObject->setType(typeObj);
|
||||
|
||||
masm.newGCThing(gen->cx, objReg, templateObject, ool->entry());
|
||||
masm.initGCThing(gen->cx, objReg, templateObject);
|
||||
masm.newGCThing(objReg, templateObject, ool->entry());
|
||||
masm.initGCThing(objReg, templateObject);
|
||||
|
||||
masm.bind(ool->rejoin());
|
||||
return true;
|
||||
@ -1355,8 +1334,9 @@ CodeGenerator::visitNewCallObject(LNewCallObject *lir)
|
||||
typedef JSObject *(*pf)(JSContext *, HandleShape, HandleTypeObject, HeapSlot *, HandleObject);
|
||||
static const VMFunction NewCallObjectInfo = FunctionInfo<pf>(NewCallObject);
|
||||
|
||||
RootedObject global(gen->cx, gen->cx->compartment->maybeGlobal());
|
||||
RootedObject templateObj(gen->cx, lir->mir()->templateObj());
|
||||
JSObject *templateObj = lir->mir()->templateObj();
|
||||
JSObject *global = &templateObj->global();
|
||||
|
||||
if (lir->isCall()) {
|
||||
pushArg(ImmGCPtr(global));
|
||||
if (lir->slots()->isRegister())
|
||||
@ -1388,8 +1368,8 @@ CodeGenerator::visitNewCallObject(LNewCallObject *lir)
|
||||
if (!ool)
|
||||
return false;
|
||||
|
||||
masm.newGCThing(gen->cx, obj, templateObj, ool->entry());
|
||||
masm.initGCThing(gen->cx, obj, templateObj);
|
||||
masm.newGCThing(obj, templateObj, ool->entry());
|
||||
masm.initGCThing(obj, templateObj);
|
||||
|
||||
if (lir->slots()->isRegister())
|
||||
masm.storePtr(ToRegister(lir->slots()), Address(obj, JSObject::offsetOfSlots()));
|
||||
@ -1417,7 +1397,7 @@ CodeGenerator::visitCreateThis(LCreateThis *lir)
|
||||
{
|
||||
JS_ASSERT(lir->mir()->hasTemplateObject());
|
||||
|
||||
RootedObject templateObject(gen->cx, lir->mir()->getTemplateObject());
|
||||
JSObject *templateObject = lir->mir()->getTemplateObject();
|
||||
gc::AllocKind allocKind = templateObject->getAllocKind();
|
||||
int thingSize = (int)gc::Arena::thingSize(allocKind);
|
||||
Register objReg = ToRegister(lir->output());
|
||||
@ -1432,11 +1412,11 @@ CodeGenerator::visitCreateThis(LCreateThis *lir)
|
||||
return false;
|
||||
|
||||
// Allocate. If the FreeList is empty, call to VM, which may GC.
|
||||
masm.newGCThing(gen->cx, objReg, templateObject, ool->entry());
|
||||
masm.newGCThing(objReg, templateObject, ool->entry());
|
||||
|
||||
// Initialize based on the templateObject.
|
||||
masm.bind(ool->rejoin());
|
||||
masm.initGCThing(gen->cx, objReg, templateObject);
|
||||
masm.initGCThing(objReg, templateObject);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1596,7 +1576,7 @@ CodeGenerator::visitMathFunctionD(LMathFunctionD *ins)
|
||||
FloatRegister input = ToFloatRegister(ins->input());
|
||||
JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg);
|
||||
|
||||
MathCache *mathCache = gen->cx->runtime->getMathCache(gen->cx);
|
||||
MathCache *mathCache = ins->mir()->cache();
|
||||
|
||||
masm.setupUnalignedABICall(2, temp);
|
||||
masm.movePtr(ImmWord(mathCache), temp);
|
||||
@ -1928,7 +1908,7 @@ CodeGenerator::visitFromCharCode(LFromCharCode *lir)
|
||||
|
||||
masm.jump(ool->entry());
|
||||
masm.bind(&fast);
|
||||
masm.movePtr(ImmWord(&gen->cx->runtime->staticStrings.unitStaticTable), output);
|
||||
masm.movePtr(ImmWord(&gen->compartment->rt->staticStrings.unitStaticTable), output);
|
||||
masm.loadPtr(BaseIndex(output, code, ScalePointer), output);
|
||||
masm.bind(ool->rejoin());
|
||||
return true;
|
||||
@ -2441,7 +2421,7 @@ CodeGenerator::visitIteratorStart(LIteratorStart *lir)
|
||||
JS_ASSERT(flags == JSITER_ENUMERATE);
|
||||
|
||||
// Fetch the most recent iterator and ensure it's not NULL.
|
||||
masm.loadPtr(AbsoluteAddress(&gen->cx->runtime->nativeIterCache.last), output);
|
||||
masm.loadPtr(AbsoluteAddress(&gen->compartment->rt->nativeIterCache.last), output);
|
||||
masm.branchTestPtr(Assembler::Zero, output, output, ool->entry());
|
||||
|
||||
// Load NativeIterator.
|
||||
@ -2634,7 +2614,7 @@ CodeGenerator::visitGetArgument(LGetArgument *lir)
|
||||
bool
|
||||
CodeGenerator::generate()
|
||||
{
|
||||
JSContext *cx = gen->cx;
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
|
||||
unsigned slots = graph.localSlotCount() +
|
||||
(graph.argumentSlotCount() * sizeof(Value) / STACK_SLOT_SIZE);
|
||||
@ -3019,11 +2999,11 @@ CodeGenerator::visitOutOfLineCacheGetProperty(OutOfLineCache *ool)
|
||||
// and which atom property it should get
|
||||
// Note: because all registers are saved, the output register should be
|
||||
// a def register, else the result will be overriden by restoreLive(ins)
|
||||
RootedPropertyName name(gen->cx);
|
||||
PropertyName *name = NULL;
|
||||
switch (ins->op()) {
|
||||
case LInstruction::LOp_InstanceOfO:
|
||||
case LInstruction::LOp_InstanceOfV:
|
||||
name = GetIonContext()->cx->runtime->atomState.classPrototypeAtom;
|
||||
name = gen->compartment->rt->atomState.classPrototypeAtom;
|
||||
objReg = ToRegister(ins->getTemp(1));
|
||||
output = TypedOrValueRegister(MIRType_Object, ToAnyRegister(ins->getDef(0)));
|
||||
break;
|
||||
@ -3320,7 +3300,7 @@ CodeGenerator::visitTypeOfV(LTypeOfV *lir)
|
||||
if (!addOutOfLineCode(ool))
|
||||
return false;
|
||||
|
||||
PropertyName **typeAtoms = gen->cx->runtime->atomState.typeAtoms;
|
||||
PropertyName **typeAtoms = gen->compartment->rt->atomState.typeAtoms;
|
||||
|
||||
// Jump to the OOL path if the value is an object. Objects are complicated
|
||||
// since they may have a typeof hook.
|
||||
@ -3792,15 +3772,10 @@ CodeGenerator::emitInstanceOf(LInstruction *ins, Register rhs)
|
||||
bool
|
||||
CodeGenerator::visitProfilingEnter(LProfilingEnter *lir)
|
||||
{
|
||||
SPSProfiler *profiler = &gen->cx->runtime->spsProfiler;
|
||||
SPSProfiler *profiler = &gen->compartment->rt->spsProfiler;
|
||||
JS_ASSERT(profiler->enabled());
|
||||
|
||||
// This could be a push for an inline script, so we can't always use
|
||||
// gen->info().script() blindly.
|
||||
JSScript *script = lir->script();
|
||||
const char *string = profiler->profileString(gen->cx, script, script->function());
|
||||
if (string == NULL)
|
||||
return false;
|
||||
const char *string = lir->profileString();
|
||||
|
||||
Register size = ToRegister(lir->temp1()->output());
|
||||
Register base = ToRegister(lir->temp2()->output());
|
||||
@ -3832,7 +3807,7 @@ CodeGenerator::visitProfilingEnter(LProfilingEnter *lir)
|
||||
bool
|
||||
CodeGenerator::visitProfilingExit(LProfilingExit *exit)
|
||||
{
|
||||
SPSProfiler *profiler = &gen->cx->runtime->spsProfiler;
|
||||
SPSProfiler *profiler = &gen->compartment->rt->spsProfiler;
|
||||
JS_ASSERT(profiler->enabled());
|
||||
Register temp = ToRegister(exit->temp());
|
||||
masm.movePtr(ImmWord(profiler->sizePointer()), temp);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "Ion.h"
|
||||
#include "IonAnalysis.h"
|
||||
#include "IonBuilder.h"
|
||||
#include "IonLinker.h"
|
||||
#include "IonSpewer.h"
|
||||
#include "LIR.h"
|
||||
#include "AliasAnalysis.h"
|
||||
@ -35,6 +36,7 @@
|
||||
#include "vm/Stack-inl.h"
|
||||
#include "ion/IonFrames-inl.h"
|
||||
#include "ion/CompilerRoot.h"
|
||||
#include "methodjit/Retcon.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::ion;
|
||||
@ -86,8 +88,9 @@ ion::GetIonContext()
|
||||
return CurrentIonContext();
|
||||
}
|
||||
|
||||
IonContext::IonContext(JSContext *cx, TempAllocator *temp)
|
||||
IonContext::IonContext(JSContext *cx, JSCompartment *compartment, TempAllocator *temp)
|
||||
: cx(cx),
|
||||
compartment(compartment),
|
||||
temp(temp),
|
||||
prev_(CurrentIonContext()),
|
||||
assemblerCount_(0)
|
||||
@ -849,12 +852,12 @@ static bool
|
||||
IonCompile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing)
|
||||
{
|
||||
TempAllocator temp(&cx->tempLifoAlloc());
|
||||
IonContext ictx(cx, &temp);
|
||||
IonContext ictx(cx, cx->compartment, &temp);
|
||||
|
||||
if (!cx->compartment->ensureIonCompartmentExists(cx))
|
||||
return false;
|
||||
|
||||
MIRGraph graph(temp);
|
||||
MIRGraph graph(&temp);
|
||||
CompileInfo *info = cx->tempLifoAlloc().new_<CompileInfo>(script, fun, osrPc, constructing);
|
||||
if (!info)
|
||||
return false;
|
||||
@ -869,7 +872,7 @@ IonCompile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc,
|
||||
enterCompiler.init(script, false, 0);
|
||||
AutoCompilerRoots roots(script->compartment()->rt);
|
||||
|
||||
IonBuilder builder(cx, temp, graph, &oracle, *info);
|
||||
IonBuilder builder(cx, &temp, &graph, &oracle, info);
|
||||
if (!Compiler(builder, graph)) {
|
||||
IonSpew(IonSpew_Abort, "IM Compilation failed.");
|
||||
return false;
|
||||
@ -1144,7 +1147,7 @@ EnterIon(JSContext *cx, StackFrame *fp, void *jitcode)
|
||||
Value result = Int32Value(numActualArgs);
|
||||
{
|
||||
AssertCompartmentUnchanged pcc(cx);
|
||||
IonContext ictx(cx, NULL);
|
||||
IonContext ictx(cx, cx->compartment, NULL);
|
||||
IonActivation activation(cx, fp);
|
||||
JSAutoResolveFlags rf(cx, RESOLVE_INFER);
|
||||
|
||||
|
@ -176,14 +176,16 @@ enum MethodStatus
|
||||
|
||||
// An Ion context is needed to enter into either an Ion method or an instance
|
||||
// of the Ion compiler. It points to a temporary allocator and the active
|
||||
// JSContext.
|
||||
// JSContext, either of which may be NULL, and the active compartment, which
|
||||
// will not be NULL.
|
||||
class IonContext
|
||||
{
|
||||
public:
|
||||
IonContext(JSContext *cx, TempAllocator *temp);
|
||||
IonContext(JSContext *cx, JSCompartment *compartment, TempAllocator *temp);
|
||||
~IonContext();
|
||||
|
||||
JSContext *cx;
|
||||
JSCompartment *compartment;
|
||||
TempAllocator *temp;
|
||||
int getNextAssemblerId() {
|
||||
return assemblerCount_++;
|
||||
|
@ -17,26 +17,6 @@
|
||||
namespace js {
|
||||
namespace ion {
|
||||
|
||||
class IonAllocPolicy
|
||||
{
|
||||
public:
|
||||
void *malloc_(size_t bytes) {
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
return cx->tempLifoAlloc().alloc(bytes);
|
||||
}
|
||||
void *realloc_(void *p, size_t oldBytes, size_t bytes) {
|
||||
void *n = malloc_(bytes);
|
||||
if (!n)
|
||||
return n;
|
||||
memcpy(n, p, Min(oldBytes, bytes));
|
||||
return n;
|
||||
}
|
||||
void free_(void *p) {
|
||||
}
|
||||
void reportAllocOverflow() const {
|
||||
}
|
||||
};
|
||||
|
||||
class TempAllocator
|
||||
{
|
||||
LifoAlloc *lifoAlloc_;
|
||||
@ -68,6 +48,11 @@ class TempAllocator
|
||||
return p;
|
||||
}
|
||||
|
||||
LifoAlloc *lifoAlloc()
|
||||
{
|
||||
return lifoAlloc_;
|
||||
}
|
||||
|
||||
bool ensureBallast() {
|
||||
// Most infallible Ion allocations are small, so we use a ballast of
|
||||
// ~16K for now.
|
||||
@ -75,6 +60,25 @@ class TempAllocator
|
||||
}
|
||||
};
|
||||
|
||||
class IonAllocPolicy
|
||||
{
|
||||
public:
|
||||
void *malloc_(size_t bytes) {
|
||||
return GetIonContext()->temp->allocate(bytes);
|
||||
}
|
||||
void *realloc_(void *p, size_t oldBytes, size_t bytes) {
|
||||
void *n = malloc_(bytes);
|
||||
if (!n)
|
||||
return n;
|
||||
memcpy(n, p, Min(oldBytes, bytes));
|
||||
return n;
|
||||
}
|
||||
void free_(void *p) {
|
||||
}
|
||||
void reportAllocOverflow() const {
|
||||
}
|
||||
};
|
||||
|
||||
class AutoIonContextAlloc
|
||||
{
|
||||
TempAllocator tempAlloc_;
|
||||
|
@ -23,10 +23,11 @@
|
||||
using namespace js;
|
||||
using namespace js::ion;
|
||||
|
||||
IonBuilder::IonBuilder(JSContext *cx, TempAllocator &temp, MIRGraph &graph, TypeOracle *oracle,
|
||||
CompileInfo &info, size_t inliningDepth, uint32 loopDepth)
|
||||
: MIRGenerator(cx, temp, graph, info),
|
||||
script(info.script()),
|
||||
IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
|
||||
TypeOracle *oracle, CompileInfo *info, size_t inliningDepth, uint32 loopDepth)
|
||||
: MIRGenerator(cx->compartment, temp, graph, info),
|
||||
script(info->script()),
|
||||
cx(cx),
|
||||
loopDepth_(loopDepth),
|
||||
callerResumePoint_(NULL),
|
||||
callerBuilder_(NULL),
|
||||
@ -35,7 +36,14 @@ IonBuilder::IonBuilder(JSContext *cx, TempAllocator &temp, MIRGraph &graph, Type
|
||||
failedBoundsCheck_(script->failedBoundsCheck),
|
||||
lazyArguments_(NULL)
|
||||
{
|
||||
pc = info.startPC();
|
||||
pc = info->startPC();
|
||||
}
|
||||
|
||||
void
|
||||
IonBuilder::clearForBackEnd()
|
||||
{
|
||||
cx = NULL;
|
||||
oracle = NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -279,8 +287,13 @@ IonBuilder::build()
|
||||
|
||||
// Emit the start instruction, so we can begin real instructions.
|
||||
current->makeStart(MStart::New(MStart::StartType_Default));
|
||||
if (instrumentedProfiling())
|
||||
current->add(MProfilingEnter::New(script));
|
||||
if (instrumentedProfiling()) {
|
||||
SPSProfiler *profiler = &cx->runtime->spsProfiler;
|
||||
const char *string = profiler->profileString(cx, script, script->function());
|
||||
if (!string)
|
||||
return false;
|
||||
current->add(MProfilingEnter::New(string));
|
||||
}
|
||||
|
||||
// Parameters have been checked to correspond to the typeset, now we unbox
|
||||
// what we can in an infallible manner.
|
||||
@ -393,8 +406,13 @@ IonBuilder::buildInline(IonBuilder *callerBuilder, MResumePoint *callerResumePoi
|
||||
current->setCallerResumePoint(callerResumePoint);
|
||||
|
||||
// Flag the entry into an inlined function with a special MStart block
|
||||
if (instrumentedProfiling())
|
||||
current->add(MProfilingEnter::New(script));
|
||||
if (instrumentedProfiling()) {
|
||||
SPSProfiler *profiler = &cx->runtime->spsProfiler;
|
||||
const char *string = profiler->profileString(cx, script, script->function());
|
||||
if (!string)
|
||||
return false;
|
||||
current->add(MProfilingEnter::New(string));
|
||||
}
|
||||
|
||||
// Connect the entrance block to the last block in the caller's graph.
|
||||
MBasicBlock *predecessor = callerBuilder->current;
|
||||
@ -1165,7 +1183,7 @@ IonBuilder::processIfEnd(CFGState &state)
|
||||
}
|
||||
|
||||
current = state.branch.ifFalse;
|
||||
graph_.moveBlockToEnd(current);
|
||||
graph().moveBlockToEnd(current);
|
||||
pc = current->pc();
|
||||
return ControlStatus_Joined;
|
||||
}
|
||||
@ -1180,7 +1198,7 @@ IonBuilder::processIfElseTrueEnd(CFGState &state)
|
||||
state.stopAt = state.branch.falseEnd;
|
||||
pc = state.branch.ifFalse->pc();
|
||||
current = state.branch.ifFalse;
|
||||
graph_.moveBlockToEnd(current);
|
||||
graph().moveBlockToEnd(current);
|
||||
return ControlStatus_Jumped;
|
||||
}
|
||||
|
||||
@ -1230,7 +1248,7 @@ IonBuilder::processBrokenLoop(CFGState &state)
|
||||
|
||||
// A broken loop is not a real loop (it has no header or backedge), so
|
||||
// reset the loop depth.
|
||||
for (MBasicBlockIterator i(graph_.begin(state.loop.entry)); i != graph_.end(); i++) {
|
||||
for (MBasicBlockIterator i(graph().begin(state.loop.entry)); i != graph().end(); i++) {
|
||||
if (i->loopDepth() > loopDepth_)
|
||||
i->setLoopDepth(i->loopDepth() - 1);
|
||||
}
|
||||
@ -1241,7 +1259,7 @@ IonBuilder::processBrokenLoop(CFGState &state)
|
||||
current = state.loop.successor;
|
||||
if (current) {
|
||||
JS_ASSERT(current->loopDepth() == loopDepth_);
|
||||
graph_.moveBlockToEnd(current);
|
||||
graph().moveBlockToEnd(current);
|
||||
}
|
||||
|
||||
// Join the breaks together and continue parsing.
|
||||
@ -1285,7 +1303,7 @@ IonBuilder::finishLoop(CFGState &state, MBasicBlock *successor)
|
||||
if (!state.loop.entry->setBackedge(current))
|
||||
return ControlStatus_Error;
|
||||
if (successor) {
|
||||
graph_.moveBlockToEnd(successor);
|
||||
graph().moveBlockToEnd(successor);
|
||||
successor->inheritPhis(state.loop.entry);
|
||||
}
|
||||
|
||||
@ -1542,7 +1560,7 @@ IonBuilder::processNextTableSwitchCase(CFGState &state)
|
||||
successor->addPredecessor(current);
|
||||
|
||||
// Insert successor after the current block, to maintain RPO.
|
||||
graph_.moveBlockToEnd(successor);
|
||||
graph().moveBlockToEnd(successor);
|
||||
}
|
||||
|
||||
// If this is the last successor the block should stop at the end of the tableswitch
|
||||
@ -1617,7 +1635,7 @@ IonBuilder::processNextLookupSwitchCase(CFGState &state)
|
||||
}
|
||||
|
||||
// Move next body block to end to maintain RPO.
|
||||
graph_.moveBlockToEnd(successor);
|
||||
graph().moveBlockToEnd(successor);
|
||||
|
||||
// If this is the last successor the block should stop at the end of the lookupswitch
|
||||
// Else it should stop at the start of the next successor
|
||||
@ -1676,7 +1694,7 @@ IonBuilder::processAndOrEnd(CFGState &state)
|
||||
return ControlStatus_Error;
|
||||
|
||||
current = state.branch.ifFalse;
|
||||
graph_.moveBlockToEnd(current);
|
||||
graph().moveBlockToEnd(current);
|
||||
pc = current->pc();
|
||||
return ControlStatus_Joined;
|
||||
}
|
||||
@ -2156,7 +2174,7 @@ IonBuilder::tableSwitch(JSOp op, jssrcnote *sn)
|
||||
}
|
||||
|
||||
// Move defaultcase to the end, to maintain RPO.
|
||||
graph_.moveBlockToEnd(defaultcase);
|
||||
graph().moveBlockToEnd(defaultcase);
|
||||
|
||||
JS_ASSERT(tableswitch->numCases() == (uint32)(high - low + 1));
|
||||
JS_ASSERT(tableswitch->numSuccessors() > 0);
|
||||
@ -2370,7 +2388,7 @@ IonBuilder::lookupSwitch(JSOp op, jssrcnote *sn)
|
||||
for (size_t i = 0; i < bodyBlocks.length(); i++) {
|
||||
(*state.lookupswitch.bodies)[i] = bodyBlocks[i];
|
||||
}
|
||||
graph_.moveBlockToEnd(bodyBlocks[0]);
|
||||
graph().moveBlockToEnd(bodyBlocks[0]);
|
||||
|
||||
// Create control flow info
|
||||
ControlFlowInfo switchinfo(cfgStack_.length(), exitpc);
|
||||
@ -2805,7 +2823,8 @@ IonBuilder::jsop_call_inline(HandleFunction callee, uint32 argc, bool constructi
|
||||
if (!oracle.init(cx, callee->script()))
|
||||
return false;
|
||||
|
||||
IonBuilder inlineBuilder(cx, temp(), graph(), &oracle, *info, inliningDepth + 1, loopDepth_);
|
||||
IonBuilder inlineBuilder(cx, &temp(), &graph(), &oracle,
|
||||
info, inliningDepth + 1, loopDepth_);
|
||||
|
||||
// Create |this| on the caller-side for inlined constructors.
|
||||
MDefinition *thisDefn = NULL;
|
||||
@ -3244,7 +3263,7 @@ IonBuilder::inlineScriptedCall(AutoObjectVector &targets, uint32 argc, bool cons
|
||||
MConstant *constFun = disp->getFunctionConstant(i);
|
||||
RootedFunction target(cx, constFun->value().toObject().toFunction());
|
||||
MBasicBlock *block = disp->getSuccessor(i);
|
||||
graph_.moveBlockToEnd(block);
|
||||
graph().moveBlockToEnd(block);
|
||||
current = block;
|
||||
|
||||
if (!jsop_call_inline(target, argc, constructing, constFun, bottom, retvalDefns))
|
||||
@ -3255,9 +3274,9 @@ IonBuilder::inlineScriptedCall(AutoObjectVector &targets, uint32 argc, bool cons
|
||||
// a fallback case to consider. Move the fallback blocks to the end of the graph
|
||||
// and link them to the bottom block.
|
||||
if (disp->inlinePropertyTable()) {
|
||||
graph_.moveBlockToEnd(disp->fallbackPrepBlock());
|
||||
graph_.moveBlockToEnd(disp->fallbackMidBlock());
|
||||
graph_.moveBlockToEnd(disp->fallbackEndBlock());
|
||||
graph().moveBlockToEnd(disp->fallbackPrepBlock());
|
||||
graph().moveBlockToEnd(disp->fallbackMidBlock());
|
||||
graph().moveBlockToEnd(disp->fallbackEndBlock());
|
||||
|
||||
// Link the end fallback block to bottom.
|
||||
MBasicBlock *fallbackEndBlock = disp->fallbackEndBlock();
|
||||
@ -3270,7 +3289,7 @@ IonBuilder::inlineScriptedCall(AutoObjectVector &targets, uint32 argc, bool cons
|
||||
}
|
||||
}
|
||||
|
||||
graph_.moveBlockToEnd(bottom);
|
||||
graph().moveBlockToEnd(bottom);
|
||||
|
||||
bottom->inheritSlots(top);
|
||||
|
||||
@ -3803,19 +3822,36 @@ IonBuilder::jsop_compare(JSOp op)
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
IonBuilder::getNewArrayTemplateObject(uint32 count)
|
||||
{
|
||||
JSObject *templateObject = NewDenseUnallocatedArray(cx, count);
|
||||
if (!templateObject)
|
||||
return NULL;
|
||||
|
||||
if (types::UseNewTypeForInitializer(cx, script, pc, JSProto_Array)) {
|
||||
if (!templateObject->setSingletonType(cx))
|
||||
return NULL;
|
||||
} else {
|
||||
types::TypeObject *type = types::TypeScript::InitObject(cx, script, pc, JSProto_Array);
|
||||
if (!type)
|
||||
return NULL;
|
||||
templateObject->setType(type);
|
||||
}
|
||||
|
||||
return templateObject;
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_newarray(uint32 count)
|
||||
{
|
||||
JS_ASSERT(script->hasGlobal());
|
||||
|
||||
types::TypeObject *type = NULL;
|
||||
if (!types::UseNewTypeForInitializer(cx, script, pc, JSProto_Array)) {
|
||||
type = types::TypeScript::InitObject(cx, script, pc, JSProto_Array);
|
||||
if (!type)
|
||||
return false;
|
||||
}
|
||||
JSObject *templateObject = getNewArrayTemplateObject(count);
|
||||
if (!templateObject)
|
||||
return false;
|
||||
|
||||
MNewArray *ins = new MNewArray(count, type, MNewArray::NewArray_Allocating);
|
||||
MNewArray *ins = new MNewArray(count, templateObject, MNewArray::NewArray_Allocating);
|
||||
|
||||
current->add(ins);
|
||||
current->push(ins);
|
||||
@ -3829,14 +3865,29 @@ IonBuilder::jsop_newobject(HandleObject baseObj)
|
||||
// Don't bake in the TypeObject for non-CNG scripts.
|
||||
JS_ASSERT(script->hasGlobal());
|
||||
|
||||
types::TypeObject *type = NULL;
|
||||
if (!types::UseNewTypeForInitializer(cx, script, pc, JSProto_Object)) {
|
||||
type = types::TypeScript::InitObject(cx, script, pc, JSProto_Object);
|
||||
if (!type)
|
||||
return false;
|
||||
JSObject *templateObject;
|
||||
|
||||
if (baseObj) {
|
||||
templateObject = CopyInitializerObject(cx, baseObj);
|
||||
} else {
|
||||
gc::AllocKind kind = GuessObjectGCKind(0);
|
||||
templateObject = NewBuiltinClassInstance(cx, &ObjectClass, kind);
|
||||
}
|
||||
|
||||
MNewObject *ins = MNewObject::New(baseObj, type);
|
||||
if (!templateObject)
|
||||
return false;
|
||||
|
||||
if (types::UseNewTypeForInitializer(cx, script, pc, JSProto_Object)) {
|
||||
if (!templateObject->setSingletonType(cx))
|
||||
return false;
|
||||
} else {
|
||||
types::TypeObject *type = types::TypeScript::InitObject(cx, script, pc, JSProto_Object);
|
||||
if (!type)
|
||||
return false;
|
||||
templateObject->setType(type);
|
||||
}
|
||||
|
||||
MNewObject *ins = MNewObject::New(templateObject);
|
||||
|
||||
current->add(ins);
|
||||
current->push(ins);
|
||||
@ -3886,27 +3937,28 @@ IonBuilder::jsop_initprop(HandlePropertyName name)
|
||||
MDefinition *value = current->pop();
|
||||
MDefinition *obj = current->peek(-1);
|
||||
|
||||
RootedObject baseObj(cx, obj->toNewObject()->baseObj());
|
||||
RootedObject templateObject(cx, obj->toNewObject()->templateObject());
|
||||
|
||||
if (!oracle->propertyWriteCanSpecialize(script, pc)) {
|
||||
// This should only happen for a few names like __proto__.
|
||||
return abort("INITPROP Monitored initprop");
|
||||
}
|
||||
|
||||
// JSOP_NEWINIT becomes an MNewObject without a known base.
|
||||
if (!baseObj) {
|
||||
RootedObject holder(cx);
|
||||
RootedShape shape(cx);
|
||||
RootedId id(cx, NameToId(name));
|
||||
bool res = LookupPropertyWithFlags(cx, templateObject, id,
|
||||
JSRESOLVE_QUALIFIED, &holder, &shape);
|
||||
if (!res)
|
||||
return false;
|
||||
|
||||
if (!shape || holder != templateObject) {
|
||||
// JSOP_NEWINIT becomes an MNewObject without preconfigured properties.
|
||||
MInitProp *init = MInitProp::New(obj, name, value);
|
||||
current->add(init);
|
||||
return resumeAfter(init);
|
||||
}
|
||||
|
||||
RootedObject holder(cx);
|
||||
RootedShape shape(cx);
|
||||
RootedId id(cx, NameToId(name));
|
||||
DebugOnly<bool> res = LookupPropertyWithFlags(cx, baseObj, id,
|
||||
JSRESOLVE_QUALIFIED, &holder, &shape);
|
||||
JS_ASSERT(res && shape && holder == baseObj);
|
||||
|
||||
bool needsBarrier = true;
|
||||
TypeOracle::BinaryTypes b = oracle->binaryTypes(script, pc);
|
||||
if (b.lhsTypes &&
|
||||
@ -3916,7 +3968,7 @@ IonBuilder::jsop_initprop(HandlePropertyName name)
|
||||
needsBarrier = false;
|
||||
}
|
||||
|
||||
if (baseObj->isFixedSlot(shape->slot())) {
|
||||
if (templateObject->isFixedSlot(shape->slot())) {
|
||||
MStoreFixedSlot *store = MStoreFixedSlot::New(obj, shape->slot(), value);
|
||||
if (needsBarrier)
|
||||
store->setNeedsBarrier();
|
||||
@ -3928,7 +3980,7 @@ IonBuilder::jsop_initprop(HandlePropertyName name)
|
||||
MSlots *slots = MSlots::New(obj);
|
||||
current->add(slots);
|
||||
|
||||
MStoreSlot *store = MStoreSlot::New(slots, baseObj->dynamicSlotIndex(shape->slot()), value);
|
||||
MStoreSlot *store = MStoreSlot::New(slots, templateObject->dynamicSlotIndex(shape->slot()), value);
|
||||
if (needsBarrier)
|
||||
store->setNeedsBarrier();
|
||||
|
||||
@ -3967,7 +4019,7 @@ IonBuilder::newBlockAfter(MBasicBlock *at, MBasicBlock *predecessor, jsbytecode
|
||||
MBasicBlock *block = MBasicBlock::New(graph(), info(), predecessor, pc, MBasicBlock::NORMAL);
|
||||
if (!block)
|
||||
return NULL;
|
||||
graph_.insertBlockAfter(at, block);
|
||||
graph().insertBlockAfter(at, block);
|
||||
return block;
|
||||
}
|
||||
|
||||
@ -3987,7 +4039,7 @@ IonBuilder::newOsrPreheader(MBasicBlock *predecessor, jsbytecode *loopEntry)
|
||||
// Create two blocks: one for the OSR entry with no predecessors, one for
|
||||
// the preheader, which has the OSR entry block as a predecessor. The
|
||||
// OSR block is always the second block (with id 1).
|
||||
MBasicBlock *osrBlock = newBlockAfter(*graph_.begin(), loopEntry);
|
||||
MBasicBlock *osrBlock = newBlockAfter(*graph().begin(), loopEntry);
|
||||
MBasicBlock *preheader = newBlock(predecessor, loopEntry);
|
||||
if (!osrBlock || !preheader)
|
||||
return NULL;
|
||||
@ -5705,7 +5757,11 @@ IonBuilder::jsop_delprop(JSAtom *atom)
|
||||
bool
|
||||
IonBuilder::jsop_regexp(RegExpObject *reobj)
|
||||
{
|
||||
MRegExp *ins = MRegExp::New(reobj, MRegExp::MustClone);
|
||||
JSObject *prototype = script->global().getOrCreateRegExpPrototype(cx);
|
||||
if (!prototype)
|
||||
return false;
|
||||
|
||||
MRegExp *ins = MRegExp::New(reobj, prototype, MRegExp::MustClone);
|
||||
current->add(ins);
|
||||
current->push(ins);
|
||||
|
||||
|
@ -159,8 +159,8 @@ class IonBuilder : public MIRGenerator
|
||||
static int CmpSuccessors(const void *a, const void *b);
|
||||
|
||||
public:
|
||||
IonBuilder(JSContext *cx, TempAllocator &temp, MIRGraph &graph, TypeOracle *oracle,
|
||||
CompileInfo &info, size_t inliningDepth = 0, uint32 loopDepth = 0);
|
||||
IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
|
||||
TypeOracle *oracle, CompileInfo *info, size_t inliningDepth = 0, uint32 loopDepth = 0);
|
||||
|
||||
bool build();
|
||||
bool buildInline(IonBuilder *callerBuilder, MResumePoint *callerResumePoint,
|
||||
@ -284,6 +284,8 @@ class IonBuilder : public MIRGenerator
|
||||
|
||||
MInstruction *addBoundsCheck(MDefinition *index, MDefinition *length);
|
||||
|
||||
JSObject *getNewArrayTemplateObject(uint32 count);
|
||||
|
||||
bool invalidatedIdempotentCache();
|
||||
|
||||
bool loadSlot(MDefinition *obj, Shape *shape, MIRType rvalType);
|
||||
@ -423,7 +425,11 @@ class IonBuilder : public MIRGenerator
|
||||
// A builder is inextricably tied to a particular script.
|
||||
JSScript * const script;
|
||||
|
||||
void clearForBackEnd();
|
||||
|
||||
private:
|
||||
JSContext *cx;
|
||||
|
||||
jsbytecode *pc;
|
||||
MBasicBlock *current;
|
||||
uint32 loopDepth_;
|
||||
|
@ -338,8 +338,8 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output)
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::newGCThing(JSContext *cx, const Register &result,
|
||||
HandleObject templateObject, Label *fail)
|
||||
MacroAssembler::newGCThing(const Register &result,
|
||||
JSObject *templateObject, Label *fail)
|
||||
{
|
||||
// Inlined equivalent of js::gc::NewGCThing() without failure case handling.
|
||||
|
||||
@ -347,12 +347,13 @@ MacroAssembler::newGCThing(JSContext *cx, const Register &result,
|
||||
JS_ASSERT(allocKind >= gc::FINALIZE_OBJECT0 && allocKind <= gc::FINALIZE_OBJECT_LAST);
|
||||
int thingSize = (int)gc::Arena::thingSize(allocKind);
|
||||
|
||||
JS_ASSERT(cx->typeInferenceEnabled());
|
||||
JS_ASSERT(!templateObject->hasDynamicElements());
|
||||
|
||||
JSCompartment *compartment = GetIonContext()->compartment;
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
// Don't execute the inline path if gcZeal is active.
|
||||
movePtr(ImmWord(cx->runtime), result);
|
||||
movePtr(ImmWord(compartment->rt), result);
|
||||
loadPtr(Address(result, offsetof(JSRuntime, gcZeal_)), result);
|
||||
branch32(Assembler::NotEqual, result, Imm32(0), fail);
|
||||
#endif
|
||||
@ -362,7 +363,7 @@ MacroAssembler::newGCThing(JSContext *cx, const Register &result,
|
||||
// If a FreeSpan is replaced, its members are updated in the freeLists table,
|
||||
// which the code below always re-reads.
|
||||
gc::FreeSpan *list = const_cast<gc::FreeSpan *>
|
||||
(cx->compartment->arenas.getFreeList(allocKind));
|
||||
(compartment->arenas.getFreeList(allocKind));
|
||||
loadPtr(AbsoluteAddress(&list->first), result);
|
||||
branchPtr(Assembler::BelowOrEqual, AbsoluteAddress(&list->last), result, fail);
|
||||
|
||||
@ -372,7 +373,7 @@ MacroAssembler::newGCThing(JSContext *cx, const Register &result,
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::initGCThing(JSContext *cx, const Register &obj, HandleObject templateObject)
|
||||
MacroAssembler::initGCThing(const Register &obj, JSObject *templateObject)
|
||||
{
|
||||
// Fast initialization of an empty object returned by NewGCThing().
|
||||
|
||||
|
@ -73,7 +73,7 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
: autoRooter_(cx, thisFromCtor()),
|
||||
enoughMemory_(true)
|
||||
{
|
||||
ionContext_.construct(cx, (js::ion::TempAllocator *)NULL);
|
||||
ionContext_.construct(cx, cx->compartment, (js::ion::TempAllocator *)NULL);
|
||||
alloc_.construct(cx);
|
||||
#ifdef JS_CPU_ARM
|
||||
m_buffer.id = GetIonContext()->getNextAssemblerId();
|
||||
@ -406,8 +406,8 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
void clampDoubleToUint8(FloatRegister input, Register output);
|
||||
|
||||
// Inline allocation.
|
||||
void newGCThing(JSContext *cx, const Register &result, HandleObject templateObject, Label *fail);
|
||||
void initGCThing(JSContext *cx, const Register &obj, HandleObject templateObject);
|
||||
void newGCThing(const Register &result, JSObject *templateObject, Label *fail);
|
||||
void initGCThing(const Register &obj, JSObject *templateObject);
|
||||
|
||||
// If the IonCode that created this assembler needs to transition into the VM,
|
||||
// we want to store the IonCode on the stack in order to mark it during a GC.
|
||||
|
@ -2862,8 +2862,8 @@ class LProfilingEnter : public LInstructionHelper<0, 0, 2>
|
||||
return getTemp(1);
|
||||
}
|
||||
|
||||
JSScript *script() const {
|
||||
return mir_->toProfilingEnter()->script();
|
||||
const char *profileString() const {
|
||||
return mir_->toProfilingEnter()->profileString();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -146,7 +146,11 @@ IonBuilder::inlineMathFunction(MMathFunction::Function function, uint32 argc, bo
|
||||
if (!discardCall(argc, argv, current))
|
||||
return InliningStatus_Error;
|
||||
|
||||
MMathFunction *ins = MMathFunction::New(argv[1], function);
|
||||
MathCache *cache = cx->runtime->getMathCache(cx);
|
||||
if (!cache)
|
||||
return InliningStatus_Error;
|
||||
|
||||
MMathFunction *ins = MMathFunction::New(argv[1], function, cache);
|
||||
current->add(ins);
|
||||
current->push(ins);
|
||||
return InliningStatus_Inlined;
|
||||
@ -179,8 +183,11 @@ IonBuilder::inlineArray(uint32 argc, bool constructing)
|
||||
if (!discardCall(argc, argv, current))
|
||||
return InliningStatus_Error;
|
||||
|
||||
types::TypeObject *type = types::TypeScript::InitObject(cx, script, pc, JSProto_Array);
|
||||
MNewArray *ins = new MNewArray(initLength, type, MNewArray::NewArray_Unallocating);
|
||||
JSObject *templateObject = getNewArrayTemplateObject(initLength);
|
||||
if (!templateObject)
|
||||
return InliningStatus_Error;
|
||||
|
||||
MNewArray *ins = new MNewArray(initLength, templateObject, MNewArray::NewArray_Unallocating);
|
||||
current->add(ins);
|
||||
current->push(ins);
|
||||
|
||||
|
@ -763,7 +763,7 @@ MMod::foldsTo(bool useValueNumbers)
|
||||
if (MDefinition *folded = EvaluateConstantOperands(this))
|
||||
return folded;
|
||||
|
||||
JSRuntime *rt = GetIonContext()->cx->runtime;
|
||||
JSRuntime *rt = GetIonContext()->compartment->rt;
|
||||
double NaN = rt->NaNValue.toDouble();
|
||||
double Inf = rt->positiveInfinityValue.toDouble();
|
||||
|
||||
@ -1078,8 +1078,8 @@ MTypeOf::foldsTo(bool useValueNumbers)
|
||||
return this;
|
||||
}
|
||||
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
return MConstant::New(StringValue(cx->runtime->atomState.typeAtoms[type]));
|
||||
JSRuntime *rt = GetIonContext()->compartment->rt;
|
||||
return MConstant::New(StringValue(rt->atomState.typeAtoms[type]));
|
||||
}
|
||||
|
||||
MBitAnd *
|
||||
@ -1196,11 +1196,8 @@ MToDouble::foldsTo(bool useValueNumbers)
|
||||
{
|
||||
if (input()->isConstant()) {
|
||||
const Value &v = input()->toConstant()->value();
|
||||
if (v.isPrimitive()) {
|
||||
double out;
|
||||
DebugOnly<bool> ok = ToNumber(GetIonContext()->cx, v, &out);
|
||||
JS_ASSERT(ok);
|
||||
|
||||
if (v.isNumber()) {
|
||||
double out = v.toNumber();
|
||||
return MConstant::New(DoubleValue(out));
|
||||
}
|
||||
}
|
||||
|
@ -948,17 +948,17 @@ class MNewArray : public MNullaryInstruction
|
||||
private:
|
||||
// Number of space to allocate for the array.
|
||||
uint32 count_;
|
||||
// Type of the object.
|
||||
HeapPtr<types::TypeObject> type_;
|
||||
// Template for the created object.
|
||||
HeapPtr<JSObject> templateObject_;
|
||||
// Allocate space at initialization or not
|
||||
AllocatingBehaviour allocating_;
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(NewArray);
|
||||
|
||||
MNewArray(uint32 count, types::TypeObject *type, AllocatingBehaviour allocating)
|
||||
MNewArray(uint32 count, JSObject *templateObject, AllocatingBehaviour allocating)
|
||||
: count_(count),
|
||||
type_(type),
|
||||
templateObject_(templateObject),
|
||||
allocating_(allocating)
|
||||
{
|
||||
setResultType(MIRType_Object);
|
||||
@ -968,8 +968,8 @@ class MNewArray : public MNullaryInstruction
|
||||
return count_;
|
||||
}
|
||||
|
||||
types::TypeObject *type() const {
|
||||
return type_;
|
||||
JSObject *templateObject() const {
|
||||
return templateObject_;
|
||||
}
|
||||
|
||||
bool isAllocating() const {
|
||||
@ -990,11 +990,11 @@ class MNewArray : public MNullaryInstruction
|
||||
class MNewObject : public MNullaryInstruction
|
||||
{
|
||||
CompilerRootObject baseObj_;
|
||||
HeapPtr<types::TypeObject> type_;
|
||||
// Template for the created object.
|
||||
HeapPtr<JSObject> templateObject_;
|
||||
|
||||
MNewObject(HandleObject baseObj, types::TypeObject *type)
|
||||
: baseObj_(baseObj),
|
||||
type_(type)
|
||||
MNewObject(JSObject *templateObject)
|
||||
: templateObject_(templateObject)
|
||||
{
|
||||
setResultType(MIRType_Object);
|
||||
}
|
||||
@ -1002,15 +1002,12 @@ class MNewObject : public MNullaryInstruction
|
||||
public:
|
||||
INSTRUCTION_HEADER(NewObject);
|
||||
|
||||
static MNewObject *New(HandleObject baseObj, types::TypeObject *type) {
|
||||
return new MNewObject(baseObj, type);
|
||||
static MNewObject *New(JSObject *templateObject) {
|
||||
return new MNewObject(templateObject);
|
||||
}
|
||||
|
||||
JSObject *baseObj() const {
|
||||
return baseObj_;
|
||||
}
|
||||
types::TypeObject *type() const {
|
||||
return type_;
|
||||
JSObject *templateObject() const {
|
||||
return templateObject_;
|
||||
}
|
||||
};
|
||||
|
||||
@ -2281,9 +2278,10 @@ class MMathFunction
|
||||
|
||||
private:
|
||||
Function function_;
|
||||
MathCache *cache_;
|
||||
|
||||
MMathFunction(MDefinition *input, Function function)
|
||||
: MUnaryInstruction(input), function_(function)
|
||||
MMathFunction(MDefinition *input, Function function, MathCache *cache)
|
||||
: MUnaryInstruction(input), function_(function), cache_(cache)
|
||||
{
|
||||
setResultType(MIRType_Double);
|
||||
setMovable();
|
||||
@ -2291,12 +2289,15 @@ class MMathFunction
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(MathFunction);
|
||||
static MMathFunction *New(MDefinition *input, Function function) {
|
||||
return new MMathFunction(input, function);
|
||||
static MMathFunction *New(MDefinition *input, Function function, MathCache *cache) {
|
||||
return new MMathFunction(input, function, cache);
|
||||
}
|
||||
Function function() const {
|
||||
return function_;
|
||||
}
|
||||
MathCache *cache() const {
|
||||
return cache_;
|
||||
}
|
||||
MDefinition *input() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
@ -2886,10 +2887,12 @@ class MRegExp : public MNullaryInstruction
|
||||
|
||||
private:
|
||||
HeapPtr<RegExpObject> source_;
|
||||
HeapPtr<JSObject> prototype_;
|
||||
CloneBehavior shouldClone_;
|
||||
|
||||
MRegExp(RegExpObject *source, CloneBehavior shouldClone)
|
||||
MRegExp(RegExpObject *source, JSObject *prototype, CloneBehavior shouldClone)
|
||||
: source_(source),
|
||||
prototype_(prototype),
|
||||
shouldClone_(shouldClone)
|
||||
{
|
||||
setResultType(MIRType_Object);
|
||||
@ -2903,13 +2906,16 @@ class MRegExp : public MNullaryInstruction
|
||||
public:
|
||||
INSTRUCTION_HEADER(RegExp)
|
||||
|
||||
static MRegExp *New(RegExpObject *source, CloneBehavior shouldClone) {
|
||||
return new MRegExp(source, shouldClone);
|
||||
static MRegExp *New(RegExpObject *source, JSObject *prototype, CloneBehavior shouldClone) {
|
||||
return new MRegExp(source, prototype, shouldClone);
|
||||
}
|
||||
|
||||
const HeapPtr<RegExpObject> &source() const {
|
||||
return source_;
|
||||
}
|
||||
JSObject *getRegExpPrototype() const {
|
||||
return prototype_;
|
||||
}
|
||||
CloneBehavior shouldClone() const {
|
||||
return shouldClone_;
|
||||
}
|
||||
@ -5154,22 +5160,22 @@ class MNewCallObject : public MUnaryInstruction
|
||||
// ones)
|
||||
class MProfilingEnter : public MNullaryInstruction
|
||||
{
|
||||
JSScript *script_;
|
||||
const char *string_;
|
||||
|
||||
MProfilingEnter(JSScript *script) : script_(script) {
|
||||
JS_ASSERT(script != NULL);
|
||||
MProfilingEnter(const char *string) : string_(string) {
|
||||
JS_ASSERT(string != NULL);
|
||||
setGuard();
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(ProfilingEnter);
|
||||
|
||||
static MProfilingEnter *New(JSScript *script) {
|
||||
return new MProfilingEnter(script);
|
||||
static MProfilingEnter *New(const char *string) {
|
||||
return new MProfilingEnter(string);
|
||||
}
|
||||
|
||||
JSScript *script() {
|
||||
return script_;
|
||||
const char *profileString() {
|
||||
return string_;
|
||||
}
|
||||
|
||||
AliasSet getAliasSet() const {
|
||||
|
@ -28,22 +28,22 @@ class MStart;
|
||||
class MIRGenerator
|
||||
{
|
||||
public:
|
||||
MIRGenerator(JSContext *cx, TempAllocator &temp, MIRGraph &graph, CompileInfo &info);
|
||||
MIRGenerator(JSCompartment *compartment, TempAllocator *temp, MIRGraph *graph, CompileInfo *info);
|
||||
|
||||
TempAllocator &temp() {
|
||||
return temp_;
|
||||
return *temp_;
|
||||
}
|
||||
MIRGraph &graph() {
|
||||
return graph_;
|
||||
return *graph_;
|
||||
}
|
||||
bool ensureBallast() {
|
||||
return temp().ensureBallast();
|
||||
}
|
||||
IonCompartment *ionCompartment() const {
|
||||
return cx->compartment->ionCompartment();
|
||||
return compartment->ionCompartment();
|
||||
}
|
||||
CompileInfo &info() {
|
||||
return info_;
|
||||
return *info_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -61,14 +61,14 @@ class MIRGenerator
|
||||
}
|
||||
|
||||
public:
|
||||
JSContext *cx;
|
||||
JSCompartment *compartment;
|
||||
|
||||
protected:
|
||||
CompileInfo &info_;
|
||||
TempAllocator &temp_;
|
||||
CompileInfo *info_;
|
||||
TempAllocator *temp_;
|
||||
JSFunction *fun_;
|
||||
uint32 nslots_;
|
||||
MIRGraph &graph_;
|
||||
MIRGraph *graph_;
|
||||
bool error_;
|
||||
};
|
||||
|
||||
|
@ -16,8 +16,9 @@
|
||||
using namespace js;
|
||||
using namespace js::ion;
|
||||
|
||||
MIRGenerator::MIRGenerator(JSContext *cx, TempAllocator &temp, MIRGraph &graph, CompileInfo &info)
|
||||
: cx(cx),
|
||||
MIRGenerator::MIRGenerator(JSCompartment *compartment,
|
||||
TempAllocator *temp, MIRGraph *graph, CompileInfo *info)
|
||||
: compartment(compartment),
|
||||
info_(info),
|
||||
temp_(temp),
|
||||
graph_(graph),
|
||||
|
@ -454,7 +454,7 @@ typedef Vector<MBasicBlock *, 1, IonAllocPolicy> MIRGraphExits;
|
||||
class MIRGraph
|
||||
{
|
||||
InlineList<MBasicBlock> blocks_;
|
||||
TempAllocator &alloc_;
|
||||
TempAllocator *alloc_;
|
||||
MIRGraphExits *exitAccumulator_;
|
||||
uint32 blockIdGen_;
|
||||
uint32 idGen_;
|
||||
@ -465,7 +465,7 @@ class MIRGraph
|
||||
#endif
|
||||
|
||||
public:
|
||||
MIRGraph(TempAllocator &alloc)
|
||||
MIRGraph(TempAllocator *alloc)
|
||||
: alloc_(alloc),
|
||||
exitAccumulator_(NULL),
|
||||
blockIdGen_(0),
|
||||
@ -479,7 +479,7 @@ class MIRGraph
|
||||
|
||||
template <typename T>
|
||||
T * allocate(size_t count = 1) {
|
||||
return reinterpret_cast<T *>(alloc_.allocate(sizeof(T) * count));
|
||||
return reinterpret_cast<T *>(alloc_->allocate(sizeof(T) * count));
|
||||
}
|
||||
|
||||
void addBlock(MBasicBlock *block);
|
||||
|
@ -250,28 +250,20 @@ NewInitArray(JSContext *cx, uint32_t count, types::TypeObject *type)
|
||||
}
|
||||
|
||||
JSObject*
|
||||
NewInitObject(JSContext *cx, HandleObject baseObj, types::TypeObject *type)
|
||||
NewInitObject(JSContext *cx, HandleObject templateObject)
|
||||
{
|
||||
RootedObject obj(cx);
|
||||
if (baseObj) {
|
||||
// JSOP_NEWOBJECT
|
||||
obj = CopyInitializerObject(cx, baseObj);
|
||||
} else {
|
||||
// JSOP_NEWINIT
|
||||
gc::AllocKind kind = GuessObjectGCKind(0);
|
||||
obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
|
||||
}
|
||||
RootedObject obj(cx, CopyInitializerObject(cx, templateObject));
|
||||
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
if (!type) {
|
||||
if (templateObject->hasSingletonType()) {
|
||||
if (!obj->setSingletonType(cx))
|
||||
return NULL;
|
||||
|
||||
types::TypeScript::Monitor(cx, ObjectValue(*obj));
|
||||
} else {
|
||||
obj->setType(type);
|
||||
obj->setType(templateObject->type());
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
@ -424,7 +424,7 @@ bool IteratorMore(JSContext *cx, HandleObject obj, JSBool *res);
|
||||
|
||||
// Allocation functions for JSOP_NEWARRAY and JSOP_NEWOBJECT
|
||||
JSObject *NewInitArray(JSContext *cx, uint32_t count, types::TypeObject *type);
|
||||
JSObject *NewInitObject(JSContext *cx, HandleObject baseObj, types::TypeObject *type);
|
||||
JSObject *NewInitObject(JSContext *cx, HandleObject templateObject);
|
||||
|
||||
bool ArrayPopDense(JSContext *cx, JSObject *obj, Value *rval);
|
||||
bool ArrayPushDense(JSContext *cx, JSObject *obj, const Value &v, uint32_t *length);
|
||||
|
@ -176,8 +176,9 @@ CodeGeneratorARM::generateOutOfLineCode()
|
||||
// Push the frame size, so the handler can recover the IonScript.
|
||||
masm.ma_mov(Imm32(frameSize()), lr);
|
||||
|
||||
IonCompartment *ion = gen->cx->compartment->ionCompartment();
|
||||
IonCode *handler = ion->getGenericBailoutHandler(gen->cx);
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
IonCompartment *ion = cx->compartment->ionCompartment();
|
||||
IonCode *handler = ion->getGenericBailoutHandler(cx);
|
||||
if (!handler)
|
||||
return false;
|
||||
masm.branch(handler);
|
||||
@ -1409,7 +1410,7 @@ CodeGeneratorARM::visitInterruptCheck(LInterruptCheck *lir)
|
||||
if (!ool)
|
||||
return false;
|
||||
|
||||
void *interrupt = (void*)&gen->cx->runtime->interrupt;
|
||||
void *interrupt = (void*)&gen->compartment->rt->interrupt;
|
||||
masm.load32(AbsoluteAddress(interrupt), lr);
|
||||
masm.ma_cmp(lr, Imm32(0));
|
||||
masm.ma_b(ool->entry(), Assembler::NonZero);
|
||||
@ -1430,9 +1431,12 @@ CodeGeneratorARM::generateInvalidateEpilogue()
|
||||
|
||||
// Push the return address of the point that we bailed out at onto the stack
|
||||
masm.Push(lr);
|
||||
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
|
||||
// Push the Ion script onto the stack (when we determine what that pointer is).
|
||||
invalidateEpilogueData_ = masm.pushWithPatch(ImmWord(uintptr_t(-1)));
|
||||
IonCode *thunk = gen->cx->compartment->ionCompartment()->getOrCreateInvalidationThunk(gen->cx);
|
||||
IonCode *thunk = cx->compartment->ionCompartment()->getOrCreateInvalidationThunk(cx);
|
||||
if (!thunk)
|
||||
return false;
|
||||
|
||||
|
@ -201,7 +201,7 @@ CodeGeneratorShared::encode(LSnapshot *snapshot)
|
||||
DebugOnly<jsbytecode *> bailPC = pc;
|
||||
if (mir->mode() == MResumePoint::ResumeAfter)
|
||||
bailPC = GetNextPc(pc);
|
||||
JS_ASSERT(exprStack == js_ReconstructStackDepth(gen->cx, script, bailPC));
|
||||
JS_ASSERT(exprStack == js_ReconstructStackDepth(GetIonContext()->cx, script, bailPC));
|
||||
|
||||
#ifdef TRACK_SNAPSHOTS
|
||||
LInstruction *ins = instruction();
|
||||
@ -360,8 +360,9 @@ CodeGeneratorShared::callVM(const VMFunction &fun, LInstruction *ins, const Regi
|
||||
#endif
|
||||
|
||||
// Generate the wrapper of the VM function.
|
||||
IonCompartment *ion = gen->cx->compartment->ionCompartment();
|
||||
IonCode *wrapper = ion->generateVMWrapper(gen->cx, fun);
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
IonCompartment *ion = cx->compartment->ionCompartment();
|
||||
IonCode *wrapper = ion->generateVMWrapper(cx, fun);
|
||||
if (!wrapper)
|
||||
return false;
|
||||
|
||||
|
@ -293,8 +293,9 @@ CodeGeneratorX86Shared::generateOutOfLineCode()
|
||||
// Push the frame size, so the handler can recover the IonScript.
|
||||
masm.push(Imm32(frameSize()));
|
||||
|
||||
IonCompartment *ion = gen->cx->compartment->ionCompartment();
|
||||
IonCode *handler = ion->getGenericBailoutHandler(gen->cx);
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
IonCompartment *ion = cx->compartment->ionCompartment();
|
||||
IonCode *handler = ion->getGenericBailoutHandler(cx);
|
||||
if (!handler)
|
||||
return false;
|
||||
|
||||
@ -1248,9 +1249,11 @@ CodeGeneratorX86Shared::generateInvalidateEpilogue()
|
||||
|
||||
masm.bind(&invalidate_);
|
||||
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
|
||||
// Push the Ion script onto the stack (when we determine what that pointer is).
|
||||
invalidateEpilogueData_ = masm.pushWithPatch(ImmWord(uintptr_t(-1)));
|
||||
IonCode *thunk = gen->cx->compartment->ionCompartment()->getOrCreateInvalidationThunk(gen->cx);
|
||||
IonCode *thunk = cx->compartment->ionCompartment()->getOrCreateInvalidationThunk(cx);
|
||||
if (!thunk)
|
||||
return false;
|
||||
|
||||
|
@ -304,7 +304,7 @@ CodeGeneratorX64::visitInterruptCheck(LInterruptCheck *lir)
|
||||
if (!ool)
|
||||
return false;
|
||||
|
||||
void *interrupt = (void*)&gen->cx->runtime->interrupt;
|
||||
void *interrupt = (void*)&gen->compartment->rt->interrupt;
|
||||
masm.movq(ImmWord(interrupt), ScratchReg);
|
||||
masm.cmpl(Operand(ScratchReg, 0), Imm32(0));
|
||||
masm.j(Assembler::NonZero, ool->entry());
|
||||
|
@ -298,7 +298,7 @@ CodeGeneratorX86::visitInterruptCheck(LInterruptCheck *lir)
|
||||
if (!ool)
|
||||
return false;
|
||||
|
||||
void *interrupt = (void*)&gen->cx->runtime->interrupt;
|
||||
void *interrupt = (void*)&gen->compartment->rt->interrupt;
|
||||
masm.cmpl(Operand(interrupt), Imm32(0));
|
||||
masm.j(Assembler::NonZero, ool->entry());
|
||||
masm.bind(ool->rejoin());
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include "ion/IonFrames.h"
|
||||
#include "ion/MoveResolver.h"
|
||||
|
||||
#include "jscompartment.h"
|
||||
|
||||
namespace js {
|
||||
namespace ion {
|
||||
|
||||
@ -707,8 +709,8 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
// Save an exit frame (which must be aligned to the stack pointer) to
|
||||
// ThreadData::ionTop.
|
||||
void linkExitFrame() {
|
||||
JSContext *cx = GetIonContext()->cx;
|
||||
movl(StackPointer, Operand(&cx->runtime->ionTop));
|
||||
JSCompartment *compartment = GetIonContext()->compartment;
|
||||
movl(StackPointer, Operand(&compartment->rt->ionTop));
|
||||
}
|
||||
|
||||
void callWithExitFrame(IonCode *target, Register dynStack) {
|
||||
|
@ -26,6 +26,7 @@ namespace ion {
|
||||
}
|
||||
|
||||
# define ION_DISABLED_SCRIPT ((js::ion::IonScript *)0x1)
|
||||
# define ION_COMPILING_SCRIPT ((js::ion::IonScript *)0x2)
|
||||
|
||||
struct Shape;
|
||||
|
||||
|
@ -1029,7 +1029,7 @@ mjit::EnterMethodJIT(JSContext *cx, StackFrame *fp, void *code, Value *stackLimi
|
||||
JSBool ok;
|
||||
{
|
||||
AssertCompartmentUnchanged pcc(cx);
|
||||
ion::IonContext ictx(cx, NULL);
|
||||
ion::IonContext ictx(cx, cx->compartment, NULL);
|
||||
ion::IonActivation activation(cx, NULL);
|
||||
JSAutoResolveFlags rf(cx, RESOLVE_INFER);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user