Bug 1137688 - Add eager simd unboxing phase. r=sunfish,bbouvier
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Tue, 03 Mar 2015 14:25:22 +0100
changeset 247051 703cef22656c230195dc9909ec331a879789e73c
parent 247050 e142f57da9acbdf55cfccdbb57dbdf9871e270f8
child 247052 23f0b767c77e9a62c9fac91090da20e035811d4e
push id884
push userdburns@mozilla.com
push dateTue, 03 Mar 2015 15:29:12 +0000
reviewerssunfish, bbouvier
bugs1137688
milestone39.0a1
Bug 1137688 - Add eager simd unboxing phase. r=sunfish,bbouvier
js/src/jit/CodeGenerator.cpp
js/src/jit/CodeGenerator.h
js/src/jit/EagerSimdUnbox.cpp
js/src/jit/EagerSimdUnbox.h
js/src/jit/Ion.cpp
js/src/jit/IonOptimizationLevels.cpp
js/src/jit/IonOptimizationLevels.h
js/src/jit/JitCompartment.h
js/src/jit/JitOptions.cpp
js/src/jit/JitOptions.h
js/src/jit/MIR.h
js/src/jit/ValueNumbering.cpp
js/src/moz.build
js/src/vm/TraceLogging.cpp
js/src/vm/TraceLoggingTypes.h
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -149,16 +149,17 @@ StringObject *
 MNewStringObject::templateObj() const {
     return &templateObj_->as<StringObject>();
 }
 
 CodeGenerator::CodeGenerator(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm)
   : CodeGeneratorSpecific(gen, graph, masm)
   , ionScriptLabels_(gen->alloc())
   , scriptCounts_(nullptr)
+  , simdRefreshTemplatesDuringLink_(0)
 {
 }
 
 CodeGenerator::~CodeGenerator()
 {
     MOZ_ASSERT_IF(!gen->compilingAsmJS(), masm.numAsmJSAbsoluteLinks() == 0);
     js_delete(scriptCounts_);
 }
@@ -4410,16 +4411,17 @@ void
 CodeGenerator::visitSimdBox(LSimdBox *lir)
 {
     FloatRegister in = ToFloatRegister(lir->input());
     Register object = ToRegister(lir->output());
     Register temp = ToRegister(lir->temp());
     InlineTypedObject *templateObject = lir->mir()->templateObject();
     gc::InitialHeap initialHeap = lir->mir()->initialHeap();
     MIRType type = lir->mir()->input()->type();
+    registerSimdTemplate(templateObject);
 
     MOZ_ASSERT(lir->safepoint()->liveRegs().has(in),
                "Save the input register across the oolCallVM");
     OutOfLineCode *ool = oolCallVM(NewTypedObjectInfo, lir,
                                    (ArgList(), ImmGCPtr(templateObject), Imm32(initialHeap)),
                                    StoreRegisterTo(object));
 
     masm.createGCObject(object, temp, templateObject, initialHeap, ool->entry());
@@ -4434,16 +4436,39 @@ CodeGenerator::visitSimdBox(LSimdBox *li
         masm.storeUnalignedFloat32x4(in, objectData);
         break;
       default:
         MOZ_CRASH("Unknown SIMD kind when generating code for SimdBox.");
     }
 }
 
 void
