зеркало из https://github.com/mozilla/gecko-dev.git
Bug 850849 - Various fixes to WeakMap to support generational GC; r=billm
--HG-- extra : rebase_source : 14849035ade2868a189d2cfebd7f682df759ccb6
This commit is contained in:
Родитель
f9628f44fd
Коммит
6c2c636700
|
@ -280,6 +280,12 @@ Mark(JSTracer *trc, HeapPtr<ion::IonCode> *code, const char *name)
|
|||
MarkIonCode(trc, code, name);
|
||||
}
|
||||
|
||||
inline void
|
||||
Mark(JSTracer *trc, JSObject **objp, const char *name)
|
||||
{
|
||||
MarkObjectUnbarriered(trc, objp, name);
|
||||
}
|
||||
|
||||
bool
|
||||
IsCellMarked(Cell **thingp);
|
||||
|
||||
|
|
|
@ -2472,7 +2472,8 @@ typedef void
|
|||
|
||||
enum WeakMapTraceKind {
|
||||
DoNotTraceWeakMaps = 0,
|
||||
TraceWeakMapValues = 1
|
||||
TraceWeakMapValues = 1,
|
||||
TraceWeakMapKeysValues = 2
|
||||
};
|
||||
|
||||
struct JSTracer {
|
||||
|
|
|
@ -50,7 +50,7 @@ class WeakMapBase {
|
|||
// many keys as possible have been marked, and add ourselves to the list of
|
||||
// known-live WeakMaps to be scanned in the iterative marking phase, by
|
||||
// markAllIteratively.
|
||||
JS_ASSERT(!tracer->eagerlyTraceWeakMaps);
|
||||
JS_ASSERT(tracer->eagerlyTraceWeakMaps == DoNotTraceWeakMaps);
|
||||
|
||||
// Add ourselves to the list if we are not already in the list. We can already
|
||||
// be in the list if the weak map is marked more than once due delayed marking.
|
||||
|
@ -63,8 +63,12 @@ class WeakMapBase {
|
|||
// nicely as needed by the true ephemeral marking algorithm --- custom tracers
|
||||
// such as the cycle collector must use their own means for cycle detection.
|
||||
// So here we do a conservative approximation: pretend all keys are live.
|
||||
if (tracer->eagerlyTraceWeakMaps)
|
||||
nonMarkingTrace(tracer);
|
||||
if (tracer->eagerlyTraceWeakMaps == DoNotTraceWeakMaps)
|
||||
return;
|
||||
|
||||
nonMarkingTraceValues(tracer);
|
||||
if (tracer->eagerlyTraceWeakMaps == TraceWeakMapKeysValues)
|
||||
nonMarkingTraceKeys(tracer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,7 +104,8 @@ class WeakMapBase {
|
|||
protected:
|
||||
// Instance member functions called by the above. Instantiations of WeakMap override
|
||||
// these with definitions appropriate for their Key and Value types.
|
||||
virtual void nonMarkingTrace(JSTracer *tracer) = 0;
|
||||
virtual void nonMarkingTraceKeys(JSTracer *tracer) = 0;
|
||||
virtual void nonMarkingTraceValues(JSTracer *tracer) = 0;
|
||||
virtual bool markIteratively(JSTracer *tracer) = 0;
|
||||
virtual void sweep() = 0;
|
||||
virtual void traceMappings(WeakMapTracer *tracer) = 0;
|
||||
|
@ -141,7 +146,16 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, publ
|
|||
return true;
|
||||
}
|
||||
|
||||
void nonMarkingTrace(JSTracer *trc) {
|
||||
void nonMarkingTraceKeys(JSTracer *trc) {
|
||||
for (Enum e(*this); !e.empty(); e.popFront()) {
|
||||
Key key(e.front().key);
|
||||
gc::Mark(trc, &key, "WeakMap Key");
|
||||
if (key != e.front().key)
|
||||
e.rekeyFront(key, key);
|
||||
}
|
||||
}
|
||||
|
||||
void nonMarkingTraceValues(JSTracer *trc) {
|
||||
for (Range r = Base::all(); !r.empty(); r.popFront())
|
||||
gc::Mark(trc, &r.front().value, "WeakMap entry");
|
||||
}
|
||||
|
@ -190,6 +204,8 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, publ
|
|||
Key k(e.front().key);
|
||||
if (gc::IsAboutToBeFinalized(&k))
|
||||
e.removeFront();
|
||||
else if (k != e.front().key)
|
||||
e.rekeyFront(k, k);
|
||||
}
|
||||
/*
|
||||
* Once we've swept, all remaining edges should stay within the
|
||||
|
|
Загрузка…
Ссылка в новой задаче