Merge backout.

This commit is contained in:
David Anderson 2011-02-01 13:48:57 -08:00
commit 0dfec96f2e
6 changed files with 176 additions and 206 deletions

View File

@ -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

View File

@ -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();

View File

@ -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 +

View File

@ -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

View File

@ -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++;

View File

@ -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;