+CodeGenerator::registerSimdTemplate(InlineTypedObject *templateObject)
+{
+    simdRefreshTemplatesDuringLink_ |=
+        1 << uint32_t(templateObject->typeDescr().as<SimdTypeDescr>().type());
+}
+
+void
+CodeGenerator::captureSimdTemplate(JSContext *cx)
+{
+    JitCompartment *jitCompartment = cx->compartment()->jitCompartment();
+    while (simdRefreshTemplatesDuringLink_) {
+        uint32_t typeIndex = mozilla::CountTrailingZeroes32(simdRefreshTemplatesDuringLink_);
+        simdRefreshTemplatesDuringLink_ ^= 1 << typeIndex;
+        SimdTypeDescr::Type type = SimdTypeDescr::Type(typeIndex);
+
+        // Note: the weak-reference on the template object should not have been
+        // garbage collected. It is either registered by IonBuilder, or verified
+        // before using it in the EagerSimdUnbox phase.
+        jitCompartment->registerSimdTemplateObjectFor(type);
+    }
+}
+
+void
 CodeGenerator::visitSimdUnbox(LSimdUnbox *lir)
 {
     Register object = ToRegister(lir->input());
     FloatRegister simd = ToFloatRegister(lir->output());
     Register temp = ToRegister(lir->temp());
     Label bail;
 
     // obj->group()
@@ -7403,16 +7428,22 @@ struct AutoDiscardIonCode
 };
 
 bool
 CodeGenerator::link(JSContext *cx, CompilerConstraintList *constraints)
 {
     RootedScript script(cx, gen->info().script());
     OptimizationLevel optimizationLevel = gen->optimizationInfo().level();
 
+    // Capture the SIMD template objects which are used during the
+    // compilation. This iterates over the template objects, using read-barriers
+    // to let the GC know that the generated code relies on these template
+    // objects.
+    captureSimdTemplate(cx);
+
     // We finished the new IonScript. Invalidate the current active IonScript,
     // so we can replace it with this new (probably higher optimized) version.
     if (script->hasIonScript()) {
         MOZ_ASSERT(script->ionScript()->isRecompiling());
         // Do a normal invalidate, except don't cancel offThread compilations,
         // since that will cancel this compilation too.
         if (!Invalidate(cx, script, /* resetUses */ false, /* cancelOffThread*/ false))
             return false;
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -467,14 +467,30 @@ class CodeGenerator : public CodeGenerat
 #endif
 
     // Script counts created during code generation.
     IonScriptCounts *scriptCounts_;
 
 #if defined(JS_ION_PERF)
     PerfSpewer perfSpewer_;
 #endif
+
+    // This integer is a bit mask of all SimdTypeDescr::Type indexes.  When a
+    // MSimdBox instruction is encoded, it might have either been created by
+    // IonBuilder, or by the Eager Simd Unbox phase.
+    //
+    // As the template objects are weak references, the JitCompartment is using
+    // Read Barriers, but such barrier cannot be used during the compilation. To
+    // work around this issue, the barriers are captured during
+    // CodeGenerator::link.
+    //
+    // Instead of saving the pointers, we just save the index of the Read
+    // Barriered objects in a bit mask.
+    uint32_t simdRefreshTemplatesDuringLink_;
+
+    void registerSimdTemplate(InlineTypedObject *templateObject);
+    void captureSimdTemplate(JSContext *cx);
 };
 
 } // namespace jit
 } // namespace js
 
 #endif /* jit_CodeGenerator_h */
