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 5ba5649de9
commit eddc75fd8f
2 changed files with 43 additions and 27 deletions

View File

@ -138,6 +138,7 @@ struct NullPtr
namespace gc { namespace gc {
struct Cell; struct Cell;
struct PersistentRootedMarker;
} /* namespace gc */ } /* namespace gc */
} /* namespace js */ } /* namespace js */
@ -1098,7 +1099,6 @@ MutableHandle<T>::MutableHandle(PersistentRooted<T> *root)
ptr = root->address(); ptr = root->address();
} }
/* /*
* A copyable, assignable global GC root type with arbitrary lifetime, an * A copyable, assignable global GC root type with arbitrary lifetime, an
* infallible constructor, and automatic unrooting on destruction. * infallible constructor, and automatic unrooting on destruction.
@ -1132,9 +1132,10 @@ MutableHandle<T>::MutableHandle(PersistentRooted<T> *root)
* marked when the object itself is marked. * marked when the object itself is marked.
*/ */
template<typename T> template<typename T>
class PersistentRooted : public mozilla::LinkedListElement<PersistentRooted<T> > { class PersistentRooted : private mozilla::LinkedListElement<PersistentRooted<T> > {
typedef mozilla::LinkedList<PersistentRooted> List; friend class mozilla::LinkedList<PersistentRooted>;
typedef mozilla::LinkedListElement<PersistentRooted> Element; friend class mozilla::LinkedListElement<PersistentRooted>;
friend class js::gc::PersistentRootedMarker;
void registerWithRuntime(JSRuntime *rt) { void registerWithRuntime(JSRuntime *rt) {
JS::shadow::Runtime *srt = JS::shadow::Runtime::asShadowRuntime(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. namespace js {
template<typename Referent> namespace gc {
static void struct PersistentRootedMarker
MarkPersistentRootedChain(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(); template<typename Referent>
r != nullptr; static void
r = r->getNext()) 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); marker(trc, r->address(), name);
} }
};
}
} }
void void
@ -640,20 +654,21 @@ js::gc::MarkPersistentRootedChains(JSTracer *trc)
{ {
JSRuntime *rt = trc->runtime; JSRuntime *rt = trc->runtime;
MarkPersistentRootedChain(trc, rt->functionPersistentRooteds, &MarkObjectRoot, // Mark the PersistentRooted chains of types that may be null.
"PersistentRooted<JSFunction *>"); PersistentRootedMarker::markChainIfNotNull(trc, rt->functionPersistentRooteds, &MarkObjectRoot,
MarkPersistentRootedChain(trc, rt->objectPersistentRooteds, &MarkObjectRoot, "PersistentRooted<JSFunction *>");
"PersistentRooted<JSObject *>"); PersistentRootedMarker::markChainIfNotNull(trc, rt->objectPersistentRooteds, &MarkObjectRoot,
MarkPersistentRootedChain(trc, rt->scriptPersistentRooteds, &MarkScriptRoot, "PersistentRooted<JSObject *>");
"PersistentRooted<JSScript *>"); PersistentRootedMarker::markChainIfNotNull(trc, rt->scriptPersistentRooteds, &MarkScriptRoot,
MarkPersistentRootedChain(trc, rt->stringPersistentRooteds, &MarkStringRoot, "PersistentRooted<JSScript *>");
"PersistentRooted<JSString *>"); PersistentRootedMarker::markChainIfNotNull(trc, rt->stringPersistentRooteds, &MarkStringRoot,
"PersistentRooted<JSString *>");
// Mark the PersistentRooted chains of types that are never null. // Mark the PersistentRooted chains of types that are never null.
for (JS::PersistentRootedId *r = rt->idPersistentRooteds.getFirst(); r != nullptr; r = r->getNext()) PersistentRootedMarker::markChain(trc, rt->idPersistentRooteds, &MarkIdRoot,
MarkIdRoot(trc, r->address(), "PersistentRooted<jsid>"); "PersistentRooted<jsid>");
for (JS::PersistentRootedValue *r = rt->valuePersistentRooteds.getFirst(); r != nullptr; r = r->getNext()) PersistentRootedMarker::markChain(trc, rt->valuePersistentRooteds, &MarkValueRoot,
MarkValueRoot(trc, r->address(), "PersistentRooted<Value>"); "PersistentRooted<Value>");
} }
void void