From eddc75fd8f35b90c616db3d074405353aa9a4a0d Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 22 Jan 2014 11:28:06 +0000 Subject: [PATCH] Bug 961077 - Make PersistentRooted use private inheritance when deriving from LinkedListElement r=sfink --- js/public/RootingAPI.h | 9 +++--- js/src/gc/RootMarking.cpp | 61 ++++++++++++++++++++++++--------------- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index 9f448d3018c2..2df52442a5f2 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -138,6 +138,7 @@ struct NullPtr namespace gc { struct Cell; +struct PersistentRootedMarker; } /* namespace gc */ } /* namespace js */ @@ -1098,7 +1099,6 @@ MutableHandle::MutableHandle(PersistentRooted *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::MutableHandle(PersistentRooted *root) * marked when the object itself is marked. */ template -class PersistentRooted : public mozilla::LinkedListElement > { - typedef mozilla::LinkedList List; - typedef mozilla::LinkedListElement Element; +class PersistentRooted : private mozilla::LinkedListElement > { + friend class mozilla::LinkedList; + friend class mozilla::LinkedListElement; + friend class js::gc::PersistentRootedMarker; void registerWithRuntime(JSRuntime *rt) { JS::shadow::Runtime *srt = JS::shadow::Runtime::asShadowRuntime(rt); diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index cfb039c332a5..a8016d44ed7e 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -618,21 +618,35 @@ JSPropertyDescriptor::trace(JSTracer *trc) } } -// Mark a chain of PersistentRooted pointers that might be null. -template -static void -MarkPersistentRootedChain(JSTracer *trc, - mozilla::LinkedList > &list, - void (*marker)(JSTracer *trc, Referent **ref, const char *name), - const char *name) +namespace js { +namespace gc { +struct PersistentRootedMarker { - for (PersistentRooted *r = list.getFirst(); - r != nullptr; - r = r->getNext()) + template + static void + markChainIfNotNull(JSTracer *trc, + mozilla::LinkedList > &list, + void (*marker)(JSTracer *trc, Referent **ref, const char *name), + const char *name) { - if (r->get()) + for (PersistentRooted *r = list.getFirst(); r; r = r->getNext()) { + if (r->get()) + marker(trc, r->address(), name); + } + } + + template + static void + markChain(JSTracer *trc, + mozilla::LinkedList > &list, + void (*marker)(JSTracer *trc, Referent *ref, const char *name), + const char *name) + { + for (PersistentRooted *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"); - MarkPersistentRootedChain(trc, rt->objectPersistentRooteds, &MarkObjectRoot, - "PersistentRooted"); - MarkPersistentRootedChain(trc, rt->scriptPersistentRooteds, &MarkScriptRoot, - "PersistentRooted"); - MarkPersistentRootedChain(trc, rt->stringPersistentRooteds, &MarkStringRoot, - "PersistentRooted"); + // Mark the PersistentRooted chains of types that may be null. + PersistentRootedMarker::markChainIfNotNull(trc, rt->functionPersistentRooteds, &MarkObjectRoot, + "PersistentRooted"); + PersistentRootedMarker::markChainIfNotNull(trc, rt->objectPersistentRooteds, &MarkObjectRoot, + "PersistentRooted"); + PersistentRootedMarker::markChainIfNotNull(trc, rt->scriptPersistentRooteds, &MarkScriptRoot, + "PersistentRooted"); + PersistentRootedMarker::markChainIfNotNull(trc, rt->stringPersistentRooteds, &MarkStringRoot, + "PersistentRooted"); // 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"); - for (JS::PersistentRootedValue *r = rt->valuePersistentRooteds.getFirst(); r != nullptr; r = r->getNext()) - MarkValueRoot(trc, r->address(), "PersistentRooted"); + PersistentRootedMarker::markChain(trc, rt->idPersistentRooteds, &MarkIdRoot, + "PersistentRooted"); + PersistentRootedMarker::markChain(trc, rt->valuePersistentRooteds, &MarkValueRoot, + "PersistentRooted"); } void