Bug 850849 - Various fixes to WeakMap to support generational GC; r=billm

--HG--
extra : rebase_source : 14849035ade2868a189d2cfebd7f682df759ccb6
This commit is contained in:
Terrence Cole 2013-03-13 15:12:24 -07:00
parent f9628f44fd
commit 6c2c636700
3 changed files with 29 additions and 6 deletions

View File

@ -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);

View File

@ -2472,7 +2472,8 @@ typedef void
enum WeakMapTraceKind {
DoNotTraceWeakMaps = 0,
TraceWeakMapValues = 1
TraceWeakMapValues = 1,
TraceWeakMapKeysValues = 2
};
struct JSTracer {

View File

@ -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