Bug 1479603 - [Part 4] Remove SharedIC support from Ion r=jandem
authorMatthew Gaudet <mgaudet@mozilla.com>
Thu, 16 Aug 2018 10:42:30 -0700
changeset 490871 92b4cab82784725d2a0b83157cab605e8d3db2ea
parent 490870 9a64325eeacb61c7de1e00977233a234627b7f44
child 490872 68b7d42b931d9b0e7be37ad0098eb1b013e6cdca
push id1815
push userffxbld-merge
push dateMon, 15 Oct 2018 10:40:45 +0000
treeherdermozilla-release@18d4c09e9378 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1479603
milestone63.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 1479603 - [Part 4] Remove SharedIC support from Ion r=jandem
js/src/jit/CodeGenerator.cpp
js/src/jit/CodeGenerator.h
js/src/jit/Ion.cpp
js/src/jit/IonCode.h
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -10291,61 +10291,16 @@ CodeGenerator::generate()
 
     // Dump Native to bytecode entries to spew.
     dumpNativeToBytecodeEntries();
 
     return !masm.oom();
 }
 
 bool
-CodeGenerator::linkSharedStubs(JSContext* cx)
-{
-    for (uint32_t i = 0; i < sharedStubs_.length(); i++) {
-        ICStub *stub = nullptr;
-
-        switch (sharedStubs_[i].kind) {
-          case ICStub::Kind::Compare_Fallback: {
-            ICCompare_Fallback::Compiler stubCompiler(cx, ICStubCompiler::Engine::IonSharedIC);
-            stub = stubCompiler.getStub(&stubSpace_);
-            break;
-          }
-          case ICStub::Kind::GetProp_Fallback: {
-            ICGetProp_Fallback::Compiler stubCompiler(cx, ICStubCompiler::Engine::IonSharedIC);
-            stub = stubCompiler.getStub(&stubSpace_);
-            break;
-          }
-          case ICStub::Kind::NewArray_Fallback: {
-            JSScript* script = sharedStubs_[i].entry.script();
-            jsbytecode* pc = sharedStubs_[i].entry.pc(script);
-            ObjectGroup* group = ObjectGroup::allocationSiteGroup(cx, script, pc, JSProto_Array);
-            if (!group)
-                return false;
-
-            ICNewArray_Fallback::Compiler stubCompiler(cx, group, ICStubCompiler::Engine::IonSharedIC);
-            stub = stubCompiler.getStub(&stubSpace_);
-            break;
-          }
-          case ICStub::Kind::NewObject_Fallback: {
-            ICNewObject_Fallback::Compiler stubCompiler(cx, ICStubCompiler::Engine::IonSharedIC);
-            stub = stubCompiler.getStub(&stubSpace_);
-            break;
-          }
-          default:
-            MOZ_CRASH("Unsupported shared stub.");
-        }
-
-        if (!stub)
-            return false;
-
-        sharedStubs_[i].entry.setFirstStub(stub);
-    }
-    return true;
-}
-
-bool
 CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints)
 {
     // We cancel off-thread Ion compilations in a few places during GC, but if
     // this compilation was performed off-thread it will already have been
     // removed from the relevant lists by this point. Don't allow GC here.
     JS::AutoAssertNoGC nogc(cx);
 
     RootedScript script(cx, gen->info().script());
@@ -10363,19 +10318,16 @@ CodeGenerator::link(JSContext* cx, Compi
         // Do a normal invalidate, except don't cancel offThread compilations,
         // since that will cancel this compilation too.
         Invalidate(cx, script, /* resetUses */ false, /* cancelOffThread*/ false);
     }
 
     if (scriptCounts_ && !script->hasScriptCounts() && !script->initScriptCounts(cx))
         return false;
 
-    if (!linkSharedStubs(cx))
-        return false;
-
     // Check to make sure we didn't have a mid-build invalidation. If so, we
     // will trickle to jit::Compile() and return Method_Skipped.
     uint32_t warmUpCount = script->getWarmUpCount();
 
     IonCompilationId compilationId = cx->runtime()->jitRuntime()->nextCompilationId();
     cx->zone()->types.currentCompilationIdRef().emplace(compilationId);
     auto resetCurrentId = mozilla::MakeScopeExit([cx] {
         cx->zone()->types.currentCompilationIdRef().reset();
@@ -10408,18 +10360,17 @@ CodeGenerator::link(JSContext* cx, Compi
 
     IonScript* ionScript =
         IonScript::New(cx, compilationId,
                        graph.totalSlotCount(), argumentSlots, scriptFrameSize,
                        snapshots_.listSize(), snapshots_.RVATableSize(),
                        recovers_.size(), bailouts_.length(), graph.numConstants(),
                        safepointIndices_.length(), osiIndices_.length(),
                        icList_.length(), runtimeData_.length(),
-                       safepoints_.size(), sharedStubs_.length(),
-                       optimizationLevel);
+                       safepoints_.size(), optimizationLevel);
     if (!ionScript)
         return false;
     auto guardIonScript = mozilla::MakeScopeExit([&ionScript] {
         // Use js_free instead of IonScript::Destroy: the cache list is still
         // uninitialized.
         js_free(ionScript);
     });
 
@@ -10550,32 +10501,16 @@ CodeGenerator::link(JSContext* cx, Compi
                 Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, patchableTLScripts_[i]),
                                                    ImmPtr((void*) uintptr_t(textId)),
                                                    ImmPtr((void*)0));
             }
         }
     }
 #endif
 
