mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 781393 - JS VM stack values shouldn't always be clobbered during marking (r=bhackett)
This commit is contained in:
parent
2e2b4aca5e
commit
ba92c54858
14
js/src/jit-test/tests/basic/bug781393.js
Normal file
14
js/src/jit-test/tests/basic/bug781393.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
gczeal(4,1);
|
||||||
|
function check(o)
|
||||||
|
{
|
||||||
|
print(o);
|
||||||
|
assertEq(o.b, 3);
|
||||||
|
}
|
||||||
|
function f()
|
||||||
|
{
|
||||||
|
for (var i=0; i<3; i++) {
|
||||||
|
var o = {b: 3};
|
||||||
|
check(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
@ -486,6 +486,15 @@ JSCompartment::discardJitCode(FreeOp *fop)
|
|||||||
#endif /* JS_METHODJIT */
|
#endif /* JS_METHODJIT */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
JSCompartment::isDiscardingJitCode(JSTracer *trc)
|
||||||
|
{
|
||||||
|
if (!IS_GC_MARKING_TRACER(trc))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !gcPreserveCode;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
JSCompartment::sweep(FreeOp *fop, bool releaseTypes)
|
JSCompartment::sweep(FreeOp *fop, bool releaseTypes)
|
||||||
{
|
{
|
||||||
|
@ -325,6 +325,7 @@ struct JSCompartment
|
|||||||
|
|
||||||
void markTypes(JSTracer *trc);
|
void markTypes(JSTracer *trc);
|
||||||
void discardJitCode(js::FreeOp *fop);
|
void discardJitCode(js::FreeOp *fop);
|
||||||
|
bool isDiscardingJitCode(JSTracer *trc);
|
||||||
void sweep(js::FreeOp *fop, bool releaseTypes);
|
void sweep(js::FreeOp *fop, bool releaseTypes);
|
||||||
void sweepCrossCompartmentWrappers();
|
void sweepCrossCompartmentWrappers();
|
||||||
void purge();
|
void purge();
|
||||||
|
@ -648,35 +648,40 @@ StackSpace::markFrameValues(JSTracer *trc, StackFrame *fp, Value *slotsEnd, jsby
|
|||||||
for (Value *vp = slotsBegin; vp < fixedEnd; vp++) {
|
for (Value *vp = slotsBegin; vp < fixedEnd; vp++) {
|
||||||
uint32_t slot = analyze::LocalSlot(script, vp - slotsBegin);
|
uint32_t slot = analyze::LocalSlot(script, vp - slotsBegin);
|
||||||
|
|
||||||
/*
|
/* Will this slot be synced by the JIT? */
|
||||||
* Will this slot be synced by the JIT? If not, replace with a dummy
|
|
||||||
* value with the same type tag.
|
|
||||||
*/
|
|
||||||
if (!analysis->trackSlot(slot) || analysis->liveness(slot).live(offset)) {
|
if (!analysis->trackSlot(slot) || analysis->liveness(slot).live(offset)) {
|
||||||
gc::MarkValueRoot(trc, vp, "vm_stack");
|
gc::MarkValueRoot(trc, vp, "vm_stack");
|
||||||
} else if (vp->isDouble()) {
|
} else if (script->compartment()->isDiscardingJitCode(trc)) {
|
||||||
*vp = DoubleValue(0.0);
|
|
||||||
} else {
|
|
||||||
/*
|
/*
|
||||||
* It's possible that *vp may not be a valid Value. For example, it
|
* If we're throwing away analysis information, we need to replace
|
||||||
* may be tagged as a NullValue but the low bits may be nonzero so
|
* non-live Values with ones that can safely be marked in later
|
||||||
* that isNull() returns false. This can cause problems later on
|
* collections.
|
||||||
* when marking the value. Extracting the type in this way and then
|
|
||||||
* overwriting the value circumvents the problem.
|
|
||||||
*/
|
*/
|
||||||
JSValueType type = vp->extractNonDoubleType();
|
if (vp->isDouble()) {
|
||||||
if (type == JSVAL_TYPE_INT32)
|
*vp = DoubleValue(0.0);
|
||||||
*vp = Int32Value(0);
|
} else {
|
||||||
else if (type == JSVAL_TYPE_UNDEFINED)
|
/*
|
||||||
*vp = UndefinedValue();
|
* It's possible that *vp may not be a valid Value. For example,
|
||||||
else if (type == JSVAL_TYPE_BOOLEAN)
|
* it may be tagged as a NullValue but the low bits may be
|
||||||
*vp = BooleanValue(false);
|
* nonzero so that isNull() returns false. This can cause
|
||||||
else if (type == JSVAL_TYPE_STRING)
|
* problems later on when marking the value. Extracting the type
|
||||||
*vp = StringValue(trc->runtime->atomState.nullAtom);
|
* in this way and then overwriting the value circumvents the
|
||||||
else if (type == JSVAL_TYPE_NULL)
|
* problem.
|
||||||
*vp = NullValue();
|
*/
|
||||||
else if (type == JSVAL_TYPE_OBJECT)
|
JSValueType type = vp->extractNonDoubleType();
|
||||||
*vp = ObjectValue(fp->scopeChain()->global());
|
if (type == JSVAL_TYPE_INT32)
|
||||||
|
*vp = Int32Value(0);
|
||||||
|
else if (type == JSVAL_TYPE_UNDEFINED)
|
||||||
|
*vp = UndefinedValue();
|
||||||
|
else if (type == JSVAL_TYPE_BOOLEAN)
|
||||||
|
*vp = BooleanValue(false);
|
||||||
|
else if (type == JSVAL_TYPE_STRING)
|
||||||
|
*vp = StringValue(trc->runtime->atomState.nullAtom);
|
||||||
|
else if (type == JSVAL_TYPE_NULL)
|
||||||
|
*vp = NullValue();
|
||||||
|
else if (type == JSVAL_TYPE_OBJECT)
|
||||||
|
*vp = ObjectValue(fp->scopeChain()->global());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user