Bug 1447578 part 3 - Remove MacroAssembler rooting/tracing code. r=jonco
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 21 Mar 2018 16:58:04 +0100
changeset 1460144 af5c036e68f4fa99b6c6fcd2c7d27de9b2dce200
parent 1460143 3d56f55622c6844c162aa5b65d98745eebf09530
child 1460145 ff52c7cdce5e03f31224c3d215c48020e878849e
push id260095
push userecoal95@gmail.com
push dateWed, 21 Mar 2018 17:01:50 +0000
treeherdertry@0c24a9ae2a68 [default view] [failures only]
reviewersjonco
bugs1447578
milestone61.0a1
Bug 1447578 part 3 - Remove MacroAssembler rooting/tracing code. r=jonco
js/public/RootingAPI.h
js/src/gc/RootMarking.cpp
js/src/jit/CodeGenerator.cpp
js/src/jit/Ion.cpp
js/src/jit/Linker.h
js/src/jit/MacroAssembler.cpp
js/src/jit/MacroAssembler.h
js/src/jit/arm/Assembler-arm.cpp
js/src/jit/arm/Assembler-arm.h
js/src/jit/arm64/Assembler-arm64.cpp
js/src/jit/arm64/Assembler-arm64.h
js/src/jit/mips32/Assembler-mips32.cpp
js/src/jit/mips32/Assembler-mips32.h
js/src/jit/mips64/Assembler-mips64.cpp
js/src/jit/mips64/Assembler-mips64.h
js/src/jit/none/MacroAssembler-none.h
js/src/jit/x86-shared/Assembler-x86-shared.cpp
js/src/jit/x86-shared/Assembler-x86-shared.h
--- a/js/public/RootingAPI.h
+++ b/js/public/RootingAPI.h
@@ -890,17 +890,16 @@ class JS_PUBLIC_API(AutoGCRooter)
     ptrdiff_t tag_;
 
     enum {
         VALARRAY =     -2, /* js::AutoValueArray */
         PARSER =       -3, /* js::frontend::Parser */
 #if defined(JS_BUILD_BINAST)
         BINPARSER =    -4, /* js::frontend::BinSource */
 #endif // defined(JS_BUILD_BINAST)
-        IONMASM =     -19, /* js::jit::MacroAssembler */
         WRAPVECTOR =  -20, /* js::AutoWrapperVector */
         WRAPPER =     -21, /* js::AutoWrapperRooter */
         CUSTOM =      -26  /* js::CustomAutoRooter */
     };
 
   private:
     AutoGCRooter ** const stackTop;
 
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -157,21 +157,16 @@ AutoGCRooter::trace(JSTracer* trc)
          * We don't know the template size parameter, but we can safely treat it
          * as an AutoValueArray<1> because the length is stored separately.
          */
         AutoValueArray<1>* array = static_cast<AutoValueArray<1>*>(this);
         TraceRootRange(trc, array->length(), array->begin(), "js::AutoValueArray");
         return;
       }
 
