Bug 830042 - Tolerate objects/strings with a null payload when marking VM stack, r=billm.

This commit is contained in:
Brian Hackett 2013-01-16 14:48:10 -07:00
parent 387e5b8af2
commit 190d56fcd0
3 changed files with 38 additions and 1 deletions

View File

@ -498,6 +498,24 @@ MarkValueInternal(JSTracer *trc, Value *v)
}
}
static inline void
MarkValueInternalMaybeNullPayload(JSTracer *trc, Value *v)
{
if (v->isMarkable()) {
void *thing = v->toGCThing();
if (thing) {
JS_SET_TRACING_LOCATION(trc, (void *)v);
MarkKind(trc, &thing, v->gcKind());
if (v->isString())
v->setString((JSString *)thing);
else
v->setObjectOrNull((JSObject *)thing);
return;
}
}
JS_UNSET_TRACING_LOCATION(trc);
}
void
gc::MarkValue(JSTracer *trc, EncapsulatedValue *v, const char *name)
{
@ -548,6 +566,16 @@ gc::MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name)
}
}
void
gc::MarkValueRootRangeMaybeNullPayload(JSTracer *trc, size_t len, Value *vec, const char *name)
{
JS_ROOT_MARKING_ASSERT(trc);
for (size_t i = 0; i < len; ++i) {
JS_SET_TRACING_INDEX(trc, name, i);
MarkValueInternalMaybeNullPayload(trc, &vec[i]);
}
}
bool
gc::IsValueMarked(Value *v)
{

View File

@ -174,6 +174,9 @@ MarkValueRootRange(JSTracer *trc, Value *begin, Value *end, const char *name)
MarkValueRootRange(trc, end - begin, begin, name);
}
void
MarkValueRootRangeMaybeNullPayload(JSTracer *trc, size_t len, Value *vec, const char *name);
void
MarkTypeRoot(JSTracer *trc, types::Type *v, const char *name);

View File

@ -642,8 +642,14 @@ StackSpace::containingSegment(const StackFrame *target) const
void
StackSpace::markFrame(JSTracer *trc, StackFrame *fp, Value *slotsEnd)
{
/*
* JM may leave values with object/string type but a null payload on the
* stack. This can happen if the script was initially compiled by Ion,
* which replaced dead values with undefined, and later ran under JM which
* assumed values were of the original type.
*/
Value *slotsBegin = fp->slots();
gc::MarkValueRootRange(trc, slotsBegin, slotsEnd, "vm_stack");
gc::MarkValueRootRangeMaybeNullPayload(trc, slotsEnd - slotsBegin, slotsBegin, "vm_stack");
}
void