new file mode 100644
--- /dev/null
+++ b/js/src/jit/EagerSimdUnbox.cpp
@@ -0,0 +1,139 @@
+/* -*- 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/EagerSimdUnbox.h"
+
+#include "jit/MIR.h"
+#include "jit/MIRGenerator.h"
+#include "jit/MIRGraph.h"
+
+namespace js {
+namespace jit {
+
+static SimdTypeDescr::Type
+MIRTypeToSimdTypeDescr(MIRType type)
+{
+    MOZ_ASSERT(IsSimdType(type));
+    switch (type) {
+      case MIRType_Float32x4:   return SimdTypeDescr::TYPE_FLOAT32;
+      case MIRType_Int32x4:     return SimdTypeDescr::TYPE_INT32;
+      default:                  break;
+    }
+    MOZ_CRASH("unexpected MIRType");
+}
+
+// Do not optimize any Phi instruction which has conflicting Unbox operations,
+// as this might imply some intended polymorphism.
+static bool
+CanUnboxSimdPhi(const JitCompartment *jitCompartment, MPhi *phi, MIRType unboxType)
+{
+    MOZ_ASSERT(phi->type() == MIRType_Object);
+
+    // If we are unboxing, we are more than likely to have boxed this SIMD type
+    // once in baseline, otherwise, we cannot create a MSimdBox as we have no
+    // template object to use.
+    if (!jitCompartment->maybeGetSimdTemplateObjectFor(MIRTypeToSimdTypeDescr(unboxType)))
+        return false;
+
+    MResumePoint *entry = phi->block()->entryResumePoint();
+    for (MUseIterator i(phi->usesBegin()), e(phi->usesEnd()); i != e; i++) {
+        // If we cannot recover the Simd object at the entry of the basic block,
+        // then we would have to box the content anyways.
+        if ((*i)->consumer() == entry && !entry->isRecoverableOperand(*i))
+            return false;
+
+        if (!(*i)->consumer()->isDefinition())
+            continue;
+
+        MDefinition *def = (*i)->consumer()->toDefinition();
+        if (def->isSimdUnbox() && def->toSimdUnbox()->type() != unboxType)
+            return false;
+    }
+
+    return true;
+}
+
+static void
+UnboxSimdPhi(const JitCompartment *jitCompartment, MIRGraph &graph, MPhi *phi, MIRType unboxType)
+{
+    TempAllocator &alloc = graph.alloc();
+
+    // Unbox and replace all operands.
+    for (size_t i = 0, e = phi->numOperands(); i < e; i++) {
+        MDefinition *op = phi->getOperand(i);
+        MSimdUnbox *unbox = MSimdUnbox::New(alloc, op, unboxType);
+        op->block()->insertAtEnd(unbox);
+        phi->replaceOperand(i, unbox);
+    }
+
+    // Change the MIRType of the Phi.
+    phi->setResultType(unboxType);
+
+    MBasicBlock *phiBlock = phi->block();
+    MInstruction *atRecover = phiBlock->safeInsertTop(nullptr, MBasicBlock::IgnoreRecover);
+    MInstruction *at = phiBlock->safeInsertTop(atRecover);
+
+    // Note, we capture the uses-list now, as new instructions are not visited.
+    MUseIterator i(phi->usesBegin()), e(phi->usesEnd());
+
+    // Add a MSimdBox, and replace all the Phi uses with it.
+    JSObject *templateObject =
+        jitCompartment->maybeGetSimdTemplateObjectFor(MIRTypeToSimdTypeDescr(unboxType));
+    InlineTypedObject *inlineTypedObject = &templateObject->as<InlineTypedObject>();
+    MSimdBox *recoverBox = MSimdBox::New(alloc, nullptr, phi, inlineTypedObject, gc::DefaultHeap);
+    recoverBox->setRecoveredOnBailout();
+    phiBlock->insertBefore(atRecover, recoverBox);
+
+    MSimdBox *box = nullptr;
+    while (i != e) {
+        MUse *use = *i++;
+        MNode *ins = use->consumer();
+
+        if ((ins->isDefinition() && ins->toDefinition()->isRecoveredOnBailout()) ||
+            (ins->isResumePoint() && ins->toResumePoint()->isRecoverableOperand(use)))
+        {
+            use->replaceProducer(recoverBox);
+            continue;
+        }
+
+        if (!box) {
+            box = MSimdBox::New(alloc, nullptr, phi, inlineTypedObject, gc::DefaultHeap);
+            phiBlock->insertBefore(at, box);
+        }
+
+        use->replaceProducer(box);
+    }
+}
+
+bool
+EagerSimdUnbox(MIRGenerator *mir, MIRGraph &graph)
+{
+    const JitCompartment *jitCompartment = GetJitContext()->compartment->jitCompartment();
+    for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) {
+        if (mir->shouldCancel("Eager Simd Unbox"))
+            return false;
+
+        for (MInstructionReverseIterator ins = block->rbegin(); ins != block->rend(); ins++) {
+            if (!ins->isSimdUnbox())
+                continue;
+
+            MSimdUnbox *unbox = ins->toSimdUnbox();
+            if (!unbox->input()->isPhi())
+                continue;
+
+            MPhi *phi = unbox->input()->toPhi();
+            if (!CanUnboxSimdPhi(jitCompartment, phi, unbox->type()))
+                continue;
+
+            UnboxSimdPhi(jitCompartment, graph, phi, unbox->type());
+        }
+    }
+
+    return true;
+}
+
+} /* namespace jit */
+} /* namespace js */
new file mode 100644
--- /dev/null
+++ b/js/src/jit/EagerSimdUnbox.h
@@ -0,0 +1,23 @@
+/* -*- 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/. */
+
+// This file declares eager SIMD unboxing.
+#ifndef jit_EagerSimdUnbox_h
+#define jit_EagerSimdUnbox_h
+
+namespace js {
+namespace jit {
+
+class MIRGenerator;
+class MIRGraph;
+
+bool
+EagerSimdUnbox(MIRGenerator *mir, MIRGraph &graph);
+
+} // namespace jit
+} // namespace js
+
+#endif /* jit_EagerSimdUnbox_h */
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -16,16 +16,17 @@
 #include "gc/Marking.h"
 #include "jit/AliasAnalysis.h"
 #include "jit/AlignmentMaskAnalysis.h"
 #include "jit/BacktrackingAllocator.h"
 #include "jit/BaselineFrame.h"
 #include "jit/BaselineInspector.h"
 #include "jit/BaselineJIT.h"
 #include "jit/CodeGenerator.h"
