Store list of interned global slots in struct FragmentInfo

This commit is contained in:
Andreas Gal 2008-07-15 01:03:49 -07:00
parent 9f761173f0
commit bac6ed12f4
2 changed files with 51 additions and 4 deletions

View File

@ -464,16 +464,25 @@ TraceRecorder::TraceRecorder(JSContext* cx, Fragmento* fragmento, Fragment* _fra
lir = func_filter = new (&gc) FuncFilter(lir, *this);
lir->ins0(LIR_trace);
if (fragment->vmprivate == NULL) {
/* generate the entry map and stash it in the trace */
/* calculate the number of globals we want to intern */
unsigned internableGlobals = findInternableGlobals(entryFrame, NULL);
/* generate the entry map and store it in the trace */
unsigned entryNativeFrameSlots = nativeFrameSlots(entryFrame, entryRegs);
LIns* data = lir_buf_writer->skip(sizeof(*fragmentInfo) -
sizeof(fragmentInfo->typeMap) + entryNativeFrameSlots * sizeof(char));
LIns* data = lir_buf_writer->skip(sizeof(*fragmentInfo) +
internableGlobals * sizeof(uint16) +
entryNativeFrameSlots * sizeof(uint8));
fragmentInfo = (VMFragmentInfo*)data->payload();
fragmentInfo->typeMap = (uint8*)(fragmentInfo + 1);
fragmentInfo->internedGlobalSlots = (uint16*)(fragmentInfo->typeMap +
entryNativeFrameSlots * sizeof(uint8));
fragmentInfo->entryNativeFrameSlots = entryNativeFrameSlots;
fragmentInfo->nativeStackBase = (entryNativeFrameSlots -
(entryRegs.sp - entryFrame->spbase)) * sizeof(double);
fragmentInfo->maxNativeFrameSlots = entryNativeFrameSlots;
fragmentInfo->maxCallDepth = 0;
/* setup the list of global properties we want to intern */
findInternableGlobals(entryFrame, fragmentInfo->internedGlobalSlots);
fragmentInfo->internedGlobalSlotCount = internableGlobals;
/* build the entry type map */
uint8* m = fragmentInfo->typeMap;
/* remember the coerced type of each active slot in the type map */
@ -570,6 +579,41 @@ TraceRecorder::isGlobal(jsval* p) const
size_t(p - globalObj->dslots) < size_t(globalObj->dslots[-1] - JS_INITIAL_NSLOTS);
}
unsigned
TraceRecorder::findInternableGlobals(JSStackFrame* fp, uint16* slots) const
{
unsigned count = 0;
unsigned n;
JSAtom** atoms = fp->script->atomMap.vector;
unsigned natoms = fp->script->atomMap.length;
for (n = 0; n < natoms; ++n) {
JSAtom* atom = atoms[n];
if (!ATOM_IS_STRING(atom))
continue;
jsid id = ATOM_TO_JSID(atom);
JSObject* pobj;
JSProperty *prop;
JSScopeProperty* sprop;
if (!js_LookupProperty(cx, globalObj, id, &pobj, &prop))
continue;
if (!prop)
continue; /* property not found -- string constant? */
if (pobj == globalObj) {
sprop = (JSScopeProperty*) prop;
unsigned slot;
if (SPROP_HAS_STUB_GETTER(sprop) &&
SPROP_HAS_STUB_SETTER(sprop) &&
(slot = sprop->slot) == slot) {
if (slots)
*slots++ = slot;
++count;
}
}
JS_UNLOCK_OBJ(cx, pobj);
}
return count;
}
/* Calculate the total number of native frame slots we need from this frame
all the way back to the entry frame, including the current stack usage. */
unsigned

View File

@ -91,7 +91,9 @@ struct VMFragmentInfo {
unsigned maxNativeFrameSlots;
size_t nativeStackBase;
unsigned maxCallDepth;
uint8 typeMap[1];
unsigned internedGlobalSlotCount;
uint8 *typeMap;
uint16 *internedGlobalSlots;
};
extern struct nanojit::CallInfo builtins[];
@ -131,6 +133,7 @@ class TraceRecorder {
JSStackFrame* findFrame(jsval* p) const;
bool onFrame(jsval* p) const;
bool isGlobal(jsval* p) const;
unsigned findInternableGlobals(JSStackFrame* fp, uint16* slots) const;
unsigned nativeFrameSlots(JSStackFrame* fp, JSFrameRegs& regs) const;
size_t nativeFrameOffset(jsval* p) const;
void import(jsval* p, uint8& t, char *prefix, int index);