mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 989348 - BaselineCompiler: Optimize JSOP_ARRAYPUSH. r=djvj
This commit is contained in:
parent
22af9b2a16
commit
49b3d9bb1a
@ -1790,22 +1790,34 @@ BaselineCompiler::emit_JSOP_ENDINIT()
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef bool (*NewbornArrayPushFn)(JSContext *, HandleObject, const Value &);
|
||||
static const VMFunction NewbornArrayPushInfo = FunctionInfo<NewbornArrayPushFn>(NewbornArrayPush);
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_ARRAYPUSH()
|
||||
{
|
||||
// Keep value in R0, object in R1.
|
||||
frame.popRegsAndSync(2);
|
||||
#ifdef DEBUG
|
||||
{
|
||||
Label fail;
|
||||
Label ok;
|
||||
// Stub register is unused in mainline code, so we can use it as
|
||||
// scratch
|
||||
Register scratchReg = BaselineStubReg;
|
||||
masm.branchTestObject(Assembler::NotEqual, R1, &fail);
|
||||
Register objReg = masm.extractObject(R1, ExtractTemp0);
|
||||
masm.branchTestObjClass(Assembler::Equal, objReg, scratchReg, &ArrayObject::class_, &ok);
|
||||
|
||||
masm.bind(&fail);
|
||||
masm.assumeUnreachable("JSOP_ARRAYPUSH operand 1 is not an array.");
|
||||
|
||||
masm.bind(&ok);
|
||||
}
|
||||
#endif
|
||||
// R1 is guaranteed to be a boxed Array object
|
||||
masm.unboxObject(R1, R1.scratchReg());
|
||||
|
||||
prepareVMCall();
|
||||
|
||||
pushArg(R0);
|
||||
pushArg(R1.scratchReg());
|
||||
|
||||
return callVM(NewbornArrayPushInfo);
|
||||
// Call IC.
|
||||
ICArrayPush_Fallback::Compiler stubCompiler(cx);
|
||||
return emitOpIC(stubCompiler.getStub(&stubSpace_));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -9655,6 +9655,102 @@ ICTableSwitch::fixupJumpTable(JSScript *script, BaselineScript *baseline)
|
||||
table_[i] = baseline->nativeCodeForPC(script, (jsbytecode *) table_[i]);
|
||||
}
|
||||
|
||||
//
|
||||
// ArrayPush_Fallback
|
||||
//
|
||||
static bool
|
||||
DoArrayPushFallback(JSContext *cx, BaselineFrame *frame, ICArrayPush_Fallback *stub_,
|
||||
HandleObject obj, HandleValue v)
|
||||
{
|
||||
// This fallback stub may trigger debug mode toggling.
|
||||
DebugModeOSRVolatileStub<ICArrayPush_Fallback *> stub(frame, stub_);
|
||||
|
||||
FallbackICSpew(cx, stub, "ArrayPush");
|
||||
|
||||
if (!NewbornArrayPush(cx, obj, v))
|
||||
return false;
|
||||
|
||||
// Check if debug mode toggling made the stub invalid.
|
||||
if (stub.invalid())
|
||||
return true;
|
||||
|
||||
if (!stub->hasStub(ICStub::ArrayPush_Native))
|
||||
{
|
||||
ICArrayPush_Native::Compiler compiler(cx);
|
||||
ICStub *newStub = compiler.getStub(compiler.getStubSpace(frame->script()));
|
||||
if (!newStub)
|
||||
return false;
|
||||
stub->addNewStub(newStub);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef bool (*DoArrayPushFallbackFn)(JSContext *, BaselineFrame *, ICArrayPush_Fallback *,
|
||||
HandleObject, HandleValue);
|
||||
static const VMFunction DoArrayPushFallbackInfo = FunctionInfo<DoArrayPushFallbackFn>(DoArrayPushFallback);
|
||||
|
||||
bool
|
||||
ICArrayPush_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
// Restore the tail call register.
|
||||
EmitRestoreTailCallReg(masm);
|
||||
|
||||
// Push arguments.
|
||||
masm.pushValue(R0);
|
||||
masm.push(R1.scratchReg());
|
||||
masm.push(BaselineStubReg);
|
||||
masm.pushBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
|
||||
|
||||
return tailCallVM(DoArrayPushFallbackInfo, masm);
|
||||
}
|
||||
|
||||
//
|
||||
// ArrayPush_Native
|
||||
//
|
||||
|
||||
bool
|
||||
ICArrayPush_Native::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
|
||||
Register obj = R1.scratchReg();
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
regs.take(obj);
|
||||
Register elementsTemp = regs.takeAny();
|
||||
Register length = regs.takeAny();
|
||||
|
||||
masm.loadPtr(Address(obj, JSObject::offsetOfElements()), elementsTemp);
|
||||
masm.load32(Address(elementsTemp, ObjectElements::offsetOfLength()), length);
|
||||
#ifdef DEBUG
|
||||
{
|
||||
Label ok;
|
||||
masm.branch32(Assembler::Equal,
|
||||
Address(elementsTemp,
|
||||
ObjectElements::offsetOfInitializedLength()),
|
||||
length,
|
||||
&ok);
|
||||
masm.assumeUnreachable("ArrayPush array length != initializedLength");
|
||||
masm.bind(&ok);
|
||||
}
|
||||
#endif
|
||||
masm.branch32(Assembler::BelowOrEqual,
|
||||
Address(elementsTemp, ObjectElements::offsetOfCapacity()),
|
||||
length, &failure);
|
||||
Int32Key key = Int32Key(length);
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(Value) == 8);
|
||||
masm.storeValue(R0, BaseIndex(elementsTemp, length, TimesEight));
|
||||
masm.bumpKey(&key, 1);
|
||||
masm.store32(length, Address(elementsTemp, ObjectElements::offsetOfLength()));
|
||||
masm.store32(length, Address(elementsTemp, ObjectElements::offsetOfInitializedLength()));
|
||||
EmitReturnFromIC(masm);
|
||||
|
||||
masm.bind(&failure);
|
||||
EmitStubGuardFailure(masm);
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// IteratorNew_Fallback
|
||||
//
|
||||
|
@ -377,6 +377,9 @@ class ICEntry
|
||||
_(Call_ScriptedApplyArguments) \
|
||||
_(Call_ScriptedFunCall) \
|
||||
\
|
||||
_(ArrayPush_Fallback) \
|
||||
_(ArrayPush_Native) \
|
||||
\
|
||||
_(GetElem_Fallback) \
|
||||
_(GetElem_NativeSlot) \
|
||||
_(GetElem_NativePrototypeSlot) \
|
||||
@ -2899,6 +2902,69 @@ class ICUnaryArith_Double : public ICStub
|
||||
};
|
||||
};
|
||||
|
||||
// ArrayPush
|
||||
// JSOP_ARRAYPUSH
|
||||
|
||||
class ICArrayPush_Fallback : public ICFallbackStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
explicit ICArrayPush_Fallback(JitCode *stubCode)
|
||||
: ICFallbackStub(ArrayPush_Fallback, stubCode)
|
||||
{}
|
||||
|
||||
public:
|
||||
static inline ICArrayPush_Fallback *New(ICStubSpace *space, JitCode *code) {
|
||||
if (!code)
|
||||
return nullptr;
|
||||
return space->allocate<ICArrayPush_Fallback>(code);
|
||||
}
|
||||
|
||||
class Compiler : public ICStubCompiler {
|
||||
protected:
|
||||
bool generateStubCode(MacroAssembler &masm);
|
||||
|
||||
public:
|
||||
Compiler(JSContext *cx)
|
||||
: ICStubCompiler(cx, ICStub::ArrayPush_Fallback)
|
||||
{}
|
||||
|
||||
ICStub *getStub(ICStubSpace *space) {
|
||||
return ICArrayPush_Fallback::New(space, getStubCode());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class ICArrayPush_Native : public ICStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
explicit ICArrayPush_Native(JitCode *stubCode)
|
||||
: ICStub(ArrayPush_Native, stubCode)
|
||||
{}
|
||||
|
||||
public:
|
||||
static inline ICArrayPush_Native *New(ICStubSpace *space, JitCode *code) {
|
||||
if (!code)
|
||||
return nullptr;
|
||||
return space->allocate<ICArrayPush_Native>(code);
|
||||
}
|
||||
|
||||
class Compiler : public ICStubCompiler {
|
||||
protected:
|
||||
bool generateStubCode(MacroAssembler &masm);
|
||||
|
||||
public:
|
||||
Compiler(JSContext *cx)
|
||||
: ICStubCompiler(cx, ICStub::ArrayPush_Native)
|
||||
{}
|
||||
|
||||
ICStub *getStub(ICStubSpace *space) {
|
||||
return ICArrayPush_Native::New(space, getStubCode());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// GetElem
|
||||
// JSOP_GETELEM
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user