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 831132 92b4cab82784725d2a0b83157cab605e8d3db2ea
parent 831131 9a64325eeacb61c7de1e00977233a234627b7f44
child 831133 68b7d42b931d9b0e7be37ad0098eb1b013e6cdca
push id118868
push userbmo:zjz@zjz.name
push dateFri, 24 Aug 2018 07:04:39 +0000
reviewersjandem
bugs1479603
milestone63.0a1
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);
 };