-      case IONMASM: {
-        static_cast<js::jit::MacroAssembler::AutoRooter*>(this)->masm()->trace(trc);
-        return;
-      }
-
       case WRAPPER: {
         /*
          * We need to use TraceManuallyBarrieredEdge here because we trace
          * wrapper roots in every slice. This is because of some rule-breaking
          * in RemapAllWrappersForObject; see comment there.
          */
         TraceManuallyBarrieredEdge(trc, &static_cast<AutoWrapperRooter*>(this)->value.get(),
                                    "JS::AutoWrapperRooter.value");
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -10297,17 +10297,17 @@ CodeGenerator::link(JSContext* cx, Compi
     if (!ionScript)
         return false;
     auto guardIonScript = mozilla::MakeScopeExit([&ionScript] {
         // Use js_free instead of IonScript::Destroy: the cache list and
         // backedge list are still uninitialized.
         js_free(ionScript);
     });
 
-    Linker linker(masm, nogc);
+    Linker linker(masm);
     AutoFlushICache afc("IonLink");
     JitCode* code = linker.newCode(cx, CodeKind::Ion, !patchableBackedges_.empty());
     if (!code)
         return false;
 
     // Encode native to bytecode map if profiling is enabled.
     if (isProfilerInstrumentationEnabled()) {
         // Generate native-to-bytecode main table.
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -570,22 +570,16 @@ LinkCodeGen(JSContext* cx, IonBuilder* b
 static bool
 LinkBackgroundCodeGen(JSContext* cx, IonBuilder* builder)
 {
     CodeGenerator* codegen = builder->backgroundCodegen();
     if (!codegen)
         return false;
 
     JitContext jctx(cx, &builder->alloc());
-
-    // Root the assembler until the builder is finished below. As it was
-    // constructed off thread, the assembler has not been rooted previously,
-    // though any GC activity would discard the builder.
-    MacroAssembler::AutoRooter masm(cx, &codegen->masm);
-
     return LinkCodeGen(cx, builder, codegen);
 }
 
 void
 jit::LinkIonScript(JSContext* cx, HandleScript calleeScript)
 {
     IonBuilder* builder;
 
--- a/js/src/jit/Linker.h
+++ b/js/src/jit/Linker.h
@@ -27,25 +27,16 @@ class Linker
         return nullptr;
     }
 
   public:
     // Construct a linker with a rooted macro assembler.
     explicit Linker(MacroAssembler& masm)
       : masm(masm)
     {
-        MOZ_ASSERT(masm.isRooted());
-        masm.finish();
-    }
-
-    // If the macro assembler isn't rooted then care must be taken as it often
-    // contains GC pointers.
-    Linker(MacroAssembler& masm, JS::AutoRequireNoGC& nogc)
-      : masm(masm)
-    {
         masm.finish();
     }
 
     // Create a new JitCode object and populate it with the contents of the
     // macro assember buffer.
     //
     // This method cannot GC. Errors are reported to the context.
     JitCode* newCode(JSContext* cx, CodeKind kind, bool hasPatchableBackedges = false);
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -2805,17 +2805,16 @@ MacroAssembler::alignJitStackBasedOnNArg
 
 MacroAssembler::MacroAssembler(JSContext* cx)
   : framePushed_(0),
 #ifdef DEBUG
     inCall_(false),
 #endif
     emitProfilingInstrumentation_(false)
 {
-    constructRoot(cx);
     jitContext_.emplace(cx, (js::jit::TempAllocator*)nullptr);
     alloc_.emplace(cx);
     moveResolver_.setAllocator(*jitContext_->temp);
 #if defined(JS_CODEGEN_ARM)
     initWithAllocator();
     m_buffer.id = GetJitContext()->getNextAssemblerId();
 #elif defined(JS_CODEGEN_ARM64)
     initWithAllocator();
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -236,31 +236,16 @@ enum class CharEncoding { Latin1, TwoByt
 // lifoAlloc use if one will be destroyed before the other.
 class MacroAssembler : public MacroAssemblerSpecific
 {
     MacroAssembler* thisFromCtor() {
         return this;
     }
 
   public:
-    class AutoRooter : public JS::AutoGCRooter
-    {
-        MacroAssembler* masm_;
-
-      public:
-        AutoRooter(JSContext* cx, MacroAssembler* masm)
-          : JS::AutoGCRooter(cx, IONMASM),
-            masm_(masm)
-        { }
-
-        MacroAssembler* masm() const {
-            return masm_;
-        }
-    };
-
     /*
      * Base class for creating a branch.
      */
     class Branch
     {
         bool init_;
         Condition cond_;
         Label* jump_;
@@ -322,17 +307,16 @@ class MacroAssembler : public MacroAssem
         BranchGCPtr(Condition cond, Register reg, ImmGCPtr ptr, Label* jump)
           : Branch(cond, reg, jump),
             ptr_(ptr)
         { }
 
         void emit(MacroAssembler& masm);
     };
 
-    mozilla::Maybe<AutoRooter> autoRooter_;
     mozilla::Maybe<JitContext> jitContext_;
     mozilla::Maybe<AutoJitContextAlloc> alloc_;
 
   private:
     // Labels for handling exceptions and failures.
     NonAssertingLabel failureLabel_;
 
   protected:
@@ -340,21 +324,19 @@ class MacroAssembler : public MacroAssem
     MacroAssembler()
       : framePushed_(0),
 #ifdef DEBUG
         inCall_(false),
 #endif
         emitProfilingInstrumentation_(false)
     {
         JitContext* jcx = GetJitContext();
-        JSContext* cx = jcx->cx;
-        if (cx)
-            constructRoot(cx);
 
         if (!jcx->temp) {
+            JSContext* cx = jcx->cx;
             MOZ_ASSERT(cx);
             alloc_.emplace(cx);
         }
 
         moveResolver_.setAllocator(*jcx->temp);
 
 #if defined(JS_CODEGEN_ARM)
         initWithAllocator();
@@ -388,26 +370,16 @@ class MacroAssembler : public MacroAssem
         // Stubs + builtins + the baseline compiler all require the native SP,
         // not the PSP.
         SetStackPointer64(sp);
         armbuffer_.id = 0;
 #endif
     }
 
   public:
-#ifdef DEBUG
-    bool isRooted() const {
-        return autoRooter_.isSome();
-    }
-#endif
-
-    void constructRoot(JSContext* cx) {
-        autoRooter_.emplace(cx, this);
-    }
-
     MoveResolver& moveResolver() {
         return moveResolver_;
     }
 
     size_t instructionsSize() const {
         return size();
     }
 
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -805,19 +805,18 @@ Assembler::GetCF32Target(Iter* iter)
 uintptr_t
 Assembler::GetPointer(uint8_t* instPtr)
 {
     InstructionIterator iter((Instruction*)instPtr);
     uintptr_t ret = (uintptr_t)GetPtr32Target(iter, nullptr, nullptr);
     return ret;
 }
 
-template<class Iter>
 const uint32_t*
-Assembler::GetPtr32Target(Iter start, Register* dest, RelocStyle* style)
+Assembler::GetPtr32Target(InstructionIterator start, Register* dest, RelocStyle* style)
 {
     Instruction* load1 = start.cur();
     Instruction* load2 = start.next();
 
     if (load1->is<InstMovW>() && load2->is<InstMovT>()) {
         if (style)
             *style = L_MOVWT;
 
@@ -872,19 +871,18 @@ Assembler::TraceJumpRelocations(JSTracer
     RelocationIterator iter(reader);
     while (iter.read()) {
         InstructionIterator institer((Instruction*) (code->raw() + iter.offset()));
         JitCode* child = CodeFromJump(&institer);
         TraceManuallyBarrieredEdge(trc, &child, "rel32");
     }
 }
 
-template <class Iter>
 static void
-TraceOneDataRelocation(JSTracer* trc, Iter iter)
+TraceOneDataRelocation(JSTracer* trc, InstructionIterator iter)
 {
     Register dest;
     Assembler::RelocStyle rs;
     const void* prior = Assembler::GetPtr32Target(iter, &dest, &rs);
     void* ptr = const_cast<void*>(prior);
 
     // No barrier needed since these are constants.
     TraceManuallyBarrieredGenericPointerEdge(trc, reinterpret_cast<gc::Cell**>(&ptr),
@@ -896,75 +894,41 @@ TraceOneDataRelocation(JSTracer* trc, It
         // L_LDR won't cause any instructions to be updated.
         if (rs != Assembler::L_LDR) {
             AutoFlushICache::flush(uintptr_t(iter.cur()), 4);
             AutoFlushICache::flush(uintptr_t(iter.next()), 4);
         }
     }
 }
 
-static void
-TraceDataRelocations(JSTracer* trc, uint8_t* buffer, CompactBufferReader& reader)
+/* static */ void
+Assembler::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader)
 {
     while (reader.more()) {
         size_t offset = reader.readUnsigned();
-        InstructionIterator iter((Instruction*)(buffer + offset));
+        InstructionIterator iter((Instruction*)(code->raw() + offset));
         TraceOneDataRelocation(trc, iter);
     }
 }
 
-static void
-TraceDataRelocations(JSTracer* trc, ARMBuffer* buffer, CompactBufferReader& reader)
-{
-    while (reader.more()) {
-        BufferOffset offset(reader.readUnsigned());
-        BufferInstructionIterator iter(offset, buffer);
-        TraceOneDataRelocation(trc, iter);
-    }
-}
-
-void
-Assembler::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader)
-{
-    ::TraceDataRelocations(trc, code->raw(), reader);
-}
-
 void
 Assembler::copyJumpRelocationTable(uint8_t* dest)
 {
     if (jumpRelocations_.length())
         memcpy(dest, jumpRelocations_.buffer(), jumpRelocations_.length());
 }
 
 void
 Assembler::copyDataRelocationTable(uint8_t* dest)
 {
     if (dataRelocations_.length())
         memcpy(dest, dataRelocations_.buffer(), dataRelocations_.length());
 }
 
 void
-Assembler::trace(JSTracer* trc)
-{
-    for (size_t i = 0; i < jumps_.length(); i++) {
-        RelativePatch& rp = jumps_[i];
-        if (rp.kind() == Relocation::JITCODE) {
-            JitCode* code = JitCode::FromExecutable((uint8_t*)rp.target());
-            TraceManuallyBarrieredEdge(trc, &code, "masmrel32");
-            MOZ_ASSERT(code == JitCode::FromExecutable((uint8_t*)rp.target()));
-        }
-    }
-
-    if (dataRelocations_.length()) {
-        CompactBufferReader reader(dataRelocations_);
-        ::TraceDataRelocations(trc, &m_buffer, reader);
-    }
-}
-
-void
 Assembler::processCodeLabels(uint8_t* rawCode)
 {
     for (const CodeLabel& label : codeLabels_) {
         Bind(rawCode, label);
     }
 }
 
 void
--- a/js/src/jit/arm/Assembler-arm.h
+++ b/js/src/jit/arm/Assembler-arm.h
@@ -1138,16 +1138,43 @@ PatchJump(CodeLocationJump& jump_, CodeL
           ReprotectCode reprotect = DontReprotect);
 
 static inline void
 PatchBackedge(CodeLocationJump& jump_, CodeLocationLabel label, JitZoneGroup::BackedgeTarget target)
 {
     PatchJump(jump_, label);
 }
 
+class InstructionIterator
+{
+  private:
+    Instruction* inst_;
+
+  public:
+    explicit InstructionIterator(Instruction* inst)
+      : inst_(inst)
+    {
+        maybeSkipAutomaticInstructions();
+    }
+
+    // Advances to the next intentionally-inserted instruction.
+    Instruction* next();
+
+    // Advances past any automatically-inserted instructions.
+    Instruction* maybeSkipAutomaticInstructions();
+
+    Instruction* cur() const {
+        return inst_;
+    }
+
+  protected:
+    // Advances past the given number of instruction-length bytes.
+    inline void advanceRaw(ptrdiff_t instructions = 1);
+};
+
 class Assembler;
 typedef js::jit::AssemblerBufferWithConstantPools<1024, 4, Instruction, Assembler> ARMBuffer;
 
 class Assembler : public AssemblerShared
 {
   public:
     // ARM conditional constants:
     enum ARMCondition : uint32_t {
@@ -1337,18 +1364,16 @@ class Assembler : public AssemblerShared
     }
 
     static Condition InvertCondition(Condition cond);
     static Condition UnsignedCondition(Condition cond);
     static Condition ConditionWithoutEqual(Condition cond);
 
     static DoubleCondition InvertCondition(DoubleCondition cond);
 
-    // MacroAssemblers hold onto gcthings, so they are traced by the GC.
-    void trace(JSTracer* trc);
     void writeRelocation(BufferOffset src) {
         jumpRelocations_.writeUnsigned(src.getOffset());
     }
 
     void writeDataRelocation(BufferOffset offset, ImmGCPtr ptr) {
         if (ptr.value) {
             if (gc::IsInsideNursery(ptr.value))
                 embedsNurseryPointers_ = true;
@@ -1371,18 +1396,18 @@ class Assembler : public AssemblerShared
   public:
     // Given the start of a Control Flow sequence, grab the value that is
     // finally branched to given the start of a function that loads an address
     // into a register get the address that ends up in the register.
     template <class Iter>
     static const uint32_t* GetCF32Target(Iter* iter);
 
     static uintptr_t GetPointer(uint8_t*);
-    template <class Iter>
-    static const uint32_t* GetPtr32Target(Iter iter, Register* dest = nullptr, RelocStyle* rs = nullptr);
+    static const uint32_t* GetPtr32Target(InstructionIterator iter, Register* dest = nullptr,
+                                          RelocStyle* rs = nullptr);
 
     bool oom() const;
 
     void setPrinter(Sprinter* sp) {
 #ifdef JS_DISASM_ARM
         spew_.setPrinter(sp);
 #endif
     }
@@ -2011,16 +2036,22 @@ class Instruction
     // instruction. raw() just coerces this into a pointer to a uint32_t.
     const uint32_t* raw() const { return &data; }
     uint32_t size() const { return 4; }
 }; // Instruction
 
 // Make sure that it is the right size.
 JS_STATIC_ASSERT(sizeof(Instruction) == 4);
 
+inline void
+InstructionIterator::advanceRaw(ptrdiff_t instructions)
+{
+    inst_ = inst_ + instructions;
+}
+
 // Data Transfer Instructions.
 class InstDTR : public Instruction
 {
   public:
     enum IsByte_ {
         IsByte = 0x00400000,
         IsWord = 0x00000000
     };
@@ -2251,51 +2282,16 @@ class InstCMP : public InstALU
 
 class InstMOV : public InstALU
 {
   public:
     static bool IsTHIS (const Instruction& i);
     static InstMOV* AsTHIS (const Instruction& i);
 };
 
-class InstructionIterator
-{
-  private:
-    Instruction* inst_;
-
-  public:
-    explicit InstructionIterator(Instruction* inst)
-      : inst_(inst)
-    {
-        maybeSkipAutomaticInstructions();
-    }
-
-    // Advances to the next intentionally-inserted instruction.
-    Instruction* next();
-
-    // Advances past any automatically-inserted instructions.
-    Instruction* maybeSkipAutomaticInstructions();
-
-    Instruction* cur() const {
-        return inst_;
-    }
-
-  protected:
-    // Advances past the given number of instruction-length bytes.
-    void advanceRaw(ptrdiff_t instructions = 1) {
-        inst_ = inst_ + instructions;
-    }
-
-    // Look ahead, including automatically-inserted instructions
-    // and PoolHeaders.
-    Instruction* peekRaw(ptrdiff_t instructions = 1) const {
-        return inst_ + instructions;
-    }
-};
-
 // Compile-time iterator over instructions, with a safe interface that
 // references not-necessarily-linear Instructions by linear BufferOffset.
 class BufferInstructionIterator : public ARMBuffer::AssemblerBufferInstIterator
 {
   public:
     BufferInstructionIterator(BufferOffset bo, ARMBuffer* buffer)
       : ARMBuffer::AssemblerBufferInstIterator(bo, buffer)
     {}
--- a/js/src/jit/arm64/Assembler-arm64.cpp
+++ b/js/src/jit/arm64/Assembler-arm64.cpp
@@ -323,35 +323,16 @@ Assembler::bindLater(Label* label, wasm:
             append(wasm::OldTrapSite(target, b.getOffset()));
             b = NextLink(b);
         } while (b.assigned());
     }
     label->reset();
 }
 
 void
-Assembler::trace(JSTracer* trc)
-{
-    for (size_t i = 0; i < pendingJumps_.length(); i++) {
-        RelativePatch& rp = pendingJumps_[i];
-        if (rp.kind == Relocation::JITCODE) {
-            JitCode* code = JitCode::FromExecutable((uint8_t*)rp.target);
-            TraceManuallyBarrieredEdge(trc, &code, "masmrel32");
-            MOZ_ASSERT(code == JitCode::FromExecutable((uint8_t*)rp.target));
-        }
-    }
-
-    // TODO: Trace.
-#if 0
-    if (tmpDataRelocations_.length())
-        ::TraceDataRelocations(trc, &armbuffer_, &tmpDataRelocations_);
-#endif
-}
-
-void
 Assembler::addJumpRelocation(BufferOffset src, Relocation::Kind reloc)
 {
     // Only JITCODE relocations are patchable at runtime.
     MOZ_ASSERT(reloc == Relocation::JITCODE);
 
     // The jump relocation table starts with a fixed-width integer pointing
     // to the start of the extended jump table. But, we don't know the
     // actual extended jump table offset yet, so write a 0 which we'll
@@ -600,19 +581,21 @@ Assembler::TraceJumpRelocations(JSTracer
     RelocationIterator iter(reader);
     while (iter.read()) {
         JitCode* child = CodeFromJump(code, code->raw() + iter.offset());
         TraceManuallyBarrieredEdge(trc, &child, "rel32");
         MOZ_ASSERT(child == CodeFromJump(code, code->raw() + iter.offset()));
     }
 }
 
-static void
-TraceDataRelocations(JSTracer* trc, uint8_t* buffer, CompactBufferReader& reader)
+/* static */ void
+Assembler::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader)
 {
+    uint8_t* buffer = code->raw();
+
     while (reader.more()) {
         size_t offset = reader.readUnsigned();
         Instruction* load = (Instruction*)&buffer[offset];
 
         // The only valid traceable operation is a 64-bit load to an ARMRegister.
         // Refer to movePatchablePtr() for generation.
         MOZ_ASSERT(load->Mask(vixl::LoadLiteralMask) == vixl::LDR_x_lit);
 
@@ -638,60 +621,16 @@ TraceDataRelocations(JSTracer* trc, uint
         TraceManuallyBarrieredGenericPointerEdge(trc, reinterpret_cast<gc::Cell**>(literalAddr),
                                                  "ion-masm-ptr");
 
         // TODO: Flush caches at end?
     }
 }
 
 void
-Assembler::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader)
-{
-    ::TraceDataRelocations(trc, code->raw(), reader);
-}
-
-void
-Assembler::FixupNurseryObjects(JSContext* cx, JitCode* code, CompactBufferReader& reader,
-                               const ObjectVector& nurseryObjects)
-{
-
-    MOZ_ASSERT(!nurseryObjects.empty());
-
-    uint8_t* buffer = code->raw();
-    bool hasNurseryPointers = false;
-
-    while (reader.more()) {
-        size_t offset = reader.readUnsigned();
-        Instruction* ins = (Instruction*)&buffer[offset];
-
-        uintptr_t* literalAddr = ins->LiteralAddress<uintptr_t*>();
-        uintptr_t literal = *literalAddr;
-
-        if (literal >> JSVAL_TAG_SHIFT)
-            continue; // This is a Value.
-
-        if (!(literal & 0x1))
-            continue;
-
-        uint32_t index = literal >> 1;
-        JSObject* obj = nurseryObjects[index];
-        *literalAddr = uintptr_t(obj);
-
-        // Either all objects are still in the nursery, or all objects are tenured.
-        MOZ_ASSERT_IF(hasNurseryPointers, IsInsideNursery(obj));
-
-        if (!hasNurseryPointers && IsInsideNursery(obj))
-            hasNurseryPointers = true;
-    }
-
-    if (hasNurseryPointers)
-        cx->zone()->group()->storeBuffer().putWholeCell(code);
-}
-
-void
 Assembler::retarget(Label* label, Label* target)
 {
 #ifdef JS_DISASM_ARM64
     spew_.spewRetarget(label, target);
 #endif
     if (label->used()) {
         if (target->bound()) {
             bind(label, BufferOffset(target));
--- a/js/src/jit/arm64/Assembler-arm64.h
+++ b/js/src/jit/arm64/Assembler-arm64.h
@@ -176,17 +176,16 @@ class Assembler : public vixl::Assembler
     { }
 
     typedef vixl::Condition Condition;
 
     void finish();
     bool appendRawCode(const uint8_t* code, size_t numBytes);
     bool reserve(size_t size);
     bool swapBuffer(wasm::Bytes& bytes);
-    void trace(JSTracer* trc);
 
     // Emit the jump table, returning the BufferOffset to the first entry in the table.
     BufferOffset emitExtendedJumpTable();
     BufferOffset ExtendedJumpTable_;
     void executableCopy(uint8_t* buffer, bool flushICache = true);
 
     BufferOffset immPool(ARMRegister dest, uint8_t* value, vixl::LoadLiteralOp op,
                          const LiteralDoc& doc, ARMBuffer::PoolEntry* pe = nullptr);
@@ -330,19 +329,16 @@ class Assembler : public vixl::Assembler
     // Toggle a jmp or cmp emitted by toggledJump().
     static void ToggleToJmp(CodeLocationLabel inst_);
     static void ToggleToCmp(CodeLocationLabel inst_);
     static void ToggleCall(CodeLocationLabel inst_, bool enabled);
 
     static void TraceJumpRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader);
     static void TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader);
 
-    static void FixupNurseryObjects(JSContext* cx, JitCode* code, CompactBufferReader& reader,
-                                    const ObjectVector& nurseryObjects);
-
   public:
     // A Jump table entry is 2 instructions, with 8 bytes of raw data
     static const size_t SizeOfJumpTableEntry = 16;
 
     struct JumpTableEntry
     {
         uint32_t ldr;
         uint32_t br;
--- a/js/src/jit/mips32/Assembler-mips32.cpp
+++ b/js/src/jit/mips32/Assembler-mips32.cpp
@@ -200,42 +200,26 @@ TraceOneDataRelocation(JSTracer* trc, In
     TraceManuallyBarrieredGenericPointerEdge(trc, reinterpret_cast<gc::Cell**>(&ptr),
                                                  "ion-masm-ptr");
     if (ptr != prior) {
         AssemblerMIPSShared::UpdateLuiOriValue(inst, inst->next(), uint32_t(ptr));
         AutoFlushICache::flush(uintptr_t(inst), 8);
     }
 }
 
-static void
-TraceDataRelocations(JSTracer* trc, uint8_t* buffer, CompactBufferReader& reader)
+/* static */ void
+Assembler::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader)
 {
     while (reader.more()) {
         size_t offset = reader.readUnsigned();
-        Instruction* inst = (Instruction*)(buffer + offset);
+        Instruction* inst = (Instruction*)(code->raw() + offset);
         TraceOneDataRelocation(trc, inst);
     }
 }
 
-static void
-TraceDataRelocations(JSTracer* trc, MIPSBuffer* buffer, CompactBufferReader& reader)
-{
-    while (reader.more()) {
-        BufferOffset bo (reader.readUnsigned());
-        MIPSBuffer::AssemblerBufferInstIterator iter(bo, buffer);
-        TraceOneDataRelocation(trc, iter.cur());
-    }
-}
-
-void
-Assembler::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader)
-{
-    ::TraceDataRelocations(trc, code->raw(), reader);
-}
-
 Assembler::Condition
 Assembler::UnsignedCondition(Condition cond)
 {
     switch (cond) {
       case Zero:
       case NonZero:
         return cond;
       case LessThan:
@@ -272,33 +256,16 @@ Assembler::ConditionWithoutEqual(Conditi
       case AboveOrEqual:
         return Above;
       default:
         MOZ_CRASH("unexpected condition");
     }
 }
 
 void
-Assembler::trace(JSTracer* trc)
-{
-    for (size_t i = 0; i < jumps_.length(); i++) {
-        RelativePatch& rp = jumps_[i];
-        if (rp.kind == Relocation::JITCODE) {
-            JitCode* code = JitCode::FromExecutable((uint8_t*)rp.target);
-            TraceManuallyBarrieredEdge(trc, &code, "masmrel32");
-            MOZ_ASSERT(code == JitCode::FromExecutable((uint8_t*)rp.target));
-        }
-    }
-    if (dataRelocations_.length()) {
-        CompactBufferReader reader(dataRelocations_);
-        ::TraceDataRelocations(trc, &m_buffer, reader);
-    }
-}
-
-void
 Assembler::Bind(uint8_t* rawCode, const CodeLabel& label)
 {
     if (label.patchAt().bound()) {
 
         auto mode = label.linkMode();
         intptr_t offset = label.patchAt().offset();
         intptr_t target = label.target().offset();
 
--- a/js/src/jit/mips32/Assembler-mips32.h
+++ b/js/src/jit/mips32/Assembler-mips32.h
@@ -147,19 +147,16 @@ class Assembler : public AssemblerMIPSSh
   public:
     Assembler()
       : AssemblerMIPSShared()
     { }
 
     static Condition UnsignedCondition(Condition cond);
     static Condition ConditionWithoutEqual(Condition cond);
 
-    // MacroAssemblers hold onto gcthings, so they are traced by the GC.
-    void trace(JSTracer* trc);
-
     static uintptr_t GetPointer(uint8_t*);
 
   protected:
     // This is used to access the odd register form the pair of single
     // precision registers that make one double register.
     FloatRegister getOddPair(FloatRegister reg) {
         MOZ_ASSERT(reg.isDouble());
         MOZ_ASSERT(reg.id() % 2 == 0);
--- a/js/src/jit/mips64/Assembler-mips64.cpp
+++ b/js/src/jit/mips64/Assembler-mips64.cpp
@@ -178,59 +178,26 @@ TraceOneDataRelocation(JSTracer* trc, In
     }
 
     if (ptr != prior) {
         Assembler::UpdateLoad64Value(inst, uint64_t(ptr));
         AutoFlushICache::flush(uintptr_t(inst), 6 * sizeof(uint32_t));
     }
 }
 
-static void
-TraceDataRelocations(JSTracer* trc, uint8_t* buffer, CompactBufferReader& reader)
+/* static */ void
+Assembler::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader)
 {
     while (reader.more()) {
         size_t offset = reader.readUnsigned();
-        Instruction* inst = (Instruction*)(buffer + offset);
+        Instruction* inst = (Instruction*)(code->raw() + offset);
         TraceOneDataRelocation(trc, inst);
     }
 }
 
-static void
-TraceDataRelocations(JSTracer* trc, MIPSBuffer* buffer, CompactBufferReader& reader)
-{
-    while (reader.more()) {
-        BufferOffset bo (reader.readUnsigned());
-        MIPSBuffer::AssemblerBufferInstIterator iter(bo, buffer);
-        TraceOneDataRelocation(trc, iter.cur());
-    }
-}
-
-void
-Assembler::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader)
-{
-    ::TraceDataRelocations(trc, code->raw(), reader);
-}
-
-void
-Assembler::trace(JSTracer* trc)
-{
-    for (size_t i = 0; i < jumps_.length(); i++) {
-        RelativePatch& rp = jumps_[i];
-        if (rp.kind == Relocation::JITCODE) {
-            JitCode* code = JitCode::FromExecutable((uint8_t*)rp.target);
-            TraceManuallyBarrieredEdge(trc, &code, "masmrel32");
-            MOZ_ASSERT(code == JitCode::FromExecutable((uint8_t*)rp.target));
-        }
-    }
-    if (dataRelocations_.length()) {
-        CompactBufferReader reader(dataRelocations_);
-        ::TraceDataRelocations(trc, &m_buffer, reader);
-    }
-}
-
 void
 Assembler::Bind(uint8_t* rawCode, const CodeLabel& label)
 {
     if (label.patchAt().bound()) {
 
         auto mode = label.linkMode();
         intptr_t offset = label.patchAt().offset();
         intptr_t target = label.target().offset();
--- a/js/src/jit/mips64/Assembler-mips64.h
+++ b/js/src/jit/mips64/Assembler-mips64.h
@@ -155,19 +155,16 @@ static constexpr Scale ScalePointer = Ti
 
 class Assembler : public AssemblerMIPSShared
 {
   public:
     Assembler()
       : AssemblerMIPSShared()
     { }
 
-    // MacroAssemblers hold onto gcthings, so they are traced by the GC.
-    void trace(JSTracer* trc);
-
     static uintptr_t GetPointer(uint8_t*);
 
     using AssemblerMIPSShared::bind;
 
     void bind(RepatchLabel* label);
     static void Bind(uint8_t* rawCode, const CodeLabel& label);
 
     void processCodeLabels(uint8_t* rawCode);
--- a/js/src/jit/none/MacroAssembler-none.h
+++ b/js/src/jit/none/MacroAssembler-none.h
@@ -196,17 +196,16 @@ class MacroAssemblerNone : public Assemb
 
     size_t numCodeLabels() const { MOZ_CRASH(); }
     CodeLabel codeLabel(size_t) { MOZ_CRASH(); }
 
     bool reserve(size_t size) { MOZ_CRASH(); }
     bool appendRawCode(const uint8_t* code, size_t numBytes) { MOZ_CRASH(); }
     bool swapBuffer(wasm::Bytes& bytes) { MOZ_CRASH(); }
 
-    void trace(JSTracer*) { MOZ_CRASH(); }
     static void TraceJumpRelocations(JSTracer*, JitCode*, CompactBufferReader&) { MOZ_CRASH(); }
     static void TraceDataRelocations(JSTracer*, JitCode*, CompactBufferReader&) { MOZ_CRASH(); }
 
     static bool SupportsFloatingPoint() { return false; }
     static bool SupportsSimd() { return false; }
     static bool SupportsUnalignedAccesses() { return false; }
 
     void executableCopy(void*, bool = true) { MOZ_CRASH(); }
--- a/js/src/jit/x86-shared/Assembler-x86-shared.cpp
+++ b/js/src/jit/x86-shared/Assembler-x86-shared.cpp
@@ -34,25 +34,24 @@ AssemblerX86Shared::copyJumpRelocationTa
 
 void
 AssemblerX86Shared::copyDataRelocationTable(uint8_t* dest)
 {
     if (dataRelocations_.length())
         memcpy(dest, dataRelocations_.buffer(), dataRelocations_.length());
 }
 
-static void
-TraceDataRelocations(JSTracer* trc, CompactBufferReader& reader,
-                     uint8_t* buffer, size_t bufferSize)
+/* static */ void
+AssemblerX86Shared::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader)
 {
     while (reader.more()) {
         size_t offset = reader.readUnsigned();
-        MOZ_ASSERT(offset >= sizeof(void*) && offset <= bufferSize);
+        MOZ_ASSERT(offset >= sizeof(void*) && offset <= code->instructionsSize());
 
-        uint8_t* src = buffer + offset;
+        uint8_t* src = code->raw() + offset;
         void* data = X86Encoding::GetPointer(src);
 
 #ifdef JS_PUNBOX64
         // All pointers on x64 will have the top bits cleared. If those bits
         // are not cleared, this must be a Value.
         uintptr_t word = reinterpret_cast<uintptr_t>(data);
         if (word >> JSVAL_TAG_SHIFT) {
             Value value = Value::fromRawBits(word);
@@ -71,39 +70,16 @@ TraceDataRelocations(JSTracer* trc, Comp
         MOZ_ASSERT(gc::IsCellPointerValid(cell));
         TraceManuallyBarrieredGenericPointerEdge(trc, &cell, "jit-masm-ptr");
         if (cell != data)
             X86Encoding::SetPointer(src, cell);
     }
 }
 
 void
-AssemblerX86Shared::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader)
-{
-    ::TraceDataRelocations(trc, reader, code->raw(), code->instructionsSize());
-}
-
-void
-AssemblerX86Shared::trace(JSTracer* trc)
-{
-    for (size_t i = 0; i < jumps_.length(); i++) {
-        RelativePatch& rp = jumps_[i];
-        if (rp.kind == Relocation::JITCODE) {
-            JitCode* code = JitCode::FromExecutable((uint8_t*)rp.target);
-            TraceManuallyBarrieredEdge(trc, &code, "masmrel32");
-            MOZ_ASSERT(code == JitCode::FromExecutable((uint8_t*)rp.target));
-        }
-    }
-    if (dataRelocations_.length()) {
-        CompactBufferReader reader(dataRelocations_);
-        ::TraceDataRelocations(trc, reader, masm.data(), masm.size());
-    }
-}
-
-void
 AssemblerX86Shared::executableCopy(void* buffer)
 {
     masm.executableCopy(buffer);
 
     // Crash diagnostics for bug 1124397. Check the code buffer has not been
     // poisoned with 0xE5 bytes.
     static const size_t MinPoisoned = 16;
     const uint8_t* bytes = (const uint8_t*)buffer;
--- a/js/src/jit/x86-shared/Assembler-x86-shared.h
+++ b/js/src/jit/x86-shared/Assembler-x86-shared.h
@@ -390,19 +390,16 @@ class AssemblerX86Shared : public Assemb
     // handle NaNs properly and may therefore require a secondary condition.
     // Use NaNCondFromDoubleCondition to determine what else is needed.
     static inline Condition ConditionFromDoubleCondition(DoubleCondition cond) {
         return static_cast<Condition>(cond & ~DoubleConditionBits);
     }
 
     static void TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader);
 
-    // MacroAssemblers hold onto gcthings, so they are traced by the GC.
-    void trace(JSTracer* trc);
-
     bool oom() const {
         return AssemblerShared::oom() ||
                masm.oom() ||
                jumpRelocations_.oom() ||
                dataRelocations_.oom();
     }
     bool reserve(size_t size) {
         return masm.reserve(size);