Bug 1479603 - [Part 11] Remove SharedIC.h,cpp r=jandem
authorMatthew Gaudet <mgaudet@mozilla.com>
Wed, 22 Aug 2018 15:12:30 -0400
changeset 831139 5a2381311cedc81a16222f90b854675fa004c4db
parent 831138 370a45e8ea65c3fe50b9abd4651c525c18ab6934
child 831140 1d0c2d31df1e988a334a3cada9eb5113f1610e69
push id118868
push userbmo:zjz@zjz.name
push dateFri, 24 Aug 2018 07:04:39 +0000
reviewersjandem
bugs1479603
milestone63.0a1
Bug 1479603 - [Part 11] Remove SharedIC.h,cpp r=jandem
js/src/jit/BaselineIC.cpp
js/src/jit/BaselineIC.h
js/src/jit/CacheIR.h
js/src/jit/JitRealm.h
js/src/jit/SharedIC.cpp
js/src/jit/SharedIC.h
js/src/moz.build
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -1,17 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 #include "jit/BaselineIC.h"
 
+#include "mozilla/Casting.h"
 #include "mozilla/DebugOnly.h"
+#include "mozilla/IntegerPrintfMacros.h"
+#include "mozilla/Sprintf.h"
 #include "mozilla/TemplateLib.h"
 
 #include "jsfriendapi.h"
 #include "jslibmath.h"
 #include "jstypes.h"
 
 #include "builtin/Eval.h"
 #include "gc/Policy.h"
@@ -46,16 +49,295 @@
 #include "vm/StringObject-inl.h"
 #include "vm/UnboxedObject-inl.h"
 
 using mozilla::DebugOnly;
 
 namespace js {
 namespace jit {
 
+
+#ifdef JS_JITSPEW
+void
+FallbackICSpew(JSContext* cx, ICFallbackStub* stub, const char* fmt, ...)
+{
+    if (JitSpewEnabled(JitSpew_BaselineICFallback)) {
+        RootedScript script(cx, GetTopJitJSScript(cx));
+        jsbytecode* pc = stub->icEntry()->pc(script);
+
+        char fmtbuf[100];
+        va_list args;
+        va_start(args, fmt);
+        (void) VsprintfLiteral(fmtbuf, fmt, args);
+        va_end(args);
+
+        JitSpew(JitSpew_BaselineICFallback,
+                "Fallback hit for (%s:%u) (pc=%zu,line=%d,uses=%d,stubs=%zu): %s",
+                script->filename(),
+                script->lineno(),
+                script->pcToOffset(pc),
+                PCToLineNumber(script, pc),
+                script->getWarmUpCount(),
+                stub->numOptimizedStubs(),
+                fmtbuf);
+    }
+}
+
+void
+TypeFallbackICSpew(JSContext* cx, ICTypeMonitor_Fallback* stub, const char* fmt, ...)
+{
+    if (JitSpewEnabled(JitSpew_BaselineICFallback)) {
+        RootedScript script(cx, GetTopJitJSScript(cx));
+        jsbytecode* pc = stub->icEntry()->pc(script);
+
+        char fmtbuf[100];
+        va_list args;
+        va_start(args, fmt);
+        (void) VsprintfLiteral(fmtbuf, fmt, args);
+        va_end(args);
+
+        JitSpew(JitSpew_BaselineICFallback,
+                "Type monitor fallback hit for (%s:%u) (pc=%zu,line=%d,uses=%d,stubs=%d): %s",
+                script->filename(),
+                script->lineno(),
+                script->pcToOffset(pc),
+                PCToLineNumber(script, pc),
+                script->getWarmUpCount(),
+                (int) stub->numOptimizedMonitorStubs(),
+                fmtbuf);
+    }
+}
+#endif // JS_JITSPEW
+
+ICFallbackStub*
+ICEntry::fallbackStub() const
+{
+    return firstStub()->getChainFallback();
+}
+
+void
+ICEntry::trace(JSTracer* trc)
+{
+    if (!hasStub())
+        return;
+    for (ICStub* stub = firstStub(); stub; stub = stub->next())
+        stub->trace(trc);
+}
+
+ICStubConstIterator&
+ICStubConstIterator::operator++()
+{
+    MOZ_ASSERT(currentStub_ != nullptr);
+    currentStub_ = currentStub_->next();
+    return *this;
+}
+
+
+ICStubIterator::ICStubIterator(ICFallbackStub* fallbackStub, bool end)
+  : icEntry_(fallbackStub->icEntry()),
+    fallbackStub_(fallbackStub),
+    previousStub_(nullptr),
+    currentStub_(end ? fallbackStub : icEntry_->firstStub()),
+    unlinked_(false)
+{ }
+
+ICStubIterator&
+ICStubIterator::operator++()
+{
+    MOZ_ASSERT(currentStub_->next() != nullptr);
+    if (!unlinked_)
+        previousStub_ = currentStub_;
+    currentStub_ = currentStub_->next();
+    unlinked_ = false;
+    return *this;
+}
+
+void
+ICStubIterator::unlink(JSContext* cx)
+{
+    MOZ_ASSERT(currentStub_->next() != nullptr);
+    MOZ_ASSERT(currentStub_ != fallbackStub_);
+    MOZ_ASSERT(!unlinked_);
+
+    fallbackStub_->unlinkStub(cx->zone(), previousStub_, currentStub_);
+
+    // Mark the current iterator position as unlinked, so operator++ works properly.
+    unlinked_ = true;
+}
+
+/* static */ bool
+ICStub::NonCacheIRStubMakesGCCalls(Kind kind)
+{
+    MOZ_ASSERT(IsValidKind(kind));
+    MOZ_ASSERT(!IsCacheIRKind(kind));
+
+    switch (kind) {
+      case Call_Fallback:
+      case Call_Scripted:
+      case Call_AnyScripted:
+      case Call_Native:
+      case Call_ClassHook:
+      case Call_ScriptedApplyArray:
+      case Call_ScriptedApplyArguments:
+      case Call_ScriptedFunCall:
+      case Call_ConstStringSplit:
+      case WarmUpCounter_Fallback:
+      case RetSub_Fallback:
+      // These two fallback stubs don't actually make non-tail calls,
+      // but the fallback code for the bailout path needs to pop the stub frame
+      // pushed during the bailout.
+      case GetProp_Fallback:
+      case SetProp_Fallback:
+        return true;
+      default:
+        return false;
+    }
+}
+
+bool
+ICStub::makesGCCalls() const
+{
+    switch (kind()) {
+      case CacheIR_Regular:
+        return toCacheIR_Regular()->stubInfo()->makesGCCalls();
+      case CacheIR_Monitored:
+        return toCacheIR_Monitored()->stubInfo()->makesGCCalls();
+      case CacheIR_Updated:
+        return toCacheIR_Updated()->stubInfo()->makesGCCalls();
+      default:
+        return NonCacheIRStubMakesGCCalls(kind());
+    }
+}
+
+void
+ICStub::traceCode(JSTracer* trc, const char* name)
+{
+    JitCode* stubJitCode = jitCode();
+    TraceManuallyBarrieredEdge(trc, &stubJitCode, name);
+}
+
+void
+ICStub::updateCode(JitCode* code)
+{
+    // Write barrier on the old code.
+    JitCode::writeBarrierPre(jitCode());
+    stubCode_ = code->raw();
+}
+
+/* static */ void
+ICStub::trace(JSTracer* trc)
+{
+    traceCode(trc, "shared-stub-jitcode");
+
+    // If the stub is a monitored fallback stub, then trace the monitor ICs hanging
+    // off of that stub.  We don't need to worry about the regular monitored stubs,
+    // because the regular monitored stubs will always have a monitored fallback stub
+    // that references the same stub chain.
+    if (isMonitoredFallback()) {
+        ICTypeMonitor_Fallback* lastMonStub =
+            toMonitoredFallbackStub()->maybeFallbackMonitorStub();
+        if (lastMonStub) {
+            for (ICStubConstIterator iter(lastMonStub->firstMonitorStub());
+                 !iter.atEnd();
+                 iter++)
+            {
+                MOZ_ASSERT_IF(iter->next() == nullptr, *iter == lastMonStub);
+                iter->trace(trc);
+            }
+        }
+    }
+
+    if (isUpdated()) {
+        for (ICStubConstIterator iter(toUpdatedStub()->firstUpdateStub()); !iter.atEnd(); iter++) {
+            MOZ_ASSERT_IF(iter->next() == nullptr, iter->isTypeUpdate_Fallback());
+            iter->trace(trc);
+        }
+    }
+
+    switch (kind()) {
+      case ICStub::Call_Scripted: {
+        ICCall_Scripted* callStub = toCall_Scripted();
+        TraceEdge(trc, &callStub->callee(), "baseline-callscripted-callee");
+        TraceNullableEdge(trc, &callStub->templateObject(), "baseline-callscripted-template");
+        break;
+      }
+      case ICStub::Call_Native: {
+        ICCall_Native* callStub = toCall_Native();
+        TraceEdge(trc, &callStub->callee(), "baseline-callnative-callee");
+        TraceNullableEdge(trc, &callStub->templateObject(), "baseline-callnative-template");
+        break;
+      }
+      case ICStub::Call_ClassHook: {
+        ICCall_ClassHook* callStub = toCall_ClassHook();
+        TraceNullableEdge(trc, &callStub->templateObject(), "baseline-callclasshook-template");
+        break;
+      }
+      case ICStub::Call_ConstStringSplit: {
+        ICCall_ConstStringSplit* callStub = toCall_ConstStringSplit();
+        TraceEdge(trc, &callStub->templateObject(), "baseline-callstringsplit-template");
+        TraceEdge(trc, &callStub->expectedSep(), "baseline-callstringsplit-sep");
+        TraceEdge(trc, &callStub->expectedStr(), "baseline-callstringsplit-str");
+        break;
+      }
+      case ICStub::TypeMonitor_SingleObject: {
+        ICTypeMonitor_SingleObject* monitorStub = toTypeMonitor_SingleObject();
+        TraceEdge(trc, &monitorStub->object(), "baseline-monitor-singleton");
+        break;
+      }
+      case ICStub::TypeMonitor_ObjectGroup: {
+        ICTypeMonitor_ObjectGroup* monitorStub = toTypeMonitor_ObjectGroup();
+        TraceEdge(trc, &monitorStub->group(), "baseline-monitor-group");
+        break;
+      }
+      case ICStub::TypeUpdate_SingleObject: {
+        ICTypeUpdate_SingleObject* updateStub = toTypeUpdate_SingleObject();
+        TraceEdge(trc, &updateStub->object(), "baseline-update-singleton");
+        break;
+      }
+      case ICStub::TypeUpdate_ObjectGroup: {
+        ICTypeUpdate_ObjectGroup* updateStub = toTypeUpdate_ObjectGroup();
+        TraceEdge(trc, &updateStub->group(), "baseline-update-group");
+        break;
+      }
+      case ICStub::NewArray_Fallback: {
+        ICNewArray_Fallback* stub = toNewArray_Fallback();
+        TraceNullableEdge(trc, &stub->templateObject(), "baseline-newarray-template");
+        TraceEdge(trc, &stub->templateGroup(), "baseline-newarray-template-group");
+        break;
+      }
+      case ICStub::NewObject_Fallback: {
+        ICNewObject_Fallback* stub = toNewObject_Fallback();
+        TraceNullableEdge(trc, &stub->templateObject(), "baseline-newobject-template");
+        break;
+      }
+      case ICStub::Rest_Fallback: {
+        ICRest_Fallback* stub = toRest_Fallback();
+        TraceEdge(trc, &stub->templateObject(), "baseline-rest-template");
+        break;
+      }
+      case ICStub::CacheIR_Regular:
+        TraceCacheIRStub(trc, this, toCacheIR_Regular()->stubInfo());
+        break;
+      case ICStub::CacheIR_Monitored:
+        TraceCacheIRStub(trc, this, toCacheIR_Monitored()->stubInfo());
+        break;
+      case ICStub::CacheIR_Updated: {
+        ICCacheIR_Updated* stub = toCacheIR_Updated();
+        TraceNullableEdge(trc, &stub->updateStubGroup(), "baseline-update-stub-group");
+        TraceEdge(trc, &stub->updateStubId(), "baseline-update-stub-id");
+        TraceCacheIRStub(trc, this, stub->stubInfo());
+        break;
+      }
+      default:
+        break;
+    }
+}
+
+
+
 //
 // WarmUpCounter_Fallback
 //
 
 
 //
 // The following data is kept in a temporary heap-allocated buffer, stored in
 // JitRuntime (high memory addresses at top, low at bottom):
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -6,30 +6,704 @@
 
 #ifndef jit_BaselineIC_h
 #define jit_BaselineIC_h
 
 #include "mozilla/Assertions.h"
 
 #include "builtin/TypedObject.h"
 #include "gc/Barrier.h"
+#include "gc/GC.h"
 #include "jit/BaselineICList.h"
 #include "jit/BaselineJIT.h"
-#include "jit/SharedIC.h"
+#include "jit/ICState.h"
 #include "jit/SharedICRegisters.h"
 #include "js/GCVector.h"
 #include "vm/ArrayObject.h"
 #include "vm/BytecodeUtil.h"
 #include "vm/JSContext.h"
 #include "vm/Realm.h"
 #include "vm/UnboxedObject.h"
 
 namespace js {
 namespace jit {
 
+// [SMDOC] JIT Inline Caches (ICs)
+//
+// Baseline Inline Caches are polymorphic caches that aggressively
+// share their stub code.
+//
+// Every polymorphic site contains a linked list of stubs which are
+// specific to that site.  These stubs are composed of a |StubData|
+// structure that stores parametrization information (e.g.
+// the shape pointer for a shape-check-and-property-get stub), any
+// dynamic information (e.g. warm-up counters), a pointer to the stub code,
+// and a pointer to the next stub state in the linked list.
+//
+// Every BaselineScript keeps an table of |CacheDescriptor| data
+// structures, which store the following:
+//      A pointer to the first StubData in the cache.
+//      The bytecode PC of the relevant IC.
+//      The machine-code PC where the call to the stubcode returns.
+//
+// A diagram:
+//
+//        Control flow                  Pointers
+//      =======#                     ----.     .---->
+//             #                         |     |
+//             #======>                  \-----/
+//
+//
+//                                   .---------------------------------------.
+//                                   |         .-------------------------.   |
+//                                   |         |         .----.          |   |
+//         Baseline                  |         |         |    |          |   |
+//         JIT Code              0   ^     1   ^     2   ^    |          |   |
+//     +--------------+    .-->+-----+   +-----+   +-----+    |          |   |
+//     |              |  #=|==>|     |==>|     |==>| FB  |    |          |   |
+//     |              |  # |   +-----+   +-----+   +-----+    |          |   |
+//     |              |  # |      #         #         #       |          |   |
+//     |==============|==# |      #         #         #       |          |   |
+//     |=== IC =======|    |      #         #         #       |          |   |
+//  .->|==============|<===|======#=========#=========#       |          |   |
+//  |  |              |    |                                  |          |   |
+//  |  |              |    |                                  |          |   |
+//  |  |              |    |                                  |          |   |
+//  |  |              |    |                                  v          |   |
+//  |  |              |    |                              +---------+    |   |
+//  |  |              |    |                              | Fallback|    |   |
+//  |  |              |    |                              | Stub    |    |   |
+//  |  |              |    |                              | Code    |    |   |
+//  |  |              |    |                              +---------+    |   |
+//  |  +--------------+    |                                             |   |
+//  |         |_______     |                              +---------+    |   |
+//  |                |     |                              | Stub    |<---/   |
+//  |        IC      |     \--.                           | Code    |        |
+//  |    Descriptor  |        |                           +---------+        |
+//  |      Table     v        |                                              |
+//  |  +-----------------+    |                           +---------+        |
+//  \--| Ins | PC | Stub |----/                           | Stub    |<-------/
+//     +-----------------+                                | Code    |
+//     |       ...       |                                +---------+
+//     +-----------------+
+//                                                          Shared
+//                                                          Stub Code
+//
+//
+// Type ICs
+// ========
+//
+// Type ICs are otherwise regular ICs that are actually nested within
+// other IC chains.  They serve to optimize locations in the code where the
+// baseline compiler would have otherwise had to perform a type Monitor operation
+// (e.g. the result of GetProp, GetElem, etc.), or locations where the baseline
+// compiler would have had to modify a heap typeset using the type of an input
+// value (e.g. SetProp, SetElem, etc.)
+//
+// There are two kinds of Type ICs: Monitor and Update.
+//
+// Note that type stub bodies are no-ops.  The stubs only exist for their
+// guards, and their existence simply signifies that the typeset (implicit)
+// that is being checked already contains that type.
+//
+// TypeMonitor ICs
+// ---------------
+// Monitor ICs are shared between stubs in the general IC, and monitor the resulting
+// types of getter operations (call returns, getprop outputs, etc.)
+//
+//        +-----------+     +-----------+     +-----------+     +-----------+
+//   ---->| Stub 1    |---->| Stub 2    |---->| Stub 3    |---->| FB Stub   |
+//        +-----------+     +-----------+     +-----------+     +-----------+
+//             |                  |                 |                  |
+//             |------------------/-----------------/                  |
+//             v                                                       |
+//        +-----------+     +-----------+     +-----------+            |
+//        | Type 1    |---->| Type 2    |---->| Type FB   |            |
+//        +-----------+     +-----------+     +-----------+            |
+//             |                 |                  |                  |
+//  <----------/-----------------/------------------/------------------/
+//                r e t u r n    p a t h
+//
+// After an optimized IC stub successfully executes, it passes control to the type stub
+// chain to check the resulting type.  If no type stub succeeds, and the monitor fallback
+// stub is reached, the monitor fallback stub performs a manual monitor, and also adds the
+// appropriate type stub to the chain.
+//
+// The IC's main fallback, in addition to generating new mainline stubs, also generates
+// type stubs as reflected by its returned value.
+//
+// NOTE: The type IC chain returns directly to the mainline code, not back to the
+// stub it was entered from.  Thus, entering a type IC is a matter of a |jump|, not
+// a |call|.  This allows us to safely call a VM Monitor function from within the monitor IC's
+// fallback chain, since the return address (needed for stack inspection) is preserved.
+//
+//
+// TypeUpdate ICs
+// --------------
+// Update ICs update heap typesets and monitor the input types of setter operations
+// (setelem, setprop inputs, etc.).  Unlike monitor ICs, they are not shared
+// between stubs on an IC, but instead are kept track of on a per-stub basis.
+//
+// This is because the main stubs for the operation will each identify a potentially
+// different ObjectGroup to update.  New input types must be tracked on a group-to-
+// group basis.
+//
+// Type-update ICs cannot be called in tail position (they must return to the
+// the stub that called them so that the stub may continue to perform its original
+// purpose).  This means that any VMCall to perform a manual type update from C++ must be
+// done from within the main IC stub.  This necessitates that the stub enter a
+// "BaselineStub" frame before making the call.
+//
+// If the type-update IC chain could itself make the VMCall, then the BaselineStub frame
+// must be entered before calling the type-update chain, and exited afterward.  This
+// is very expensive for a common case where we expect the type-update fallback to not
+// be called.  To avoid the cost of entering and exiting a BaselineStub frame when
+// using the type-update IC chain, we design the chain to not perform any VM-calls
+// in its fallback.
+//
+// Instead, the type-update IC chain is responsible for returning 1 or 0, depending
+// on if a type is represented in the chain or not.  The fallback stub simply returns
+// 0, and all other optimized stubs return 1.
+// If the chain returns 1, then the IC stub goes ahead and performs its operation.
+// If the chain returns 0, then the IC stub performs a call to the fallback function
+// inline (doing the requisite BaselineStub frame enter/exit).
+// This allows us to avoid the expensive subfram enter/exit in the common case.
+//
+//                                 r e t u r n    p a t h
+//   <--------------.-----------------.-----------------.-----------------.
+//                  |                 |                 |                 |
+//        +-----------+     +-----------+     +-----------+     +-----------+
+//   ---->| Stub 1    |---->| Stub 2    |---->| Stub 3    |---->| FB Stub   |
+//        +-----------+     +-----------+     +-----------+     +-----------+
+//          |   ^             |   ^             |   ^
+//          |   |             |   |             |   |
+//          |   |             |   |             |   |----------------.
+//          |   |             |   |             v   |1               |0
+//          |   |             |   |         +-----------+    +-----------+
+//          |   |             |   |         | Type 3.1  |--->|    FB 3   |
+//          |   |             |   |         +-----------+    +-----------+
+//          |   |             |   |
+//          |   |             |   \-------------.-----------------.
+//          |   |             |   |             |                 |
+//          |   |             v   |1            |1                |0
+//          |   |         +-----------+     +-----------+     +-----------+
+//          |   |         | Type 2.1  |---->| Type 2.2  |---->|    FB 2   |
+//          |   |         +-----------+     +-----------+     +-----------+
+//          |   |
+//          |   \-------------.-----------------.
+//          |   |             |                 |
+//          v   |1            |1                |0
+//     +-----------+     +-----------+     +-----------+
+//     | Type 1.1  |---->| Type 1.2  |---->|   FB 1    |
+//     +-----------+     +-----------+     +-----------+
+//
+
+class ICStub;
+class ICFallbackStub;
+
+
+#define FORWARD_DECLARE_STUBS(kindName) class IC##kindName;
+    IC_BASELINE_STUB_KIND_LIST(FORWARD_DECLARE_STUBS)
+#undef FORWARD_DECLARE_STUBS
+
+#ifdef JS_JITSPEW
+void FallbackICSpew(JSContext* cx, ICFallbackStub* stub, const char* fmt, ...)
+    MOZ_FORMAT_PRINTF(3, 4);
+void TypeFallbackICSpew(JSContext* cx, ICTypeMonitor_Fallback* stub, const char* fmt, ...)
+    MOZ_FORMAT_PRINTF(3, 4);
+#else
+#define FallbackICSpew(...)
+#define TypeFallbackICSpew(...)
+#endif
+
+//
+// An entry in the JIT IC descriptor table.
+//
+class ICEntry
+{
+  private:
+    // A pointer to the shared IC stub for this instruction.
+    ICStub* firstStub_;
+
+    // Offset from the start of the JIT code where the IC
+    // load and call instructions are.
+    uint32_t returnOffset_;
+
+    // The PC of this IC's bytecode op within the JSScript.
+    uint32_t pcOffset_ : 28;
+
+  public:
+    enum Kind {
+        // A for-op IC entry.
+        Kind_Op = 0,
+
+        // A non-op IC entry.
+        Kind_NonOp,
+
+        // A fake IC entry for returning from a callVM for an op.
+        Kind_CallVM,
+
+        // A fake IC entry for returning from a callVM not for an op (e.g., in
+        // the prologue).
+        Kind_NonOpCallVM,
+
+        // A fake IC entry for returning from a callVM to after the
+        // warmup counter.
+        Kind_WarmupCounter,
+
+        // A fake IC entry for returning from a callVM to the interrupt
+        // handler via the over-recursion check on function entry.
+        Kind_StackCheck,
+
+        // As above, but for the early check. See emitStackCheck.
+        Kind_EarlyStackCheck,
+
+        // A fake IC entry for returning from DebugTrapHandler.
+        Kind_DebugTrap,
+
+        // A fake IC entry for returning from a callVM to
+        // Debug{Prologue,AfterYield,Epilogue}.
+        Kind_DebugPrologue,
+        Kind_DebugAfterYield,
+        Kind_DebugEpilogue,
+
+        Kind_Invalid
+    };
+
+  private:
+    // What this IC is for.
+    Kind kind_ : 4;
+
+    // Set the kind and asserts that it's sane.
+    void setKind(Kind kind) {
+        MOZ_ASSERT(kind < Kind_Invalid);
+        kind_ = kind;
+        MOZ_ASSERT(this->kind() == kind);
+    }
+
+  public:
+    ICEntry(uint32_t pcOffset, Kind kind)
+      : firstStub_(nullptr), returnOffset_(), pcOffset_(pcOffset)
+    {
+        // The offset must fit in at least 28 bits, since we shave off 4 for
+        // the Kind enum.
+        MOZ_ASSERT(pcOffset_ == pcOffset);
+        JS_STATIC_ASSERT(BaselineScript::MAX_JSSCRIPT_LENGTH <= (1u << 28) - 1);
+        MOZ_ASSERT(pcOffset <= BaselineScript::MAX_JSSCRIPT_LENGTH);
+        setKind(kind);
+    }
+
+    CodeOffset returnOffset() const {
+        return CodeOffset(returnOffset_);
+    }
+
+    void setReturnOffset(CodeOffset offset) {
+        MOZ_ASSERT(offset.offset() <= (size_t) UINT32_MAX);
+        returnOffset_ = (uint32_t) offset.offset();
+    }
+
+    uint32_t pcOffset() const {
+        return pcOffset_;
+    }
+
+    jsbytecode* pc(JSScript* script) const {
+        return script->offsetToPC(pcOffset_);
+    }
+
+    Kind kind() const {
+        // MSVC compiles enums as signed.
+        return Kind(kind_ & 0xf);
+    }
+    bool isForOp() const {
+        return kind() == Kind_Op;
+    }
+
+    void setFakeKind(Kind kind) {
+        MOZ_ASSERT(kind != Kind_Op && kind != Kind_NonOp);
+        setKind(kind);
+    }
+
+    bool hasStub() const {
+        return firstStub_ != nullptr;
+    }
+    ICStub* firstStub() const {
+        MOZ_ASSERT(hasStub());
+        return firstStub_;
+    }
+
+    ICFallbackStub* fallbackStub() const;
+
+    void setFirstStub(ICStub* stub) {
+        firstStub_ = stub;
+    }
+
+    static inline size_t offsetOfFirstStub() {
+        return offsetof(ICEntry, firstStub_);
+    }
+
+    inline ICStub** addressOfFirstStub() {
+        return &firstStub_;
+    }
+
+    void trace(JSTracer* trc);
+};
+
+class ICMonitoredStub;
+class ICMonitoredFallbackStub;
+class ICUpdatedStub;
+
+// Constant iterator that traverses arbitrary chains of ICStubs.
+// No requirements are made of the ICStub used to construct this
+// iterator, aside from that the stub be part of a nullptr-terminated
+// chain.
+// The iterator is considered to be at its end once it has been
+// incremented _past_ the last stub.  Thus, if 'atEnd()' returns
+// true, the '*' and '->' operations are not valid.
+class ICStubConstIterator
+{
+    friend class ICStub;
+    friend class ICFallbackStub;
+
+  private:
+    ICStub* currentStub_;
+
+  public:
+    explicit ICStubConstIterator(ICStub* currentStub) : currentStub_(currentStub) {}
+
+    static ICStubConstIterator StartingAt(ICStub* stub) {
+        return ICStubConstIterator(stub);
+    }
+    static ICStubConstIterator End(ICStub* stub) {
+        return ICStubConstIterator(nullptr);
+    }
+
+    bool operator ==(const ICStubConstIterator& other) const {
+        return currentStub_ == other.currentStub_;
+    }
+    bool operator !=(const ICStubConstIterator& other) const {
+        return !(*this == other);
+    }
+
+    ICStubConstIterator& operator++();
+
+    ICStubConstIterator operator++(int) {
+        ICStubConstIterator oldThis(*this);
+        ++(*this);
+        return oldThis;
+    }
+
+    ICStub* operator*() const {
+        MOZ_ASSERT(currentStub_);
+        return currentStub_;
+    }
+
+    ICStub* operator ->() const {
+        MOZ_ASSERT(currentStub_);
+        return currentStub_;
+    }
+
+    bool atEnd() const {
+        return currentStub_ == nullptr;
+    }
+};
+
+// Iterator that traverses "regular" IC chains that start at an ICEntry
+// and are terminated with an ICFallbackStub.
+//
+// The iterator is considered to be at its end once it is _at_ the
+// fallback stub.  Thus, unlike the ICStubConstIterator, operators
+// '*' and '->' are valid even if 'atEnd()' returns true - they
+// will act on the fallback stub.
+//
+// This iterator also allows unlinking of stubs being traversed.
+// Note that 'unlink' does not implicitly advance the iterator -
+// it must be advanced explicitly using '++'.
+class ICStubIterator
+{
+    friend class ICFallbackStub;
+
+  private:
+    ICEntry* icEntry_;
+    ICFallbackStub* fallbackStub_;
+    ICStub* previousStub_;
+    ICStub* currentStub_;
+    bool unlinked_;
+
+    explicit ICStubIterator(ICFallbackStub* fallbackStub, bool end=false);
+  public:
+
+    bool operator ==(const ICStubIterator& other) const {
+        // == should only ever be called on stubs from the same chain.
+        MOZ_ASSERT(icEntry_ == other.icEntry_);
+        MOZ_ASSERT(fallbackStub_ == other.fallbackStub_);
+        return currentStub_ == other.currentStub_;
+    }
+    bool operator !=(const ICStubIterator& other) const {
+        return !(*this == other);
+    }
+
+    ICStubIterator& operator++();
+
+    ICStubIterator operator++(int) {
+        ICStubIterator oldThis(*this);
+        ++(*this);
+        return oldThis;
+    }
+
+    ICStub* operator*() const {
+        return currentStub_;
+    }
+
+    ICStub* operator ->() const {
+        return currentStub_;
+    }
+
+    bool atEnd() const {
+        return currentStub_ == (ICStub*) fallbackStub_;
+    }
+
+    void unlink(JSContext* cx);
+};
+
+//
+// Base class for all IC stubs.
+//
+class ICStub
+{
+    friend class ICFallbackStub;
+
+  public:
+    enum Kind {
+        INVALID = 0,
+#define DEF_ENUM_KIND(kindName) kindName,
+        IC_BASELINE_STUB_KIND_LIST(DEF_ENUM_KIND)
+#undef DEF_ENUM_KIND
+        LIMIT
+    };
+
+    static bool IsValidKind(Kind k) {
+        return (k > INVALID) && (k < LIMIT);
+    }
+    static bool IsCacheIRKind(Kind k) {
+        return k == CacheIR_Regular || k == CacheIR_Monitored || k == CacheIR_Updated;
+    }
+
+    static const char* KindString(Kind k) {
+        switch(k) {
+#define DEF_KIND_STR(kindName) case kindName: return #kindName;
+            IC_BASELINE_STUB_KIND_LIST(DEF_KIND_STR)
+#undef DEF_KIND_STR
+          default:
+            MOZ_CRASH("Invalid kind.");
+        }
+    }
+
+    enum Trait {
+        Regular             = 0x0,
+        Fallback            = 0x1,
+        Monitored           = 0x2,
+        MonitoredFallback   = 0x3,
+        Updated             = 0x4
+    };
+
+    void traceCode(JSTracer* trc, const char* name);
+    void updateCode(JitCode* stubCode);
+    void trace(JSTracer* trc);
+
+    template <typename T, typename... Args>
+    static T* New(JSContext* cx, ICStubSpace* space, JitCode* code, Args&&... args) {
+        if (!code)
+            return nullptr;
+        T* result = space->allocate<T>(code, std::forward<Args>(args)...);
+        if (!result)
+            ReportOutOfMemory(cx);
+        return result;
+    }
+
+  protected:
+    // The raw jitcode to call for this stub.
+    uint8_t* stubCode_;
+
+    // Pointer to next IC stub.  This is null for the last IC stub, which should
+    // either be a fallback or inert IC stub.
+    ICStub* next_;
+
+    // A 16-bit field usable by subtypes of ICStub for subtype-specific small-info
+    uint16_t extra_;
+
+    // The kind of the stub.
+    //  High bit is 'isFallback' flag.
+    //  Second high bit is 'isMonitored' flag.
+    Trait trait_ : 3;
+    Kind kind_ : 13;
+
+    inline ICStub(Kind kind, JitCode* stubCode)
+      : stubCode_(stubCode->raw()),
+        next_(nullptr),
+        extra_(0),
+        trait_(Regular),
+        kind_(kind)
+    {
+        MOZ_ASSERT(stubCode != nullptr);
+    }
+
+    inline ICStub(Kind kind, Trait trait, JitCode* stubCode)
+      : stubCode_(stubCode->raw()),
+        next_(nullptr),
+        extra_(0),
+        trait_(trait),
+        kind_(kind)
+    {
+        MOZ_ASSERT(stubCode != nullptr);
+    }
+
+    inline Trait trait() const {
+        // Workaround for MSVC reading trait_ as signed value.
+        return (Trait)(trait_ & 0x7);
+    }
+
+  public:
+
+    inline Kind kind() const {
+        return static_cast<Kind>(kind_);
+    }
+
+    inline bool isFallback() const {
+        return trait() == Fallback || trait() == MonitoredFallback;
+    }
+
+    inline bool isMonitored() const {
+        return trait() == Monitored;
+    }
+
+    inline bool isUpdated() const {
+        return trait() == Updated;
+    }
+
+    inline bool isMonitoredFallback() const {
+        return trait() == MonitoredFallback;
+    }
+
+    inline const ICFallbackStub* toFallbackStub() const {
+        MOZ_ASSERT(isFallback());
+        return reinterpret_cast<const ICFallbackStub*>(this);
+    }
+
+    inline ICFallbackStub* toFallbackStub() {
+        MOZ_ASSERT(isFallback());
+        return reinterpret_cast<ICFallbackStub*>(this);
+    }
+
+    inline const ICMonitoredStub* toMonitoredStub() const {
+        MOZ_ASSERT(isMonitored());
+        return reinterpret_cast<const ICMonitoredStub*>(this);
+    }
+
+    inline ICMonitoredStub* toMonitoredStub() {
+        MOZ_ASSERT(isMonitored());
+        return reinterpret_cast<ICMonitoredStub*>(this);
+    }
+
+    inline const ICMonitoredFallbackStub* toMonitoredFallbackStub() const {
+        MOZ_ASSERT(isMonitoredFallback());
+        return reinterpret_cast<const ICMonitoredFallbackStub*>(this);
+    }
+
+    inline ICMonitoredFallbackStub* toMonitoredFallbackStub() {
+        MOZ_ASSERT(isMonitoredFallback());
+        return reinterpret_cast<ICMonitoredFallbackStub*>(this);
+    }
+
+    inline const ICUpdatedStub* toUpdatedStub() const {
+        MOZ_ASSERT(isUpdated());
+        return reinterpret_cast<const ICUpdatedStub*>(this);
+    }
+
+    inline ICUpdatedStub* toUpdatedStub() {
+        MOZ_ASSERT(isUpdated());
+        return reinterpret_cast<ICUpdatedStub*>(this);
+    }
+
+#define KIND_METHODS(kindName)   \
+    inline bool is##kindName() const { return kind() == kindName; } \
+    inline const IC##kindName* to##kindName() const { \
+        MOZ_ASSERT(is##kindName()); \
+        return reinterpret_cast<const IC##kindName*>(this); \
+    } \
+    inline IC##kindName* to##kindName() { \
+        MOZ_ASSERT(is##kindName()); \
+        return reinterpret_cast<IC##kindName*>(this); \
+    }
+    IC_BASELINE_STUB_KIND_LIST(KIND_METHODS)
+#undef KIND_METHODS
+
+    inline ICStub* next() const {
+        return next_;
+    }
+
+    inline bool hasNext() const {
+        return next_ != nullptr;
+    }
+
+    inline void setNext(ICStub* stub) {
+        // Note: next_ only needs to be changed under the compilation lock for
+        // non-type-monitor/update ICs.
+        next_ = stub;
+    }
+
+    inline ICStub** addressOfNext() {
+        return &next_;
+    }
+
+    inline JitCode* jitCode() {
+        return JitCode::FromExecutable(stubCode_);
+    }
+
+    inline uint8_t* rawStubCode() const {
+        return stubCode_;
+    }
+
+    // This method is not valid on TypeUpdate stub chains!
+    inline ICFallbackStub* getChainFallback() {
+        ICStub* lastStub = this;
+        while (lastStub->next_)
+            lastStub = lastStub->next_;
+        MOZ_ASSERT(lastStub->isFallback());
+        return lastStub->toFallbackStub();
+    }
+
+    inline ICStubConstIterator beginHere() {
+        return ICStubConstIterator::StartingAt(this);
+    }
+
+    static inline size_t offsetOfNext() {
+        return offsetof(ICStub, next_);
+    }
+
+    static inline size_t offsetOfStubCode() {
+        return offsetof(ICStub, stubCode_);
+    }
+
+    static inline size_t offsetOfExtra() {
+        return offsetof(ICStub, extra_);
+    }
+
+    static bool NonCacheIRStubMakesGCCalls(Kind kind);
+    bool makesGCCalls() const;
+
+    // Optimized stubs get purged on GC.  But some stubs can be active on the
+    // stack during GC - specifically the ones that can make calls.  To ensure
+    // that these do not get purged, all stubs that can make calls are allocated
+    // in the fallback stub space.
+    bool allocatedInFallbackSpace() const {
+        MOZ_ASSERT(next());
+        return makesGCCalls();
+    }
+};
+
 class ICFallbackStub : public ICStub
 {
     friend class ICStubConstIterator;
   protected:
     // Fallback stubs need these fields to easily add new stubs to
     // the linked list of stubs for an IC.
 
     // The IC entry for this linked list of stubs.
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -9,17 +9,19 @@
 
 #include "mozilla/Maybe.h"
 
 #include "NamespaceImports.h"
 
 #include "gc/Rooting.h"
 #include "jit/CompactBuffer.h"
 #include "jit/ICState.h"
-#include "jit/SharedIC.h"
+#include "jit/MacroAssembler.h"
+#include "vm/Iteration.h"
+#include "vm/Shape.h"
 
 namespace js {
 namespace jit {
 
 
 enum class BaselineCacheIRStubKind;
 
 // [SMDOC] CacheIR
--- a/js/src/jit/JitRealm.h
+++ b/js/src/jit/JitRealm.h
@@ -337,17 +337,17 @@ class JitRuntime
         return disambiguationId_++;
     }
 };
 
 enum class CacheKind : uint8_t;
 class CacheIRStubInfo;
 
 enum class ICStubEngine : uint8_t {
-    // Baseline IC, see SharedIC.h and BaselineIC.h.
+    // Baseline IC, see BaselineIC.h.
     Baseline = 0,
 
     // Ion IC, see IonIC.h.
     IonIC
 };
 
 struct CacheIRStubKey : public DefaultHasher<CacheIRStubKey> {
     struct Lookup {
deleted file mode 100644
--- a/js/src/jit/SharedIC.cpp
+++ /dev/null
@@ -1,317 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * 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/. */
-
-#include "jit/SharedIC.h"
-
-#include "mozilla/Casting.h"
-#include "mozilla/IntegerPrintfMacros.h"
-#include "mozilla/Sprintf.h"
-
-#include "jslibmath.h"
-#include "jstypes.h"
-
-#include "gc/Policy.h"
-#include "jit/BaselineCacheIRCompiler.h"
-#include "jit/BaselineDebugModeOSR.h"
-#include "jit/BaselineIC.h"
-#include "jit/JitSpewer.h"
-#include "jit/Linker.h"
-#include "jit/SharedICHelpers.h"
-#ifdef JS_ION_PERF
-# include "jit/PerfSpewer.h"
-#endif
-#include "jit/VMFunctions.h"
-#include "vm/Interpreter.h"
-#include "vm/StringType.h"
-
-#include "jit/MacroAssembler-inl.h"
-#include "jit/SharedICHelpers-inl.h"
-#include "vm/Interpreter-inl.h"
-
-using mozilla::BitwiseCast;
-
-namespace js {
-namespace jit {
-
-#ifdef JS_JITSPEW
-void
-FallbackICSpew(JSContext* cx, ICFallbackStub* stub, const char* fmt, ...)
-{
-    if (JitSpewEnabled(JitSpew_BaselineICFallback)) {
-        RootedScript script(cx, GetTopJitJSScript(cx));
-        jsbytecode* pc = stub->icEntry()->pc(script);
-
-        char fmtbuf[100];
-        va_list args;
-        va_start(args, fmt);
-        (void) VsprintfLiteral(fmtbuf, fmt, args);
-        va_end(args);
-
-        JitSpew(JitSpew_BaselineICFallback,
-                "Fallback hit for (%s:%u) (pc=%zu,line=%d,uses=%d,stubs=%zu): %s",
-                script->filename(),
-                script->lineno(),
-                script->pcToOffset(pc),
-                PCToLineNumber(script, pc),
-                script->getWarmUpCount(),
-                stub->numOptimizedStubs(),
-                fmtbuf);
-    }
-}
-
-void
-TypeFallbackICSpew(JSContext* cx, ICTypeMonitor_Fallback* stub, const char* fmt, ...)
-{
-    if (JitSpewEnabled(JitSpew_BaselineICFallback)) {
-        RootedScript script(cx, GetTopJitJSScript(cx));
-        jsbytecode* pc = stub->icEntry()->pc(script);
-
-        char fmtbuf[100];
-        va_list args;
-        va_start(args, fmt);
-        (void) VsprintfLiteral(fmtbuf, fmt, args);
-        va_end(args);
-
-        JitSpew(JitSpew_BaselineICFallback,
-                "Type monitor fallback hit for (%s:%u) (pc=%zu,line=%d,uses=%d,stubs=%d): %s",
-                script->filename(),
-                script->lineno(),
-                script->pcToOffset(pc),
-                PCToLineNumber(script, pc),
-                script->getWarmUpCount(),
-                (int) stub->numOptimizedMonitorStubs(),
-                fmtbuf);
-    }
-}
-#endif // JS_JITSPEW
-
-ICFallbackStub*
-ICEntry::fallbackStub() const
-{
-    return firstStub()->getChainFallback();
-}
-
-void
-ICEntry::trace(JSTracer* trc)
-{
-    if (!hasStub())
-        return;
-    for (ICStub* stub = firstStub(); stub; stub = stub->next())
-        stub->trace(trc);
-}
-
-ICStubConstIterator&
-ICStubConstIterator::operator++()
-{
-    MOZ_ASSERT(currentStub_ != nullptr);
-    currentStub_ = currentStub_->next();
-    return *this;
-}
-
-
-ICStubIterator::ICStubIterator(ICFallbackStub* fallbackStub, bool end)
-  : icEntry_(fallbackStub->icEntry()),
-    fallbackStub_(fallbackStub),
-    previousStub_(nullptr),
-    currentStub_(end ? fallbackStub : icEntry_->firstStub()),
-    unlinked_(false)
-{ }
-
-ICStubIterator&
-ICStubIterator::operator++()
-{
-    MOZ_ASSERT(currentStub_->next() != nullptr);
-    if (!unlinked_)
-        previousStub_ = currentStub_;
-    currentStub_ = currentStub_->next();
-    unlinked_ = false;
-    return *this;
-}
-
-void
-ICStubIterator::unlink(JSContext* cx)
-{
-    MOZ_ASSERT(currentStub_->next() != nullptr);
-    MOZ_ASSERT(currentStub_ != fallbackStub_);
-    MOZ_ASSERT(!unlinked_);
-
-    fallbackStub_->unlinkStub(cx->zone(), previousStub_, currentStub_);
-
-    // Mark the current iterator position as unlinked, so operator++ works properly.
-    unlinked_ = true;
-}
-
-/* static */ bool
-ICStub::NonCacheIRStubMakesGCCalls(Kind kind)
-{
-    MOZ_ASSERT(IsValidKind(kind));
-    MOZ_ASSERT(!IsCacheIRKind(kind));
-
-    switch (kind) {
-      case Call_Fallback:
-      case Call_Scripted:
-      case Call_AnyScripted:
-      case Call_Native:
-      case Call_ClassHook:
-      case Call_ScriptedApplyArray:
-      case Call_ScriptedApplyArguments:
-      case Call_ScriptedFunCall:
-      case Call_ConstStringSplit:
-      case WarmUpCounter_Fallback:
-      case RetSub_Fallback:
-      // These two fallback stubs don't actually make non-tail calls,
-      // but the fallback code for the bailout path needs to pop the stub frame
-      // pushed during the bailout.
-      case GetProp_Fallback:
-      case SetProp_Fallback:
-        return true;
-      default:
-        return false;
-    }
-}
-
-bool
-ICStub::makesGCCalls() const
-{
-    switch (kind()) {
-      case CacheIR_Regular:
-        return toCacheIR_Regular()->stubInfo()->makesGCCalls();
-      case CacheIR_Monitored:
-        return toCacheIR_Monitored()->stubInfo()->makesGCCalls();
-      case CacheIR_Updated:
-        return toCacheIR_Updated()->stubInfo()->makesGCCalls();
-      default:
-        return NonCacheIRStubMakesGCCalls(kind());
-    }
-}
-
-void
-ICStub::traceCode(JSTracer* trc, const char* name)
-{
-    JitCode* stubJitCode = jitCode();
-    TraceManuallyBarrieredEdge(trc, &stubJitCode, name);
-}
-
-void
-ICStub::updateCode(JitCode* code)
-{
-    // Write barrier on the old code.
-    JitCode::writeBarrierPre(jitCode());
-    stubCode_ = code->raw();
-}
-
-/* static */ void
-ICStub::trace(JSTracer* trc)
-{
-    traceCode(trc, "shared-stub-jitcode");
-
-    // If the stub is a monitored fallback stub, then trace the monitor ICs hanging
-    // off of that stub.  We don't need to worry about the regular monitored stubs,
-    // because the regular monitored stubs will always have a monitored fallback stub
-    // that references the same stub chain.
-    if (isMonitoredFallback()) {
-        ICTypeMonitor_Fallback* lastMonStub =
-            toMonitoredFallbackStub()->maybeFallbackMonitorStub();
-        if (lastMonStub) {
-            for (ICStubConstIterator iter(lastMonStub->firstMonitorStub());
-                 !iter.atEnd();
-                 iter++)
-            {
-                MOZ_ASSERT_IF(iter->next() == nullptr, *iter == lastMonStub);
-                iter->trace(trc);
-            }
-        }
-    }
-
-    if (isUpdated()) {
-        for (ICStubConstIterator iter(toUpdatedStub()->firstUpdateStub()); !iter.atEnd(); iter++) {
-            MOZ_ASSERT_IF(iter->next() == nullptr, iter->isTypeUpdate_Fallback());
-            iter->trace(trc);
-        }
-    }
-
-    switch (kind()) {
-      case ICStub::Call_Scripted: {
-        ICCall_Scripted* callStub = toCall_Scripted();
-        TraceEdge(trc, &callStub->callee(), "baseline-callscripted-callee");
-        TraceNullableEdge(trc, &callStub->templateObject(), "baseline-callscripted-template");
-        break;
-      }
-      case ICStub::Call_Native: {
-        ICCall_Native* callStub = toCall_Native();
-        TraceEdge(trc, &callStub->callee(), "baseline-callnative-callee");
-        TraceNullableEdge(trc, &callStub->templateObject(), "baseline-callnative-template");
-        break;
-      }
-      case ICStub::Call_ClassHook: {
-        ICCall_ClassHook* callStub = toCall_ClassHook();
-        TraceNullableEdge(trc, &callStub->templateObject(), "baseline-callclasshook-template");
-        break;
-      }
-      case ICStub::Call_ConstStringSplit: {
-        ICCall_ConstStringSplit* callStub = toCall_ConstStringSplit();
-        TraceEdge(trc, &callStub->templateObject(), "baseline-callstringsplit-template");
-        TraceEdge(trc, &callStub->expectedSep(), "baseline-callstringsplit-sep");
-        TraceEdge(trc, &callStub->expectedStr(), "baseline-callstringsplit-str");
-        break;
-      }
-      case ICStub::TypeMonitor_SingleObject: {
-        ICTypeMonitor_SingleObject* monitorStub = toTypeMonitor_SingleObject();
-        TraceEdge(trc, &monitorStub->object(), "baseline-monitor-singleton");
-        break;
-      }
-      case ICStub::TypeMonitor_ObjectGroup: {
-        ICTypeMonitor_ObjectGroup* monitorStub = toTypeMonitor_ObjectGroup();
-        TraceEdge(trc, &monitorStub->group(), "baseline-monitor-group");
-        break;
-      }
-      case ICStub::TypeUpdate_SingleObject: {
-        ICTypeUpdate_SingleObject* updateStub = toTypeUpdate_SingleObject();
-        TraceEdge(trc, &updateStub->object(), "baseline-update-singleton");
-        break;
-      }
-      case ICStub::TypeUpdate_ObjectGroup: {
-        ICTypeUpdate_ObjectGroup* updateStub = toTypeUpdate_ObjectGroup();
-        TraceEdge(trc, &updateStub->group(), "baseline-update-group");
-        break;
-      }
-      case ICStub::NewArray_Fallback: {
-        ICNewArray_Fallback* stub = toNewArray_Fallback();
-        TraceNullableEdge(trc, &stub->templateObject(), "baseline-newarray-template");
-        TraceEdge(trc, &stub->templateGroup(), "baseline-newarray-template-group");
-        break;
-      }
-      case ICStub::NewObject_Fallback: {
-        ICNewObject_Fallback* stub = toNewObject_Fallback();
-        TraceNullableEdge(trc, &stub->templateObject(), "baseline-newobject-template");
-        break;
-      }
-      case ICStub::Rest_Fallback: {
-        ICRest_Fallback* stub = toRest_Fallback();
-        TraceEdge(trc, &stub->templateObject(), "baseline-rest-template");
-        break;
-      }
-      case ICStub::CacheIR_Regular:
-        TraceCacheIRStub(trc, this, toCacheIR_Regular()->stubInfo());
-        break;
-      case ICStub::CacheIR_Monitored:
-        TraceCacheIRStub(trc, this, toCacheIR_Monitored()->stubInfo());
-        break;
-      case ICStub::CacheIR_Updated: {
-        ICCacheIR_Updated* stub = toCacheIR_Updated();
-        TraceNullableEdge(trc, &stub->updateStubGroup(), "baseline-update-stub-group");
-        TraceEdge(trc, &stub->updateStubId(), "baseline-update-stub-id");
-        TraceCacheIRStub(trc, this, stub->stubInfo());
-        break;
-      }
-      default:
-        break;
-    }
-}
-
-
-} // namespace jit
-} // namespace js
deleted file mode 100644
--- a/js/src/jit/SharedIC.h
+++ /dev/null
@@ -1,700 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * 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/. */
-
-#ifndef jit_SharedIC_h
-#define jit_SharedIC_h
-
-#include "gc/GC.h"
-#include "jit/BaselineICList.h"
-#include "jit/BaselineJIT.h"
-#include "jit/ICState.h"
-#include "jit/MacroAssembler.h"
-#include "jit/SharedICRegisters.h"
-#include "vm/JSContext.h"
-#include "vm/Realm.h"
-#include "vm/ReceiverGuard.h"
-#include "vm/TypedArrayObject.h"
-
-namespace js {
-namespace jit {
-
-// [SMDOC] JIT Inline Caches (ICs)
-//
-// Baseline Inline Caches are polymorphic caches that aggressively
-// share their stub code.
-//
-// Every polymorphic site contains a linked list of stubs which are
-// specific to that site.  These stubs are composed of a |StubData|
-// structure that stores parametrization information (e.g.
-// the shape pointer for a shape-check-and-property-get stub), any
-// dynamic information (e.g. warm-up counters), a pointer to the stub code,
-// and a pointer to the next stub state in the linked list.
-//
-// Every BaselineScript keeps an table of |CacheDescriptor| data
-// structures, which store the following:
-//      A pointer to the first StubData in the cache.
-//      The bytecode PC of the relevant IC.
-//      The machine-code PC where the call to the stubcode returns.
-//
-// A diagram:
-//
-//        Control flow                  Pointers
-//      =======#                     ----.     .---->
-//             #                         |     |
-//             #======>                  \-----/
-//
-//
-//                                   .---------------------------------------.
-//                                   |         .-------------------------.   |
-//                                   |         |         .----.          |   |
-//         Baseline                  |         |         |    |          |   |
-//         JIT Code              0   ^     1   ^     2   ^    |          |   |
-//     +--------------+    .-->+-----+   +-----+   +-----+    |          |   |
-//     |              |  #=|==>|     |==>|     |==>| FB  |    |          |   |
-//     |              |  # |   +-----+   +-----+   +-----+    |          |   |
-//     |              |  # |      #         #         #       |          |   |
-//     |==============|==# |      #         #         #       |          |   |
-//     |=== IC =======|    |      #         #         #       |          |   |
-//  .->|==============|<===|======#=========#=========#       |          |   |
-//  |  |              |    |                                  |          |   |
-//  |  |              |    |                                  |          |   |
-//  |  |              |    |                                  |          |   |
-//  |  |              |    |                                  v          |   |
-//  |  |              |    |                              +---------+    |   |
-//  |  |              |    |                              | Fallback|    |   |
-//  |  |              |    |                              | Stub    |    |   |
-//  |  |              |    |                              | Code    |    |   |
-//  |  |              |    |                              +---------+    |   |
-//  |  +--------------+    |                                             |   |
-//  |         |_______     |                              +---------+    |   |
-//  |                |     |                              | Stub    |<---/   |
-//  |        IC      |     \--.                           | Code    |        |
-//  |    Descriptor  |        |                           +---------+        |
-//  |      Table     v        |                                              |
-//  |  +-----------------+    |                           +---------+        |
-//  \--| Ins | PC | Stub |----/                           | Stub    |<-------/
-//     +-----------------+                                | Code    |
-//     |       ...       |                                +---------+
-//     +-----------------+
-//                                                          Shared
-//                                                          Stub Code
-//
-//
-// Type ICs
-// ========
-//
-// Type ICs are otherwise regular ICs that are actually nested within
-// other IC chains.  They serve to optimize locations in the code where the
-// baseline compiler would have otherwise had to perform a type Monitor operation
-// (e.g. the result of GetProp, GetElem, etc.), or locations where the baseline
-// compiler would have had to modify a heap typeset using the type of an input
-// value (e.g. SetProp, SetElem, etc.)
-//
-// There are two kinds of Type ICs: Monitor and Update.
-//
-// Note that type stub bodies are no-ops.  The stubs only exist for their
-// guards, and their existence simply signifies that the typeset (implicit)
-// that is being checked already contains that type.
-//
-// TypeMonitor ICs
-// ---------------
-// Monitor ICs are shared between stubs in the general IC, and monitor the resulting
-// types of getter operations (call returns, getprop outputs, etc.)
-//
-//        +-----------+     +-----------+     +-----------+     +-----------+
-//   ---->| Stub 1    |---->| Stub 2    |---->| Stub 3    |---->| FB Stub   |
-//        +-----------+     +-----------+     +-----------+     +-----------+
-//             |                  |                 |                  |
-//             |------------------/-----------------/                  |
-//             v                                                       |
-//        +-----------+     +-----------+     +-----------+            |
-//        | Type 1    |---->| Type 2    |---->| Type FB   |            |
-//        +-----------+     +-----------+     +-----------+            |
-//             |                 |                  |                  |
-//  <----------/-----------------/------------------/------------------/
-//                r e t u r n    p a t h
-//
-// After an optimized IC stub successfully executes, it passes control to the type stub
-// chain to check the resulting type.  If no type stub succeeds, and the monitor fallback
-// stub is reached, the monitor fallback stub performs a manual monitor, and also adds the
-// appropriate type stub to the chain.
-//
-// The IC's main fallback, in addition to generating new mainline stubs, also generates
-// type stubs as reflected by its returned value.
-//
-// NOTE: The type IC chain returns directly to the mainline code, not back to the
-// stub it was entered from.  Thus, entering a type IC is a matter of a |jump|, not
-// a |call|.  This allows us to safely call a VM Monitor function from within the monitor IC's
-// fallback chain, since the return address (needed for stack inspection) is preserved.
-//
-//
-// TypeUpdate ICs
-// --------------
-// Update ICs update heap typesets and monitor the input types of setter operations
-// (setelem, setprop inputs, etc.).  Unlike monitor ICs, they are not shared
-// between stubs on an IC, but instead are kept track of on a per-stub basis.
-//
-// This is because the main stubs for the operation will each identify a potentially
-// different ObjectGroup to update.  New input types must be tracked on a group-to-
-// group basis.
-//
-// Type-update ICs cannot be called in tail position (they must return to the
-// the stub that called them so that the stub may continue to perform its original
-// purpose).  This means that any VMCall to perform a manual type update from C++ must be
-// done from within the main IC stub.  This necessitates that the stub enter a
-// "BaselineStub" frame before making the call.
-//
-// If the type-update IC chain could itself make the VMCall, then the BaselineStub frame
-// must be entered before calling the type-update chain, and exited afterward.  This
-// is very expensive for a common case where we expect the type-update fallback to not
-// be called.  To avoid the cost of entering and exiting a BaselineStub frame when
-// using the type-update IC chain, we design the chain to not perform any VM-calls
-// in its fallback.
-//
-// Instead, the type-update IC chain is responsible for returning 1 or 0, depending
-// on if a type is represented in the chain or not.  The fallback stub simply returns
-// 0, and all other optimized stubs return 1.
-// If the chain returns 1, then the IC stub goes ahead and performs its operation.
-// If the chain returns 0, then the IC stub performs a call to the fallback function
-// inline (doing the requisite BaselineStub frame enter/exit).
-// This allows us to avoid the expensive subfram enter/exit in the common case.
-//
-//                                 r e t u r n    p a t h
-//   <--------------.-----------------.-----------------.-----------------.
-//                  |                 |                 |                 |
-//        +-----------+     +-----------+     +-----------+     +-----------+
-//   ---->| Stub 1    |---->| Stub 2    |---->| Stub 3    |---->| FB Stub   |
-//        +-----------+     +-----------+     +-----------+     +-----------+
-//          |   ^             |   ^             |   ^
-//          |   |             |   |             |   |
-//          |   |             |   |             |   |----------------.
-//          |   |             |   |             v   |1               |0
-//          |   |             |   |         +-----------+    +-----------+
-//          |   |             |   |         | Type 3.1  |--->|    FB 3   |
-//          |   |             |   |         +-----------+    +-----------+
-//          |   |             |   |
-//          |   |             |   \-------------.-----------------.
-//          |   |             |   |             |                 |
-//          |   |             v   |1            |1                |0
-//          |   |         +-----------+     +-----------+     +-----------+
-//          |   |         | Type 2.1  |---->| Type 2.2  |---->|    FB 2   |
-//          |   |         +-----------+     +-----------+     +-----------+
-//          |   |
-//          |   \-------------.-----------------.
-//          |   |             |                 |
-//          v   |1            |1                |0
-//     +-----------+     +-----------+     +-----------+
-//     | Type 1.1  |---->| Type 1.2  |---->|   FB 1    |
-//     +-----------+     +-----------+     +-----------+
-//
-
-class ICStub;
-class ICFallbackStub;
-
-
-#define FORWARD_DECLARE_STUBS(kindName) class IC##kindName;
-    IC_BASELINE_STUB_KIND_LIST(FORWARD_DECLARE_STUBS)
-#undef FORWARD_DECLARE_STUBS
-
-#ifdef JS_JITSPEW
-void FallbackICSpew(JSContext* cx, ICFallbackStub* stub, const char* fmt, ...)
-    MOZ_FORMAT_PRINTF(3, 4);
-void TypeFallbackICSpew(JSContext* cx, ICTypeMonitor_Fallback* stub, const char* fmt, ...)
-    MOZ_FORMAT_PRINTF(3, 4);
-#else
-#define FallbackICSpew(...)
-#define TypeFallbackICSpew(...)
-#endif
-
-//
-// An entry in the JIT IC descriptor table.
-//
-class ICEntry
-{
-  private:
-    // A pointer to the shared IC stub for this instruction.
-    ICStub* firstStub_;
-
-    // Offset from the start of the JIT code where the IC
-    // load and call instructions are.
-    uint32_t returnOffset_;
-
-    // The PC of this IC's bytecode op within the JSScript.
-    uint32_t pcOffset_ : 28;
-
-  public:
-    enum Kind {
-        // A for-op IC entry.
-        Kind_Op = 0,
-
-        // A non-op IC entry.
-        Kind_NonOp,
-
-        // A fake IC entry for returning from a callVM for an op.
-        Kind_CallVM,
-
-        // A fake IC entry for returning from a callVM not for an op (e.g., in
-        // the prologue).
-        Kind_NonOpCallVM,
-
-        // A fake IC entry for returning from a callVM to after the
-        // warmup counter.
-        Kind_WarmupCounter,
-
-        // A fake IC entry for returning from a callVM to the interrupt
-        // handler via the over-recursion check on function entry.
-        Kind_StackCheck,
-
-        // As above, but for the early check. See emitStackCheck.
-        Kind_EarlyStackCheck,
-
-        // A fake IC entry for returning from DebugTrapHandler.
-        Kind_DebugTrap,
-
-        // A fake IC entry for returning from a callVM to
-        // Debug{Prologue,AfterYield,Epilogue}.
-        Kind_DebugPrologue,
-        Kind_DebugAfterYield,
-        Kind_DebugEpilogue,
-
-        Kind_Invalid
-    };
-
-  private:
-    // What this IC is for.
-    Kind kind_ : 4;
-
-    // Set the kind and asserts that it's sane.
-    void setKind(Kind kind) {
-        MOZ_ASSERT(kind < Kind_Invalid);
-        kind_ = kind;
-        MOZ_ASSERT(this->kind() == kind);
-    }
-
-  public:
-    ICEntry(uint32_t pcOffset, Kind kind)
-      : firstStub_(nullptr), returnOffset_(), pcOffset_(pcOffset)
-    {
-        // The offset must fit in at least 28 bits, since we shave off 4 for
-        // the Kind enum.
-        MOZ_ASSERT(pcOffset_ == pcOffset);
-        JS_STATIC_ASSERT(BaselineScript::MAX_JSSCRIPT_LENGTH <= (1u << 28) - 1);
-        MOZ_ASSERT(pcOffset <= BaselineScript::MAX_JSSCRIPT_LENGTH);
-        setKind(kind);
-    }
-
-    CodeOffset returnOffset() const {
-        return CodeOffset(returnOffset_);
-    }
-
-    void setReturnOffset(CodeOffset offset) {
-        MOZ_ASSERT(offset.offset() <= (size_t) UINT32_MAX);
-        returnOffset_ = (uint32_t) offset.offset();
-    }
-
-    uint32_t pcOffset() const {
-        return pcOffset_;
-    }
-
-    jsbytecode* pc(JSScript* script) const {
-        return script->offsetToPC(pcOffset_);
-    }
-
-    Kind kind() const {
-        // MSVC compiles enums as signed.
-        return Kind(kind_ & 0xf);
-    }
-    bool isForOp() const {
-        return kind() == Kind_Op;
-    }
-
-    void setFakeKind(Kind kind) {
-        MOZ_ASSERT(kind != Kind_Op && kind != Kind_NonOp);
-        setKind(kind);
-    }
-
-    bool hasStub() const {
-        return firstStub_ != nullptr;
-    }
-    ICStub* firstStub() const {
-        MOZ_ASSERT(hasStub());
-        return firstStub_;
-    }
-
-    ICFallbackStub* fallbackStub() const;
-
-    void setFirstStub(ICStub* stub) {
-        firstStub_ = stub;
-    }
-
-    static inline size_t offsetOfFirstStub() {
-        return offsetof(ICEntry, firstStub_);
-    }
-
-    inline ICStub** addressOfFirstStub() {
-        return &firstStub_;
-    }
-
-    void trace(JSTracer* trc);
-};
-
-class ICMonitoredStub;
-class ICMonitoredFallbackStub;
-class ICUpdatedStub;
-
-// Constant iterator that traverses arbitrary chains of ICStubs.
-// No requirements are made of the ICStub used to construct this
-// iterator, aside from that the stub be part of a nullptr-terminated
-// chain.
-// The iterator is considered to be at its end once it has been
-// incremented _past_ the last stub.  Thus, if 'atEnd()' returns
-// true, the '*' and '->' operations are not valid.
-class ICStubConstIterator
-{
-    friend class ICStub;
-    friend class ICFallbackStub;
-
-  private:
-    ICStub* currentStub_;
-
-  public:
-    explicit ICStubConstIterator(ICStub* currentStub) : currentStub_(currentStub) {}
-
-    static ICStubConstIterator StartingAt(ICStub* stub) {
-        return ICStubConstIterator(stub);
-    }
-    static ICStubConstIterator End(ICStub* stub) {
-        return ICStubConstIterator(nullptr);
-    }
-
-    bool operator ==(const ICStubConstIterator& other) const {
-        return currentStub_ == other.currentStub_;
-    }
-    bool operator !=(const ICStubConstIterator& other) const {
-        return !(*this == other);
-    }
-
-    ICStubConstIterator& operator++();
-
-    ICStubConstIterator operator++(int) {
-        ICStubConstIterator oldThis(*this);
-        ++(*this);
-        return oldThis;
-    }
-
-    ICStub* operator*() const {
-        MOZ_ASSERT(currentStub_);
-        return currentStub_;
-    }
-
-    ICStub* operator ->() const {
-        MOZ_ASSERT(currentStub_);
-        return currentStub_;
-    }
-
-    bool atEnd() const {
-        return currentStub_ == nullptr;
-    }
-};
-
-// Iterator that traverses "regular" IC chains that start at an ICEntry
-// and are terminated with an ICFallbackStub.
-//
-// The iterator is considered to be at its end once it is _at_ the
-// fallback stub.  Thus, unlike the ICStubConstIterator, operators
-// '*' and '->' are valid even if 'atEnd()' returns true - they
-// will act on the fallback stub.
-//
-// This iterator also allows unlinking of stubs being traversed.
-// Note that 'unlink' does not implicitly advance the iterator -
-// it must be advanced explicitly using '++'.
-class ICStubIterator
-{
-    friend class ICFallbackStub;
-
-  private:
-    ICEntry* icEntry_;
-    ICFallbackStub* fallbackStub_;
-    ICStub* previousStub_;
-    ICStub* currentStub_;
-    bool unlinked_;
-
-    explicit ICStubIterator(ICFallbackStub* fallbackStub, bool end=false);
-  public:
-
-    bool operator ==(const ICStubIterator& other) const {
-        // == should only ever be called on stubs from the same chain.
-        MOZ_ASSERT(icEntry_ == other.icEntry_);
-        MOZ_ASSERT(fallbackStub_ == other.fallbackStub_);
-        return currentStub_ == other.currentStub_;
-    }
-    bool operator !=(const ICStubIterator& other) const {
-        return !(*this == other);
-    }
-
-    ICStubIterator& operator++();
-
-    ICStubIterator operator++(int) {
-        ICStubIterator oldThis(*this);
-        ++(*this);
-        return oldThis;
-    }
-
-    ICStub* operator*() const {
-        return currentStub_;
-    }
-
-    ICStub* operator ->() const {
-        return currentStub_;
-    }
-
-    bool atEnd() const {
-        return currentStub_ == (ICStub*) fallbackStub_;
-    }
-
-    void unlink(JSContext* cx);
-};
-
-//
-// Base class for all IC stubs.
-//
-class ICStub
-{
-    friend class ICFallbackStub;
-
-  public:
-    enum Kind {
-        INVALID = 0,
-#define DEF_ENUM_KIND(kindName) kindName,
-        IC_BASELINE_STUB_KIND_LIST(DEF_ENUM_KIND)
-#undef DEF_ENUM_KIND
-        LIMIT
-    };
-
-    static bool IsValidKind(Kind k) {
-        return (k > INVALID) && (k < LIMIT);
-    }
-    static bool IsCacheIRKind(Kind k) {
-        return k == CacheIR_Regular || k == CacheIR_Monitored || k == CacheIR_Updated;
-    }
-
-    static const char* KindString(Kind k) {
-        switch(k) {
-#define DEF_KIND_STR(kindName) case kindName: return #kindName;
-            IC_BASELINE_STUB_KIND_LIST(DEF_KIND_STR)
-#undef DEF_KIND_STR
-          default:
-            MOZ_CRASH("Invalid kind.");
-        }
-    }
-
-    enum Trait {
-        Regular             = 0x0,
-        Fallback            = 0x1,
-        Monitored           = 0x2,
-        MonitoredFallback   = 0x3,
-        Updated             = 0x4
-    };
-
-    void traceCode(JSTracer* trc, const char* name);
-    void updateCode(JitCode* stubCode);
-    void trace(JSTracer* trc);
-
-    template <typename T, typename... Args>
-    static T* New(JSContext* cx, ICStubSpace* space, JitCode* code, Args&&... args) {
-        if (!code)
-            return nullptr;
-        T* result = space->allocate<T>(code, std::forward<Args>(args)...);
-        if (!result)
-            ReportOutOfMemory(cx);
-        return result;
-    }
-
-  protected:
-    // The raw jitcode to call for this stub.
-    uint8_t* stubCode_;
-
-    // Pointer to next IC stub.  This is null for the last IC stub, which should
-    // either be a fallback or inert IC stub.
-    ICStub* next_;
-
-    // A 16-bit field usable by subtypes of ICStub for subtype-specific small-info
-    uint16_t extra_;
-
-    // The kind of the stub.
-    //  High bit is 'isFallback' flag.
-    //  Second high bit is 'isMonitored' flag.
-    Trait trait_ : 3;
-    Kind kind_ : 13;
-
-    inline ICStub(Kind kind, JitCode* stubCode)
-      : stubCode_(stubCode->raw()),
-        next_(nullptr),
-        extra_(0),
-        trait_(Regular),
-        kind_(kind)
-    {
-        MOZ_ASSERT(stubCode != nullptr);
-    }
-
-    inline ICStub(Kind kind, Trait trait, JitCode* stubCode)
-      : stubCode_(stubCode->raw()),
-        next_(nullptr),
-        extra_(0),
-        trait_(trait),
-        kind_(kind)
-    {
-        MOZ_ASSERT(stubCode != nullptr);
-    }
-
-    inline Trait trait() const {
-        // Workaround for MSVC reading trait_ as signed value.
-        return (Trait)(trait_ & 0x7);
-    }
-
-  public:
-
-    inline Kind kind() const {
-        return static_cast<Kind>(kind_);
-    }
-
-    inline bool isFallback() const {
-        return trait() == Fallback || trait() == MonitoredFallback;
-    }
-
-    inline bool isMonitored() const {
-        return trait() == Monitored;
-    }
-
-    inline bool isUpdated() const {
-        return trait() == Updated;
-    }
-
-    inline bool isMonitoredFallback() const {
-        return trait() == MonitoredFallback;
-    }
-
-    inline const ICFallbackStub* toFallbackStub() const {
-        MOZ_ASSERT(isFallback());
-        return reinterpret_cast<const ICFallbackStub*>(this);
-    }
-
-    inline ICFallbackStub* toFallbackStub() {
-        MOZ_ASSERT(isFallback());
-        return reinterpret_cast<ICFallbackStub*>(this);
-    }
-
-    inline const ICMonitoredStub* toMonitoredStub() const {
-        MOZ_ASSERT(isMonitored());
-        return reinterpret_cast<const ICMonitoredStub*>(this);
-    }
-
-    inline ICMonitoredStub* toMonitoredStub() {
-        MOZ_ASSERT(isMonitored());
-        return reinterpret_cast<ICMonitoredStub*>(this);
-    }
-
-    inline const ICMonitoredFallbackStub* toMonitoredFallbackStub() const {
-        MOZ_ASSERT(isMonitoredFallback());
-        return reinterpret_cast<const ICMonitoredFallbackStub*>(this);
-    }
-
-    inline ICMonitoredFallbackStub* toMonitoredFallbackStub() {
-        MOZ_ASSERT(isMonitoredFallback());
-        return reinterpret_cast<ICMonitoredFallbackStub*>(this);
-    }
-
-    inline const ICUpdatedStub* toUpdatedStub() const {
-        MOZ_ASSERT(isUpdated());
-        return reinterpret_cast<const ICUpdatedStub*>(this);
-    }
-
-    inline ICUpdatedStub* toUpdatedStub() {
-        MOZ_ASSERT(isUpdated());
-        return reinterpret_cast<ICUpdatedStub*>(this);
-    }
-
-#define KIND_METHODS(kindName)   \
-    inline bool is##kindName() const { return kind() == kindName; } \
-    inline const IC##kindName* to##kindName() const { \
-        MOZ_ASSERT(is##kindName()); \
-        return reinterpret_cast<const IC##kindName*>(this); \
-    } \
-    inline IC##kindName* to##kindName() { \
-        MOZ_ASSERT(is##kindName()); \
-        return reinterpret_cast<IC##kindName*>(this); \
-    }
-    IC_BASELINE_STUB_KIND_LIST(KIND_METHODS)
-#undef KIND_METHODS
-
-    inline ICStub* next() const {
-        return next_;
-    }
-
-    inline bool hasNext() const {
-        return next_ != nullptr;
-    }
-
-    inline void setNext(ICStub* stub) {
-        // Note: next_ only needs to be changed under the compilation lock for
-        // non-type-monitor/update ICs.
-        next_ = stub;
-    }
-
-    inline ICStub** addressOfNext() {
-        return &next_;
-    }
-
-    inline JitCode* jitCode() {
-        return JitCode::FromExecutable(stubCode_);
-    }
-
-    inline uint8_t* rawStubCode() const {
-        return stubCode_;
-    }
-
-    // This method is not valid on TypeUpdate stub chains!
-    inline ICFallbackStub* getChainFallback() {
-        ICStub* lastStub = this;
-        while (lastStub->next_)
-            lastStub = lastStub->next_;
-        MOZ_ASSERT(lastStub->isFallback());
-        return lastStub->toFallbackStub();
-    }
-
-    inline ICStubConstIterator beginHere() {
-        return ICStubConstIterator::StartingAt(this);
-    }
-
-    static inline size_t offsetOfNext() {
-        return offsetof(ICStub, next_);
-    }
-
-    static inline size_t offsetOfStubCode() {
-        return offsetof(ICStub, stubCode_);
-    }
-
-    static inline size_t offsetOfExtra() {
-        return offsetof(ICStub, extra_);
-    }
-
-    static bool NonCacheIRStubMakesGCCalls(Kind kind);
-    bool makesGCCalls() const;
-
-    // Optimized stubs get purged on GC.  But some stubs can be active on the
-    // stack during GC - specifically the ones that can make calls.  To ensure
-    // that these do not get purged, all stubs that can make calls are allocated
-    // in the fallback stub space.
-    bool allocatedInFallbackSpace() const {
-        MOZ_ASSERT(next());
-        return makesGCCalls();
-    }
-};
-
-} // namespace jit
-} // namespace js
-
-#endif /* jit_SharedIC_h */
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -318,17 +318,16 @@ UNIFIED_SOURCES += [
     'jit/RematerializedFrame.cpp',
     'jit/Safepoints.cpp',
     'jit/ScalarReplacement.cpp',
     'jit/shared/Assembler-shared.cpp',
     'jit/shared/BaselineCompiler-shared.cpp',
     'jit/shared/CodeGenerator-shared.cpp',
     'jit/shared/Disassembler-shared.cpp',
     'jit/shared/Lowering-shared.cpp',
-    'jit/SharedIC.cpp',
     'jit/Sink.cpp',
     'jit/Snapshots.cpp',
     'jit/StupidAllocator.cpp',
     'jit/TypedObjectPrediction.cpp',
     'jit/TypePolicy.cpp',
     'jit/ValueNumbering.cpp',
     'jit/VMFunctions.cpp',
     'jit/WasmBCE.cpp',