Bug 1266887 - Store Rooted heads on the Zone; r=sfink

--HG--
extra : rebase_source : 30686e746021d123947ade0ad51b10f1b3d32ee9
This commit is contained in:
Terrence Cole 2016-04-25 12:32:36 -07:00
parent d03c6f2984
commit 4bf8df3a44
5 changed files with 47 additions and 25 deletions

View File

@ -114,13 +114,21 @@ struct Zone
JSTracer* const barrierTracer_; // A pointer to the JSRuntime's |gcMarker|.
public:
// Stack GC roots for Rooted GC pointers.
js::RootedListHeads stackRoots_;
template <typename T> friend class JS::Rooted;
bool needsIncrementalBarrier_;
Zone(JSRuntime* runtime, JSTracer* barrierTracerArg)
: runtime_(runtime),
barrierTracer_(barrierTracerArg),
needsIncrementalBarrier_(false)
{}
{
for (auto& stackRootPtr : stackRoots_) {
stackRootPtr = nullptr;
}
}
bool needsIncrementalBarrier() const {
return needsIncrementalBarrier_;
@ -143,7 +151,7 @@ struct Zone
return runtime_;
}
static JS::shadow::Zone* asShadowZone(JS::Zone* zone) {
static MOZ_ALWAYS_INLINE JS::shadow::Zone* asShadowZone(JS::Zone* zone) {
return reinterpret_cast<JS::shadow::Zone*>(zone);
}
};

View File

@ -634,18 +634,25 @@ namespace JS {
template <typename T>
class MOZ_RAII Rooted : public js::RootedBase<T>
{
/* Note: CX is a subclass of either ContextFriendFields or PerThreadDataFriendFields. */
void registerWithRootLists(js::RootLists& roots) {
this->stack = &roots.stackRoots_[JS::MapTypeToRootKind<T>::kind];
inline void registerWithRootLists(js::RootedListHeads& roots) {
this->stack = &roots[JS::MapTypeToRootKind<T>::kind];
this->prev = *stack;
*stack = reinterpret_cast<Rooted<void*>*>(this);
}
js::RootLists& rootLists(js::ContextFriendFields* cx) { return cx->roots; }
js::RootLists& rootLists(JSContext* cx) { return js::ContextFriendFields::get(cx)->roots; }
js::RootLists& rootLists(js::PerThreadDataFriendFields* pt) { return pt->roots; }
js::RootLists& rootLists(JSRuntime* rt) {
return js::PerThreadDataFriendFields::getMainThread(rt)->roots;
inline js::RootedListHeads& rootLists(js::ContextFriendFields* cx) {
return rootLists(reinterpret_cast<JSContext*>(cx));
}
inline js::RootedListHeads& rootLists(JSContext* cx) {
if (JS::Zone* zone = js::GetContextZone(cx))
return JS::shadow::Zone::asShadowZone(zone)->stackRoots_;
return rootLists(js::GetRuntime(cx));
}
inline js::RootedListHeads& rootLists(js::PerThreadDataFriendFields* pt) {
return pt->roots.stackRoots_;
}
inline js::RootedListHeads& rootLists(JSRuntime* rt) {
return js::PerThreadDataFriendFields::getMainThread(rt)->roots.stackRoots_;
}
public:

View File

@ -65,25 +65,31 @@ MarkExactStackRootList(JSTracer* trc, JS::Rooted<void*>* rooter, const char* nam
}
}
static inline void
TraceStackRoots(JSTracer* trc, RootedListHeads& stackRoots)
{
#define MARK_ROOTS(name, type, _) \
MarkExactStackRootList<type*>(trc, stackRoots[JS::RootKind::name], "exact-" #name);
JS_FOR_EACH_TRACEKIND(MARK_ROOTS)
#undef MARK_ROOTS
MarkExactStackRootList<jsid>(trc, stackRoots[JS::RootKind::Id], "exact-id");
MarkExactStackRootList<Value>(trc, stackRoots[JS::RootKind::Value], "exact-value");
MarkExactStackRootList<ConcreteTraceable,
js::DispatchWrapper<ConcreteTraceable>::TraceWrapped>(
trc, stackRoots[JS::RootKind::Traceable], "Traceable");
}
void
js::RootLists::traceStackRoots(JSTracer* trc)
{
#define MARK_ROOTS(name, type, _) \
MarkExactStackRootList<type*>(trc, stackRoots_[JS::RootKind::name], "exact-" #name);
JS_FOR_EACH_TRACEKIND(MARK_ROOTS)
#undef MARK_ROOTS
MarkExactStackRootList<jsid>(trc, stackRoots_[JS::RootKind::Id], "exact-id");
MarkExactStackRootList<Value>(trc, stackRoots_[JS::RootKind::Value], "exact-value");
MarkExactStackRootList<ConcreteTraceable,
js::DispatchWrapper<ConcreteTraceable>::TraceWrapped>(
trc, stackRoots_[JS::RootKind::Traceable], "Traceable");
TraceStackRoots(trc, stackRoots_);
}
static void
MarkExactStackRoots(JSRuntime* rt, JSTracer* trc)
{
for (ContextIter cx(rt); !cx.done(); cx.next())
cx->roots.traceStackRoots(trc);
for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next())
TraceStackRoots(trc, zone->stackRoots_);
rt->mainThread.roots.traceStackRoots(trc);
}
@ -113,8 +119,6 @@ JS_FOR_EACH_TRACEKIND(MARK_ROOTS)
static void
MarkPersistentRooted(JSRuntime* rt, JSTracer* trc)
{
for (ContextIter cx(rt); !cx.done(); cx.next())
cx->roots.tracePersistentRoots(trc);
rt->mainThread.roots.tracePersistentRoots(trc);
}

View File

@ -265,12 +265,15 @@ enum StackKind
StackKindCount
};
using RootedListHeads = mozilla::EnumeratedArray<JS::RootKind, JS::RootKind::Limit,
JS::Rooted<void*>*>;
// Abstracts JS rooting mechanisms so they can be shared between the JSContext
// and JSRuntime.
class RootLists
{
// Stack GC roots for Rooted GC heap pointers.
mozilla::EnumeratedArray<JS::RootKind, JS::RootKind::Limit, JS::Rooted<void*>*> stackRoots_;
RootedListHeads stackRoots_;
template <typename T> friend class JS::Rooted;
// Stack GC roots for AutoFooRooter classes.

View File

@ -37,7 +37,7 @@ Symbol::newInternal(ExclusiveContext* cx, JS::SymbolCode code, JSAtom* descripti
Symbol*
Symbol::new_(ExclusiveContext* cx, JS::SymbolCode code, JSString* description)
{
RootedAtom atom(cx);
JSAtom* atom = nullptr;
if (description) {
atom = AtomizeString(cx, description);
if (!atom)