Bug 1181155 - Use a common root list definition between JSContext and JSRuntime; r=jonco

This commit is contained in:
Terrence Cole 2015-07-07 08:47:09 -07:00
parent a28184b2b3
commit 6ab6ea9a1e
6 changed files with 44 additions and 49 deletions

View File

@ -642,7 +642,7 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
template <typename CX>
void init(CX* cx) {
js::ThingRootKind kind = js::RootKind<T>::rootKind();
this->stack = &cx->thingGCRooters[kind];
this->stack = &cx->roots.stackRoots_[kind];
this->prev = *stack;
*stack = reinterpret_cast<Rooted<void*>*>(this);
}

View File

@ -81,7 +81,7 @@ template <class T, void MarkFunc(JSTracer* trc, T* ref, const char* name), class
static inline void
MarkExactStackRootList(JSTracer* trc, Source* s, const char* name)
{
Rooted<T>* rooter = s->template gcRooters<T>();
Rooted<T>* rooter = s->roots.template gcRooters<T>();
while (rooter) {
T* addr = rooter->address();
if (!IgnoreExactRoot(addr))
@ -282,7 +282,7 @@ AutoGCRooter::traceAll(JSTracer* trc)
AutoGCRooter::traceAllWrappers(JSTracer* trc)
{
for (ContextIter cx(trc->runtime()); !cx.done(); cx.next()) {
for (AutoGCRooter* gcr = cx->autoGCRooters; gcr; gcr = gcr->down) {
for (AutoGCRooter* gcr = cx->roots.autoGCRooters_; gcr; gcr = gcr->down) {
if (gcr->tag_ == WRAPVECTOR || gcr->tag_ == WRAPPER)
gcr->trace(trc);
}

View File

@ -6126,18 +6126,18 @@ JS_CallOnce(JSCallOnceType* once, JSInitCallback func)
}
AutoGCRooter::AutoGCRooter(JSContext* cx, ptrdiff_t tag)
: down(ContextFriendFields::get(cx)->autoGCRooters),
: down(ContextFriendFields::get(cx)->roots.autoGCRooters_),
tag_(tag),
stackTop(&ContextFriendFields::get(cx)->autoGCRooters)
stackTop(&ContextFriendFields::get(cx)->roots.autoGCRooters_)
{
MOZ_ASSERT(this != *stackTop);
*stackTop = this;
}
AutoGCRooter::AutoGCRooter(ContextFriendFields* cx, ptrdiff_t tag)
: down(cx->autoGCRooters),
: down(cx->roots.autoGCRooters_),
tag_(tag),
stackTop(&cx->autoGCRooters)
stackTop(&cx->roots.autoGCRooters_)
{
MOZ_ASSERT(this != *stackTop);
*stackTop = this;

View File

@ -156,7 +156,7 @@ js::DestroyContext(JSContext* cx, DestroyContextMode mode)
if (cx->outstandingRequests != 0)
MOZ_CRASH();
cx->checkNoGCRooters();
cx->roots.checkNoGCRooters();
if (mode != DCM_NEW_FAILED) {
if (JSContextCallback cxCallback = rt->cxCallback) {
@ -188,10 +188,10 @@ js::DestroyContext(JSContext* cx, DestroyContextMode mode)
}
void
ContextFriendFields::checkNoGCRooters() {
RootLists::checkNoGCRooters() {
#ifdef DEBUG
for (int i = 0; i < THING_ROOT_LIMIT; ++i)
MOZ_ASSERT(thingGCRooters[i] == nullptr);
MOZ_ASSERT(stackRoots_[i] == nullptr);
#endif
}

View File

@ -50,7 +50,6 @@ PerThreadDataFriendFields::PerThreadDataFriendFields()
for (int i=0; i<StackKindCount; i++)
nativeStackLimit[i] = UINTPTR_MAX;
#endif
PodArrayZero(thingGCRooters);
}
JS_FRIEND_API(void)

View File

@ -239,7 +239,7 @@ class JS_PUBLIC_API(AutoGCRooter)
/* T must be a context type */
template<typename T>
static void traceAllInContext(T* cx, JSTracer* trc) {
for (AutoGCRooter* gcr = cx->autoGCRooters; gcr; gcr = gcr->down)
for (AutoGCRooter* gcr = cx->roots.autoGCRooters_; gcr; gcr = gcr->down)
gcr->trace(trc);
}
@ -355,6 +355,32 @@ template <> struct RootKind<JSScript*> : SpecificRootKind<JSScript*, THING_ROOT_
template <> struct RootKind<jsid> : SpecificRootKind<jsid, THING_ROOT_ID> {};
template <> struct RootKind<JS::Value> : SpecificRootKind<JS::Value, THING_ROOT_VALUE> {};
// Abstracts JS rooting mechanisms so they can be shared between the JSContext
// and JSRuntime.
class RootLists
{
// Stack GC roots for stack-allocated GC heap pointers.
JS::Rooted<void*>* stackRoots_[THING_ROOT_LIMIT];
template <typename T> friend class JS::Rooted;
// Stack GC roots for stack-allocated AutoFooRooter classes.
JS::AutoGCRooter* autoGCRooters_;
friend class JS::AutoGCRooter;
public:
RootLists() : autoGCRooters_(nullptr) {
mozilla::PodArrayZero(stackRoots_);
}
template <class T>
inline JS::Rooted<T>* gcRooters() {
js::ThingRootKind kind = RootKind<T>::rootKind();
return reinterpret_cast<JS::Rooted<T>*>(stackRoots_[kind]);
}
void checkNoGCRooters();
};
struct ContextFriendFields
{
protected:
@ -367,11 +393,12 @@ struct ContextFriendFields
JS::Zone* zone_;
public:
/* Rooting structures. */
RootLists roots;
explicit ContextFriendFields(JSRuntime* rt)
: runtime_(rt), compartment_(nullptr), zone_(nullptr), autoGCRooters(nullptr)
{
mozilla::PodArrayZero(thingGCRooters);
}
: runtime_(rt), compartment_(nullptr), zone_(nullptr)
{}
static const ContextFriendFields* get(const JSContext* cx) {
return reinterpret_cast<const ContextFriendFields*>(cx);
@ -381,25 +408,6 @@ struct ContextFriendFields
return reinterpret_cast<ContextFriendFields*>(cx);
}
private:
/*
* Stack allocated GC roots for stack GC heap pointers, which may be
* overwritten if moved during a GC.
*/
JS::Rooted<void*>* thingGCRooters[THING_ROOT_LIMIT];
public:
template <class T>
inline JS::Rooted<T>* gcRooters() {
js::ThingRootKind kind = RootKind<T>::rootKind();
return reinterpret_cast<JS::Rooted<T>*>(thingGCRooters[kind]);
}
void checkNoGCRooters();
/* Stack of thread-stack-allocated GC roots. */
JS::AutoGCRooter* autoGCRooters;
friend JSRuntime* GetRuntime(const JSContext* cx);
friend JSCompartment* GetContextCompartment(const JSContext* cx);
friend JS::Zone* GetContextZone(const JSContext* cx);
@ -454,23 +462,11 @@ struct PerThreadDataFriendFields
};
public:
/* Rooting structures. */
RootLists roots;
PerThreadDataFriendFields();
private:
/*
* Stack allocated GC roots for stack GC heap pointers, which may be
* overwritten if moved during a GC.
*/
JS::Rooted<void*>* thingGCRooters[THING_ROOT_LIMIT];
public:
template <class T>
inline JS::Rooted<T>* gcRooters() {
js::ThingRootKind kind = RootKind<T>::rootKind();
return reinterpret_cast<JS::Rooted<T>*>(thingGCRooters[kind]);
}
/* Limit pointer for checking native stack consumption. */
uintptr_t nativeStackLimit[js::StackKindCount];