+#include "jit/EagerSimdUnbox.h"
 #include "jit/EdgeCaseAnalysis.h"
 #include "jit/EffectiveAddressAnalysis.h"
 #include "jit/IonAnalysis.h"
 #include "jit/IonBuilder.h"
 #include "jit/IonOptimizationLevels.h"
 #include "jit/JitcodeMap.h"
 #include "jit/JitCommon.h"
 #include "jit/JitCompartment.h"
@@ -1245,16 +1246,27 @@ OptimizeMIR(MIRGenerator *mir)
             return false;
         IonSpewPass("Apply types");
         AssertExtendedGraphCoherency(graph);
 
         if (mir->shouldCancel("Apply types"))
             return false;
     }
 
+    if (mir->optimizationInfo().eagerSimdUnboxEnabled()) {
+        AutoTraceLog log(logger, TraceLogger_EagerSimdUnbox);
+        if (!EagerSimdUnbox(mir, graph))
+            return false;
+        IonSpewPass("Eager Simd Unbox");
+        AssertGraphCoherency(graph);
+
+        if (mir->shouldCancel("Eager Simd Unbox"))
+            return false;
+    }
+
     if (mir->optimizationInfo().amaEnabled()) {
         AutoTraceLog log(logger, TraceLogger_AlignmentMaskAnalysis);
         AlignmentMaskAnalysis ama(graph);
         if (!ama.analyze())
             return false;
         IonSpewPass("Alignment Mask Analysis");
         AssertExtendedGraphCoherency(graph);
 
--- a/js/src/jit/IonOptimizationLevels.cpp
+++ b/js/src/jit/IonOptimizationLevels.cpp
@@ -23,16 +23,17 @@ OptimizationInfo::initNormalOptimization
 {
     level_ = Optimization_Normal;
 
     eaa_ = true;
     edgeCaseAnalysis_ = true;
     eliminateRedundantChecks_ = true;
     inlineInterpreted_ = true;
     inlineNative_ = true;
+    eagerSimdUnbox_ = true;
     gvn_ = true;
     licm_ = true;
     rangeAnalysis_ = true;
     loopUnrolling_ = true;
     autoTruncate_ = true;
     sink_ = true;
     registerAllocator_ = RegisterAllocator_Backtracking;
 
@@ -52,16 +53,17 @@ OptimizationInfo::initAsmjsOptimizationI
     // The AsmJS optimization level
     // Disables some passes that don't work well with asmjs.
 
     // Take normal option values for not specified values.
     initNormalOptimizationInfo();
 
     ama_ = true;
     level_ = Optimization_AsmJS;
+    eagerSimdUnbox_ = false;           // AsmJS has no boxing / unboxing.
     edgeCaseAnalysis_ = false;
     eliminateRedundantChecks_ = false;
     autoTruncate_ = false;
     sink_ = false;
     registerAllocator_ = RegisterAllocator_Backtracking;
     scalarReplacement_ = false;        // AsmJS has no objects.
 }
 
--- a/js/src/jit/IonOptimizationLevels.h
+++ b/js/src/jit/IonOptimizationLevels.h
@@ -59,16 +59,19 @@ class OptimizationInfo
     bool eliminateRedundantChecks_;
 
     // Toggles whether interpreted scripts get inlined.
     bool inlineInterpreted_;
 
     // Toggles whether native scripts get inlined.
     bool inlineNative_;
 
+    // Toggles whether eager unboxing of SIMD is used.
+    bool eagerSimdUnbox_;
+
     // Toggles whether global value numbering is used.
     bool gvn_;
 
     // Toggles whether loop invariant code motion is performed.
     bool licm_;
 
     // Toggles whether Range Analysis is used.
     bool rangeAnalysis_;
@@ -137,16 +140,20 @@ class OptimizationInfo
     }
 
     bool inlineNative() const {
         return inlineNative_ && !js_JitOptions.disableInlining;
     }
 
     uint32_t compilerWarmUpThreshold(JSScript *script, jsbytecode *pc = nullptr) const;
 
