diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index bc8a438ccd48..200f6a99676a 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -152,11 +152,6 @@ template class PersistentRooted; /* This is exposing internal state of the GC for inlining purposes. */ JS_FRIEND_API(bool) isGCEnabled(); -#if defined(JS_DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) -extern void -CheckStackRoots(JSContext *cx); -#endif - /* * JS::NullPtr acts like a nullptr pointer in contexts that require a Handle. * @@ -819,15 +814,6 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase Rooted **stack, *prev; #endif -#if defined(JS_DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) - /* Has the rooting analysis ever scanned this Rooted's stack location? */ - friend void JS::CheckStackRoots(JSContext*); -#endif - -#ifdef JSGC_ROOT_ANALYSIS - bool scanned; -#endif - /* * |ptr| must be the last field in Rooted because the analysis treats all * Rooted as Rooted during the analysis. See bug 829372. @@ -861,81 +847,6 @@ class RootedBase JS::Handle as() const; }; -/* - * Mark a stack location as a root for the rooting analysis, without actually - * rooting it in release builds. This should only be used for stack locations - * of GC things that cannot be relocated by a garbage collection, and that - * are definitely reachable via another path. - */ -class SkipRoot -{ -#if defined(JS_DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) - - SkipRoot **stack, *prev; - const uint8_t *start; - const uint8_t *end; - - template - void init(CX *cx, const T *ptr, size_t count) { - SkipRoot **head = &cx->skipGCRooters; - this->stack = head; - this->prev = *stack; - *stack = this; - this->start = (const uint8_t *) ptr; - this->end = this->start + (sizeof(T) * count); - } - - public: - ~SkipRoot() { - MOZ_ASSERT(*stack == this); - *stack = prev; - } - - SkipRoot *previous() { return prev; } - - bool contains(const uint8_t *v, size_t len) { - return v >= start && v + len <= end; - } - -#else /* JS_DEBUG && JSGC_ROOT_ANALYSIS */ - - template - void init(js::ContextFriendFields *cx, const T *ptr, size_t count) {} - - public: - ~SkipRoot() { - // An empty destructor is needed to avoid warnings from clang about - // unused local variables of this type. - } - -#endif /* JS_DEBUG && JSGC_ROOT_ANALYSIS */ - - template - SkipRoot(JSContext *cx, const T *ptr, size_t count = 1 - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - { - init(ContextFriendFields::get(cx), ptr, count); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - template - SkipRoot(ContextFriendFields *cx, const T *ptr, size_t count = 1 - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - { - init(cx, ptr, count); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - template - SkipRoot(PerThreadData *pt, const T *ptr, size_t count = 1 - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - { - init(PerThreadDataFriendFields::get(pt), ptr, count); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; /* * RootedGeneric allows a class to instantiate its own Rooted type by @@ -958,15 +869,14 @@ class JS_PUBLIC_API(RootedGeneric) { public: JS::Rooted rooter; - SkipRoot skip; RootedGeneric(js::ContextFriendFields *cx) - : rooter(cx), skip(cx, rooter.address()) + : rooter(cx) { } RootedGeneric(js::ContextFriendFields *cx, const GCType &initial) - : rooter(cx, initial), skip(cx, rooter.address()) + : rooter(cx, initial) { } @@ -1287,17 +1197,6 @@ class PersistentRooted : private mozilla::LinkedListElement namespace js { -/* - * Hook for dynamic root analysis. Checks the native stack and poisons - * references to GC things which have not been rooted. - */ -inline void MaybeCheckStackRoots(JSContext *cx) -{ -#if defined(JS_DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) - JS::CheckStackRoots(cx); -#endif -} - /* Base class for automatic read-only object rooting during compilation. */ class CompilerRootNode { diff --git a/js/src/assembler/jit/ExecutableAllocatorPosix.cpp b/js/src/assembler/jit/ExecutableAllocatorPosix.cpp index 62c9d8cc2342..3a66bfdffc20 100644 --- a/js/src/assembler/jit/ExecutableAllocatorPosix.cpp +++ b/js/src/assembler/jit/ExecutableAllocatorPosix.cpp @@ -43,14 +43,7 @@ size_t ExecutableAllocator::determinePageSize() ExecutablePool::Allocation ExecutableAllocator::systemAlloc(size_t n) { - void* allocation; -#ifdef JSGC_ROOT_ANALYSIS - do { -#endif - allocation = mmap(NULL, n, INITIAL_PROTECTION_FLAGS, MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, 0); -#ifdef JSGC_ROOT_ANALYSIS - } while (allocation && JS::IsPoisonedPtr(allocation)); -#endif + void *allocation = mmap(NULL, n, INITIAL_PROTECTION_FLAGS, MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, 0); if (allocation == MAP_FAILED) allocation = NULL; ExecutablePool::Allocation alloc = { reinterpret_cast(allocation), n }; @@ -58,7 +51,7 @@ ExecutablePool::Allocation ExecutableAllocator::systemAlloc(size_t n) } void ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc) -{ +{ int result = munmap(alloc.pages, alloc.size); ASSERT_UNUSED(result, !result); } diff --git a/js/src/builtin/Intl.cpp b/js/src/builtin/Intl.cpp index 29dda165de05..a6a12b6a362c 100644 --- a/js/src/builtin/Intl.cpp +++ b/js/src/builtin/Intl.cpp @@ -1290,7 +1290,6 @@ NewUNumberFormat(JSContext *cx, HandleObject numberFormat) bool uUseGrouping = true; // Sprinkle appropriate rooting flavor over things the GC might care about. - SkipRoot skip(cx, &uCurrency); RootedString currency(cx); // We don't need to look at numberingSystem - it can only be set via @@ -1783,7 +1782,6 @@ js::intl_patternForSkeleton(JSContext *cx, unsigned argc, Value *vp) const jschar *skeleton = JS_GetStringCharsZ(cx, jsskeleton); if (!skeleton) return false; - SkipRoot skip(cx, &skeleton); uint32_t skeletonLen = u_strlen(JSCharToUChar(skeleton)); UErrorCode status = U_ZERO_ERROR; @@ -1845,9 +1843,6 @@ NewUDateFormat(JSContext *cx, HandleObject dateTimeFormat) const UChar *uPattern = nullptr; uint32_t uPatternLength = 0; - SkipRoot skipTimeZone(cx, &uTimeZone); - SkipRoot skipPattern(cx, &uPattern); - // We don't need to look at calendar and numberingSystem - they can only be // set via the Unicode locale extension and are therefore already set on // locale. diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 49969f7369f6..f7767a969302 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -43,13 +43,8 @@ GetBuildConfiguration(JSContext *cx, unsigned argc, jsval *vp) RootedObject info(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr())); if (!info) return false; - RootedValue value(cx); -#ifdef JSGC_ROOT_ANALYSIS - value = BooleanValue(true); -#else - value = BooleanValue(false); -#endif + RootedValue value(cx, BooleanValue(false)); if (!JS_SetProperty(cx, info, "rooting-analysis", value)) return false; diff --git a/js/src/configure.in b/js/src/configure.in index ba8d026efe8f..4071ec5d656d 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -3258,17 +3258,6 @@ if test -n "$JSGC_GENERATIONAL"; then AC_DEFINE(JSGC_GENERATIONAL) fi -dnl ======================================================== -dnl = Perform moving GC stack rooting analysis -dnl ======================================================== -MOZ_ARG_ENABLE_BOOL(root-analysis, -[ --enable-root-analysis Enable moving GC stack root analysis], - JSGC_ROOT_ANALYSIS=1, - JSGC_ROOT_ANALYSIS= ) -if test -n "$JSGC_ROOT_ANALYSIS"; then - AC_DEFINE(JSGC_ROOT_ANALYSIS) -fi - dnl ======================================================== dnl = Use exact stack rooting for GC dnl ======================================================== diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index 57e7216d25dc..3556691c7488 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -188,7 +188,6 @@ frontend::CompileScript(ExclusiveContext *cx, LifoAlloc *alloc, HandleObject sco SourceCompressionTask *extraSct /* = nullptr */) { RootedString source(cx, source_); - SkipRoot skip(cx, &chars); #if JS_TRACE_LOGGING js::AutoTraceLog logger(js::TraceLogging::defaultLogger(), @@ -507,7 +506,6 @@ CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, const ReadOnlyComp // FIXME: make Function pass in two strings and parse them as arguments and // ProgramElements respectively. - SkipRoot skip(cx, &chars); MaybeCallSourceHandler(cx, options, chars, length); diff --git a/js/src/frontend/TokenStream.cpp b/js/src/frontend/TokenStream.cpp index 5364080f952a..c59912d2f7ba 100644 --- a/js/src/frontend/TokenStream.cpp +++ b/js/src/frontend/TokenStream.cpp @@ -278,10 +278,7 @@ TokenStream::TokenStream(ExclusiveContext *cx, const ReadOnlyCompileOptions &opt tokenbuf(cx), cx(cx), originPrincipals(options.originPrincipals(cx)), - strictModeGetter(smg), - tokenSkip(cx, &tokens), - linebaseSkip(cx, &linebase), - prevLinebaseSkip(cx, &prevLinebase) + strictModeGetter(smg) { // The caller must ensure that a reference is held on the supplied principals // throughout compilation. diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index 329dc4c31678..85b001922824 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -747,8 +747,7 @@ class MOZ_STACK_CLASS TokenStream class TokenBuf { public: TokenBuf(ExclusiveContext *cx, const jschar *buf, size_t length) - : base_(buf), limit_(buf + length), ptr(buf), - skipBase(cx, &base_), skipLimit(cx, &limit_), skipPtr(cx, &ptr) + : base_(buf), limit_(buf + length), ptr(buf) { } bool hasRawChars() const { @@ -827,9 +826,6 @@ class MOZ_STACK_CLASS TokenStream const jschar *base_; // base of buffer const jschar *limit_; // limit for quick bounds check const jschar *ptr; // next char to get - - // We are not yet moving strings - SkipRoot skipBase, skipLimit, skipPtr; }; TokenKind getTokenInternal(Modifier modifier); @@ -898,15 +894,6 @@ class MOZ_STACK_CLASS TokenStream ExclusiveContext *const cx; JSPrincipals *const originPrincipals; StrictModeGetter *strictModeGetter; // used to test for strict mode - - // The tokens array stores pointers to JSAtoms. These are rooted by the - // atoms table using AutoKeepAtoms in the Parser. This SkipRoot tells the - // exact rooting analysis to ignore the atoms in the tokens array. - SkipRoot tokenSkip; - - // Bug 846011 - SkipRoot linebaseSkip; - SkipRoot prevLinebaseSkip; }; // Steal one JSREPORT_* bit (see jsapi.h) to tell that arguments to the error diff --git a/js/src/gc/GCInternals.h b/js/src/gc/GCInternals.h index 02ca149c5be6..2ee1793f5038 100644 --- a/js/src/gc/GCInternals.h +++ b/js/src/gc/GCInternals.h @@ -96,11 +96,6 @@ class IncrementalSafety IncrementalSafety IsIncrementalGCSafe(JSRuntime *rt); -#ifdef JSGC_ROOT_ANALYSIS -void * -GetAddressableGCThing(JSRuntime *rt, uintptr_t w); -#endif - #ifdef JS_GC_ZEAL void StartVerifyPreBarriers(JSRuntime *rt); diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index ad37f309357f..4c3a6a5b1d6b 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -52,19 +52,6 @@ js::Nursery::init() return false; void *heap = MapAlignedPages(runtime(), NurserySize, Alignment); -#ifdef JSGC_ROOT_ANALYSIS - // Our poison pointers are not guaranteed to be invalid on 64-bit - // architectures, and often are valid. We can't just reserve the full - // poison range, because it might already have been taken up by something - // else (shared library, previous allocation). So we'll just loop and - // discard poison pointers until we get something valid. - // - // This leaks all of these poisoned pointers. It would be better if they - // were marked as uncommitted, but it's a little complicated to avoid - // clobbering pre-existing unrelated mappings. - while (IsPoisonedPtr(heap) || IsPoisonedPtr((void*)(uintptr_t(heap) + NurserySize))) - heap = MapAlignedPages(runtime(), NurserySize, Alignment); -#endif if (!heap) return false; diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index 3363f8a43acc..ba4f54cabc34 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -186,21 +186,6 @@ IsAddressableGCThing(JSRuntime *rt, uintptr_t w, return CGCT_VALID; } -#ifdef JSGC_ROOT_ANALYSIS -void * -js::gc::GetAddressableGCThing(JSRuntime *rt, uintptr_t w) -{ - void *thing; - ArenaHeader *aheader; - AllocKind thingKind; - ConservativeGCTest status = - IsAddressableGCThing(rt, w, false, &thingKind, &aheader, &thing); - if (status != CGCT_VALID) - return nullptr; - return thing; -} -#endif - /* * Returns CGCT_VALID and mark it if the w can be a live GC thing and sets * thingKind accordingly. Otherwise returns the reason for rejection. diff --git a/js/src/gc/Verifier.cpp b/js/src/gc/Verifier.cpp index f521d7572625..7cb15ad4e302 100644 --- a/js/src/gc/Verifier.cpp +++ b/js/src/gc/Verifier.cpp @@ -24,287 +24,6 @@ using namespace js; 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, Rooted *rootp) -{ - return w >= (uintptr_t*)rootp->address() && w < (uintptr_t*)(rootp->address() + 1); -} - -static MOZ_ALWAYS_INLINE bool -CheckStackRootThing(uintptr_t *w, Rooted *rootp, ThingRootKind kind) -{ - if (kind == THING_ROOT_BINDINGS) - return CheckNonAddressThing(w, reinterpret_cast *>(rootp)); - - if (kind == THING_ROOT_PROPERTY_DESCRIPTOR) - return CheckNonAddressThing(w, reinterpret_cast *>(rootp)); - - if (kind == THING_ROOT_VALUE) - return CheckNonAddressThing(w, reinterpret_cast *>(rootp)); - - return rootp->address() == static_cast(w); -} - -struct Rooter { - Rooted *rooter; - ThingRootKind kind; -}; - -static void -CheckStackRoot(JSRuntime *rt, uintptr_t *w, Rooter *begin, Rooter *end) -{ - /* Mark memory as defined for valgrind, as in MarkWordConservatively. */ -#ifdef MOZ_VALGRIND - VALGRIND_MAKE_MEM_DEFINED(&w, sizeof(w)); -#endif - - void *thing = GetAddressableGCThing(rt, *w); - if (!thing) - return; - - /* Don't check atoms as these will never be subject to generational collection. */ - if (rt->isAtomsZone(static_cast(thing)->tenuredZone())) - return; - - /* - * Note that |thing| may be in a free list (InFreeList(aheader, thing)), - * but we can skip that check because poisoning the pointer can't hurt; the - * pointer still cannot be used for a non-gcthing. - */ - - for (Rooter *p = begin; p != end; p++) { - if (CheckStackRootThing(w, p->rooter, p->kind)) - return; - } - - SkipRoot *skip = TlsPerThreadData.get()->skipGCRooters; - while (skip) { - if (skip->contains(reinterpret_cast(w), sizeof(w))) - return; - skip = skip->previous(); - } - for (ContextIter cx(rt); !cx.done(); cx.next()) { - skip = cx->skipGCRooters; - while (skip) { - if (skip->contains(reinterpret_cast(w), sizeof(w))) - return; - skip = skip->previous(); - } - } - - /* - * Only poison the last byte in the word. It is easy to get accidental - * collisions when a value that does not occupy a full word is used to - * overwrite a now-dead GC thing pointer. In this case we want to avoid - * damaging the smaller value. - */ - JS::PoisonPtr(w); -} - -static void -CheckStackRootsRange(JSRuntime *rt, uintptr_t *begin, uintptr_t *end, Rooter *rbegin, Rooter *rend) -{ - JS_ASSERT(begin <= end); - for (uintptr_t *i = begin; i != end; ++i) - CheckStackRoot(rt, i, rbegin, rend); -} - -static void -CheckStackRootsRangeAndSkipJit(JSRuntime *rt, uintptr_t *begin, uintptr_t *end, Rooter *rbegin, Rooter *rend) -{ - /* - * Regions of the stack between Ion activiations are marked exactly through - * a different mechanism. We need to skip these regions when checking the - * stack so that we do not poison IonMonkey's things. - */ - uintptr_t *i = begin; - -#if defined(JS_ION) - for (jit::JitActivationIterator iter(rt); !iter.done(); ++iter) { - uintptr_t *jitMin, *jitEnd; - iter.jitStackRange(jitMin, jitEnd); - - uintptr_t *upto = Min(jitMin, end); - if (upto > i) - CheckStackRootsRange(rt, i, upto, rbegin, rend); - else - break; - i = jitEnd; - } -#endif - - /* The topmost Ion activiation may be beyond our prior top. */ - if (i < end) - CheckStackRootsRange(rt, i, end, rbegin, rend); -} - -static int -CompareRooters(const void *vpA, const void *vpB) -{ - const Rooter *a = static_cast(vpA); - const Rooter *b = static_cast(vpB); - // There should be no duplicates, and we wouldn't care about their order anyway. - return (a->rooter < b->rooter) ? -1 : 1; -} - -/* - * In the pathological cases that dominate much of the test case runtime, - * rooting analysis spends tons of time scanning the stack during a tight-ish - * loop. Since statically, everything is either rooted or it isn't, these scans - * are almost certain to be worthless. Detect these cases by checking whether - * the addresses of the top several rooters in the stack are recurring. Note - * that there may be more than one CheckRoots call within the loop, so we may - * alternate between a couple of stacks rather than just repeating the same one - * over and over, so we need more than a depth-1 memory. - */ -static bool -SuppressCheckRoots(js::Vector &rooters) -{ - static const unsigned int NumStackMemories = 6; - static const size_t StackCheckDepth = 10; - - static uint32_t stacks[NumStackMemories]; - static unsigned int numMemories = 0; - static unsigned int oldestMemory = 0; - - // Ugh. Sort the rooters. This should really be an O(n) rank selection - // followed by a sort. Interestingly, however, the overall scan goes a bit - // *faster* with this sort. Better branch prediction of the later - // partitioning pass, perhaps. - 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. - unsigned int pos; - - // 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. - for (pos = 0; pos < numMemories; pos++) { - if (stacks[pos] == hash) { - // Skip this check. Technically, it is incorrect to not update the - // LRU queue position, but it'll cost us at most one extra check - // for every time a hot stack falls out of the window. - return true; - } - } - - // Replace the oldest remembered stack with our current stack. - stacks[oldestMemory] = hash; - oldestMemory = (oldestMemory + 1) % NumStackMemories; - if (numMemories < NumStackMemories) - numMemories++; - - return false; -} - -static void -GatherRooters(js::Vector &rooters, - Rooted **thingGCRooters, - unsigned thingRootKind) -{ - Rooted *rooter = thingGCRooters[thingRootKind]; - while (rooter) { - Rooter r = { rooter, ThingRootKind(thingRootKind) }; - JS_ALWAYS_TRUE(rooters.append(r)); - rooter = rooter->previous(); - } -} - -void -JS::CheckStackRoots(JSContext *cx) -{ - JSRuntime *rt = cx->runtime(); - - if (rt->gcZeal_ != ZealStackRootingValue) - return; - - // GCs can't happen when analysis/inference/compilation are active. - if (cx->compartment()->activeAnalysis) - return; - - if (rt->mainThread.suppressGC) - return; - - // Can switch to the atoms compartment during analysis. - if (IsAtomsCompartment(cx->compartment())) { - for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) { - if (c.get()->activeAnalysis) - return; - } - } - - AutoCopyFreeListToArenas copy(rt, WithAtoms); - - ConservativeGCData *cgcd = &rt->conservativeGC; - cgcd->recordStackTop(); - - JS_ASSERT(cgcd->hasStackToScan()); - uintptr_t *stackMin, *stackEnd; - stackMin = cgcd->nativeStackTop + 1; - stackEnd = reinterpret_cast(rt->nativeStackBase); - JS_ASSERT(stackMin <= stackEnd); - - // Gather up all of the rooters - js::Vector rooters; - for (unsigned i = 0; i < THING_ROOT_LIMIT; i++) { - for (ContextIter cx(rt); !cx.done(); cx.next()) { - GatherRooters(rooters, cx->thingGCRooters, i); - } - - GatherRooters(rooters, rt->mainThread.thingGCRooters, i); - } - - if (SuppressCheckRoots(rooters)) - return; - - // Truncate stackEnd to just after the address of the youngest - // already-scanned rooter on the stack, to avoid re-scanning the rest of - // the stack. - void *firstScanned = nullptr; - for (Rooter *p = rooters.begin(); p != rooters.end(); p++) { - if (p->rooter->scanned) { - uintptr_t *addr = reinterpret_cast(p->rooter); - if (stackEnd > addr) { - stackEnd = addr; - firstScanned = p->rooter; - } - } - } - - // Partition the stack by the already-scanned start address. Put everything - // that needs to be searched at the end of the vector. - Rooter *firstToScan = rooters.begin(); - if (firstScanned) { - for (Rooter *p = rooters.begin(); p != rooters.end(); p++) { - if (p->rooter >= firstScanned) { - Swap(*firstToScan, *p); - ++firstToScan; - } - } - } - - CheckStackRootsRangeAndSkipJit(rt, stackMin, stackEnd, firstToScan, rooters.end()); - CheckStackRootsRange(rt, cgcd->registerSnapshot.words, - ArrayEnd(cgcd->registerSnapshot.words), - firstToScan, rooters.end()); - - // Mark all rooters as scanned. - for (Rooter *p = rooters.begin(); p != rooters.end(); p++) - p->rooter->scanned = true; -} - -#endif /* DEBUG && JS_GC_ZEAL && JSGC_ROOT_ANALYSIS && !JS_THREADSAFE */ - #ifdef JS_GC_ZEAL /* diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index ee660cd2a7d5..827b7f6b1fed 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -1212,7 +1212,6 @@ GetPropertyIC::tryAttachNative(JSContext *cx, IonScript *ion, HandleObject obj, *emitted = true; MacroAssembler masm(cx, ion, script_, pc_); - SkipRoot skip(cx, &masm); RepatchStubAppender attacher(*this); const char *attachKind; @@ -2994,7 +2993,6 @@ GetElementIC::attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj, Label failures; MacroAssembler masm(cx, ion); - SkipRoot skip(cx, &masm); // Ensure the index is a string. ValueOperand val = index().reg().valueReg(); diff --git a/js/src/jit/IonTypes.h b/js/src/jit/IonTypes.h index 0a7d9276ef7b..4db7ec7cbbbe 100644 --- a/js/src/jit/IonTypes.h +++ b/js/src/jit/IonTypes.h @@ -245,10 +245,7 @@ IsNullOrUndefined(MIRType type) // Make sure registers are not modified between an instruction and // its OsiPoint. -// -// Skip this check in rooting analysis builds, which poison unrooted -// pointers on the stack. -# if defined(JS_ION) && !defined(JSGC_ROOT_ANALYSIS) +# if defined(JS_ION) # define CHECK_OSIPOINT_REGISTERS 1 # endif #endif diff --git a/js/src/jsapi-tests/testConservativeGC.cpp b/js/src/jsapi-tests/testConservativeGC.cpp index 16c4456804f4..e51496c7426e 100644 --- a/js/src/jsapi-tests/testConservativeGC.cpp +++ b/js/src/jsapi-tests/testConservativeGC.cpp @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#if !defined(JSGC_ROOT_ANALYSIS) && !defined(JSGC_USE_EXACT_ROOTING) +#if !defined(JSGC_USE_EXACT_ROOTING) #include "jsobj.h" @@ -85,4 +85,4 @@ BEGIN_TEST(testDerivedValues) } END_TEST(testDerivedValues) -#endif /* !defined(JSGC_ROOT_ANALYSIS) && !defined(JSGC_USE_EXACT_ROOTING) */ +#endif /* !defined(JSGC_USE_EXACT_ROOTING) */ diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 334b5734e8ae..0f85c9f8afb7 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -142,12 +142,11 @@ class AutoValueArray : public AutoGCRooter { const size_t length_; Value elements_[N]; - js::SkipRoot skip_; public: AutoValueArray(JSContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, VALARRAY), length_(N), skip_(cx, elements_, N) + : AutoGCRooter(cx, VALARRAY), length_(N) { /* Always initialize in case we GC before assignment. */ mozilla::PodArrayZero(elements_); @@ -176,20 +175,17 @@ class AutoVectorRooter : protected AutoGCRooter typedef js::Vector VectorImpl; VectorImpl vector; - /* Prevent overwriting of inline elements in vector. */ - js::SkipRoot vectorRoot; - public: explicit AutoVectorRooter(JSContext *cx, ptrdiff_t tag MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), vector(cx), vectorRoot(cx, &vector) + : AutoGCRooter(cx, tag), vector(cx) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; } explicit AutoVectorRooter(js::ContextFriendFields *cx, ptrdiff_t tag MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), vector(cx), vectorRoot(cx, &vector) + : AutoGCRooter(cx, tag), vector(cx) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; } @@ -1039,10 +1035,6 @@ MOZ_ALWAYS_INLINE bool ToNumber(JSContext *cx, HandleValue v, double *out) { AssertArgumentsAreSane(cx, v); - { - js::SkipRoot root(cx, &v); - js::MaybeCheckStackRoots(cx); - } if (v.isNumber()) { *out = v.toNumber(); @@ -1117,7 +1109,6 @@ MOZ_ALWAYS_INLINE bool ToUint16(JSContext *cx, JS::HandleValue v, uint16_t *out) { AssertArgumentsAreSane(cx, v); - js::MaybeCheckStackRoots(cx); if (v.isInt32()) { *out = uint16_t(v.toInt32()); @@ -1130,7 +1121,6 @@ MOZ_ALWAYS_INLINE bool ToInt32(JSContext *cx, JS::HandleValue v, int32_t *out) { AssertArgumentsAreSane(cx, v); - js::MaybeCheckStackRoots(cx); if (v.isInt32()) { *out = v.toInt32(); @@ -1143,7 +1133,6 @@ MOZ_ALWAYS_INLINE bool ToUint32(JSContext *cx, JS::HandleValue v, uint32_t *out) { AssertArgumentsAreSane(cx, v); - js::MaybeCheckStackRoots(cx); if (v.isInt32()) { *out = uint32_t(v.toInt32()); @@ -1156,13 +1145,11 @@ MOZ_ALWAYS_INLINE bool ToInt64(JSContext *cx, JS::HandleValue v, int64_t *out) { AssertArgumentsAreSane(cx, v); - js::MaybeCheckStackRoots(cx); if (v.isInt32()) { *out = int64_t(v.toInt32()); return true; } - return js::ToInt64Slow(cx, v, out); } @@ -1170,14 +1157,12 @@ MOZ_ALWAYS_INLINE bool ToUint64(JSContext *cx, JS::HandleValue v, uint64_t *out) { AssertArgumentsAreSane(cx, v); - js::MaybeCheckStackRoots(cx); if (v.isInt32()) { /* Account for sign extension of negatives into the longer 64bit space. */ *out = uint64_t(int64_t(v.toInt32())); return true; } - return js::ToUint64Slow(cx, v, out); } diff --git a/js/src/jsatom.cpp b/js/src/jsatom.cpp index c9f76870c5ab..da09f23cad17 100644 --- a/js/src/jsatom.cpp +++ b/js/src/jsatom.cpp @@ -325,7 +325,6 @@ AtomizeAndtake(ExclusiveContext *cx, jschar *tbchars, size_t length, InternBehav */ AtomSet& atoms = cx->atoms(); AtomSet::AddPtr p = atoms.lookupForAdd(lookup); - SkipRoot skipHash(cx, &p); /* Prevent the hash from being poisoned. */ if (p) { JSAtom *atom = p->asPtr(); p->setTagged(bool(ib)); @@ -377,7 +376,6 @@ AtomizeAndCopyChars(ExclusiveContext *cx, const jschar *tbchars, size_t length, AtomSet& atoms = cx->atoms(); AtomSet::AddPtr p = atoms.lookupForAdd(lookup); - SkipRoot skipHash(cx, &p); /* Prevent the hash from being poisoned. */ if (p) { JSAtom *atom = p->asPtr(); p->setTagged(bool(ib)); diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index 2eef7b117636..241f2bf7df22 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -232,7 +232,7 @@ js::DestroyContext(JSContext *cx, DestroyContextMode mode) MOZ_CRASH(); #endif -#if (defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)) && defined(DEBUG) +#if defined(JSGC_USE_EXACT_ROOTING) && defined(DEBUG) for (int i = 0; i < THING_ROOT_LIMIT; ++i) JS_ASSERT(cx->thingGCRooters[i] == nullptr); #endif diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 2c96173b11d6..f5322b3fe582 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -393,12 +393,6 @@ class ExclusiveContext : public ThreadSafeContext void addPendingOverRecursed(); }; -inline void -MaybeCheckStackRoots(ExclusiveContext *cx) -{ - MaybeCheckStackRoots(cx->maybeJSContext()); -} - } /* namespace js */ struct JSContext : public js::ExclusiveContext, @@ -934,7 +928,7 @@ class AutoArrayRooter : private AutoGCRooter public: AutoArrayRooter(JSContext *cx, size_t len, Value *vec MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, len), array(vec), skip(cx, array, len) + : AutoGCRooter(cx, len), array(vec) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; JS_ASSERT(tag_ >= 0); @@ -980,7 +974,6 @@ class AutoArrayRooter : private AutoGCRooter private: Value *array; - js::SkipRoot skip; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index f6fb42d0d383..4618377899ed 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -39,12 +39,9 @@ JS_STATIC_ASSERT(offsetof(JSRuntime, mainThread) == PerThreadDataFriendFields::PerThreadDataFriendFields() { PodArrayZero(nativeStackLimit); -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) +#if defined(JSGC_USE_EXACT_ROOTING) PodArrayZero(thingGCRooters); #endif -#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) - skipGCRooters = nullptr; -#endif } JS_FRIEND_API(void) diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 685242152b42..c6df08f8083e 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -1589,9 +1589,6 @@ FunctionConstructor(JSContext *cx, unsigned argc, Value *vp, GeneratorKind gener const jschar *chars = linear->chars(); size_t length = linear->length(); - /* Protect inlined chars from root analysis poisoning. */ - SkipRoot skip(cx, &chars); - /* * NB: (new Function) is not lexically closed by its caller, it's just an * anonymous function in the top-level scope that its constructor inhabits. diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 1b31b4ae0941..71969cfcf220 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -746,21 +746,6 @@ ChunkPool::expireAndFree(JSRuntime *rt, bool releaseAll) Chunk::allocate(JSRuntime *rt) { Chunk *chunk = AllocChunk(rt); - -#ifdef JSGC_ROOT_ANALYSIS - // Our poison pointers are not guaranteed to be invalid on 64-bit - // architectures, and often are valid. We can't just reserve the full - // poison range, because it might already have been taken up by something - // else (shared library, previous allocation). So we'll just loop and - // discard poison pointers until we get something valid. - // - // This leaks all of these poisoned pointers. It would be better if they - // were marked as uncommitted, but it's a little complicated to avoid - // clobbering pre-existing unrelated mappings. - while (IsPoisonedPtr(chunk)) - chunk = AllocChunk(rt); -#endif - if (!chunk) return nullptr; chunk->init(rt); @@ -4926,10 +4911,6 @@ Collect(JSRuntime *rt, bool incremental, int64_t budget, TraceLogging::GC_STOP); #endif - ContextIter cx(rt); - if (!cx.done()) - MaybeCheckStackRoots(cx); - #ifdef JS_GC_ZEAL if (rt->gcDeterministicOnly && !IsDeterministicGCReason(reason)) return; diff --git a/js/src/jsgcinlines.h b/js/src/jsgcinlines.h index 90053f953578..148f6551a512 100644 --- a/js/src/jsgcinlines.h +++ b/js/src/jsgcinlines.h @@ -437,8 +437,6 @@ CheckAllocatorState(ThreadSafeContext *cx, AllocKind kind) // handle that here. Just check in case we need to collect instead. js::gc::GCIfNeeded(ncx); } - - MaybeCheckStackRoots(ncx); } return true; diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index d6b7a5fd9470..1efe71d34e02 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -3384,17 +3384,7 @@ CheckNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun) size_t numBytes = sizeof(TypeNewScript) + (initializerList.length() * sizeof(TypeNewScript::Initializer)); - TypeNewScript *newScript; -#ifdef JSGC_ROOT_ANALYSIS - // calloc can legitimately return a pointer that appears to be poisoned. - void *p; - do { - p = cx->calloc_(numBytes); - } while (IsPoisonedPtr(p)); - newScript = (TypeNewScript *) p; -#else - newScript = (TypeNewScript *) cx->calloc_(numBytes); -#endif + TypeNewScript *newScript = (TypeNewScript *) cx->calloc_(numBytes); if (!newScript) return; diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index dd0b710a3945..da22734bf472 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -1562,25 +1562,6 @@ js::NonObjectToNumberSlow(ThreadSafeContext *cx, Value v, double *out) bool js::ToNumberSlow(ExclusiveContext *cx, Value v, double *out) { -#ifdef DEBUG - /* - * MSVC bizarrely miscompiles this, complaining about the first brace below - * being unmatched (!). The error message points at both this opening brace - * and at the corresponding SkipRoot constructor. The error seems to derive - * from the presence guard-object macros on the SkipRoot class/constructor, - * which seems well in the weeds for an unmatched-brace syntax error. - * Otherwise the problem is inscrutable, and I haven't found a workaround. - * So for now just disable it when compiling with MSVC -- not ideal, but at - * least Windows debug shell builds complete again. - */ -#ifndef _MSC_VER - { - SkipRoot skip(cx, &v); - MaybeCheckStackRoots(cx); - } -#endif -#endif - JS_ASSERT(!v.isNumber()); goto skip_int_double; for (;;) { diff --git a/js/src/jsnum.h b/js/src/jsnum.h index 87b88b537244..56ec184dd381 100644 --- a/js/src/jsnum.h +++ b/js/src/jsnum.h @@ -151,10 +151,6 @@ StringToNumber(ThreadSafeContext *cx, JSString *str, double *result); MOZ_ALWAYS_INLINE bool ToNumber(JSContext *cx, JS::MutableHandleValue vp) { -#ifdef DEBUG - MaybeCheckStackRoots(cx); -#endif - if (vp.isNumber()) return true; double d; @@ -233,13 +229,6 @@ IsDefinitelyIndex(const Value &v, uint32_t *indexp) static inline bool ToInteger(JSContext *cx, HandleValue v, double *dp) { -#ifdef DEBUG - { - SkipRoot skip(cx, &v); - MaybeCheckStackRoots(cx); - } -#endif - if (v.isInt32()) { *dp = v.toInt32(); return true; diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index 0a20d7f33688..472a7ec21ec3 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -795,7 +795,7 @@ class AutoPropDescArrayRooter : private AutoGCRooter { public: AutoPropDescArrayRooter(JSContext *cx) - : AutoGCRooter(cx, DESCRIPTORS), descriptors(cx), skip(cx, &descriptors) + : AutoGCRooter(cx, DESCRIPTORS), descriptors(cx) { } PropDesc *append() { @@ -817,7 +817,6 @@ class AutoPropDescArrayRooter : private AutoGCRooter private: PropDescArray descriptors; - SkipRoot skip; }; /* diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index 4bbf3c44ae9e..ad81d85a9c81 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -20,7 +20,7 @@ #include "js/TypeDecls.h" -#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) || defined(JS_DEBUG) +#if defined(JSGC_USE_EXACT_ROOTING) || defined(JS_DEBUG) # define JSGC_TRACK_EXACT_ROOTS #endif @@ -269,8 +269,6 @@ class ExclusiveContext; class Allocator; -class SkipRoot; - enum ThingRootKind { THING_ROOT_OBJECT, @@ -342,9 +340,6 @@ struct ContextFriendFields { #ifdef JSGC_TRACK_EXACT_ROOTS mozilla::PodArrayZero(thingGCRooters); -#endif -#if defined(JS_DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) - skipGCRooters = nullptr; #endif } @@ -364,18 +359,6 @@ struct ContextFriendFields JS::Rooted *thingGCRooters[THING_ROOT_LIMIT]; #endif -#if defined(JS_DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) - /* - * Stack allocated list of stack locations which hold non-relocatable - * GC heap pointers (where the target is rooted somewhere else) or integer - * values which may be confused for GC heap pointers. These are used to - * suppress false positives which occur when a rooting analysis treats the - * location as holding a relocatable pointer, but have no other effect on - * GC behavior. - */ - SkipRoot *skipGCRooters; -#endif - /* Stack of thread-stack-allocated GC roots. */ JS::AutoGCRooter *autoGCRooters; @@ -443,18 +426,6 @@ struct PerThreadDataFriendFields JS::Rooted *thingGCRooters[THING_ROOT_LIMIT]; #endif -#if defined(JS_DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) - /* - * Stack allocated list of stack locations which hold non-relocatable - * GC heap pointers (where the target is rooted somewhere else) or integer - * values which may be confused for GC heap pointers. These are used to - * suppress false positives which occur when a rooting analysis treats the - * location as holding a relocatable pointer, but have no other effect on - * GC behavior. - */ - SkipRoot *skipGCRooters; -#endif - /* Limit pointer for checking native stack consumption. */ uintptr_t nativeStackLimit[StackKindCount]; diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 4e5c89c10f62..8c5e96537444 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -2117,7 +2117,6 @@ struct ReplaceData { ReplaceData(JSContext *cx) : str(cx), g(cx), lambda(cx), elembase(cx), repstr(cx), - dollarRoot(cx, &dollar), dollarEndRoot(cx, &dollarEnd), fig(cx, NullValue()), sb(cx) {} @@ -2147,8 +2146,6 @@ struct ReplaceData Rooted repstr; /* replacement string */ const jschar *dollar; /* null or pointer to first $ in repstr */ const jschar *dollarEnd; /* limit pointer for js_strchr_limit */ - SkipRoot dollarRoot; /* XXX prevent dollar from being relocated */ - SkipRoot dollarEndRoot; /* ditto */ int leftIndex; /* left context index in str->chars */ JSSubString dollarStr; /* for "$$" InterpretDollar result */ bool calledBack; /* record whether callback has been called */ diff --git a/js/src/jsstr.h b/js/src/jsstr.h index cb1436bc444f..012bed3e5197 100644 --- a/js/src/jsstr.h +++ b/js/src/jsstr.h @@ -149,13 +149,6 @@ template static MOZ_ALWAYS_INLINE JSString * ToString(JSContext *cx, JS::HandleValue v) { -#ifdef DEBUG - if (allowGC) { - SkipRoot skip(cx, &v); - MaybeCheckStackRoots(cx); - } -#endif - if (v.isString()) return v.toString(); return ToStringSlow(cx, v); diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 75ba3e298f24..08115d0c12cf 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -2720,8 +2720,6 @@ EvalInContext(JSContext *cx, unsigned argc, jsval *vp) if (!src) return false; - SkipRoot skip(cx, &src); - bool lazy = false; if (srclen == 4) { if (src[0] == 'l' && src[1] == 'a' && src[2] == 'z' && src[3] == 'y') { diff --git a/js/src/vm/CharacterEncoding.cpp b/js/src/vm/CharacterEncoding.cpp index 072331638509..b206c2f94a1a 100644 --- a/js/src/vm/CharacterEncoding.cpp +++ b/js/src/vm/CharacterEncoding.cpp @@ -333,9 +333,6 @@ typedef bool (*CountAction)(JSContext *, const UTF8Chars, jschar *, size_t *, bo static TwoByteCharsZ InflateUTF8StringHelper(JSContext *cx, const UTF8Chars src, CountAction countAction, size_t *outlen) { - // Malformed UTF8 chars could trigger errors and hence GC. - MaybeCheckStackRoots(cx); - *outlen = 0; bool isAscii; diff --git a/js/src/vm/OldDebugAPI.cpp b/js/src/vm/OldDebugAPI.cpp index 85b491f6ad3c..cd26624d116d 100644 --- a/js/src/vm/OldDebugAPI.cpp +++ b/js/src/vm/OldDebugAPI.cpp @@ -1306,9 +1306,6 @@ JSAbstractFramePtr::evaluateUCInStackFrame(JSContext *cx, const char *filename, unsigned lineno, MutableHandleValue rval) { - /* Protect inlined chars from root analysis poisoning. */ - SkipRoot skipChars(cx, &chars); - if (!CheckDebugMode(cx)) return false; diff --git a/js/src/vm/RegExpObject.cpp b/js/src/vm/RegExpObject.cpp index a27ede89bef1..d7cf8c537735 100644 --- a/js/src/vm/RegExpObject.cpp +++ b/js/src/vm/RegExpObject.cpp @@ -520,9 +520,6 @@ RegExpRunStatus RegExpShared::execute(JSContext *cx, const jschar *chars, size_t length, size_t *lastIndex, MatchPairs &matches) { - /* Protect inlined chars from root analysis poisoning. */ - SkipRoot skip(cx, &chars); - /* Compile the code at point-of-use. */ if (!compileIfNecessary(cx)) return RegExpRunStatus_Error; @@ -576,9 +573,6 @@ RegExpRunStatus RegExpShared::executeMatchOnly(JSContext *cx, const jschar *chars, size_t length, size_t *lastIndex, MatchPair &match) { - /* These chars may be inline in a string. See bug 846011. */ - SkipRoot skipChars(cx, &chars); - /* Compile the code at point-of-use. */ if (!compileMatchOnlyIfNecessary(cx)) return RegExpRunStatus_Error; diff --git a/js/src/vm/RegExpStatics.h b/js/src/vm/RegExpStatics.h index 6ad908106244..335b0f05db7e 100644 --- a/js/src/vm/RegExpStatics.h +++ b/js/src/vm/RegExpStatics.h @@ -171,7 +171,7 @@ class AutoRegExpStaticsBuffer : private JS::CustomAutoRooter public: explicit AutoRegExpStaticsBuffer(JSContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : CustomAutoRooter(cx), statics(RegExpStatics::InitBuffer()), skip(cx, &statics) + : CustomAutoRooter(cx), statics(RegExpStatics::InitBuffer()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; } @@ -195,7 +195,6 @@ class AutoRegExpStaticsBuffer : private JS::CustomAutoRooter } RegExpStatics statics; - SkipRoot skip; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index b6b977647346..652fb8cb1c8f 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -141,18 +141,6 @@ struct ConservativeGCData */ uintptr_t *nativeStackTop; -#if defined(JSGC_ROOT_ANALYSIS) && (JS_STACK_GROWTH_DIRECTION < 0) - /* - * Record old contents of the native stack from the last time there was a - * scan, to reduce the overhead involved in repeatedly rescanning the - * native stack during root analysis. oldStackData stores words in reverse - * order starting at oldStackEnd. - */ - uintptr_t *oldStackMin, *oldStackEnd; - uintptr_t *oldStackData; - size_t oldStackCapacity; // in sizeof(uintptr_t) -#endif - union { jmp_buf jmpbuf; uintptr_t words[JS_HOWMANY(sizeof(jmp_buf), sizeof(uintptr_t))]; diff --git a/js/src/vm/Shape-inl.h b/js/src/vm/Shape-inl.h index 68d6eb9e0220..29d5ffd8f87a 100644 --- a/js/src/vm/Shape-inl.h +++ b/js/src/vm/Shape-inl.h @@ -188,8 +188,7 @@ inline AutoRooterGetterSetter::Inner::Inner(ThreadSafeContext *cx, uint8_t attrs, PropertyOp *pgetter_, StrictPropertyOp *psetter_) : CustomAutoRooter(cx), attrs(attrs), - pgetter(pgetter_), psetter(psetter_), - getterRoot(cx, pgetter_), setterRoot(cx, psetter_) + pgetter(pgetter_), psetter(psetter_) { JS_ASSERT_IF(attrs & JSPROP_GETTER, !IsPoisonedPtr(*pgetter)); JS_ASSERT_IF(attrs & JSPROP_SETTER, !IsPoisonedPtr(*psetter)); diff --git a/js/src/vm/Shape.cpp b/js/src/vm/Shape.cpp index b3dd8b53fb39..4e09cd9db3e8 100644 --- a/js/src/vm/Shape.cpp +++ b/js/src/vm/Shape.cpp @@ -1710,7 +1710,6 @@ EmptyShape::getInitialShape(ExclusiveContext *cx, const Class *clasp, TaggedProt if (p) return p->shape; - SkipRoot skip(cx, &p); /* The hash may look like a GC pointer and get poisoned. */ Rooted protoRoot(cx, proto); RootedObject parentRoot(cx, parent); RootedObject metadataRoot(cx, metadata); diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h index d9a42d5b3717..d67e8d71178e 100644 --- a/js/src/vm/Shape.h +++ b/js/src/vm/Shape.h @@ -338,7 +338,7 @@ class AutoPropDescRooter : private JS::CustomAutoRooter public: explicit AutoPropDescRooter(JSContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : CustomAutoRooter(cx), skip(cx, &propDesc) + : CustomAutoRooter(cx) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; } @@ -388,7 +388,6 @@ class AutoPropDescRooter : private JS::CustomAutoRooter virtual void trace(JSTracer *trc); PropDesc propDesc; - SkipRoot skip; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; @@ -1321,7 +1320,6 @@ class AutoRooterGetterSetter uint8_t attrs; PropertyOp *pgetter; StrictPropertyOp *psetter; - SkipRoot getterRoot, setterRoot; }; public: diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index bef1beebddc2..61ca69192637 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -920,7 +920,6 @@ class TypedArrayObjectTemplate : public TypedArrayObject #endif NativeType *dest = static_cast(thisTypedArray->viewData()) + offset; - SkipRoot skipDest(cx, &dest); if (ar->is() && !ar->isIndexed() && ar->getDenseInitializedLength() >= len) { JS_ASSERT(ar->as().length() == len); @@ -931,7 +930,6 @@ class TypedArrayObjectTemplate : public TypedArrayObject * to root |src| and |dest|. */ const Value *src = ar->getDenseElements(); - SkipRoot skipSrc(cx, &src); uint32_t i = 0; do { NativeType n; @@ -1594,7 +1592,6 @@ DataViewObject::write(JSContext *cx, Handle obj, } uint8_t *data; - SkipRoot skipData(cx, &data); if (!getDataPointer(cx, obj, args, sizeof(NativeType), &data)) return false;