Bug 1268083 - Get JitcodeGlobalEntry objects by reference when marking r=jandem a=abillings
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 06 May 2016 11:16:16 +0100
changeset 296356 ecda4cb9380646791abe09dc88f3f44c554a3547
parent 296355 8ba069d19cf1b4066d747ec7b5f3d211bcba6157
child 296357 a381b242fcd57388e7a406dba27758c151ddd1a4
push id76308
push userjcoppeard@mozilla.com
push dateFri, 06 May 2016 10:27:31 +0000
treeherdermozilla-inbound@ecda4cb93806 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem, abillings
bugs1268083
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1268083 - Get JitcodeGlobalEntry objects by reference when marking r=jandem a=abillings
js/src/jit/Ion.cpp
js/src/jit/JitFrames.cpp
js/src/jit/JitcodeMap.cpp
js/src/jit/JitcodeMap.h
js/src/shell/js.cpp
js/src/vm/Stack.cpp
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -800,19 +800,18 @@ JitCode::traceChildren(JSTracer* trc)
 
 void
 JitCode::finalize(FreeOp* fop)
 {
     // If this jitcode had a bytecode map, it must have already been removed.
 #ifdef DEBUG
     JSRuntime* rt = fop->runtime();
     if (hasBytecodeMap_) {
-        JitcodeGlobalEntry result;
         MOZ_ASSERT(rt->jitRuntime()->hasJitcodeGlobalTable());
-        MOZ_ASSERT(!rt->jitRuntime()->getJitcodeGlobalTable()->lookup(raw(), &result, rt));
+        MOZ_ASSERT(!rt->jitRuntime()->getJitcodeGlobalTable()->lookup(raw()));
     }
 #endif
 
     MOZ_ASSERT(pool_);
 
     // With W^X JIT code, reprotecting memory for each JitCode instance is
     // slow, so we record the ranges and poison them later all at once. It's
     // safe to ignore OOM here, it just means we won't poison the code.
@@ -2066,18 +2065,18 @@ TrackIonAbort(JSContext* cx, JSScript* s
         return;
 
     // Only bother tracking aborts of functions we're attempting to
     // Ion-compile after successfully running in Baseline.
     if (!script->hasBaselineScript())
         return;
 
     JitcodeGlobalTable* table = cx->runtime()->jitRuntime()->getJitcodeGlobalTable();
-    JitcodeGlobalEntry entry;
-    table->lookupInfallible(script->baselineScript()->method()->raw(), &entry, cx->runtime());
+    void* ptr = script->baselineScript()->method()->raw();
+    JitcodeGlobalEntry& entry = table->lookupInfallible(ptr);
     entry.baselineEntry().trackIonAbort(pc, message);
 }
 
 static void
 TrackAndSpewIonAbort(JSContext* cx, JSScript* script, const char* message)
 {
     JitSpew(JitSpew_IonAbort, message);
     TrackIonAbort(cx, script, script->code(), message);
--- a/js/src/jit/JitFrames.cpp
+++ b/js/src/jit/JitFrames.cpp
@@ -2712,26 +2712,26 @@ JitFrameIterator::verifyReturnAddressUsi
         return true;
 
     if (rt->isHeapMinorCollecting())
         return true;
 
     JitRuntime* jitrt = rt->jitRuntime();
 
     // Look up and print bytecode info for the native address.
-    JitcodeGlobalEntry entry;
-    if (!jitrt->getJitcodeGlobalTable()->lookup(returnAddressToFp_, &entry, rt))
+    const JitcodeGlobalEntry* entry = jitrt->getJitcodeGlobalTable()->lookup(returnAddressToFp_);
+    if (!entry)
         return true;
 
     JitSpew(JitSpew_Profiling, "Found nativeToBytecode entry for %p: %p - %p",
-            returnAddressToFp_, entry.nativeStartAddr(), entry.nativeEndAddr());
+            returnAddressToFp_, entry->nativeStartAddr(), entry->nativeEndAddr());
 
     JitcodeGlobalEntry::BytecodeLocationVector location;
     uint32_t depth = UINT32_MAX;
-    if (!entry.callStackAtAddr(rt, returnAddressToFp_, location, &depth))
+    if (!entry->callStackAtAddr(rt, returnAddressToFp_, location, &depth))
         return false;
     MOZ_ASSERT(depth > 0 && depth != UINT32_MAX);
     MOZ_ASSERT(location.length() == depth);
 
     JitSpew(JitSpew_Profiling, "Found bytecode location of depth %d:", depth);
     for (size_t i = 0; i < location.length(); i++) {
         JitSpew(JitSpew_Profiling, "   %s:%" PRIuSIZE " - %" PRIuSIZE,
                 location[i].script->filename(), location[i].script->lineno(),
@@ -2866,55 +2866,55 @@ JitProfilingFrameIterator::tryInitWithPC
 
 bool
 JitProfilingFrameIterator::tryInitWithTable(JitcodeGlobalTable* table, void* pc, JSRuntime* rt,
                                             bool forLastCallSite)
 {
     if (!pc)
         return false;
 
-    JitcodeGlobalEntry entry;
-    if (!table->lookup(pc, &entry, rt))
+    const JitcodeGlobalEntry* entry = table->lookup(pc);
+    if (!entry)
         return false;
 
     JSScript* callee = frameScript();
 
-    MOZ_ASSERT(entry.isIon() || entry.isBaseline() || entry.isIonCache() || entry.isDummy());
+    MOZ_ASSERT(entry->isIon() || entry->isBaseline() || entry->isIonCache() || entry->isDummy());
 
     // Treat dummy lookups as an empty frame sequence.
-    if (entry.isDummy()) {
+    if (entry->isDummy()) {
         type_ = JitFrame_Entry;
         fp_ = nullptr;
         returnAddressToFp_ = nullptr;
         return true;
     }
 
-    if (entry.isIon()) {
+    if (entry->isIon()) {
         // If looked-up callee doesn't match frame callee, don't accept lastProfilingCallSite
-        if (entry.ionEntry().getScript(0) != callee)
+        if (entry->ionEntry().getScript(0) != callee)
             return false;
 
         type_ = JitFrame_IonJS;
         returnAddressToFp_ = pc;
         return true;
     }
 
-    if (entry.isBaseline()) {
+    if (entry->isBaseline()) {
         // If looked-up callee doesn't match frame callee, don't accept lastProfilingCallSite
-        if (forLastCallSite && entry.baselineEntry().script() != callee)
+        if (forLastCallSite && entry->baselineEntry().script() != callee)
             return false;
 
         type_ = JitFrame_BaselineJS;
         returnAddressToFp_ = pc;
         return true;
     }
 
-    if (entry.isIonCache()) {
-        JitcodeGlobalEntry ionEntry;
-        table->lookupInfallible(entry.ionCacheEntry().rejoinAddr(), &ionEntry, rt);
+    if (entry->isIonCache()) {
+        void* ptr = entry->ionCacheEntry().rejoinAddr();
+        const JitcodeGlobalEntry& ionEntry = table->lookupInfallible(ptr);
         MOZ_ASSERT(ionEntry.isIon());
 
         if (ionEntry.ionEntry().getScript(0) != callee)
             return false;
 
         type_ = JitFrame_IonJS;
         returnAddressToFp_ = pc;
         return true;
--- a/js/src/jit/JitcodeMap.cpp
+++ b/js/src/jit/JitcodeMap.cpp
@@ -211,61 +211,59 @@ void
 JitcodeGlobalEntry::BaselineEntry::destroy()
 {
     if (!str_)
         return;
     js_free((void*) str_);
     str_ = nullptr;
 }
 
-static inline void
-RejoinEntry(JSRuntime* rt, const JitcodeGlobalEntry::IonCacheEntry& cache,
-            void* ptr, JitcodeGlobalEntry* entry)
+static inline JitcodeGlobalEntry&
+RejoinEntry(JSRuntime* rt, const JitcodeGlobalEntry::IonCacheEntry& cache, void* ptr)
 {
     MOZ_ASSERT(cache.containsPointer(ptr));
 
     // There must exist an entry for the rejoin addr if this entry exists.
     JitRuntime* jitrt = rt->jitRuntime();
-    jitrt->getJitcodeGlobalTable()->lookupInfallible(cache.rejoinAddr(), entry, rt);
-    MOZ_ASSERT(entry->isIon());
+    JitcodeGlobalEntry& entry =
+        jitrt->getJitcodeGlobalTable()->lookupInfallible(cache.rejoinAddr());
+    MOZ_ASSERT(entry.isIon());
+    return entry;
 }
 
 void*
 JitcodeGlobalEntry::IonCacheEntry::canonicalNativeAddrFor(JSRuntime* rt, void* ptr) const
 {
     return nativeStartAddr_;
 }
 
 bool
 JitcodeGlobalEntry::IonCacheEntry::callStackAtAddr(JSRuntime* rt, void* ptr,
                                                    BytecodeLocationVector& results,
                                                    uint32_t* depth) const
 {
-    JitcodeGlobalEntry entry;
-    RejoinEntry(rt, *this, ptr, &entry);
+    const JitcodeGlobalEntry& entry = RejoinEntry(rt, *this, ptr);
     return entry.callStackAtAddr(rt, rejoinAddr(), results, depth);
 }
 
 uint32_t
 JitcodeGlobalEntry::IonCacheEntry::callStackAtAddr(JSRuntime* rt, void* ptr,
                                                    const char** results,
                                                    uint32_t maxResults) const
 {
-    JitcodeGlobalEntry entry;
-    RejoinEntry(rt, *this, ptr, &entry);
+    const JitcodeGlobalEntry& entry = RejoinEntry(rt, *this, ptr);
     return entry.callStackAtAddr(rt, rejoinAddr(), results, maxResults);
 }
 
 void
 JitcodeGlobalEntry::IonCacheEntry::youngestFrameLocationAtAddr(JSRuntime* rt, void* ptr,
                                                                JSScript** script,
                                                                jsbytecode** pc) const
 {
-    JitcodeGlobalEntry entry;
-    RejoinEntry(rt, *this, ptr, &entry);
+    const JitcodeGlobalEntry& entry = RejoinEntry(rt, *this, ptr);
     return entry.youngestFrameLocationAtAddr(rt, rejoinAddr(), script, pc);
 }
 
 
 static int ComparePointers(const void* a, const void* b) {
     const uint8_t* a_ptr = reinterpret_cast<const uint8_t*>(a);
     const uint8_t* b_ptr = reinterpret_cast<const uint8_t*>(b);
     if (a_ptr < b_ptr)
@@ -427,45 +425,27 @@ JitcodeGlobalTable::Enum::popFront()
 
 void
 JitcodeGlobalTable::Enum::removeFront()
 {
     MOZ_ASSERT(!empty());
     table_.releaseEntry(*cur_, prevTower_, rt_);
 }
 
-bool
-JitcodeGlobalTable::lookup(void* ptr, JitcodeGlobalEntry* result, JSRuntime* rt)
+const JitcodeGlobalEntry&
+JitcodeGlobalTable::lookupForSamplerInfallible(void* ptr, JSRuntime* rt, uint32_t sampleBufferGen)
 {
-    MOZ_ASSERT(result);
-
     JitcodeGlobalEntry* entry = lookupInternal(ptr);
-    if (!entry)
-        return false;
-
-    *result = *entry;
-    return true;
-}
-
-bool
-JitcodeGlobalTable::lookupForSampler(void* ptr, JitcodeGlobalEntry* result, JSRuntime* rt,
-                                     uint32_t sampleBufferGen)
-{
-    MOZ_ASSERT(result);
-
-    JitcodeGlobalEntry* entry = lookupInternal(ptr);
-    if (!entry)
-        return false;
+    MOZ_ASSERT(entry);
 
     entry->setGeneration(sampleBufferGen);
 
     // IonCache entries must keep their corresponding Ion entries alive.
     if (entry->isIonCache()) {
-        JitcodeGlobalEntry rejoinEntry;
-        RejoinEntry(rt, entry->ionCacheEntry(), ptr, &rejoinEntry);
+        JitcodeGlobalEntry& rejoinEntry = RejoinEntry(rt, entry->ionCacheEntry(), ptr);
         rejoinEntry.setGeneration(sampleBufferGen);
     }
 
 #ifdef DEBUG
     // JitcodeGlobalEntries are marked during the beginning of the sweep
     // phase. A read barrier is not needed, as any JS frames sampled during
     // the sweep phase of the GC must be on stack, and on-stack frames must
     // already be marked at the beginning of the sweep phase. This assumption
@@ -473,18 +453,17 @@ JitcodeGlobalTable::lookupForSampler(voi
     if (rt->isHeapBusy() &&
         rt->gc.stats.currentPhase() >= gcstats::PHASE_FINALIZE_START &&
         rt->gc.stats.currentPhase() <= gcstats::PHASE_FINALIZE_END)
     {
         MOZ_ASSERT(entry->isMarkedFromAnyThread(rt));
     }
 #endif
 
-    *result = *entry;
-    return true;
+    return *entry;
 }
 
 JitcodeGlobalEntry*
 JitcodeGlobalTable::lookupInternal(void* ptr)
 {
     JitcodeGlobalEntry query = JitcodeGlobalEntry::MakeQuery(ptr);
     JitcodeGlobalEntry* searchTower[JitcodeSkiplistTower::MAX_HEIGHT];
     searchInternal(query, searchTower);
@@ -989,47 +968,43 @@ JitcodeGlobalEntry::IonEntry::isMarkedFr
 
     return true;
 }
 
 template <class ShouldMarkProvider>
 bool
 JitcodeGlobalEntry::IonCacheEntry::mark(JSTracer* trc)
 {
-    JitcodeGlobalEntry entry;
-    RejoinEntry(trc->runtime(), *this, nativeStartAddr(), &entry);
+    JitcodeGlobalEntry& entry = RejoinEntry(trc->runtime(), *this, nativeStartAddr());
     return entry.mark<ShouldMarkProvider>(trc);
 }
 
 void
 JitcodeGlobalEntry::IonCacheEntry::sweepChildren(JSRuntime* rt)
 {
-    JitcodeGlobalEntry entry;
-    RejoinEntry(rt, *this, nativeStartAddr(), &entry);
+    JitcodeGlobalEntry& entry = RejoinEntry(rt, *this, nativeStartAddr());
     entry.sweepChildren(rt);
 }
 
 bool
 JitcodeGlobalEntry::IonCacheEntry::isMarkedFromAnyThread(JSRuntime* rt)
 {
-    JitcodeGlobalEntry entry;
-    RejoinEntry(rt, *this, nativeStartAddr(), &entry);
+    JitcodeGlobalEntry& entry = RejoinEntry(rt, *this, nativeStartAddr());
     return entry.isMarkedFromAnyThread(rt);
 }
 
 Maybe<uint8_t>
 JitcodeGlobalEntry::IonCacheEntry::trackedOptimizationIndexAtAddr(
         JSRuntime *rt,
         void* ptr,
         uint32_t* entryOffsetOut)
 {
     MOZ_ASSERT(hasTrackedOptimizations());
     MOZ_ASSERT(containsPointer(ptr));
-    JitcodeGlobalEntry entry;
-    RejoinEntry(rt, *this, ptr, &entry);
+    JitcodeGlobalEntry& entry = RejoinEntry(rt, *this, ptr);
 
     if (!entry.hasTrackedOptimizations())
         return mozilla::Nothing();
 
     uint32_t mainEntryOffsetOut;
     Maybe<uint8_t> maybeIndex =
         entry.trackedOptimizationIndexAtAddr(rt, rejoinAddr(), &mainEntryOffsetOut);
     if (maybeIndex.isNothing())
@@ -1039,33 +1014,31 @@ JitcodeGlobalEntry::IonCacheEntry::track
     *entryOffsetOut = 0;
     return maybeIndex;
 }
 
 void
 JitcodeGlobalEntry::IonCacheEntry::forEachOptimizationAttempt(
         JSRuntime *rt, uint8_t index, JS::ForEachTrackedOptimizationAttemptOp& op)
 {
-    JitcodeGlobalEntry entry;
-    RejoinEntry(rt, *this, nativeStartAddr(), &entry);
+    JitcodeGlobalEntry& entry =  RejoinEntry(rt, *this, nativeStartAddr());
     if (!entry.hasTrackedOptimizations())
         return;
     entry.forEachOptimizationAttempt(rt, index, op);
 
     // Record the outcome associated with the stub.
     op(JS::TrackedStrategy::InlineCache_OptimizedStub, trackedOutcome_);
 }
 
 void
 JitcodeGlobalEntry::IonCacheEntry::forEachOptimizationTypeInfo(
         JSRuntime *rt, uint8_t index,
         IonTrackedOptimizationsTypeInfo::ForEachOpAdapter& op)
 {
-    JitcodeGlobalEntry entry;
-    RejoinEntry(rt, *this, nativeStartAddr(), &entry);
+    JitcodeGlobalEntry& entry = RejoinEntry(rt, *this, nativeStartAddr());
     if (!entry.hasTrackedOptimizations())
         return;
     entry.forEachOptimizationTypeInfo(rt, index, op);
 }
 
 /* static */ void
 JitcodeRegionEntry::WriteHead(CompactBufferWriter& writer,
                               uint32_t nativeOffset, uint8_t scriptDepth)
@@ -1672,18 +1645,17 @@ JS::ForEachProfiledFrameOp::FrameHandle:
         return JS::ProfilingFrameIterator::Frame_Baseline;
     return JS::ProfilingFrameIterator::Frame_Ion;
 }
 
 JS_PUBLIC_API(void)
 JS::ForEachProfiledFrame(JSRuntime* rt, void* addr, ForEachProfiledFrameOp& op)
 {
     js::jit::JitcodeGlobalTable* table = rt->jitRuntime()->getJitcodeGlobalTable();
-    js::jit::JitcodeGlobalEntry entry;
-    table->lookupInfallible(addr, &entry, rt);
+    js::jit::JitcodeGlobalEntry& entry = table->lookupInfallible(addr);
 
     // Extract the stack for the entry.  Assume maximum inlining depth is <64
     const char* labels[64];
     uint32_t depth = entry.callStackAtAddr(rt, addr, labels, 64);
     MOZ_ASSERT(depth < 64);
     for (uint32_t i = depth; i != 0; i--) {
         JS::ForEachProfiledFrameOp::FrameHandle handle(rt, entry, addr, labels[i - 1], i - 1);
         op(handle);
--- a/js/src/jit/JitcodeMap.h
+++ b/js/src/jit/JitcodeMap.h
@@ -1024,25 +1024,29 @@ class JitcodeGlobalTable
             freeTowers_[i] = nullptr;
     }
     ~JitcodeGlobalTable() {}
 
     bool empty() const {
         return skiplistSize_ == 0;
     }
 
-    bool lookup(void* ptr, JitcodeGlobalEntry* result, JSRuntime* rt);
-    bool lookupForSampler(void* ptr, JitcodeGlobalEntry* result, JSRuntime* rt,
-                          uint32_t sampleBufferGen);
+    const JitcodeGlobalEntry* lookup(void* ptr) {
+        return lookupInternal(ptr);
+    }
 
-    void lookupInfallible(void* ptr, JitcodeGlobalEntry* result, JSRuntime* rt) {
-        mozilla::DebugOnly<bool> success = lookup(ptr, result, rt);
-        MOZ_ASSERT(success);
+    JitcodeGlobalEntry& lookupInfallible(void* ptr) {
+        JitcodeGlobalEntry* entry = lookupInternal(ptr);
+        MOZ_ASSERT(entry);
+        return *entry;
     }
 
+    const JitcodeGlobalEntry& lookupForSamplerInfallible(void* ptr, JSRuntime* rt,
+                                                         uint32_t sampleBufferGen);
+
     bool addEntry(const JitcodeGlobalEntry::IonEntry& entry, JSRuntime* rt) {
         return addEntry(JitcodeGlobalEntry(entry), rt);
     }
     bool addEntry(const JitcodeGlobalEntry::BaselineEntry& entry, JSRuntime* rt) {
         return addEntry(JitcodeGlobalEntry(entry), rt);
     }
     bool addEntry(const JitcodeGlobalEntry::IonCacheEntry& entry, JSRuntime* rt) {
         return addEntry(JitcodeGlobalEntry(entry), rt);
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -4836,19 +4836,18 @@ ReflectTrackedOptimizations(JSContext* c
         args.rval().setNull();
         return true;
     }
 
     // Suppress GC for the unrooted JitcodeGlobalEntry below.
     gc::AutoSuppressGC suppress(cx);
 
     jit::JitcodeGlobalTable* table = rt->jitRuntime()->getJitcodeGlobalTable();
-    jit::JitcodeGlobalEntry entry;
     jit::IonScript* ion = fun->nonLazyScript()->ionScript();
-    table->lookupInfallible(ion->method()->raw(), &entry, rt);
+    jit::JitcodeGlobalEntry& entry = table->lookupInfallible(ion->method()->raw());
 
     if (!entry.hasTrackedOptimizations()) {
         JSObject* obj = JS_NewPlainObject(cx);
         if (!obj)
             return false;
         args.rval().setObject(*obj);
         return true;
     }
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -1933,19 +1933,19 @@ JS::ProfilingFrameIterator::getPhysicalF
     }
 
     MOZ_ASSERT(isJit());
 
     // Look up an entry for the return address.
     void* returnAddr = jitIter().returnAddressToFp();
     jit::JitcodeGlobalTable* table = rt_->jitRuntime()->getJitcodeGlobalTable();
     if (hasSampleBufferGen())
-        table->lookupForSampler(returnAddr, entry, rt_, sampleBufferGen_);
+        *entry = table->lookupForSamplerInfallible(returnAddr, rt_, sampleBufferGen_);
     else
-        table->lookupInfallible(returnAddr, entry, rt_);
+        *entry = table->lookupInfallible(returnAddr);
 
     MOZ_ASSERT(entry->isIon() || entry->isIonCache() || entry->isBaseline() || entry->isDummy());
 
     // Dummy frames produce no stack frames.
     if (entry->isDummy())
         return mozilla::Nothing();
 
     Frame frame;