mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-02 07:05:24 +00:00
Funnel all write-backs to the stack and the global frame through TraceRecorder::writeBack() so we can intercept and manipulate them in one central location.
This commit is contained in:
parent
87f65aaf6b
commit
a91faa3c28
@ -1084,28 +1084,33 @@ TraceRecorder::lazilyImportGlobalSlot(unsigned slot)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Write back a value onto the stack or global frames. */
|
||||
LIns*
|
||||
TraceRecorder::writeBack(LIns* i, LIns* base, ptrdiff_t offset)
|
||||
{
|
||||
/* Sink all type casts targeting the stack into the side exit by simply storing the original
|
||||
(uncasted) value. Each guard generates the side exit map based on the types of the
|
||||
last stores to every stack location, so its safe to not perform them on-trace. */
|
||||
if (isPromoteInt(i))
|
||||
i = ::demote(lir, i);
|
||||
return lir->insStorei(i, base, offset);
|
||||
}
|
||||
|
||||
/* Update the tracker, then issue a write back store. */
|
||||
void
|
||||
TraceRecorder::set(jsval* p, LIns* i, bool initializing)
|
||||
{
|
||||
JS_ASSERT(initializing || tracker.has(p));
|
||||
tracker.set(p, i);
|
||||
/* Sink all type casts targeting the stack into the side exit by simply storing the original
|
||||
(uncasted) value. Each guard generates the side exit map based on the types of the
|
||||
last stores to every stack location, so its safe to not perform them on-trace. */
|
||||
if (isPromoteInt(i))
|
||||
i = ::demote(lir, i);
|
||||
/* If we are writing to this location for the first time, calculate the offset into the
|
||||
native frame manually, otherwise just look up the last load or store associated with
|
||||
the same source address (p) and use the same offset/base. */
|
||||
LIns* x;
|
||||
if ((x = nativeFrameTracker.get(p)) == NULL) {
|
||||
if (isGlobal(p)) {
|
||||
x = lir->insStorei(i, gp_ins, nativeGlobalOffset(p));
|
||||
} else {
|
||||
ptrdiff_t offset = nativeStackOffset(p);
|
||||
x = lir->insStorei(i, lirbuf->sp, -treeInfo->nativeStackBase + offset);
|
||||
}
|
||||
if (isGlobal(p))
|
||||
x = writeBack(i, gp_ins, nativeGlobalOffset(p));
|
||||
else
|
||||
x = writeBack(i, lirbuf->sp, -treeInfo->nativeStackBase + nativeStackOffset(p));
|
||||
nativeFrameTracker.set(p, x);
|
||||
} else {
|
||||
#define ASSERT_VALID_CACHE_HIT(base, offset) \
|
||||
@ -1116,11 +1121,11 @@ TraceRecorder::set(jsval* p, LIns* i, bool initializing)
|
||||
|
||||
if (x->isop(LIR_st) || x->isop(LIR_stq)) {
|
||||
ASSERT_VALID_CACHE_HIT(x->oprnd2(), x->oprnd3()->constval());
|
||||
lir->insStorei(i, x->oprnd2(), x->oprnd3()->constval());
|
||||
writeBack(i, x->oprnd2(), x->oprnd3()->constval());
|
||||
} else {
|
||||
JS_ASSERT(x->isop(LIR_sti) || x->isop(LIR_stqi));
|
||||
ASSERT_VALID_CACHE_HIT(x->oprnd2(), x->immdisp());
|
||||
lir->insStorei(i, x->oprnd2(), x->immdisp());
|
||||
writeBack(i, x->oprnd2(), x->immdisp());
|
||||
}
|
||||
}
|
||||
#undef ASSERT_VALID_CACHE_HIT
|
||||
|
@ -234,6 +234,7 @@ class TraceRecorder {
|
||||
nanojit::LIns* addName(nanojit::LIns* ins, const char* name);
|
||||
|
||||
nanojit::LIns* get(jsval* p);
|
||||
nanojit::LIns* writeBack(nanojit::LIns* i, nanojit::LIns* base, ptrdiff_t offset);
|
||||
void set(jsval* p, nanojit::LIns* l, bool initializing = false);
|
||||
|
||||
bool checkType(jsval& v, uint8 type, bool& recompile);
|
||||
|
Loading…
Reference in New Issue
Block a user