Bug 790836 - Don't mark the fields of IonJSFrameLayout twice; r=pierron

This also skips poisoning stack roots owned by Ion in the rooting analysis.

--HG--
extra : rebase_source : 006079bc3f443bd6630f5a3c32135fbddc279f1d
This commit is contained in:
Terrence Cole 2012-09-17 11:13:20 -07:00
parent 00587c07b1
commit b268c5d7d5
3 changed files with 54 additions and 13 deletions

View File

@ -191,6 +191,9 @@ class IonActivationIterator
return top_;
}
bool more() const;
// Returns the bottom and top addresses of the current activation.
void ionStackRange(uintptr_t *&min, uintptr_t *&end);
};
class IonJSFrameLayout;

View File

@ -174,8 +174,6 @@ IonFrameIterator::actualArgs() const
uint8 *
IonFrameIterator::prevFp() const
{
JS_ASSERT(type_ != IonFrame_Entry);
size_t currentSize = SizeOfFramePrefix(type_);
// This quick fix must be removed as soon as bug 717297 land. This is
// needed because the descriptor size of JS-to-JS frame which is just after
@ -490,6 +488,25 @@ MarkIonJSFrame(JSTracer *trc, const IonFrameIterator &frame)
#endif
}
void
IonActivationIterator::ionStackRange(uintptr_t *&min, uintptr_t *&end)
{
IonFrameIterator frames(top());
IonExitFrameLayout *exitFrame = frames.exitFrame();
IonExitFooterFrame *footer = exitFrame->footer();
const VMFunction *f = footer->function();
if (exitFrame->isWrapperExit() && f->outParam == Type_Handle)
min = reinterpret_cast<uintptr_t *>(footer->outVp());
else
min = reinterpret_cast<uintptr_t *>(footer);
while (!frames.done())
++frames;
end = reinterpret_cast<uintptr_t *>(frames.prevFp());
}
static void
MarkIonExitFrame(JSTracer *trc, const IonFrameIterator &frame)
{

View File

@ -1170,18 +1170,14 @@ MarkRangeConservativelyAndSkipIon(JSTracer *trc, JSRuntime *rt, const uintptr_t
// registers are spilled to the stack before the entry Ion frame, ensuring
// that the conservative scanner will still see them.
for (ion::IonActivationIterator ion(rt); ion.more(); ++ion) {
ion::IonFrameIterator frames(ion.top());
while (!frames.done())
++frames;
uintptr_t *ionMin = (uintptr_t *)ion.top();
uintptr_t *ionEnd = (uintptr_t *)frames.fp();
uintptr_t *ionMin, *ionEnd;
ion.ionStackRange(ionMin, ionEnd);
MarkRangeConservatively(trc, i, ionMin);
i = ionEnd;
}
#endif
// Mark everything after the most recent Ion activation.
MarkRangeConservatively(trc, i, end);
}
@ -2608,7 +2604,7 @@ MarkRuntime(JSTracer *trc, bool useSavedRoots = false)
rt->stackSpace.markAndClobber(trc);
rt->debugScopes->mark(trc);
#ifdef JS_ION
ion::MarkIonActivations(rt, trc);
#endif
@ -5022,6 +5018,31 @@ CheckStackRootsRange(JSTracer *trc, uintptr_t *begin, uintptr_t *end)
CheckStackRoot(trc, i);
}
static void
CheckStackRootsRangeAndSkipIon(JSRuntime *rt, JSTracer *trc, uintptr_t *begin, uintptr_t *end)
{
/*
* Regions of the stack between Ion activiations are marked exactly through
* a different mechanism. We need to skip these regions when checking the
* stack so that we do not poison IonMonkey's things.
*/
uintptr_t *i = begin;
#if JS_STACK_GROWTH_DIRECTION < 0 && defined(JS_ION)
for (ion::IonActivationIterator ion(rt); ion.more(); ++ion) {
uintptr_t *ionMin, *ionEnd;
ion.ionStackRange(ionMin, ionEnd);
CheckStackRootsRange(trc, i, ionMin);
i = ionEnd;
}
#endif
/* The topmost Ion activiation may be beyond our prior top. */
if (i <= end)
CheckStackRootsRange(trc, i, end);
}
static void
EmptyMarkCallback(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
{}
@ -5111,7 +5132,7 @@ JS::CheckStackRoots(JSContext *cx)
#endif
JS_ASSERT(stackMin <= stackEnd);
CheckStackRootsRange(&checker, stackMin, stackEnd);
CheckStackRootsRangeAndSkipIon(rt, &checker, stackMin, stackEnd);
CheckStackRootsRange(&checker, cgcd->registerSnapshot.words,
ArrayEnd(cgcd->registerSnapshot.words));
}
@ -5253,7 +5274,7 @@ NextNode(VerifyNode *node)
return (VerifyNode *)((char *)node + sizeof(VerifyNode) - sizeof(EdgeValue));
else
return (VerifyNode *)((char *)node + sizeof(VerifyNode) +
sizeof(EdgeValue)*(node->count - 1));
sizeof(EdgeValue)*(node->count - 1));
}
static void
@ -5828,7 +5849,7 @@ PurgeJITCaches(JSCompartment *c)
#ifdef JS_ION
/* Discard Ion caches. */
/* Discard Ion caches. */
if (script->hasIonScript())
script->ion->purgeCaches(c);