diff --git a/js/src/gc/Verifier.cpp b/js/src/gc/Verifier.cpp index eef8fbd03c75..7938f520d905 100644 --- a/js/src/gc/Verifier.cpp +++ b/js/src/gc/Verifier.cpp @@ -28,24 +28,30 @@ using namespace js::gc; using namespace mozilla; #if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) +# if JS_STACK_GROWTH_DIRECTION > 0 +# error "Root analysis is only supported on a descending stack." +# endif template bool -CheckNonAddressThing(uintptr_t *w, T *t) +CheckNonAddressThing(uintptr_t *w, Rooted *rootp) { - return w >= (uintptr_t*)t && w < (uintptr_t*)(t + 1); + return w >= (uintptr_t*)rootp->address() && w < (uintptr_t*)(rootp->address() + 1); } JS_ALWAYS_INLINE bool -CheckStackRootThing(uintptr_t *w, void *address, ThingRootKind kind) +CheckStackRootThing(uintptr_t *w, Rooted *rootp, ThingRootKind kind) { if (kind == THING_ROOT_BINDINGS) - return CheckNonAddressThing(w, static_cast(address)); + return CheckNonAddressThing(w, reinterpret_cast *>(rootp)); if (kind == THING_ROOT_PROPERTY_DESCRIPTOR) - return CheckNonAddressThing(w, static_cast(address)); + return CheckNonAddressThing(w, reinterpret_cast *>(rootp)); - return address == static_cast(w); + if (kind == THING_ROOT_VALUE) + return CheckNonAddressThing(w, reinterpret_cast *>(rootp)); + + return rootp->address() == static_cast(w); } struct Rooter { @@ -76,7 +82,7 @@ CheckStackRoot(JSRuntime *rt, uintptr_t *w, Rooter *begin, Rooter *end) */ for (Rooter *p = begin; p != end; p++) { - if (CheckStackRootThing(w, p->rooter->address(), p->kind)) + if (CheckStackRootThing(w, p->rooter, p->kind)) return; } @@ -122,7 +128,7 @@ CheckStackRootsRangeAndSkipIon(JSRuntime *rt, uintptr_t *begin, uintptr_t *end, */ uintptr_t *i = begin; -#if JS_STACK_GROWTH_DIRECTION < 0 && defined(JS_ION) +#if defined(JS_ION) for (ion::IonActivationIterator ion(rt); ion.more(); ++ion) { uintptr_t *ionMin, *ionEnd; ion.ionStackRange(ionMin, ionEnd); @@ -177,15 +183,15 @@ SuppressCheckRoots(Vector &rooters) qsort(rooters.begin(), rooters.length(), sizeof(Rooter), CompareRooters); // Forward-declare a variable so its address can be used to mark the - // current top of the stack + // current top of the stack. unsigned int pos; - // Compute the hash of the current stack + // Compute the hash of the current stack. uint32_t hash = HashGeneric(&pos); for (unsigned int i = 0; i < Min(StackCheckDepth, rooters.length()); i++) hash = AddToHash(hash, rooters[rooters.length() - i - 1].rooter); - // Scan through the remembered stacks to find the current stack + // Scan through the remembered stacks to find the current stack. for (pos = 0; pos < numMemories; pos++) { if (stacks[pos] == hash) { // Skip this check. Technically, it is incorrect to not update the @@ -195,7 +201,7 @@ SuppressCheckRoots(Vector &rooters) } } - // Replace the oldest remembered stack with our current stack + // Replace the oldest remembered stack with our current stack. stacks[oldestMemory] = hash; oldestMemory = (oldestMemory + 1) % NumStackMemories; if (numMemories < NumStackMemories) @@ -247,13 +253,9 @@ JS::CheckStackRoots(JSContext *cx) JS_ASSERT(cgcd->hasStackToScan()); uintptr_t *stackMin, *stackEnd; -#if JS_STACK_GROWTH_DIRECTION > 0 - stackMin = rt->nativeStackBase; - stackEnd = cgcd->nativeStackTop; -#else stackMin = cgcd->nativeStackTop + 1; stackEnd = reinterpret_cast(rt->nativeStackBase); -#endif + JS_ASSERT(stackMin <= stackEnd); // Gather up all of the rooters Vector rooters; @@ -275,12 +277,7 @@ JS::CheckStackRoots(JSContext *cx) for (Rooter *p = rooters.begin(); p != rooters.end(); p++) { if (p->rooter->scanned) { uintptr_t *addr = reinterpret_cast(p->rooter); -#if JS_STACK_GROWTH_DIRECTION < 0 - if (stackEnd > addr) -#else - if (stackEnd < addr) -#endif - { + if (stackEnd > addr) { stackEnd = addr; firstScanned = p->rooter; } @@ -292,25 +289,19 @@ JS::CheckStackRoots(JSContext *cx) Rooter *firstToScan = rooters.begin(); if (firstScanned) { for (Rooter *p = rooters.begin(); p != rooters.end(); p++) { -#if JS_STACK_GROWTH_DIRECTION < 0 - if (p->rooter >= firstScanned) -#else - if (p->rooter <= firstScanned) -#endif - { + if (p->rooter >= firstScanned) { Swap(*firstToScan, *p); ++firstToScan; } } } - JS_ASSERT(stackMin <= stackEnd); CheckStackRootsRangeAndSkipIon(rt, stackMin, stackEnd, firstToScan, rooters.end()); CheckStackRootsRange(rt, cgcd->registerSnapshot.words, ArrayEnd(cgcd->registerSnapshot.words), firstToScan, rooters.end()); - // Mark all rooters as scanned + // Mark all rooters as scanned. for (Rooter *p = rooters.begin(); p != rooters.end(); p++) p->rooter->scanned = true; }