+    bool eagerSimdUnboxEnabled() const {
+        return eagerSimdUnbox_ && !js_JitOptions.disableEagerSimdUnbox;
+    }
+
     bool gvnEnabled() const {
         return gvn_ && !js_JitOptions.disableGvn;
     }
 
     bool licmEnabled() const {
         return licm_ && !js_JitOptions.disableLicm;
     }
 
--- a/js/src/jit/JitCompartment.h
+++ b/js/src/jit/JitCompartment.h
@@ -443,16 +443,34 @@ class JitCompartment
 
   public:
     JSObject *getSimdTemplateObjectFor(JSContext *cx, Handle<SimdTypeDescr*> descr) {
         ReadBarrieredObject &tpl = simdTemplateObjects_[descr->type()];
         if (!tpl)
             tpl.set(TypedObject::createZeroed(cx, descr, 0, gc::TenuredHeap));
         return tpl.get();
     }
+
+    JSObject *maybeGetSimdTemplateObjectFor(SimdTypeDescr::Type type) const {
+        const ReadBarrieredObject &tpl = simdTemplateObjects_[type];
+
+        // This function is used by Eager Simd Unbox phase, so we cannot use the
+        // read barrier. For more information, see the comment above
+        // CodeGenerator::simdRefreshTemplatesDuringLink_ .
+        return tpl.unbarrieredGet();
+    }
+
+    // This function is used to call the read barrier, to mark the SIMD template
+    // type as used. This function can only be called from the main thread.
+    void registerSimdTemplateObjectFor(SimdTypeDescr::Type type) {
+        ReadBarrieredObject &tpl = simdTemplateObjects_[type];
+        MOZ_ASSERT(tpl.unbarrieredGet());
+        tpl.get();
+    }
+
     JitCode *getStubCode(uint32_t key) {
         ICStubCodeMap::AddPtr p = stubCodes_->lookupForAdd(key);
         if (p)
             return p->value();
         return nullptr;
     }
     bool putStubCode(uint32_t key, Handle<JitCode *> stubCode) {
         // Make sure to do a lookupForAdd(key) and then insert into that slot, because
--- a/js/src/jit/JitOptions.cpp
+++ b/js/src/jit/JitOptions.cpp
@@ -76,16 +76,19 @@ JitOptions::JitOptions()
 
     // Whether to enable extra code to perform dynamic validation of
     // RangeAnalysis results.
     SET_DEFAULT(checkRangeAnalysis, false);
 
     // Toggle whether eager scalar replacement is globally disabled.
     SET_DEFAULT(disableScalarReplacement, false);
 
+    // Toggle whether eager simd unboxing is globally disabled.
+    SET_DEFAULT(disableEagerSimdUnbox, false);
+
     // Toggle whether global value numbering is globally disabled.
     SET_DEFAULT(disableGvn, false);
 
     // Toggles whether loop invariant code motion is globally disabled.
     SET_DEFAULT(disableLicm, false);
 
     // Toggles whether inlining is globally disabled.
     SET_DEFAULT(disableInlining, false);
--- a/js/src/jit/JitOptions.h
+++ b/js/src/jit/JitOptions.h
@@ -42,16 +42,17 @@ LookupRegisterAllocator(const char *name
 struct JitOptions
 {
     bool checkGraphConsistency;
 #ifdef CHECK_OSIPOINT_REGISTERS
     bool checkOsiPointRegisters;
 #endif
     bool checkRangeAnalysis;
     bool disableScalarReplacement;
+    bool disableEagerSimdUnbox;
     bool disableGvn;
     bool disableLicm;
     bool disableInlining;
     bool disableEdgeCaseAnalysis;
     bool disableRangeAnalysis;
     bool disableSink;
     bool disableLoopUnrolling;
     bool disableEaa;
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -3148,17 +3148,18 @@ class MSimdBox
              gc::InitialHeap initialHeap)
       : MUnaryInstruction(op),
         templateObject_(templateObject),
         initialHeap_(initialHeap)
     {
         MOZ_ASSERT(IsSimdType(op->type()));
         setMovable();
         setResultType(MIRType_Object);
-        setResultTypeSet(MakeSingletonTypeSet(constraints, templateObject));
+        if (constraints)
+            setResultTypeSet(MakeSingletonTypeSet(constraints, templateObject));
     }
 
   public:
     INSTRUCTION_HEADER(SimdBox)
 
     static MSimdBox *New(TempAllocator &alloc,
                          CompilerConstraintList *constraints,
                          MDefinition *op,
--- a/js/src/jit/ValueNumbering.cpp
+++ b/js/src/jit/ValueNumbering.cpp
@@ -721,16 +721,22 @@ ValueNumberer::visitDefinition(MDefiniti
             JitSpew(JitSpew_GVN, "      Removing Nop%u", prev->id());
             block->discard(prev);
             return true;
         }
 
         return true;
     }
 
+    // Skip optimizations on instructions which are recovered on bailout, to
+    // avoid mixing instructions which are recovered on bailouts with
+    // instructions which are not.
+    if (def->isRecoveredOnBailout())
+        return true;
+
     // If this instruction has a dependency() into an unreachable block, we'll
     // need to update AliasAnalysis.
     MInstruction *dep = def->dependency();
     if (dep != nullptr && (dep->isDiscarded() || dep->block()->isDead())) {
         JitSpew(JitSpew_GVN, "      AliasAnalysis invalidated");
         if (updateAliasAnalysis_ && !dependenciesBroken_) {
             // TODO: Recomputing alias-analysis could theoretically expose more
             // GVN opportunities.
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -152,16 +152,17 @@ UNIFIED_SOURCES += [
     'jit/BaselineInspector.cpp',
     'jit/BaselineJIT.cpp',
     'jit/BitSet.cpp',
     'jit/BytecodeAnalysis.cpp',
     'jit/C1Spewer.cpp',
     'jit/CodeGenerator.cpp',
     'jit/CompileWrappers.cpp',
     'jit/Disassembler.cpp',
+    'jit/EagerSimdUnbox.cpp',
     'jit/EdgeCaseAnalysis.cpp',
     'jit/EffectiveAddressAnalysis.cpp',
     'jit/ExecutableAllocator.cpp',
     'jit/Ion.cpp',
     'jit/IonAnalysis.cpp',
     'jit/IonBuilder.cpp',
     'jit/IonCaches.cpp',
     'jit/IonOptimizationLevels.cpp',
--- a/js/src/vm/TraceLogging.cpp
+++ b/js/src/vm/TraceLogging.cpp
@@ -671,17 +671,19 @@ TraceLoggerThreadState::init()
     if (ContainsFlag(env, "IonCompiler")) {
         enabledTextIds[TraceLogger_IonCompilation] = true;
         enabledTextIds[TraceLogger_IonLinking] = true;
         enabledTextIds[TraceLogger_FoldTests] = true;
         enabledTextIds[TraceLogger_SplitCriticalEdges] = true;
         enabledTextIds[TraceLogger_RenumberBlocks] = true;
         enabledTextIds[TraceLogger_DominatorTree] = true;
         enabledTextIds[TraceLogger_PhiAnalysis] = true;
+        enabledTextIds[TraceLogger_ScalarReplacement] = true;
         enabledTextIds[TraceLogger_ApplyTypes] = true;
+        enabledTextIds[TraceLogger_EagerSimdUnbox] = true;
         enabledTextIds[TraceLogger_AliasAnalysis] = true;
         enabledTextIds[TraceLogger_GVN] = true;
         enabledTextIds[TraceLogger_LICM] = true;
         enabledTextIds[TraceLogger_RangeAnalysis] = true;
         enabledTextIds[TraceLogger_LoopUnrolling] = true;
         enabledTextIds[TraceLogger_EffectiveAddressAnalysis] = true;
         enabledTextIds[TraceLogger_AlignmentMaskAnalysis] = true;
         enabledTextIds[TraceLogger_EliminateDeadCode] = true;
--- a/js/src/vm/TraceLoggingTypes.h
+++ b/js/src/vm/TraceLoggingTypes.h
@@ -39,16 +39,17 @@
     _(FoldTests)                                      \
     _(SplitCriticalEdges)                             \
     _(RenumberBlocks)                                 \
     _(ScalarReplacement)                              \
     _(DominatorTree)                                  \
     _(PhiAnalysis)                                    \
     _(MakeLoopsContiguous)                            \
     _(ApplyTypes)                                     \
+    _(EagerSimdUnbox)                                 \
     _(AliasAnalysis)                                  \
     _(GVN)                                            \
     _(LICM)                                           \
     _(RangeAnalysis)                                  \
     _(LoopUnrolling)                                  \
     _(EffectiveAddressAnalysis)                       \
     _(AlignmentMaskAnalysis)                          \
     _(EliminateDeadCode)                              \