-    // Patch shared stub IC loads using IC entries
-    for (size_t i = 0; i < sharedStubs_.length(); i++) {
-        CodeOffset label = sharedStubs_[i].label;
-
-        IonICEntry& entry = ionScript->sharedStubList()[i];
-        entry = sharedStubs_[i].entry;
-        Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, label),
-                                           ImmPtr(&entry),
-                                           ImmPtr((void*)-1));
-
-        MOZ_ASSERT(entry.hasStub());
-        MOZ_ASSERT(entry.firstStub()->isFallback());
-
-        entry.firstStub()->toFallbackStub()->fixupICEntry(&entry);
-    }
-
     // for generating inline caches during the execution.
     if (runtimeData_.length())
         ionScript->copyRuntimeData(&runtimeData_[0]);
     if (icList_.length())
         ionScript->copyICEntries(&icList_[0]);
 
     for (size_t i = 0; i < icInfo_.length(); i++) {
         IonIC& ic = ionScript->getICFromIndex(i);
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -71,17 +71,16 @@ class CodeGenerator final : public CodeG
     CodeGenerator(MIRGenerator* gen, LIRGraph* graph, MacroAssembler* masm = nullptr);
     ~CodeGenerator();
 
     MOZ_MUST_USE bool generate();
     MOZ_MUST_USE bool generateWasm(wasm::FuncTypeIdDesc funcTypeId, wasm::BytecodeOffset trapOffset,
                                    wasm::FuncOffsets* offsets);
 
     MOZ_MUST_USE bool link(JSContext* cx, CompilerConstraintList* constraints);
-    MOZ_MUST_USE bool linkSharedStubs(JSContext* cx);
 
     void emitOOLTestObject(Register objreg, Label* ifTruthy, Label* ifFalsy, Register scratch);
     void emitIntToString(Register input, Register output, Label* ool);
 
     void visitOutOfLineRegExpMatcher(OutOfLineRegExpMatcher* ool);
     void visitOutOfLineRegExpSearcher(OutOfLineRegExpSearcher* ool);
     void visitOutOfLineRegExpTester(OutOfLineRegExpTester* ool);
     void visitOutOfLineRegExpPrototypeOptimizable(OutOfLineRegExpPrototypeOptimizable* ool);
@@ -284,28 +283,16 @@ class CodeGenerator final : public CodeG
 
     void emitAssertRangeI(const Range* r, Register input);
     void emitAssertRangeD(const Range* r, FloatRegister input, FloatRegister temp);
 
     void maybeEmitGlobalBarrierCheck(const LAllocation* maybeGlobal, OutOfLineCode* ool);
 
     Vector<CodeOffset, 0, JitAllocPolicy> ionScriptLabels_;
 
-    struct SharedStub {
-        ICStub::Kind kind;
-        IonICEntry entry;
-        CodeOffset label;
-
-        SharedStub(ICStub::Kind kind, IonICEntry entry, CodeOffset label)
-          : kind(kind), entry(entry), label(label)
-        {}
-    };
-
-    Vector<SharedStub, 0, SystemAllocPolicy> sharedStubs_;
-
     void branchIfInvalidated(Register temp, Label* invalidated);
 
 #ifdef DEBUG
     void emitDebugResultChecks(LInstruction* ins);
     void emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mir);
     void emitValueResultChecks(LInstruction* lir, MDefinition* mir);
 #endif
 
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -825,35 +825,33 @@ IonScript::IonScript(IonCompilationId co
     osiIndexEntries_(0),
     snapshots_(0),
     snapshotsListSize_(0),
     snapshotsRVATableSize_(0),
     recovers_(0),
     recoversSize_(0),
     constantTable_(0),
     constantEntries_(0),
-    sharedStubList_(0),
-    sharedStubEntries_(0),
     invalidationCount_(0),
     compilationId_(compilationId),
     optimizationLevel_(OptimizationLevel::Normal),
     osrPcMismatchCounter_(0),
     fallbackStubSpace_()
 {
 }
 
 IonScript*
 IonScript::New(JSContext* cx, IonCompilationId compilationId,
                uint32_t frameSlots, uint32_t argumentSlots, uint32_t frameSize,
                size_t snapshotsListSize, size_t snapshotsRVATableSize,
                size_t recoversSize, size_t bailoutEntries,
                size_t constants, size_t safepointIndices,
                size_t osiIndices, size_t icEntries,
                size_t runtimeSize,  size_t safepointsSize,
-               size_t sharedStubEntries, OptimizationLevel optimizationLevel)
+               OptimizationLevel optimizationLevel)
 {
     constexpr size_t DataAlignment = sizeof(void*);
 
     if (snapshotsListSize >= MAX_BUFFER_SIZE ||
         (bailoutEntries >= MAX_BUFFER_SIZE / sizeof(uint32_t)))
     {
         ReportOutOfMemory(cx);
         return nullptr;
@@ -866,28 +864,26 @@ IonScript::New(JSContext* cx, IonCompila
     size_t paddedRecoversSize = AlignBytes(recoversSize, DataAlignment);
     size_t paddedBailoutSize = AlignBytes(bailoutEntries * sizeof(uint32_t), DataAlignment);
     size_t paddedConstantsSize = AlignBytes(constants * sizeof(Value), DataAlignment);
     size_t paddedSafepointIndicesSize = AlignBytes(safepointIndices * sizeof(SafepointIndex), DataAlignment);
     size_t paddedOsiIndicesSize = AlignBytes(osiIndices * sizeof(OsiIndex), DataAlignment);
     size_t paddedICEntriesSize = AlignBytes(icEntries * sizeof(uint32_t), DataAlignment);
     size_t paddedRuntimeSize = AlignBytes(runtimeSize, DataAlignment);
     size_t paddedSafepointSize = AlignBytes(safepointsSize, DataAlignment);
-    size_t paddedSharedStubSize = AlignBytes(sharedStubEntries * sizeof(IonICEntry), DataAlignment);
 
     size_t bytes = paddedSnapshotsSize +
                    paddedRecoversSize +
                    paddedBailoutSize +
                    paddedConstantsSize +
                    paddedSafepointIndicesSize +
                    paddedOsiIndicesSize +
                    paddedICEntriesSize +
                    paddedRuntimeSize +
-                   paddedSafepointSize +
-                   paddedSharedStubSize;
+                   paddedSafepointSize;
     IonScript* script = cx->pod_malloc_with_extra<IonScript, uint8_t>(bytes);
     if (!script)
         return nullptr;
     new (script) IonScript(compilationId);
 
     uint32_t offsetCursor = sizeof(IonScript);
 
     script->runtimeData_ = offsetCursor;
@@ -922,20 +918,16 @@ IonScript::New(JSContext* cx, IonCompila
     script->recovers_ = offsetCursor;
     script->recoversSize_ = recoversSize;
     offsetCursor += paddedRecoversSize;
 
     script->constantTable_ = offsetCursor;
     script->constantEntries_ = constants;
     offsetCursor += paddedConstantsSize;
 
-    script->sharedStubList_ = offsetCursor;
-    script->sharedStubEntries_ = sharedStubEntries;
-    offsetCursor += paddedSharedStubSize;
-
     script->frameSlots_ = frameSlots;
     script->argumentSlots_ = argumentSlots;
 
     script->frameSize_ = frameSize;
 
     script->optimizationLevel_ = optimizationLevel;
 
     return script;
@@ -952,22 +944,16 @@ void
 IonScript::trace(JSTracer* trc)
 {
     if (method_)
         TraceEdge(trc, &method_, "method");
 
     for (size_t i = 0; i < numConstants(); i++)
         TraceEdge(trc, &getConstant(i), "constant");
 
-    // Mark all IC stub codes hanging off the IC stub entries.
-    for (size_t i = 0; i < numSharedStubs(); i++) {
-        IonICEntry& ent = sharedStubList()[i];
-        ent.trace(trc);
-    }
-
     // Trace caches so that the JSScript pointer can be updated if moved.
     for (size_t i = 0; i < numICs(); i++)
         getICFromIndex(i).trace(trc);
 }
 
 /* static */ void
 IonScript::writeBarrierPre(Zone* zone, IonScript* ionScript)
 {
@@ -1146,72 +1132,16 @@ IonScript::Destroy(FreeOp* fop, IonScrip
 
 void
 JS::DeletePolicy<js::jit::IonScript>::operator()(const js::jit::IonScript* script)
 {
     IonScript::Destroy(rt_->defaultFreeOp(), const_cast<IonScript*>(script));
 }
 
 void
-IonScript::purgeOptimizedStubs(Zone* zone)
-{
-    for (size_t i = 0; i < numSharedStubs(); i++) {
-        IonICEntry& entry = sharedStubList()[i];
-        if (!entry.hasStub())
-            continue;
-
-        ICStub* lastStub = entry.firstStub();
-        while (lastStub->next())
-            lastStub = lastStub->next();
-
-        if (lastStub->isFallback()) {
-            // Unlink all stubs allocated in the optimized space.
-            ICStub* stub = entry.firstStub();
-            ICStub* prev = nullptr;
-
-            while (stub->next()) {
-                if (!stub->allocatedInFallbackSpace()) {
-                    lastStub->toFallbackStub()->unlinkStub(zone, prev, stub);
-                    stub = stub->next();
-                    continue;
-                }
-
-                prev = stub;
-                stub = stub->next();
-            }
-
-            lastStub->toFallbackStub()->setInvalid();
-
-            MOZ_ASSERT(!lastStub->isMonitoredFallback(),
-                       "None of the shared stubs used in Ion are monitored");
-        } else if (lastStub->isTypeMonitor_Fallback()) {
-            lastStub->toTypeMonitor_Fallback()->resetMonitorStubChain(zone);
-            lastStub->toTypeMonitor_Fallback()->setInvalid();
-        } else {
-            MOZ_ASSERT(lastStub->isTableSwitch());
-        }
-    }
-
-#ifdef DEBUG
-    // All remaining stubs must be allocated in the fallback space.
-    for (size_t i = 0; i < numSharedStubs(); i++) {
-        IonICEntry& entry = sharedStubList()[i];
-        if (!entry.hasStub())
-            continue;
-
-        ICStub* stub = entry.firstStub();
-        while (stub->next()) {
-            MOZ_ASSERT(stub->allocatedInFallbackSpace());
-            stub = stub->next();
-        }
-    }
-#endif
-}
-
-void
 IonScript::purgeICs(Zone* zone)
 {
     for (size_t i = 0; i < numICs(); i++)
         getICFromIndex(i).reset(zone);
 }
 
 namespace js {
 namespace jit {
@@ -2728,17 +2658,16 @@ InvalidateActivation(FreeOp* fop, const 
             continue;
 
         IonScript* ionScript = script->ionScript();
 
         // Purge ICs before we mark this script as invalidated. This will
         // prevent lastJump_ from appearing to be a bogus pointer, just
         // in case anyone tries to read it.
         ionScript->purgeICs(script->zone());
-        ionScript->purgeOptimizedStubs(script->zone());
 
         // This frame needs to be invalidated. We do the following:
         //
         // 1. Increment the reference counter to keep the ionScript alive
         //    for the invalidation bailout or for the exception handler.
         // 2. Determine safepoint that corresponds to the current call.
         // 3. From safepoint, get distance to the OSI-patchable offset.
         // 4. From the IonScript, determine the distance between the
--- a/js/src/jit/IonCode.h
+++ b/js/src/jit/IonCode.h
@@ -253,20 +253,16 @@ struct IonScript
     // List of instructions needed to recover stack frames.
     uint32_t recovers_;
     uint32_t recoversSize_;
 
     // Constant table for constants stored in snapshots.
     uint32_t constantTable_;
     uint32_t constantEntries_;
 
-    // List of entries to the shared stub.
-    uint32_t sharedStubList_;
-    uint32_t sharedStubEntries_;
-
     // Number of references from invalidation records.
     uint32_t invalidationCount_;
 
     // Identifier of the compilation which produced this code.
     IonCompilationId compilationId_;
 
     // The optimization level this script was compiled in.
     OptimizationLevel optimizationLevel_;
@@ -331,17 +327,17 @@ struct IonScript
 
     static IonScript* New(JSContext* cx, IonCompilationId compilationId,
                           uint32_t frameSlots, uint32_t argumentSlots, uint32_t frameSize,
                           size_t snapshotsListSize, size_t snapshotsRVATableSize,
                           size_t recoversSize, size_t bailoutEntries,
                           size_t constants, size_t safepointIndexEntries,
                           size_t osiIndexEntries, size_t icEntries,
                           size_t runtimeSize, size_t safepointsSize,
-                          size_t sharedStubEntries, OptimizationLevel optimizationLevel);
+                          OptimizationLevel optimizationLevel);
     static void Trace(JSTracer* trc, IonScript* script);
     static void Destroy(FreeOp* fop, IonScript* script);
 
     static inline size_t offsetOfMethod() {
         return offsetof(IonScript, method_);
     }
     static inline size_t offsetOfOsrEntryOffset() {
         return offsetof(IonScript, osrEntryOffset_);
@@ -486,22 +482,16 @@ struct IonScript
     }
     inline IonIC& getIC(uint32_t offset) {
         MOZ_ASSERT(offset < runtimeSize_);
         return *(IonIC*) &runtimeData()[offset];
     }
     size_t numICs() const {
         return icEntries_;
     }
-    IonICEntry* sharedStubList() {
-        return (IonICEntry*) &bottomBuffer()[sharedStubList_];
-    }
-    size_t numSharedStubs() const {
-        return sharedStubEntries_;
-    }
     size_t runtimeSize() const {
         return runtimeSize_;
     }
     void purgeICs(Zone* zone);
     void copySnapshots(const SnapshotWriter* writer);
     void copyRecovers(const RecoverWriter* writer);
     void copyBailoutTable(const SnapshotOffset* table);
     void copyConstants(const Value* vp);
@@ -554,17 +544,16 @@ struct IonScript
     void clearRecompiling() {
         recompiling_ = false;
     }
 
     FallbackICStubSpace* fallbackStubSpace() {
         return &fallbackStubSpace_;
     }
     void adoptFallbackStubs(FallbackICStubSpace* stubSpace);
-    void purgeOptimizedStubs(Zone* zone);
 
     enum ShouldIncreaseAge {
         IncreaseAge = true,
         KeepAge = false
     };
 
     static void writeBarrierPre(Zone* zone, IonScript* ionScript);
 };