mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 862606 - Shift around some marking for brain transplants (r=bhackett)
This commit is contained in:
parent
ab0ca9312a
commit
259685d273
@ -814,7 +814,9 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
|
||||
gcIsFull(false),
|
||||
gcTriggerReason(JS::gcreason::NO_REASON),
|
||||
gcStrictCompartmentChecking(false),
|
||||
#ifdef DEBUG
|
||||
gcDisableStrictProxyCheckingCount(0),
|
||||
#endif
|
||||
gcIncrementalState(gc::NO_INCREMENTAL),
|
||||
gcLastMarkSlice(false),
|
||||
gcSweepOnBackgroundThread(false),
|
||||
@ -1633,6 +1635,7 @@ JS_TransplantObject(JSContext *cx, JSObject *origobjArg, JSObject *targetArg)
|
||||
JS_ASSERT(!IsCrossCompartmentWrapper(target));
|
||||
|
||||
AutoMaybeTouchDeadZones agc(cx);
|
||||
AutoDisableProxyCheck adpc(cx->runtime);
|
||||
|
||||
JSCompartment *destination = target->compartment();
|
||||
RootedValue origv(cx, ObjectValue(*origobj));
|
||||
@ -1706,6 +1709,7 @@ js_TransplantObjectWithWrapper(JSContext *cx,
|
||||
RootedObject targetwrapper(cx, targetwrapperArg);
|
||||
|
||||
AutoMaybeTouchDeadZones agc(cx);
|
||||
AutoDisableProxyCheck adpc(cx->runtime);
|
||||
|
||||
AssertHeapIsIdle(cx);
|
||||
JS_ASSERT(!IsCrossCompartmentWrapper(origobj));
|
||||
|
@ -956,6 +956,7 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
*/
|
||||
bool gcStrictCompartmentChecking;
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* If this is 0, all cross-compartment proxies must be registered in the
|
||||
* wrapper map. This checking must be disabled temporarily while creating
|
||||
@ -963,6 +964,9 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
* creation.
|
||||
*/
|
||||
uintptr_t gcDisableStrictProxyCheckingCount;
|
||||
#else
|
||||
uintptr_t unused1;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The current incremental GC phase. This is also used internally in
|
||||
|
@ -213,15 +213,7 @@ JSCompartment::wrap(JSContext *cx, MutableHandleValue vp, HandleObject existingA
|
||||
|
||||
JS_CHECK_CHROME_RECURSION(cx, return false);
|
||||
|
||||
#ifdef DEBUG
|
||||
struct AutoDisableProxyCheck {
|
||||
JSRuntime *runtime;
|
||||
AutoDisableProxyCheck(JSRuntime *rt) : runtime(rt) {
|
||||
runtime->gcDisableStrictProxyCheckingCount++;
|
||||
}
|
||||
~AutoDisableProxyCheck() { runtime->gcDisableStrictProxyCheckingCount--; }
|
||||
} adpc(rt);
|
||||
#endif
|
||||
AutoDisableProxyCheck adpc(rt);
|
||||
|
||||
/* Only GC things have to be wrapped or copied. */
|
||||
if (!vp.isMarkable())
|
||||
|
@ -5112,3 +5112,11 @@ AutoSuppressGC::AutoSuppressGC(JSCompartment *comp)
|
||||
{
|
||||
suppressGC_++;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
AutoDisableProxyCheck::AutoDisableProxyCheck(JSRuntime *rt)
|
||||
: count(rt->gcDisableStrictProxyCheckingCount)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
#endif
|
||||
|
@ -1285,6 +1285,25 @@ class AutoSuppressGC
|
||||
|
||||
} /* namespace gc */
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Use this to avoid assertions when manipulating the wrapper map. */
|
||||
struct AutoDisableProxyCheck
|
||||
{
|
||||
uintptr_t &count;
|
||||
|
||||
AutoDisableProxyCheck(JSRuntime *rt);
|
||||
|
||||
~AutoDisableProxyCheck() {
|
||||
count--;
|
||||
}
|
||||
};
|
||||
#else
|
||||
struct AutoDisableProxyCheck
|
||||
{
|
||||
AutoDisableProxyCheck(JSRuntime *rt) {}
|
||||
};
|
||||
#endif
|
||||
|
||||
void
|
||||
PurgeJITCaches(JS::Zone *zone);
|
||||
|
||||
|
@ -1773,6 +1773,12 @@ bool
|
||||
JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *aArg, JSObject *bArg,
|
||||
TradeGutsReserved &reserved)
|
||||
{
|
||||
/*
|
||||
* Avoid GC in here to avoid confusing the tracing code with our
|
||||
* intermediate state.
|
||||
*/
|
||||
AutoSuppressGC suppress(cx);
|
||||
|
||||
RootedObject a(cx, aArg);
|
||||
RootedObject b(cx, bArg);
|
||||
JS_ASSERT(a->compartment() == b->compartment());
|
||||
@ -1784,19 +1790,6 @@ JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *aArg, JSObject *bArg,
|
||||
* swaps can be performed infallibly.
|
||||
*/
|
||||
|
||||
#ifdef JSGC_INCREMENTAL
|
||||
/*
|
||||
* We need a write barrier here. If |a| was marked and |b| was not, then
|
||||
* after the swap, |b|'s guts would never be marked. The write barrier
|
||||
* solves this.
|
||||
*/
|
||||
JS::Zone *zone = a->zone();
|
||||
if (zone->needsBarrier()) {
|
||||
MarkChildren(zone->barrierTracer(), a);
|
||||
MarkChildren(zone->barrierTracer(), b);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Swap prototypes and classes on the two objects, so that TradeGuts can
|
||||
* preserve the types of the two objects.
|
||||
@ -2015,6 +2008,24 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
|
||||
a->lastProperty()->listp = &a->shape_;
|
||||
if (b->inDictionaryMode())
|
||||
b->lastProperty()->listp = &b->shape_;
|
||||
|
||||
#ifdef JSGC_INCREMENTAL
|
||||
/*
|
||||
* We need a write barrier here. If |a| was marked and |b| was not, then
|
||||
* after the swap, |b|'s guts would never be marked. The write barrier
|
||||
* solves this.
|
||||
*
|
||||
* Normally write barriers happen before the write. However, that's not
|
||||
* necessary here because nothing is being destroyed. We're just swapping.
|
||||
* We don't do the barrier before TradeGuts because ReserveForTradeGuts
|
||||
* makes changes to the objects that might confuse the tracing code.
|
||||
*/
|
||||
JS::Zone *zone = a->zone();
|
||||
if (zone->needsBarrier()) {
|
||||
MarkChildren(zone->barrierTracer(), a);
|
||||
MarkChildren(zone->barrierTracer(), b);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Use this method with extreme caution. It trades the guts of two objects. */
|
||||
|
@ -953,6 +953,8 @@ js::RemapWrapper(JSContext *cx, JSObject *wobjArg, JSObject *newTargetArg)
|
||||
Value origv = ObjectValue(*origTarget);
|
||||
JSCompartment *wcompartment = wobj->compartment();
|
||||
|
||||
AutoDisableProxyCheck adpc(cx->runtime);
|
||||
|
||||
// If we're mapping to a different target (as opposed to just recomputing
|
||||
// for the same target), we must not have an existing wrapper for the new
|
||||
// target, otherwise this will break.
|
||||
|
Loading…
Reference in New Issue
Block a user