mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge backout.
This commit is contained in:
commit
0dfec96f2e
@ -97,8 +97,7 @@ mjit::Compiler::Compiler(JSContext *cx, JSStackFrame *fp)
|
||||
frame(cx, script, fun, masm),
|
||||
branchPatches(CompilerAllocPolicy(cx, *thisFromCtor())),
|
||||
#if defined JS_MONOIC
|
||||
getGlobalNames(CompilerAllocPolicy(cx, *thisFromCtor())),
|
||||
setGlobalNames(CompilerAllocPolicy(cx, *thisFromCtor())),
|
||||
mics(CompilerAllocPolicy(cx, *thisFromCtor())),
|
||||
callICs(CompilerAllocPolicy(cx, *thisFromCtor())),
|
||||
equalityICs(CompilerAllocPolicy(cx, *thisFromCtor())),
|
||||
traceICs(CompilerAllocPolicy(cx, *thisFromCtor())),
|
||||
@ -438,8 +437,7 @@ mjit::Compiler::finishThisUp(JITScript **jitp)
|
||||
size_t totalBytes = sizeof(JITScript) +
|
||||
sizeof(NativeMapEntry) * nNmapLive +
|
||||
#if defined JS_MONOIC
|
||||
sizeof(ic::GetGlobalNameIC) * getGlobalNames.length() +
|
||||
sizeof(ic::SetGlobalNameIC) * setGlobalNames.length() +
|
||||
sizeof(ic::MICInfo) * mics.length() +
|
||||
sizeof(ic::CallICInfo) * callICs.length() +
|
||||
sizeof(ic::EqualityICInfo) * equalityICs.length() +
|
||||
sizeof(ic::TraceICInfo) * traceICs.length() +
|
||||
@ -491,62 +489,46 @@ mjit::Compiler::finishThisUp(JITScript **jitp)
|
||||
}
|
||||
|
||||
#if defined JS_MONOIC
|
||||
jit->nGetGlobalNames = getGlobalNames.length();
|
||||
if (getGlobalNames.length()) {
|
||||
jit->getGlobalNames = (ic::GetGlobalNameIC *)cursor;
|
||||
cursor += sizeof(ic::GetGlobalNameIC) * getGlobalNames.length();
|
||||
jit->nMICs = mics.length();
|
||||
if (mics.length()) {
|
||||
jit->mics = (ic::MICInfo *)cursor;
|
||||
cursor += sizeof(ic::MICInfo) * mics.length();
|
||||
} else {
|
||||
jit->getGlobalNames = NULL;
|
||||
jit->mics = NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < getGlobalNames.length(); i++) {
|
||||
ic::GetGlobalNameIC &to = jit->getGlobalNames[i];
|
||||
GetGlobalNameICInfo &from = getGlobalNames[i];
|
||||
from.copyTo(to, fullCode, stubCode);
|
||||
if (ic::MICInfo *scriptMICs = jit->mics) {
|
||||
for (size_t i = 0; i < mics.length(); i++) {
|
||||
scriptMICs[i].kind = mics[i].kind;
|
||||
scriptMICs[i].fastPathStart = fullCode.locationOf(mics[i].fastPathStart);
|
||||
scriptMICs[i].slowPathStart = stubCode.locationOf(mics[i].slowPathStart);
|
||||
if (mics[i].kind == ic::MICInfo::GET)
|
||||
scriptMICs[i].load = fullCode.locationOf(mics[i].load);
|
||||
else
|
||||
scriptMICs[i].load = fullCode.locationOf(mics[i].store).labelAtOffset(0);
|
||||
scriptMICs[i].shape = fullCode.locationOf(mics[i].shape);
|
||||
scriptMICs[i].stubCall = stubCode.locationOf(mics[i].call);
|
||||
scriptMICs[i].usePropertyCache = mics[i].usePropertyCache;
|
||||
scriptMICs[i].extraShapeGuard = 0;
|
||||
scriptMICs[i].objConst = mics[i].objConst;
|
||||
scriptMICs[i].shapeReg = mics[i].shapeReg;
|
||||
scriptMICs[i].objReg = mics[i].objReg;
|
||||
scriptMICs[i].vr = mics[i].vr;
|
||||
|
||||
int offset = fullCode.locationOf(from.load) - to.fastPathStart;
|
||||
to.loadStoreOffset = offset;
|
||||
JS_ASSERT(to.loadStoreOffset == offset);
|
||||
if (mics[i].kind == ic::MICInfo::SET) {
|
||||
int offset = fullCode.locationOf(mics[i].shapeGuardJump) -
|
||||
scriptMICs[i].fastPathStart;
|
||||
scriptMICs[i].inlineShapeJump = offset;
|
||||
JS_ASSERT(scriptMICs[i].inlineShapeJump == offset);
|
||||
|
||||
stubCode.patch(from.addrLabel, &to);
|
||||
}
|
||||
offset = fullCode.locationOf(mics[i].fastPathRejoin) -
|
||||
scriptMICs[i].fastPathStart;
|
||||
scriptMICs[i].fastRejoinOffset = offset;
|
||||
JS_ASSERT(scriptMICs[i].fastRejoinOffset == offset);
|
||||
}
|
||||
|
||||
jit->nSetGlobalNames = setGlobalNames.length();
|
||||
if (setGlobalNames.length()) {
|
||||
jit->setGlobalNames = (ic::SetGlobalNameIC *)cursor;
|
||||
cursor += sizeof(ic::SetGlobalNameIC) * setGlobalNames.length();
|
||||
} else {
|
||||
jit->setGlobalNames = NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < setGlobalNames.length(); i++) {
|
||||
ic::SetGlobalNameIC &to = jit->setGlobalNames[i];
|
||||
SetGlobalNameICInfo &from = setGlobalNames[i];
|
||||
from.copyTo(to, fullCode, stubCode);
|
||||
to.slowPathStart = stubCode.locationOf(from.slowPathStart);
|
||||
|
||||
int offset = fullCode.locationOf(from.store).labelAtOffset(0) -
|
||||
to.fastPathStart;
|
||||
to.loadStoreOffset = offset;
|
||||
JS_ASSERT(to.loadStoreOffset == offset);
|
||||
|
||||
to.extraShapeGuard = 0;
|
||||
to.objConst = from.objConst;
|
||||
to.shapeReg = from.shapeReg;
|
||||
to.objReg = from.objReg;
|
||||
to.vr = from.vr;
|
||||
|
||||
offset = fullCode.locationOf(from.shapeGuardJump) -
|
||||
to.fastPathStart;
|
||||
to.inlineShapeJump = offset;
|
||||
JS_ASSERT(to.inlineShapeJump == offset);
|
||||
|
||||
offset = fullCode.locationOf(from.fastPathRejoin) -
|
||||
to.fastPathStart;
|
||||
to.fastRejoinOffset = offset;
|
||||
JS_ASSERT(to.fastRejoinOffset == offset);
|
||||
|
||||
stubCode.patch(from.addrLabel, &to);
|
||||
stubCode.patch(mics[i].addrLabel, &scriptMICs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
jit->nCallICs = callICs.length();
|
||||
@ -2994,9 +2976,9 @@ mjit::Compiler::jsop_length()
|
||||
|
||||
#ifdef JS_MONOIC
|
||||
void
|
||||
mjit::Compiler::passMICAddress(GlobalNameICInfo &ic)
|
||||
mjit::Compiler::passMICAddress(MICGenInfo &mic)
|
||||
{
|
||||
ic.addrLabel = stubcc.masm.moveWithPatch(ImmPtr(NULL), Registers::ArgReg1);
|
||||
mic.addrLabel = stubcc.masm.moveWithPatch(ImmPtr(NULL), Registers::ArgReg1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4330,14 +4312,12 @@ mjit::Compiler::jsop_getgname(uint32 index)
|
||||
FrameEntry *fe = frame.peek(-1);
|
||||
JS_ASSERT(fe->isTypeKnown() && fe->getKnownType() == JSVAL_TYPE_OBJECT);
|
||||
|
||||
GetGlobalNameICInfo ic;
|
||||
MICGenInfo mic(ic::MICInfo::GET);
|
||||
RESERVE_IC_SPACE(masm);
|
||||
RegisterID objReg;
|
||||
Jump shapeGuard;
|
||||
|
||||
ic.usePropertyCache = true;
|
||||
|
||||
ic.fastPathStart = masm.label();
|
||||
mic.fastPathStart = masm.label();
|
||||
if (fe->isConstant()) {
|
||||
JSObject *obj = &fe->getValue().toObject();
|
||||
frame.pop();
|
||||
@ -4347,7 +4327,7 @@ mjit::Compiler::jsop_getgname(uint32 index)
|
||||
|
||||
masm.load32FromImm(&obj->objShape, objReg);
|
||||
shapeGuard = masm.branch32WithPatch(Assembler::NotEqual, objReg,
|
||||
Imm32(int32(JSObjectMap::INVALID_SHAPE)), ic.shape);
|
||||
Imm32(int32(JSObjectMap::INVALID_SHAPE)), mic.shape);
|
||||
masm.move(ImmPtr(obj), objReg);
|
||||
} else {
|
||||
objReg = frame.ownRegForData(fe);
|
||||
@ -4356,14 +4336,14 @@ mjit::Compiler::jsop_getgname(uint32 index)
|
||||
|
||||
masm.loadShape(objReg, reg);
|
||||
shapeGuard = masm.branch32WithPatch(Assembler::NotEqual, reg,
|
||||
Imm32(int32(JSObjectMap::INVALID_SHAPE)), ic.shape);
|
||||
Imm32(int32(JSObjectMap::INVALID_SHAPE)), mic.shape);
|
||||
frame.freeReg(reg);
|
||||
}
|
||||
stubcc.linkExit(shapeGuard, Uses(0));
|
||||
mic.slowPathStart = stubcc.linkExit(shapeGuard, Uses(0));
|
||||
|
||||
stubcc.leave();
|
||||
passMICAddress(ic);
|
||||
ic.slowPathCall = OOL_STUBCALL(ic::GetGlobalName);
|
||||
passMICAddress(mic);
|
||||
mic.call = OOL_STUBCALL(ic::GetGlobalName);
|
||||
|
||||
/* Garbage value. */
|
||||
uint32 slot = 1 << 24;
|
||||
@ -4376,13 +4356,14 @@ mjit::Compiler::jsop_getgname(uint32 index)
|
||||
/* After dreg is loaded, it's safe to clobber objReg. */
|
||||
RegisterID dreg = objReg;
|
||||
|
||||
ic.load = masm.loadValueWithAddressOffsetPatch(address, treg, dreg);
|
||||
mic.load = masm.loadValueWithAddressOffsetPatch(address, treg, dreg);
|
||||
|
||||
frame.pushRegs(treg, dreg);
|
||||
|
||||
stubcc.rejoin(Changes(1));
|
||||
|
||||
getGlobalNames.append(ic);
|
||||
mic.fastPathRejoin = masm.label();
|
||||
mics.append(mic);
|
||||
|
||||
#else
|
||||
jsop_getgname_slow(index);
|
||||
@ -4410,69 +4391,69 @@ mjit::Compiler::jsop_setgname(JSAtom *atom, bool usePropertyCache)
|
||||
FrameEntry *fe = frame.peek(-1);
|
||||
JS_ASSERT_IF(objFe->isTypeKnown(), objFe->getKnownType() == JSVAL_TYPE_OBJECT);
|
||||
|
||||
SetGlobalNameICInfo ic;
|
||||
|
||||
frame.pinEntry(fe, ic.vr);
|
||||
Jump shapeGuard;
|
||||
MICGenInfo mic(ic::MICInfo::SET);
|
||||
frame.pinEntry(fe, mic.vr);
|
||||
|
||||
RESERVE_IC_SPACE(masm);
|
||||
ic.fastPathStart = masm.label();
|
||||
Jump shapeGuard;
|
||||
|
||||
mic.fastPathStart = masm.label();
|
||||
if (objFe->isConstant()) {
|
||||
JSObject *obj = &objFe->getValue().toObject();
|
||||
JS_ASSERT(obj->isNative());
|
||||
|
||||
ic.objReg = frame.allocReg();
|
||||
ic.shapeReg = ic.objReg;
|
||||
ic.objConst = true;
|
||||
mic.objReg = frame.allocReg();
|
||||
mic.shapeReg = mic.objReg;
|
||||
mic.objConst = true;
|
||||
|
||||
masm.load32FromImm(&obj->objShape, ic.shapeReg);
|
||||
shapeGuard = masm.branch32WithPatch(Assembler::NotEqual, ic.shapeReg,
|
||||
masm.load32FromImm(&obj->objShape, mic.shapeReg);
|
||||
shapeGuard = masm.branch32WithPatch(Assembler::NotEqual, mic.shapeReg,
|
||||
Imm32(int32(JSObjectMap::INVALID_SHAPE)),
|
||||
ic.shape);
|
||||
masm.move(ImmPtr(obj), ic.objReg);
|
||||
mic.shape);
|
||||
masm.move(ImmPtr(obj), mic.objReg);
|
||||
} else {
|
||||
ic.objReg = frame.copyDataIntoReg(objFe);
|
||||
ic.shapeReg = frame.allocReg();
|
||||
ic.objConst = false;
|
||||
mic.objReg = frame.copyDataIntoReg(objFe);
|
||||
mic.shapeReg = frame.allocReg();
|
||||
mic.objConst = false;
|
||||
|
||||
masm.loadShape(ic.objReg, ic.shapeReg);
|
||||
shapeGuard = masm.branch32WithPatch(Assembler::NotEqual, ic.shapeReg,
|
||||
masm.loadShape(mic.objReg, mic.shapeReg);
|
||||
shapeGuard = masm.branch32WithPatch(Assembler::NotEqual, mic.shapeReg,
|
||||
Imm32(int32(JSObjectMap::INVALID_SHAPE)),
|
||||
ic.shape);
|
||||
frame.freeReg(ic.shapeReg);
|
||||
mic.shape);
|
||||
frame.freeReg(mic.shapeReg);
|
||||
}
|
||||
ic.shapeGuardJump = shapeGuard;
|
||||
ic.slowPathStart = stubcc.linkExit(shapeGuard, Uses(2));
|
||||
mic.shapeGuardJump = shapeGuard;
|
||||
mic.slowPathStart = stubcc.linkExit(shapeGuard, Uses(2));
|
||||
|
||||
stubcc.leave();
|
||||
passMICAddress(ic);
|
||||
ic.slowPathCall = OOL_STUBCALL(ic::SetGlobalName);
|
||||
passMICAddress(mic);
|
||||
mic.call = OOL_STUBCALL(ic::SetGlobalName);
|
||||
|
||||
/* Garbage value. */
|
||||
uint32 slot = 1 << 24;
|
||||
|
||||
ic.usePropertyCache = usePropertyCache;
|
||||
mic.usePropertyCache = usePropertyCache;
|
||||
|
||||
masm.loadPtr(Address(ic.objReg, offsetof(JSObject, slots)), ic.objReg);
|
||||
Address address(ic.objReg, slot);
|
||||
masm.loadPtr(Address(mic.objReg, offsetof(JSObject, slots)), mic.objReg);
|
||||
Address address(mic.objReg, slot);
|
||||
|
||||
if (ic.vr.isConstant()) {
|
||||
ic.store = masm.storeValueWithAddressOffsetPatch(ic.vr.value(), address);
|
||||
} else if (ic.vr.isTypeKnown()) {
|
||||
ic.store = masm.storeValueWithAddressOffsetPatch(ImmType(ic.vr.knownType()),
|
||||
ic.vr.dataReg(), address);
|
||||
if (mic.vr.isConstant()) {
|
||||
mic.store = masm.storeValueWithAddressOffsetPatch(mic.vr.value(), address);
|
||||
} else if (mic.vr.isTypeKnown()) {
|
||||
mic.store = masm.storeValueWithAddressOffsetPatch(ImmType(mic.vr.knownType()),
|
||||
mic.vr.dataReg(), address);
|
||||
} else {
|
||||
ic.store = masm.storeValueWithAddressOffsetPatch(ic.vr.typeReg(), ic.vr.dataReg(), address);
|
||||
mic.store = masm.storeValueWithAddressOffsetPatch(mic.vr.typeReg(), mic.vr.dataReg(), address);
|
||||
}
|
||||
|
||||
frame.freeReg(ic.objReg);
|
||||
frame.unpinEntry(ic.vr);
|
||||
frame.freeReg(mic.objReg);
|
||||
frame.unpinEntry(mic.vr);
|
||||
frame.shimmy(1);
|
||||
|
||||
stubcc.rejoin(Changes(1));
|
||||
|
||||
ic.fastPathRejoin = masm.label();
|
||||
setGlobalNames.append(ic);
|
||||
mic.fastPathRejoin = masm.label();
|
||||
mics.append(mic);
|
||||
#else
|
||||
jsop_setgname_slow(atom, usePropertyCache);
|
||||
#endif
|
||||
|
@ -67,38 +67,24 @@ class Compiler : public BaseCompiler
|
||||
};
|
||||
|
||||
#if defined JS_MONOIC
|
||||
struct GlobalNameICInfo {
|
||||
struct MICGenInfo {
|
||||
MICGenInfo(ic::MICInfo::Kind kind) : kind(kind)
|
||||
{ }
|
||||
Label fastPathStart;
|
||||
Call slowPathCall;
|
||||
DataLabel32 shape;
|
||||
DataLabelPtr addrLabel;
|
||||
bool usePropertyCache;
|
||||
|
||||
void copyTo(ic::GlobalNameIC &to, JSC::LinkBuffer &full, JSC::LinkBuffer &stub) {
|
||||
to.fastPathStart = full.locationOf(fastPathStart);
|
||||
|
||||
int offset = full.locationOf(shape) - to.fastPathStart;
|
||||
to.shapeOffset = offset;
|
||||
JS_ASSERT(to.shapeOffset == offset);
|
||||
|
||||
to.slowPathCall = stub.locationOf(slowPathCall);
|
||||
to.usePropertyCache = usePropertyCache;
|
||||
}
|
||||
};
|
||||
|
||||
struct GetGlobalNameICInfo : public GlobalNameICInfo {
|
||||
Label load;
|
||||
};
|
||||
|
||||
struct SetGlobalNameICInfo : public GlobalNameICInfo {
|
||||
Label slowPathStart;
|
||||
Label fastPathRejoin;
|
||||
Label load;
|
||||
DataLabel32 shape;
|
||||
DataLabelPtr addrLabel;
|
||||
DataLabel32 store;
|
||||
Call call;
|
||||
ic::MICInfo::Kind kind;
|
||||
Jump shapeGuardJump;
|
||||
ValueRemat vr;
|
||||
RegisterID objReg;
|
||||
RegisterID shapeReg;
|
||||
bool objConst;
|
||||
bool usePropertyCache;
|
||||
};
|
||||
|
||||
struct EqualityGenInfo {
|
||||
@ -341,8 +327,7 @@ class Compiler : public BaseCompiler
|
||||
FrameState frame;
|
||||
js::Vector<BranchPatch, 64, CompilerAllocPolicy> branchPatches;
|
||||
#if defined JS_MONOIC
|
||||
js::Vector<GetGlobalNameICInfo, 16, CompilerAllocPolicy> getGlobalNames;
|
||||
js::Vector<SetGlobalNameICInfo, 16, CompilerAllocPolicy> setGlobalNames;
|
||||
js::Vector<MICGenInfo, 64, CompilerAllocPolicy> mics;
|
||||
js::Vector<CallGenInfo, 64, CompilerAllocPolicy> callICs;
|
||||
js::Vector<EqualityGenInfo, 64, CompilerAllocPolicy> equalityICs;
|
||||
js::Vector<TraceGenInfo, 64, CompilerAllocPolicy> traceICs;
|
||||
@ -414,7 +399,7 @@ class Compiler : public BaseCompiler
|
||||
void passICAddress(BaseICInfo *ic);
|
||||
#endif
|
||||
#ifdef JS_MONOIC
|
||||
void passMICAddress(GlobalNameICInfo &mic);
|
||||
void passMICAddress(MICGenInfo &mic);
|
||||
#endif
|
||||
bool constructThis();
|
||||
|
||||
|
@ -845,8 +845,7 @@ mjit::JITScript::scriptDataSize()
|
||||
return sizeof(JITScript) +
|
||||
sizeof(NativeMapEntry) * nNmapPairs +
|
||||
#if defined JS_MONOIC
|
||||
sizeof(ic::GetGlobalNameIC) * nGetGlobalNames +
|
||||
sizeof(ic::SetGlobalNameIC) * nSetGlobalNames +
|
||||
sizeof(ic::MICInfo) * nMICs +
|
||||
sizeof(ic::CallICInfo) * nCallICs +
|
||||
sizeof(ic::EqualityICInfo) * nEqualityICs +
|
||||
sizeof(ic::TraceICInfo) * nTraceICs +
|
||||
|
@ -246,8 +246,7 @@ namespace ic {
|
||||
struct SetElementIC;
|
||||
# endif
|
||||
# if defined JS_MONOIC
|
||||
struct GetGlobalNameIC;
|
||||
struct SetGlobalNameIC;
|
||||
struct MICInfo;
|
||||
struct EqualityICInfo;
|
||||
struct TraceICInfo;
|
||||
struct CallICInfo;
|
||||
@ -277,8 +276,8 @@ typedef JSBool (JS_FASTCALL *BoolStubUInt32)(VMFrame &f, uint32);
|
||||
#ifdef JS_MONOIC
|
||||
typedef void (JS_FASTCALL *VoidStubCallIC)(VMFrame &, js::mjit::ic::CallICInfo *);
|
||||
typedef void * (JS_FASTCALL *VoidPtrStubCallIC)(VMFrame &, js::mjit::ic::CallICInfo *);
|
||||
typedef void (JS_FASTCALL *VoidStubGetGlobal)(VMFrame &, js::mjit::ic::GetGlobalNameIC *);
|
||||
typedef void (JS_FASTCALL *VoidStubSetGlobal)(VMFrame &, js::mjit::ic::SetGlobalNameIC *);
|
||||
typedef void (JS_FASTCALL *VoidStubMIC)(VMFrame &, js::mjit::ic::MICInfo *);
|
||||
typedef void * (JS_FASTCALL *VoidPtrStubMIC)(VMFrame &, js::mjit::ic::MICInfo *);
|
||||
typedef JSBool (JS_FASTCALL *BoolStubEqualityIC)(VMFrame &, js::mjit::ic::EqualityICInfo *);
|
||||
typedef void * (JS_FASTCALL *VoidPtrStubTraceIC)(VMFrame &, js::mjit::ic::TraceICInfo *);
|
||||
#endif
|
||||
@ -312,29 +311,27 @@ struct JITScript {
|
||||
/* To minimize the size of this struct on 64-bit, put uint32s after all pointers. */
|
||||
js::mjit::CallSite *callSites;
|
||||
#ifdef JS_MONOIC
|
||||
ic::GetGlobalNameIC *getGlobalNames;
|
||||
ic::SetGlobalNameIC *setGlobalNames;
|
||||
ic::CallICInfo *callICs;
|
||||
ic::EqualityICInfo *equalityICs;
|
||||
ic::TraceICInfo *traceICs;
|
||||
ic::MICInfo *mics; /* MICs in this script. */
|
||||
ic::CallICInfo *callICs; /* CallICs in this script. */
|
||||
ic::EqualityICInfo *equalityICs;
|
||||
ic::TraceICInfo *traceICs;
|
||||
#endif
|
||||
#ifdef JS_POLYIC
|
||||
ic::PICInfo *pics;
|
||||
ic::GetElementIC *getElems;
|
||||
ic::SetElementIC *setElems;
|
||||
ic::PICInfo *pics; /* PICs in this script */
|
||||
ic::GetElementIC *getElems;
|
||||
ic::SetElementIC *setElems;
|
||||
#endif
|
||||
|
||||
uint32 nCallSites:31;
|
||||
bool singleStepMode:1; /* compiled in "single step mode" */
|
||||
#ifdef JS_MONOIC
|
||||
uint32 nGetGlobalNames;
|
||||
uint32 nSetGlobalNames;
|
||||
uint32 nCallICs;
|
||||
uint32 nMICs; /* number of MonoICs */
|
||||
uint32 nCallICs; /* number of call ICs */
|
||||
uint32 nEqualityICs;
|
||||
uint32 nTraceICs;
|
||||
#endif
|
||||
#ifdef JS_POLYIC
|
||||
uint32 nPICs;
|
||||
uint32 nPICs; /* number of PolyICs */
|
||||
uint32 nGetElems;
|
||||
uint32 nSetElems;
|
||||
#endif
|
||||
|
@ -73,20 +73,22 @@ typedef JSC::MacroAssembler::DataLabel32 DataLabel32;
|
||||
#if defined JS_MONOIC
|
||||
|
||||
static void
|
||||
PatchGetFallback(VMFrame &f, ic::GetGlobalNameIC *ic)
|
||||
PatchGetFallback(VMFrame &f, ic::MICInfo *ic)
|
||||
{
|
||||
Repatcher repatch(f.jit());
|
||||
JSC::FunctionPtr fptr(JS_FUNC_TO_DATA_PTR(void *, stubs::GetGlobalName));
|
||||
repatch.relink(ic->slowPathCall, fptr);
|
||||
repatch.relink(ic->stubCall, fptr);
|
||||
}
|
||||
|
||||
void JS_FASTCALL
|
||||
ic::GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic)
|
||||
ic::GetGlobalName(VMFrame &f, ic::MICInfo *ic)
|
||||
{
|
||||
JSObject *obj = f.fp()->scopeChain().getGlobal();
|
||||
JSAtom *atom = f.fp()->script()->getAtom(GET_INDEX(f.regs.pc));
|
||||
jsid id = ATOM_TO_JSID(atom);
|
||||
|
||||
JS_ASSERT(ic->kind == ic::MICInfo::GET);
|
||||
|
||||
const Shape *shape = obj->nativeLookup(id);
|
||||
if (!shape ||
|
||||
!shape->hasDefaultGetterOrIsMethod() ||
|
||||
@ -101,11 +103,10 @@ ic::GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic)
|
||||
|
||||
/* Patch shape guard. */
|
||||
Repatcher repatcher(f.jit());
|
||||
repatcher.repatch(ic->fastPathStart.dataLabel32AtOffset(ic->shapeOffset), obj->shape());
|
||||
repatcher.repatch(ic->shape, obj->shape());
|
||||
|
||||
/* Patch loads. */
|
||||
JSC::CodeLocationLabel label = ic->fastPathStart.labelAtOffset(ic->loadStoreOffset);
|
||||
repatcher.patchAddressOffsetForValueLoad(label, slot * sizeof(Value));
|
||||
repatcher.patchAddressOffsetForValueLoad(ic->load, slot * sizeof(Value));
|
||||
|
||||
/* Do load anyway... this time. */
|
||||
stubs::GetGlobalName(f);
|
||||
@ -113,43 +114,43 @@ ic::GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic)
|
||||
|
||||
template <JSBool strict>
|
||||
static void JS_FASTCALL
|
||||
DisabledSetGlobal(VMFrame &f, ic::SetGlobalNameIC *ic)
|
||||
DisabledSetGlobal(VMFrame &f, ic::MICInfo *ic)
|
||||
{
|
||||
JSScript *script = f.fp()->script();
|
||||
JSAtom *atom = script->getAtom(GET_INDEX(f.regs.pc));
|
||||
stubs::SetGlobalName<strict>(f, atom);
|
||||
}
|
||||
|
||||
template void JS_FASTCALL DisabledSetGlobal<true>(VMFrame &f, ic::SetGlobalNameIC *ic);
|
||||
template void JS_FASTCALL DisabledSetGlobal<false>(VMFrame &f, ic::SetGlobalNameIC *ic);
|
||||
template void JS_FASTCALL DisabledSetGlobal<true>(VMFrame &f, ic::MICInfo *ic);
|
||||
template void JS_FASTCALL DisabledSetGlobal<false>(VMFrame &f, ic::MICInfo *ic);
|
||||
|
||||
template <JSBool strict>
|
||||
static void JS_FASTCALL
|
||||
DisabledSetGlobalNoCache(VMFrame &f, ic::SetGlobalNameIC *ic)
|
||||
DisabledSetGlobalNoCache(VMFrame &f, ic::MICInfo *ic)
|
||||
{
|
||||
JSScript *script = f.fp()->script();
|
||||
JSAtom *atom = script->getAtom(GET_INDEX(f.regs.pc));
|
||||
stubs::SetGlobalNameNoCache<strict>(f, atom);
|
||||
}
|
||||
|
||||
template void JS_FASTCALL DisabledSetGlobalNoCache<true>(VMFrame &f, ic::SetGlobalNameIC *ic);
|
||||
template void JS_FASTCALL DisabledSetGlobalNoCache<false>(VMFrame &f, ic::SetGlobalNameIC *ic);
|
||||
template void JS_FASTCALL DisabledSetGlobalNoCache<true>(VMFrame &f, ic::MICInfo *ic);
|
||||
template void JS_FASTCALL DisabledSetGlobalNoCache<false>(VMFrame &f, ic::MICInfo *ic);
|
||||
|
||||
static void
|
||||
PatchSetFallback(VMFrame &f, ic::SetGlobalNameIC *ic)
|
||||
PatchSetFallback(VMFrame &f, ic::MICInfo *ic)
|
||||
{
|
||||
JSScript *script = f.fp()->script();
|
||||
|
||||
Repatcher repatch(f.jit());
|
||||
VoidStubSetGlobal stub = ic->usePropertyCache
|
||||
? STRICT_VARIANT(DisabledSetGlobal)
|
||||
: STRICT_VARIANT(DisabledSetGlobalNoCache);
|
||||
VoidStubMIC stub = ic->usePropertyCache
|
||||
? STRICT_VARIANT(DisabledSetGlobal)
|
||||
: STRICT_VARIANT(DisabledSetGlobalNoCache);
|
||||
JSC::FunctionPtr fptr(JS_FUNC_TO_DATA_PTR(void *, stub));
|
||||
repatch.relink(ic->slowPathCall, fptr);
|
||||
repatch.relink(ic->stubCall, fptr);
|
||||
}
|
||||
|
||||
static LookupStatus
|
||||
UpdateSetGlobalNameStub(VMFrame &f, ic::SetGlobalNameIC *ic, JSObject *obj, const Shape *shape)
|
||||
UpdateSetGlobalNameStub(VMFrame &f, ic::MICInfo *ic, JSObject *obj, const Shape *shape)
|
||||
{
|
||||
Repatcher repatcher(ic->extraStub);
|
||||
|
||||
@ -164,7 +165,7 @@ UpdateSetGlobalNameStub(VMFrame &f, ic::SetGlobalNameIC *ic, JSObject *obj, cons
|
||||
}
|
||||
|
||||
static LookupStatus
|
||||
AttachSetGlobalNameStub(VMFrame &f, ic::SetGlobalNameIC *ic, JSObject *obj, const Shape *shape)
|
||||
AttachSetGlobalNameStub(VMFrame &f, ic::MICInfo *ic, JSObject *obj, const Shape *shape)
|
||||
{
|
||||
Assembler masm;
|
||||
|
||||
@ -246,7 +247,7 @@ AttachSetGlobalNameStub(VMFrame &f, ic::SetGlobalNameIC *ic, JSObject *obj, cons
|
||||
}
|
||||
|
||||
static LookupStatus
|
||||
UpdateSetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic, JSObject *obj, const Shape *shape)
|
||||
UpdateGlobalName(VMFrame &f, ic::MICInfo *ic, JSObject *obj, const Shape *shape)
|
||||
{
|
||||
/* Give globals a chance to appear. */
|
||||
if (!shape)
|
||||
@ -289,24 +290,22 @@ UpdateSetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic, JSObject *obj, const Sh
|
||||
|
||||
/* Object is not branded, so we can use the inline path. */
|
||||
Repatcher repatcher(f.jit());
|
||||
repatcher.repatch(ic->fastPathStart.dataLabel32AtOffset(ic->shapeOffset), obj->shape());
|
||||
|
||||
JSC::CodeLocationLabel label = ic->fastPathStart.labelAtOffset(ic->loadStoreOffset);
|
||||
repatcher.patchAddressOffsetForValueStore(label, shape->slot * sizeof(Value),
|
||||
repatcher.repatch(ic->shape, obj->shape());
|
||||
repatcher.patchAddressOffsetForValueStore(ic->load, shape->slot * sizeof(Value),
|
||||
ic->vr.isTypeKnown());
|
||||
|
||||
return Lookup_Cacheable;
|
||||
}
|
||||
|
||||
void JS_FASTCALL
|
||||
ic::SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic)
|
||||
ic::SetGlobalName(VMFrame &f, ic::MICInfo *ic)
|
||||
{
|
||||
JSObject *obj = f.fp()->scopeChain().getGlobal();
|
||||
JSScript *script = f.fp()->script();
|
||||
JSAtom *atom = script->getAtom(GET_INDEX(f.regs.pc));
|
||||
const Shape *shape = obj->nativeLookup(ATOM_TO_JSID(atom));
|
||||
|
||||
LookupStatus status = UpdateSetGlobalName(f, ic, obj, shape);
|
||||
LookupStatus status = UpdateGlobalName(f, ic, obj, shape);
|
||||
if (status == Lookup_Error)
|
||||
THROW();
|
||||
|
||||
@ -1159,21 +1158,30 @@ ic::SplatApplyArgs(VMFrame &f)
|
||||
void
|
||||
JITScript::purgeMICs()
|
||||
{
|
||||
if (!nGetGlobalNames || !nSetGlobalNames)
|
||||
if (!nMICs)
|
||||
return;
|
||||
|
||||
Repatcher repatch(this);
|
||||
|
||||
for (uint32 i = 0; i < nGetGlobalNames; i++) {
|
||||
ic::GetGlobalNameIC &ic = getGlobalNames[i];
|
||||
JSC::CodeLocationDataLabel32 label = ic.fastPathStart.dataLabel32AtOffset(ic.shapeOffset);
|
||||
repatch.repatch(label, int(JSObjectMap::INVALID_SHAPE));
|
||||
}
|
||||
for (uint32 i = 0; i < nMICs; i++) {
|
||||
ic::MICInfo &mic = mics[i];
|
||||
switch (mic.kind) {
|
||||
case ic::MICInfo::SET:
|
||||
case ic::MICInfo::GET:
|
||||
{
|
||||
/* Patch shape guard. */
|
||||
repatch.repatch(mic.shape, int(JSObjectMap::INVALID_SHAPE));
|
||||
|
||||
for (uint32 i = 0; i < nSetGlobalNames; i++) {
|
||||
ic::SetGlobalNameIC &ic = setGlobalNames[i];
|
||||
JSC::CodeLocationDataLabel32 label = ic.fastPathStart.dataLabel32AtOffset(ic.shapeOffset);
|
||||
repatch.repatch(label, int(JSObjectMap::INVALID_SHAPE));
|
||||
/*
|
||||
* If the stub call was patched, leave it alone -- it probably will
|
||||
* just be invalidated again.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
default:
|
||||
JS_NOT_REACHED("Unknown MIC type during purge");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1273,10 +1281,11 @@ JITScript::sweepCallICs(JSContext *cx, bool purgeAll)
|
||||
released++;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < nSetGlobalNames; i++) {
|
||||
ic::SetGlobalNameIC &ic = setGlobalNames[i];
|
||||
for (uint32 i = 0; i < nMICs; i ++) {
|
||||
ic::MICInfo &ic = mics[i];
|
||||
if (!ic.extraShapeGuard)
|
||||
continue;
|
||||
JS_ASSERT(ic.kind == ic::MICInfo::SET);
|
||||
repatcher.relink(ic.fastPathStart.jumpAtOffset(ic.inlineShapeJump), ic.slowPathStart);
|
||||
ic.extraShapeGuard = 0;
|
||||
released++;
|
||||
|
@ -91,12 +91,20 @@ class FrameSize
|
||||
|
||||
namespace ic {
|
||||
|
||||
struct GlobalNameIC
|
||||
{
|
||||
struct MICInfo {
|
||||
enum Kind
|
||||
#ifdef _MSC_VER
|
||||
: uint8_t
|
||||
#endif
|
||||
{
|
||||
GET,
|
||||
SET
|
||||
};
|
||||
|
||||
typedef JSC::MacroAssembler::RegisterID RegisterID;
|
||||
|
||||
JSC::CodeLocationLabel fastPathStart;
|
||||
JSC::CodeLocationCall slowPathCall;
|
||||
JSC::CodeLocationLabel fastPathStart;
|
||||
JSC::CodeLocationLabel slowPathStart;
|
||||
|
||||
/*
|
||||
* - ARM and x64 always emit exactly one instruction which needs to be
|
||||
@ -107,28 +115,19 @@ struct GlobalNameIC
|
||||
* of this, x86 is the only platform which requires non-trivial patching
|
||||
* code.
|
||||
*/
|
||||
int32 loadStoreOffset : 15;
|
||||
int32 shapeOffset : 15;
|
||||
bool usePropertyCache : 1;
|
||||
};
|
||||
|
||||
struct GetGlobalNameIC : public GlobalNameIC
|
||||
{
|
||||
};
|
||||
|
||||
struct SetGlobalNameIC : public GlobalNameIC
|
||||
{
|
||||
JSC::CodeLocationLabel slowPathStart;
|
||||
|
||||
/* Dynamically generted stub for method-write checks. */
|
||||
JSC::JITCode extraStub;
|
||||
JSC::CodeLocationLabel load;
|
||||
JSC::CodeLocationDataLabel32 shape;
|
||||
JSC::CodeLocationCall stubCall;
|
||||
|
||||
/* SET only, if we had to generate an out-of-line path. */
|
||||
Kind kind : 2;
|
||||
bool usePropertyCache : 1;
|
||||
int inlineShapeJump : 10; /* Offset into inline path for shape jump. */
|
||||
int extraShapeGuard : 6; /* Offset into stub for shape guard. */
|
||||
bool objConst : 1; /* True if the object is constant. */
|
||||
RegisterID objReg : 5; /* Register for object, if objConst is false. */
|
||||
RegisterID shapeReg : 5; /* Register for shape; volatile. */
|
||||
JSC::JITCode extraStub; /* Out-of-line generated stub. */
|
||||
|
||||
int fastRejoinOffset : 16; /* Offset from fastPathStart to rejoin. */
|
||||
int extraStoreOffset : 16; /* Offset into store code. */
|
||||
@ -160,8 +159,8 @@ struct TraceICInfo {
|
||||
|
||||
static const uint16 BAD_TRACEIC_INDEX = (uint16)0xffff;
|
||||
|
||||
void JS_FASTCALL GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic);
|
||||
void JS_FASTCALL SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic);
|
||||
void JS_FASTCALL GetGlobalName(VMFrame &f, ic::MICInfo *ic);
|
||||
void JS_FASTCALL SetGlobalName(VMFrame &f, ic::MICInfo *ic);
|
||||
|
||||
struct EqualityICInfo {
|
||||
typedef JSC::MacroAssembler::RegisterID RegisterID;
|
||||
|
Loading…
Reference in New Issue
Block a user