Bug 798678 - Add weakmap key preservation support to cycle collector (r=mccr8)

This commit is contained in:
Bill McCloskey 2012-10-17 18:22:46 -07:00
parent 9748750db4
commit 0a9fd297da
6 changed files with 37 additions and 11 deletions

View File

@ -6358,7 +6358,7 @@ public:
{
}
NS_IMETHOD_(void) NoteWeakMapping(void* map, void* key, void* val)
NS_IMETHOD_(void) NoteWeakMapping(void* map, void* key, void* kdelegate, void* val)
{
}

View File

@ -532,6 +532,14 @@ js::VisitGrayWrapperTargets(JSCompartment *comp, GCThingCallback *callback, void
}
}
JS_FRIEND_API(JSObject *)
js::GetWeakmapKeyDelegate(JSObject *key)
{
if (JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp)
return op(key);
return NULL;
}
JS_FRIEND_API(void)
JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback)
{

View File

@ -265,6 +265,9 @@ typedef void
extern JS_FRIEND_API(void)
VisitGrayWrapperTargets(JSCompartment *comp, GCThingCallback *callback, void *closure);
extern JS_FRIEND_API(JSObject *)
GetWeakmapKeyDelegate(JSObject *key);
/*
* Shadow declarations of JS internal structures, for access by inline access
* functions below. Do not use these structures in any other way. When adding

View File

@ -398,6 +398,7 @@ struct NoteWeakMapChildrenTracer : public JSTracer
nsCycleCollectionTraversalCallback &mCb;
JSObject *mMap;
void *mKey;
void *mKeyDelegate;
};
static void
@ -412,7 +413,7 @@ TraceWeakMappingChild(JSTracer *trc, void **thingp, JSGCTraceKind kind)
if (!xpc_IsGrayGCThing(thing) && !tracer->mCb.WantAllTraces())
return;
if (AddToCCKind(kind)) {
tracer->mCb.NoteWeakMapping(tracer->mMap, tracer->mKey, thing);
tracer->mCb.NoteWeakMapping(tracer->mMap, tracer->mKey, tracer->mKeyDelegate, thing);
} else {
JS_TraceChildren(trc, thing, kind);
}
@ -455,11 +456,16 @@ TraceWeakMapping(js::WeakMapTracer *trc, JSObject *m,
if (!AddToCCKind(kkind))
k = nullptr;
JSObject *kdelegate = NULL;
if (kkind == JSTRACE_OBJECT)
kdelegate = js::GetWeakmapKeyDelegate((JSObject *)k);
if (AddToCCKind(vkind)) {
tracer->mCb.NoteWeakMapping(m, k, v);
tracer->mCb.NoteWeakMapping(m, k, kdelegate, v);
} else {
tracer->mChildTracer.mMap = m;
tracer->mChildTracer.mKey = k;
tracer->mChildTracer.mKeyDelegate = kdelegate;
JS_TraceChildren(&tracer->mChildTracer, v, vkind);
}
}

View File

@ -669,6 +669,7 @@ struct WeakMapping
// map and key will be null if the corresponding objects are GC marked
PtrInfo *mMap;
PtrInfo *mKey;
PtrInfo *mKeyDelegate;
PtrInfo *mVal;
};
@ -1678,7 +1679,7 @@ public:
nsCycleCollectionParticipant *participant);
NS_IMETHOD_(void) NoteNextEdgeName(const char* name);
NS_IMETHOD_(void) NoteWeakMapping(void *map, void *key, void *val);
NS_IMETHOD_(void) NoteWeakMapping(void *map, void *key, void *kdelegate, void *val);
private:
NS_IMETHOD_(void) NoteRoot(void *root,
@ -1968,7 +1969,7 @@ GCGraphBuilder::AddWeakMapNode(void *node)
}
NS_IMETHODIMP_(void)
GCGraphBuilder::NoteWeakMapping(void *map, void *key, void *val)
GCGraphBuilder::NoteWeakMapping(void *map, void *key, void *kdelegate, void *val)
{
PtrInfo *valNode = AddWeakMapNode(val);
@ -1978,6 +1979,7 @@ GCGraphBuilder::NoteWeakMapping(void *map, void *key, void *val)
WeakMapping *mapping = mWeakMaps.AppendElement();
mapping->mMap = map ? AddWeakMapNode(map) : nullptr;
mapping->mKey = key ? AddWeakMapNode(key) : nullptr;
mapping->mKeyDelegate = kdelegate ? AddWeakMapNode(kdelegate) : mapping->mKey;
mapping->mVal = valNode;
}
@ -2021,7 +2023,7 @@ public:
NS_IMETHOD_(void) NoteNativeRoot(void *root,
nsCycleCollectionParticipant *helper) {}
NS_IMETHOD_(void) NoteNextEdgeName(const char* name) {}
NS_IMETHOD_(void) NoteWeakMapping(void *map, void *key, void *val) {}
NS_IMETHOD_(void) NoteWeakMapping(void *map, void *key, void *kdelegate, void *val) {}
bool MayHaveChild() {
return mMayHaveChild;
}
@ -2206,15 +2208,22 @@ nsCycleCollector::ScanWeakMaps()
// If mMap or mKey are null, the original object was marked black.
uint32_t mColor = wm->mMap ? wm->mMap->mColor : black;
uint32_t kColor = wm->mKey ? wm->mKey->mColor : black;
uint32_t kdColor = wm->mKeyDelegate ? wm->mKeyDelegate->mColor : black;
PtrInfo *v = wm->mVal;
// All non-null weak mapping maps, keys and values are
// roots (in the sense of WalkFromRoots) in the cycle
// collector graph, and thus should have been colored
// either black or white in ScanRoots().
NS_ASSERTION(mColor != grey, "Uncolored weak map");
NS_ASSERTION(kColor != grey, "Uncolored weak map key");
NS_ASSERTION(v->mColor != grey, "Uncolored weak map value");
MOZ_ASSERT(mColor != grey, "Uncolored weak map");
MOZ_ASSERT(kColor != grey, "Uncolored weak map key");
MOZ_ASSERT(kdColor != grey, "Uncolored weak map key delegate");
MOZ_ASSERT(v->mColor != grey, "Uncolored weak map value");
if (mColor == black && kColor != black && kdColor == black) {
GraphWalker<ScanBlackVisitor>(ScanBlackVisitor(mWhiteNodeCount)).Walk(wm->mKey);
anyChanged = true;
}
if (mColor == black && kColor == black && v->mColor != black) {
GraphWalker<ScanBlackVisitor>(ScanBlackVisitor(mWhiteNodeCount)).Walk(v);
@ -2471,7 +2480,7 @@ public:
NS_IMETHOD_(void) NoteNativeChild(void *child,
nsCycleCollectionParticipant *participant) {}
NS_IMETHOD_(void) NoteNextEdgeName(const char* name) {}
NS_IMETHOD_(void) NoteWeakMapping(void *map, void *key, void *val) {}
NS_IMETHOD_(void) NoteWeakMapping(void *map, void *key, void *kdelegate, void *val) {}
};
char *Suppressor::sSuppressionList = nullptr;

View File

@ -84,7 +84,7 @@ public:
// flags.
NS_IMETHOD_(void) NoteNextEdgeName(const char* name) = 0;
NS_IMETHOD_(void) NoteWeakMapping(void *map, void *key, void *val) = 0;
NS_IMETHOD_(void) NoteWeakMapping(void *map, void *key, void *kdelegate, void *val) = 0;
enum {
// Values for flags: