Bug 961077 - Make PersistentRooted use private inheritance when deriving from LinkedListElement r=sfink

This commit is contained in:
Jon Coppeard 2014-01-22 11:28:06 +00:00
parent a4b59f36d6
commit c6790d8bcb
2 changed files with 43 additions and 27 deletions

View File

@ -138,6 +138,7 @@ struct NullPtr
namespace gc {
struct Cell;
struct PersistentRootedMarker;
} /* namespace gc */
} /* namespace js */
@ -1098,7 +1099,6 @@ MutableHandle<T>::MutableHandle(PersistentRooted<T> *root)
ptr = root->address();
}
/*
* A copyable, assignable global GC root type with arbitrary lifetime, an
* infallible constructor, and automatic unrooting on destruction.
@ -1132,9 +1132,10 @@ MutableHandle<T>::MutableHandle(PersistentRooted<T> *root)
* marked when the object itself is marked.
*/
template<typename T>
class PersistentRooted : public mozilla::LinkedListElement<PersistentRooted<T> > {
typedef mozilla::LinkedList<PersistentRooted> List;
typedef mozilla::LinkedListElement<PersistentRooted> Element;
class PersistentRooted : private mozilla::LinkedListElement<PersistentRooted<T> > {
friend class mozilla::LinkedList<PersistentRooted>;
friend class mozilla::LinkedListElement<PersistentRooted>;
friend class js::gc::PersistentRootedMarker;
void registerWithRuntime(JSRuntime *rt) {
JS::shadow::Runtime *srt = JS::shadow::Runtime::asShadowRuntime(rt);

View File

@ -618,21 +618,35 @@ JSPropertyDescriptor::trace(JSTracer *trc)
}
}
// Mark a chain of PersistentRooted pointers that might be null.
template<typename Referent>
static void
MarkPersistentRootedChain(JSTracer *trc,
mozilla::LinkedList<PersistentRooted<Referent *> > &list,
void (*marker)(JSTracer *trc, Referent **ref, const char *name),
const char *name)
namespace js {
namespace gc {
struct PersistentRootedMarker
{
for (PersistentRooted<Referent *> *r = list.getFirst();
r != nullptr;
r = r->getNext())
template<typename Referent>
static void
markChainIfNotNull(JSTracer *trc,
mozilla::LinkedList<PersistentRooted<Referent *> > &list,
void (*marker)(JSTracer *trc, Referent **ref, const char *name),
const char *name)
{
if (r->get())
for (PersistentRooted<Referent *> *r = list.getFirst(); r; r = r->getNext()) {
if (r->get())
marker(trc, r->address(), name);
}
}
template<typename Referent>
static void
markChain(JSTracer *trc,
mozilla::LinkedList<PersistentRooted<Referent> > &list,
void (*marker)(JSTracer *trc, Referent *ref, const char *name),
const char *name)
{
for (PersistentRooted<Referent> *r = list.getFirst(); r; r = r->getNext())
marker(trc, r->address(), name);
}
};
}
}
void
@ -640,20 +654,21 @@ js::gc::MarkPersistentRootedChains(JSTracer *trc)
{
JSRuntime *rt = trc->runtime;
MarkPersistentRootedChain(trc, rt->functionPersistentRooteds, &MarkObjectRoot,
"PersistentRooted<JSFunction *>");
MarkPersistentRootedChain(trc, rt->objectPersistentRooteds, &MarkObjectRoot,
"PersistentRooted<JSObject *>");
MarkPersistentRootedChain(trc, rt->scriptPersistentRooteds, &MarkScriptRoot,
"PersistentRooted<JSScript *>");
MarkPersistentRootedChain(trc, rt->stringPersistentRooteds, &MarkStringRoot,
"PersistentRooted<JSString *>");
// Mark the PersistentRooted chains of types that may be null.
PersistentRootedMarker::markChainIfNotNull(trc, rt->functionPersistentRooteds, &MarkObjectRoot,
"PersistentRooted<JSFunction *>");
PersistentRootedMarker::markChainIfNotNull(trc, rt->objectPersistentRooteds, &MarkObjectRoot,
"PersistentRooted<JSObject *>");
PersistentRootedMarker::markChainIfNotNull(trc, rt->scriptPersistentRooteds, &MarkScriptRoot,
"PersistentRooted<JSScript *>");
PersistentRootedMarker::markChainIfNotNull(trc, rt->stringPersistentRooteds, &MarkStringRoot,
"PersistentRooted<JSString *>");
// Mark the PersistentRooted chains of types that are never null.
for (JS::PersistentRootedId *r = rt->idPersistentRooteds.getFirst(); r != nullptr; r = r->getNext())
MarkIdRoot(trc, r->address(), "PersistentRooted<jsid>");
for (JS::PersistentRootedValue *r = rt->valuePersistentRooteds.getFirst(); r != nullptr; r = r->getNext())
MarkValueRoot(trc, r->address(), "PersistentRooted<Value>");
PersistentRootedMarker::markChain(trc, rt->idPersistentRooteds, &MarkIdRoot,
"PersistentRooted<jsid>");
PersistentRootedMarker::markChain(trc, rt->valuePersistentRooteds, &MarkValueRoot,
"PersistentRooted<Value>");
}
void