Bug 1549035: Remove const string split optimization r=tcampbell
authorIain Ireland <iireland@mozilla.com>
Mon, 06 May 2019 19:48:29 +0000
changeset 531587 a40ff03e71e3c80c2305bb13dc575faa153ddaae
parent 531586 55198bafdb8734d14c2174c9ad1a1e0b7116f854
child 531588 fda45db5f8e981524e7538b7b2e259fa7828424d
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1549035
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1549035: Remove const string split optimization r=tcampbell Differential Revision: https://phabricator.services.mozilla.com/D30093
js/src/jit-test/tests/basic/bug1549035.js
js/src/jit/BaselineCacheIRCompiler.cpp
js/src/jit/BaselineIC.cpp
js/src/jit/BaselineIC.h
js/src/jit/BaselineICList.h
js/src/jit/BaselineInspector.cpp
js/src/jit/BaselineInspector.h
js/src/jit/CacheIR.cpp
js/src/jit/CacheIR.h
js/src/jit/CacheIRCompiler.cpp
js/src/jit/CacheIRCompiler.h
js/src/jit/IonCacheIRCompiler.cpp
js/src/jit/MCallOptimize.cpp
js/src/jit/VMFunctionList-inl.h
js/src/jit/VMFunctions.cpp
js/src/jit/VMFunctions.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug1549035.js
@@ -0,0 +1,11 @@
+var expected = 2;
+for (var i = 0; i < 100; ++i) {
+    if (i === 50) {
+        expected = 0;
+        String.prototype[Symbol.split] = function() {
+            return [];
+        };
+    }
+    var r = "ab".split("");
+    assertEq(r.length, expected);
+}
--- a/js/src/jit/BaselineCacheIRCompiler.cpp
+++ b/js/src/jit/BaselineCacheIRCompiler.cpp
@@ -924,37 +924,16 @@ bool BaselineCacheIRCompiler::emitLoadSt
   AutoOutputRegister output(*this);
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   masm.loadPtr(stubAddress(reader.stubOffset()), scratch);
   masm.tagValue(JSVAL_TYPE_STRING, scratch, output.valueReg());
   return true;
 }
 
-bool BaselineCacheIRCompiler::emitCallConstStringSplitResult() {
-  JitSpew(JitSpew_Codegen, __FUNCTION__);
-  Address resultTemplateAddr(stubAddress(reader.stubOffset()));
-
-  AutoScratchRegister scratch(allocator, masm);
-  allocator.discardStack(masm);
-
-  AutoStubFrame stubFrame(*this);
-  stubFrame.enter(masm, scratch);
-
-  // Push argument
-  masm.loadPtr(resultTemplateAddr, scratch);
-  masm.Push(scratch);
-
-  using Fn = bool (*)(JSContext*, HandleArrayObject, MutableHandleValue);
-  callVM<Fn, CopyStringSplitArray>(masm);
-
-  stubFrame.leave(masm);
-  return true;
-}
-
 bool BaselineCacheIRCompiler::emitCompareStringResult() {
   JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   Register left = allocator.useRegister(masm, reader.stringOperandId());
   Register right = allocator.useRegister(masm, reader.stringOperandId());
   JSOp op = reader.jsop();
 
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -562,17 +562,16 @@ bool ICStub::NonCacheIRStubMakesGCCalls(
     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:
     // These three 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:
     case GetElem_Fallback:
       return true;
@@ -651,24 +650,16 @@ void ICStub::trace(JSTracer* trc) {
       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");
@@ -3379,43 +3370,16 @@ static bool GetTemplateObjectForClassHoo
     Rooted<TypeDescr*> descr(cx, &args.callee().as<TypeDescr>());
     templateObject.set(TypedObject::createZeroed(cx, descr, gc::TenuredHeap));
     return !!templateObject;
   }
 
   return true;
 }
 
-static bool IsOptimizableConstStringSplit(Realm* callerRealm,
-                                          const Value& callee, int argc,
-                                          Value* args) {
-  if (argc != 2 || !args[0].isString() || !args[1].isString()) {
-    return false;
-  }
-
-  if (!args[0].toString()->isAtom() || !args[1].toString()->isAtom()) {
-    return false;
-  }
-
-  if (!callee.isObject() || !callee.toObject().is<JSFunction>()) {
-    return false;
-  }
-
-  JSFunction& calleeFun = callee.toObject().as<JSFunction>();
-  if (calleeFun.realm() != callerRealm) {
-    return false;
-  }
-  if (!calleeFun.isNative() ||
-      calleeFun.native() != js::intrinsic_StringSplitString) {
-    return false;
-  }
-
-  return true;
-}
-
 static bool TryAttachCallStub(JSContext* cx, ICCall_Fallback* stub,
                               HandleScript script, jsbytecode* pc, JSOp op,
                               uint32_t argc, Value* vp, bool constructing,
                               bool isSpread, bool createSingleton,
                               bool* handled) {
   bool isSuper = op == JSOP_SUPERCALL || op == JSOP_SPREADSUPERCALL;
 
   if (createSingleton || op == JSOP_EVAL || op == JSOP_STRICTEVAL) {
@@ -3426,25 +3390,16 @@ static bool TryAttachCallStub(JSContext*
     // TODO: Discard all stubs in this IC and replace with inert megamorphic
     // stub. But for now we just bail.
     return true;
   }
 
   RootedValue callee(cx, vp[0]);
   RootedValue thisv(cx, vp[1]);
 
-  // Don't attach an optimized call stub if we could potentially attach an
-  // optimized ConstStringSplit stub.
-  if (stub->numOptimizedStubs() == 0 &&
-      IsOptimizableConstStringSplit(cx->realm(), callee, argc, vp + 2)) {
-    return true;
-  }
-
-  stub->unlinkStubsWithKind(cx, ICStub::Call_ConstStringSplit);
-
   if (!callee.isObject()) {
     return true;
   }
 
   ICTypeMonitor_Fallback* typeMonitorFallback =
       stub->getFallbackMonitorStub(cx, script);
   if (!typeMonitorFallback) {
     return false;
@@ -3699,82 +3654,16 @@ static bool TryAttachCallStub(JSContext*
     stub->addNewStub(newStub);
     *handled = true;
     return true;
   }
 
   return true;
 }
 
-static bool TryAttachConstStringSplit(JSContext* cx, ICCall_Fallback* stub,
-                                      HandleScript script, uint32_t argc,
-                                      HandleValue callee, Value* vp,
-                                      jsbytecode* pc, HandleValue res,
-                                      bool* attached) {
-  if (stub->numOptimizedStubs() != 0) {
-    return true;
-  }
-
-  Value* args = vp + 2;
-
-  if (!IsOptimizableConstStringSplit(cx->realm(), callee, argc, args)) {
-    return true;
-  }
-
-  RootedString str(cx, args[0].toString());
-  RootedString sep(cx, args[1].toString());
-  RootedArrayObject obj(cx, &res.toObject().as<ArrayObject>());
-  uint32_t initLength = obj->getDenseInitializedLength();
-  MOZ_ASSERT(initLength == obj->length(),
-             "string-split result is a fully initialized array");
-
-  // Copy the array before storing in stub.
-  RootedArrayObject arrObj(cx);
-  arrObj =
-      NewFullyAllocatedArrayTryReuseGroup(cx, obj, initLength, TenuredObject);
-  if (!arrObj) {
-    return false;
-  }
-  arrObj->ensureDenseInitializedLength(cx, 0, initLength);
-
-  // Atomize all elements of the array.
-  if (initLength > 0) {
-    // Mimic NewFullyAllocatedStringArray() and directly inform TI about
-    // the element type.
-    AddTypePropertyId(cx, arrObj, JSID_VOID, TypeSet::StringType());
-
-    for (uint32_t i = 0; i < initLength; i++) {
-      JSAtom* str = js::AtomizeString(cx, obj->getDenseElement(i).toString());
-      if (!str) {
-        return false;
-      }
-
-      arrObj->initDenseElement(i, StringValue(str));
-    }
-  }
-
-  ICTypeMonitor_Fallback* typeMonitorFallback =
-      stub->getFallbackMonitorStub(cx, script);
-  if (!typeMonitorFallback) {
-    return false;
-  }
-
-  ICCall_ConstStringSplit::Compiler compiler(
-      cx, typeMonitorFallback->firstMonitorStub(), script->pcToOffset(pc), str,
-      sep, arrObj);
-  ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-  if (!newStub) {
-    return false;
-  }
-
-  stub->addNewStub(newStub);
-  *attached = true;
-  return true;
-}
-
 bool DoCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub,
                     uint32_t argc, Value* vp, MutableHandleValue res) {
   stub->incrementEnteredCount();
 
   RootedScript script(cx, frame->script());
   jsbytecode* pc = stub->icEntry()->pc(script);
   JSOp op = JSOp(*pc);
   FallbackICSpew(cx, stub, "Call(%s)", CodeName[op]);
@@ -3801,26 +3690,25 @@ bool DoCallFallback(JSContext* cx, Basel
   }
 
   // Transition stub state to megamorphic or generic if warranted.
   if (stub->state().maybeTransition()) {
     stub->discardStubs(cx);
   }
 
   bool canAttachStub = stub->state().canAttachStub();
-  bool isFirstStub = stub->numOptimizedStubs() == 0;
   bool handled = false;
   bool deferred = false;
 
   // Only bother to try optimizing JSOP_CALL with CacheIR if the chain is still
   // allowed to attach stubs.
   if (canAttachStub) {
     HandleValueArray args = HandleValueArray::fromMarkedLocation(argc, vp + 2);
     CallIRGenerator gen(cx, script, pc, op, stub->state().mode(), argc, callee,
-                        callArgs.thisv(), newTarget, args, isFirstStub);
+                        callArgs.thisv(), newTarget, args);
     switch (gen.tryAttachStub()) {
       case AttachDecision::NoAction:
         break;
       case AttachDecision::Attach: {
         ICStub* newStub = AttachBaselineCacheIRStub(
             cx, gen.writerRef(), gen.cacheKind(), gen.cacheIRStubKind(), script,
             stub, &handled);
         if (newStub) {
@@ -3891,17 +3779,17 @@ bool DoCallFallback(JSContext* cx, Basel
   if (stub->state().maybeTransition()) {
     stub->discardStubs(cx);
   }
   canAttachStub = stub->state().canAttachStub();
 
   if (deferred && canAttachStub) {
     HandleValueArray args = HandleValueArray::fromMarkedLocation(argc, vp + 2);
     CallIRGenerator gen(cx, script, pc, op, stub->state().mode(), argc, callee,
-                        callArgs.thisv(), newTarget, args, isFirstStub);
+                        callArgs.thisv(), newTarget, args);
     switch (gen.tryAttachDeferredStub(res)) {
       case AttachDecision::Attach: {
         ICStub* newStub = AttachBaselineCacheIRStub(
             cx, gen.writerRef(), gen.cacheKind(), gen.cacheIRStubKind(), script,
             stub, &handled);
         if (newStub) {
           JitSpew(JitSpew_BaselineIC, "  Attached Call CacheIR stub");
 
@@ -3916,26 +3804,16 @@ bool DoCallFallback(JSContext* cx, Basel
         break;
       case AttachDecision::TemporarilyUnoptimizable:
       case AttachDecision::Deferred:
         MOZ_ASSERT_UNREACHABLE("Impossible attach decision");
         break;
     }
   }
 
-  if (!handled && canAttachStub && !constructing) {
-    // If 'callee' is a potential Call_ConstStringSplit, try to attach an
-    // optimized ConstStringSplit stub. Note that vp[0] now holds the return
-    // value instead of the callee, so we pass the callee as well.
-    if (!TryAttachConstStringSplit(cx, stub, script, argc, callee, vp, pc, res,
-                                   &handled)) {
-      return false;
-    }
-  }
-
   if (!handled && canAttachStub) {
     stub->state().trackNotAttached();
   }
   return true;
 }
 
 bool DoSpreadCallFallback(JSContext* cx, BaselineFrame* frame,
                           ICCall_Fallback* stub, Value* vp,
@@ -3958,27 +3836,26 @@ bool DoSpreadCallFallback(JSContext* cx,
 
   // Transition stub state to megamorphic or generic if warranted.
   if (stub->state().maybeTransition()) {
     stub->discardStubs(cx);
   }
 
   // Try attaching a call stub.
   bool handled = false;
-  bool isFirstStub = stub->numOptimizedStubs() == 0;
   if (op != JSOP_SPREADEVAL && op != JSOP_STRICTSPREADEVAL &&
       stub->state().canAttachStub()) {
     // Try CacheIR first:
     RootedArrayObject aobj(cx, &arr.toObject().as<ArrayObject>());
     MOZ_ASSERT(aobj->length() == aobj->getDenseInitializedLength());
 
     HandleValueArray args = HandleValueArray::fromMarkedLocation(
         aobj->length(), aobj->getDenseElements());
     CallIRGenerator gen(cx, script, pc, op, stub->state().mode(), 1, callee,
-                        thisv, newTarget, args, isFirstStub);
+                        thisv, newTarget, args);
     switch (gen.tryAttachStub()) {
       case AttachDecision::NoAction:
         break;
       case AttachDecision::Attach: {
         ICStub* newStub = AttachBaselineCacheIRStub(
             cx, gen.writerRef(), gen.cacheKind(), gen.cacheIRStubKind(), script,
             stub, &handled);
 
@@ -4772,121 +4649,16 @@ bool ICCallScriptedCompiler::generateStu
   // Enter type monitor IC to type-check result.
   EmitEnterTypeMonitorIC(masm);
 
   masm.bind(&failure);
   EmitStubGuardFailure(masm);
   return true;
 }
 
-bool ICCall_ConstStringSplit::Compiler::generateStubCode(MacroAssembler& masm) {
-  // Stack Layout:
-  //      [ ..., CalleeVal, ThisVal, strVal, sepVal, +ICStackValueOffset+ ]
-  static const size_t SEP_DEPTH = 0;
-  static const size_t STR_DEPTH = sizeof(Value);
-  static const size_t CALLEE_DEPTH = 3 * sizeof(Value);
-
-  AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
-  Label failureRestoreArgc;
-#ifdef DEBUG
-  Label twoArg;
-  Register argcReg = R0.scratchReg();
-  masm.branch32(Assembler::Equal, argcReg, Imm32(2), &twoArg);
-  masm.assumeUnreachable("Expected argc == 2");
-  masm.bind(&twoArg);
-#endif
-  Register scratchReg = regs.takeAny();
-
-  // Guard that callee is native function js::intrinsic_StringSplitString.
-  {
-    Address calleeAddr(masm.getStackPointer(),
-                       ICStackValueOffset + CALLEE_DEPTH);
-    ValueOperand calleeVal = regs.takeAnyValue();
-
-    // Ensure that callee is an object.
-    masm.loadValue(calleeAddr, calleeVal);
-    masm.branchTestObject(Assembler::NotEqual, calleeVal, &failureRestoreArgc);
-
-    // Ensure that callee is a function.
-    Register calleeObj = masm.extractObject(calleeVal, ExtractTemp0);
-    masm.branchTestObjClass(Assembler::NotEqual, calleeObj, &JSFunction::class_,
-                            scratchReg, calleeObj, &failureRestoreArgc);
-
-    // Ensure that callee's function impl is the native
-    // intrinsic_StringSplitString.
-    masm.loadPtr(Address(calleeObj, JSFunction::offsetOfNativeOrEnv()),
-                 scratchReg);
-    masm.branchPtr(Assembler::NotEqual, scratchReg,
-                   ImmPtr(js::intrinsic_StringSplitString),
-                   &failureRestoreArgc);
-
-    regs.add(calleeVal);
-  }
-
-  // Guard sep.
-  {
-    // Ensure that sep is a string.
-    Address sepAddr(masm.getStackPointer(), ICStackValueOffset + SEP_DEPTH);
-    ValueOperand sepVal = regs.takeAnyValue();
-
-    masm.loadValue(sepAddr, sepVal);
-    masm.branchTestString(Assembler::NotEqual, sepVal, &failureRestoreArgc);
-
-    Register sep = sepVal.scratchReg();
-    masm.unboxString(sepVal, sep);
-    masm.branchPtr(Assembler::NotEqual,
-                   Address(ICStubReg, offsetOfExpectedSep()), sep,
-                   &failureRestoreArgc);
-    regs.add(sepVal);
-  }
-
-  // Guard str.
-  {
-    // Ensure that str is a string.
-    Address strAddr(masm.getStackPointer(), ICStackValueOffset + STR_DEPTH);
-    ValueOperand strVal = regs.takeAnyValue();
-
-    masm.loadValue(strAddr, strVal);
-    masm.branchTestString(Assembler::NotEqual, strVal, &failureRestoreArgc);
-
-    Register str = strVal.scratchReg();
-    masm.unboxString(strVal, str);
-    masm.branchPtr(Assembler::NotEqual,
-                   Address(ICStubReg, offsetOfExpectedStr()), str,
-                   &failureRestoreArgc);
-    regs.add(strVal);
-  }
-
-  // Main stub body.
-  {
-    Register paramReg = regs.takeAny();
-
-    // Push arguments.
-    enterStubFrame(masm, scratchReg);
-    masm.loadPtr(Address(ICStubReg, offsetOfTemplateObject()), paramReg);
-    masm.push(paramReg);
-
-    using Fn = bool (*)(JSContext*, HandleArrayObject, MutableHandleValue);
-    if (!callVM<Fn, CopyStringSplitArray>(masm)) {
-      return false;
-    }
-    leaveStubFrame(masm);
-    regs.add(paramReg);
-  }
-
-  // Enter type monitor IC to type-check result.
-  EmitEnterTypeMonitorIC(masm);
-
-  // Guard failure path.
-  masm.bind(&failureRestoreArgc);
-  masm.move32(Imm32(2), R0.scratchReg());
-  EmitStubGuardFailure(masm);
-  return true;
-}
-
 bool ICCall_Native::Compiler::generateStubCode(MacroAssembler& masm) {
   Label failure;
   AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
 
   Register argcReg = R0.scratchReg();
   regs.take(argcReg);
   regs.takeUnchecked(ICTailCallReg);
 
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -2143,83 +2143,16 @@ class ICCall_ScriptedFunCall : public IC
 
     ICStub* getStub(ICStubSpace* space) override {
       return newStub<ICCall_ScriptedFunCall>(space, getStubCode(),
                                              firstMonitorStub_, pcOffset_);
     }
   };
 };
 
-class ICCall_ConstStringSplit : public ICMonitoredStub {
-  friend class ICStubSpace;
-
- protected:
-  uint32_t pcOffset_;
-  GCPtrString expectedStr_;
-  GCPtrString expectedSep_;
-  GCPtrArrayObject templateObject_;
-
-  ICCall_ConstStringSplit(JitCode* stubCode, ICStub* firstMonitorStub,
-                          uint32_t pcOffset, JSString* str, JSString* sep,
-                          ArrayObject* templateObject)
-      : ICMonitoredStub(ICStub::Call_ConstStringSplit, stubCode,
-                        firstMonitorStub),
-        pcOffset_(pcOffset),
-        expectedStr_(str),
-        expectedSep_(sep),
-        templateObject_(templateObject) {}
-
- public:
-  static size_t offsetOfExpectedStr() {
-    return offsetof(ICCall_ConstStringSplit, expectedStr_);
-  }
-
-  static size_t offsetOfExpectedSep() {
-    return offsetof(ICCall_ConstStringSplit, expectedSep_);
-  }
-
-  static size_t offsetOfTemplateObject() {
-    return offsetof(ICCall_ConstStringSplit, templateObject_);
-  }
-
-  GCPtrString& expectedStr() { return expectedStr_; }
-
-  GCPtrString& expectedSep() { return expectedSep_; }
-
-  GCPtrArrayObject& templateObject() { return templateObject_; }
-
-  class Compiler : public ICCallStubCompiler {
-   protected:
-    ICStub* firstMonitorStub_;
-    uint32_t pcOffset_;
-    RootedString expectedStr_;
-    RootedString expectedSep_;
-    RootedArrayObject templateObject_;
-
-    MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override;
-
-   public:
-    Compiler(JSContext* cx, ICStub* firstMonitorStub, uint32_t pcOffset,
-             HandleString str, HandleString sep,
-             HandleArrayObject templateObject)
-        : ICCallStubCompiler(cx, ICStub::Call_ConstStringSplit),
-          firstMonitorStub_(firstMonitorStub),
-          pcOffset_(pcOffset),
-          expectedStr_(cx, str),
-          expectedSep_(cx, sep),
-          templateObject_(cx, templateObject) {}
-
-    ICStub* getStub(ICStubSpace* space) override {
-      return newStub<ICCall_ConstStringSplit>(
-          space, getStubCode(), firstMonitorStub_, pcOffset_, expectedStr_,
-          expectedSep_, templateObject_);
-    }
-  };
-};
-
 // IC for constructing an iterator from an input value.
 class ICGetIterator_Fallback : public ICFallbackStub {
   friend class ICStubSpace;
 
   explicit ICGetIterator_Fallback(TrampolinePtr stubCode)
       : ICFallbackStub(ICStub::GetIterator_Fallback, stubCode) {}
 };
 
--- a/js/src/jit/BaselineICList.h
+++ b/js/src/jit/BaselineICList.h
@@ -37,17 +37,16 @@ namespace jit {
   _(Call_Fallback)                    \
   _(Call_Scripted)                    \
   _(Call_AnyScripted)                 \
   _(Call_Native)                      \
   _(Call_ClassHook)                   \
   _(Call_ScriptedApplyArray)          \
   _(Call_ScriptedApplyArguments)      \
   _(Call_ScriptedFunCall)             \
-  _(Call_ConstStringSplit)            \
                                       \
   _(GetElem_Fallback)                 \
   _(SetElem_Fallback)                 \
                                       \
   _(In_Fallback)                      \
   _(HasOwn_Fallback)                  \
                                       \
   _(GetName_Fallback)                 \
--- a/js/src/jit/BaselineInspector.cpp
+++ b/js/src/jit/BaselineInspector.cpp
@@ -838,58 +838,16 @@ JSObject* BaselineInspector::getTemplate
         return result;
       }
     }
   }
 
   return nullptr;
 }
 
-bool BaselineInspector::isOptimizableConstStringSplit(jsbytecode* pc,
-                                                      JSString** strOut,
-                                                      JSString** sepOut,
-                                                      ArrayObject** objOut) {
-  if (!hasICScript()) {
-    return false;
-  }
-
-  const ICEntry& entry = icEntryFromPC(pc);
-
-  // If ConstStringSplit stub is attached, must have only one stub attached.
-  if (entry.fallbackStub()->numOptimizedStubs() != 1) {
-    return false;
-  }
-
-  ICStub* stub = entry.firstStub();
-
-  if (stub->kind() == ICStub::Call_ConstStringSplit) {
-    *strOut = stub->toCall_ConstStringSplit()->expectedStr();
-    *sepOut = stub->toCall_ConstStringSplit()->expectedSep();
-    *objOut = stub->toCall_ConstStringSplit()->templateObject();
-    return true;
-  }
-
-  if (ICStub::IsCacheIRKind(stub->kind())) {
-    mozilla::Maybe<CacheIRReader> argReader;
-    if (!MaybeArgumentReader(stub, CacheOp::MetaThreeByte, argReader) ||
-        argReader->metaKind<MetaThreeByteKind>() !=
-            MetaThreeByteKind::ConstStringSplitData) {
-      return false;
-    }
-    const CacheIRStubInfo* stubInfo = GetCacheIRStubInfo(stub);
-    *strOut = stubInfo->getStubField<JSString*>(stub, argReader->stubOffset());
-    *sepOut = stubInfo->getStubField<JSString*>(stub, argReader->stubOffset());
-    *objOut =
-        stubInfo->getStubField<ArrayObject*>(stub, argReader->stubOffset());
-    return true;
-  }
-
-  return false;
-}
-
 JSObject* BaselineInspector::getTemplateObjectForClassHook(jsbytecode* pc,
                                                            const Class* clasp) {
   if (!hasICScript()) {
     return nullptr;
   }
 
   const ICEntry& entry = icEntryFromPC(pc);
   for (ICStub* stub = entry.firstStub(); stub; stub = stub->next()) {
--- a/js/src/jit/BaselineInspector.h
+++ b/js/src/jit/BaselineInspector.h
@@ -93,20 +93,16 @@ class BaselineInspector {
   MIRType expectedBinaryArithSpecialization(jsbytecode* pc);
   MIRType expectedPropertyAccessInputType(jsbytecode* pc);
 
   bool hasSeenNegativeIndexGetElement(jsbytecode* pc);
   bool hasSeenNonIntegerIndex(jsbytecode* pc);
   bool hasSeenAccessedGetter(jsbytecode* pc);
   bool hasSeenDoubleResult(jsbytecode* pc);
 
-  MOZ_MUST_USE bool isOptimizableConstStringSplit(jsbytecode* pc,
-                                                  JSString** strOut,
-                                                  JSString** sepOut,
-                                                  ArrayObject** objOut);
   JSObject* getTemplateObject(jsbytecode* pc);
   JSObject* getTemplateObjectForNative(jsbytecode* pc, Native native);
   JSObject* getTemplateObjectForClassHook(jsbytecode* pc, const Class* clasp);
 
   // Sometimes the group a template object will have is known, even if the
   // object itself isn't.
   ObjectGroup* getTemplateObjectGroup(jsbytecode* pc);
 
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -4593,27 +4593,26 @@ void GetIteratorIRGenerator::trackAttach
   }
 #endif
 }
 
 CallIRGenerator::CallIRGenerator(JSContext* cx, HandleScript script,
                                  jsbytecode* pc, JSOp op, ICState::Mode mode,
                                  uint32_t argc, HandleValue callee,
                                  HandleValue thisval, HandleValue newTarget,
-                                 HandleValueArray args, bool isFirstStub)
+                                 HandleValueArray args)
     : IRGenerator(cx, script, pc, CacheKind::Call, mode),
       op_(op),
       argc_(argc),
       callee_(callee),
       thisval_(thisval),
       newTarget_(newTarget),
       args_(args),
       typeCheckInfo_(cx, /* needsTypeBarrier = */ true),
-      cacheIRStubKind_(BaselineCacheIRStubKind::Regular),
-      isFirstStub_(isFirstStub) {}
+      cacheIRStubKind_(BaselineCacheIRStubKind::Regular) {}
 
 AttachDecision CallIRGenerator::tryAttachArrayPush() {
   // Only optimize on obj.push(val);
   if (argc_ != 1 || !thisval_.isObject()) {
     return AttachDecision::NoAction;
   }
 
   // Where |obj| is a native array.
@@ -5016,24 +5015,16 @@ bool CallIRGenerator::getTemplateObjectF
 
   if (thisObject->is<PlainObject>()) {
     result.set(thisObject);
   }
 
   return true;
 }
 
-AttachDecision CallIRGenerator::tryAttachSelfHosted(HandleFunction calleeFunc) {
-  if (isOptimizableConstStringSplit(calleeFunc)) {
-    return AttachDecision::Deferred;
-  }
-
-  return AttachDecision::NoAction;
-}
-
 AttachDecision CallIRGenerator::tryAttachCallScripted(
     HandleFunction calleeFunc) {
   if (JitOptions.disableCacheIRCalls) {
     return AttachDecision::NoAction;
   }
 
   // Never attach optimized scripted call stubs for JSOP_FUNAPPLY.
   // MagicArguments may escape the frame through them.
@@ -5073,18 +5064,16 @@ AttachDecision CallIRGenerator::tryAttac
   }
 
   // Keep track of the function's |prototype| property in type
   // information, for use during Ion compilation.
   if (IsIonEnabled(cx_)) {
     EnsureTrackPropertyTypes(cx_, calleeFunc, NameToId(cx_->names().prototype));
   }
 
-  TRY_ATTACH(tryAttachSelfHosted(calleeFunc));
-
   RootedObject templateObj(cx_);
   bool skipAttach = false;
   if (isConstructing && isSpecialized &&
       !getTemplateObjectForScripted(calleeFunc, &templateObj, &skipAttach)) {
     cx_->clearPendingException();
     return AttachDecision::NoAction;
   }
   if (skipAttach) {
@@ -5433,143 +5422,26 @@ AttachDecision CallIRGenerator::tryAttac
   // Check for native-function optimizations.
   if (calleeFunc->isNative()) {
     return tryAttachCallNative(calleeFunc);
   }
 
   return AttachDecision::NoAction;
 }
 
-bool CallIRGenerator::isOptimizableConstStringSplit(HandleFunction calleeFunc) {
-  // If we have not yet attached any stubs to this IC...
-  if (!isFirstStub_) {
-    return false;
-  }
-
-  // And |this| is a string:
-  if (!thisval_.isString()) {
-    return false;
-  }
-
-  // And we have one argument, which is a string...
-  if (argc_ != 1 || !args_[0].isString()) {
-    return false;
-  }
-
-  // And both strings are atoms...
-  if (!thisval_.toString()->isAtom() || !args_[0].toString()->isAtom()) {
-    return false;
-  }
-
-  // And we are calling a function in the current realm...
-  if (calleeFunc->realm() != cx_->realm()) {
-    return false;
-  }
-
-  // Which is the String split self-hosted function
-  if (!IsSelfHostedFunctionWithName(calleeFunc, cx_->names().String_split)) {
-    return false;
-  }
-
-  // Then this might be a call of the form:
-  //  "literal list".split("literal separator")
-  // If so, we can cache the result and avoid having to perform the operation
-  // each time.
-  return true;
-}
-
-AttachDecision CallIRGenerator::tryAttachConstStringSplit(
-    HandleValue result, HandleFunction calleeFunc) {
-  if (JitOptions.disableCacheIRCalls) {
-    return AttachDecision::NoAction;
-  }
-
-  if (!isOptimizableConstStringSplit(calleeFunc)) {
-    return AttachDecision::NoAction;
-  }
-
-  RootedString str(cx_, thisval_.toString());
-  RootedString sep(cx_, args_[0].toString());
-  RootedArrayObject resultObj(cx_, &result.toObject().as<ArrayObject>());
-  uint32_t initLength = resultObj->getDenseInitializedLength();
-  MOZ_ASSERT(initLength == resultObj->length(),
-             "string-split result is a fully initialized array");
-
-  // Copy the array before storing in stub.
-  RootedArrayObject arrObj(cx_);
-  arrObj = NewFullyAllocatedArrayTryReuseGroup(cx_, resultObj, initLength,
-                                               TenuredObject);
-  if (!arrObj) {
-    cx_->clearPendingException();
-    return AttachDecision::NoAction;
-  }
-  arrObj->ensureDenseInitializedLength(cx_, 0, initLength);
-
-  // Atomize all elements of the array.
-  if (initLength > 0) {
-    // Mimic NewFullyAllocatedStringArray() and directly inform TI about
-    // the element type.
-    AddTypePropertyId(cx_, arrObj, JSID_VOID, TypeSet::StringType());
-
-    for (uint32_t i = 0; i < initLength; i++) {
-      JSAtom* str =
-          js::AtomizeString(cx_, resultObj->getDenseElement(i).toString());
-      if (!str) {
-        cx_->clearPendingException();
-        return AttachDecision::NoAction;
-      }
-      arrObj->initDenseElement(i, StringValue(str));
-    }
-  }
-
-  Int32OperandId argcId(writer.setInputOperandId(0));
-
-  // Guard that callee is the self-hosted String_split function
-  ValOperandId calleeValId =
-      writer.loadArgumentFixedSlot(ArgumentKind::Callee, argc_);
-  ObjOperandId calleeObjId = writer.guardIsObject(calleeValId);
-  writer.guardSpecificFunction(calleeObjId, calleeFunc);
-
-  // Guard that |this| is the expected string
-  ValOperandId strValId =
-      writer.loadArgumentFixedSlot(ArgumentKind::This, argc_);
-  StringOperandId strStringId = writer.guardIsString(strValId);
-  FieldOffset strOffset = writer.guardSpecificAtom(strStringId, &str->asAtom());
-
-  // Guard that the argument is the expected separator
-  ValOperandId sepValId =
-      writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_);
-  StringOperandId sepStringId = writer.guardIsString(sepValId);
-  FieldOffset sepOffset = writer.guardSpecificAtom(sepStringId, &sep->asAtom());
-
-  FieldOffset templateOffset = writer.callConstStringSplitResult(arrObj);
-
-  writer.typeMonitorResult();
-  cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored;
-
-  writer.metaConstStringSplitData(strOffset, sepOffset, templateOffset);
-
-  trackAttached("Const string split");
-  return AttachDecision::Attach;
-}
-
 AttachDecision CallIRGenerator::tryAttachDeferredStub(HandleValue result) {
   AutoAssertNoPendingException aanpe(cx_);
 
   // Ensure that the opcode makes sense.
   MOZ_ASSERT(op_ == JSOP_CALL || op_ == JSOP_CALL_IGNORES_RV);
 
   // Ensure that the mode makes sense.
   MOZ_ASSERT(mode_ == ICState::Mode::Specialized);
 
-  RootedFunction calleeFunc(cx_, &callee_.toObject().as<JSFunction>());
-
-  TRY_ATTACH(tryAttachConstStringSplit(result, calleeFunc));
-
-  MOZ_ASSERT_UNREACHABLE("Unexpected deferred function failure");
+  MOZ_ASSERT_UNREACHABLE("No deferred functions currently exist");
   return AttachDecision::NoAction;
 }
 
 void CallIRGenerator::trackAttached(const char* name) {
 #ifdef JS_CACHEIR_SPEW
   if (const CacheIRSpewer::Guard& sp = CacheIRSpewer::Guard(*this, name)) {
     sp.valueProperty("callee", callee_);
     sp.valueProperty("thisval", thisval_);
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -296,17 +296,16 @@ extern const uint32_t ArgLengths[];
   _(CallNumberToString, Id, Id)                                                \
   _(BooleanToString, Id, Id)                                                   \
   _(CallScriptedFunction, Id, Id, Byte)                                        \
   _(CallNativeFunction, Id, Id, Byte, IF_SIMULATOR(Field, Byte))               \
   _(CallClassHook, Id, Id, Byte, Field)                                        \
                                                                                \
   /* Meta ops generate no code, but contain data for BaselineInspector */      \
   _(MetaTwoByte, Byte, Field, Field)                                           \
-  _(MetaThreeByte, Byte, Field, Field, Field)                                  \
                                                                                \
   /* The *Result ops load a value into the cache's result register. */         \
   _(LoadFixedSlotResult, Id, Field)                                            \
   _(LoadDynamicSlotResult, Id, Field)                                          \
   _(LoadTypedObjectResult, Id, Byte, Byte, Field)                              \
   _(LoadDenseElementResult, Id, Id)                                            \
   _(LoadDenseElementHoleResult, Id, Id)                                        \
   _(CallGetSparseElementResult, Id, Id)                                        \
@@ -365,17 +364,16 @@ extern const uint32_t ArgLengths[];
   _(DoubleDecResult, Id)                                                       \
   _(LoadInt32TruthyResult, Id)                                                 \
   _(LoadDoubleTruthyResult, Id)                                                \
   _(LoadStringTruthyResult, Id)                                                \
   _(LoadObjectTruthyResult, Id)                                                \
   _(LoadValueResult, Field)                                                    \
   _(LoadNewObjectFromTemplateResult, Field, UInt32, UInt32)                    \
                                                                                \
-  _(CallConstStringSplitResult, Field)                                         \
   _(CallStringConcatResult, Id, Id)                                            \
   _(CallStringObjectConcatResult, Id, Id)                                      \
   _(CallIsSuspendedGeneratorResult, Id)                                        \
                                                                                \
   _(CompareStringResult, Id, Id, Byte)                                         \
   _(CompareObjectResult, Id, Id, Byte)                                         \
   _(CompareSymbolResult, Id, Id, Byte)                                         \
   _(CompareInt32Result, Id, Id, Byte)                                          \
@@ -630,20 +628,16 @@ void LoadShapeWrapperContents(MacroAssem
                               Label* failure);
 
 enum class MetaTwoByteKind : uint8_t {
   NativeTemplateObject,
   ScriptedTemplateObject,
   ClassTemplateObject,
 };
 
-enum class MetaThreeByteKind : uint8_t {
-  ConstStringSplitData,
-};
-
 #ifdef JS_SIMULATOR
 bool CallAnyNative(JSContext* cx, unsigned argc, Value* vp);
 #endif
 
 // Class to record CacheIR + some additional metadata for code generation.
 class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter {
   JSContext* cx_;
   CompactBufferWriter buffer_;
@@ -1435,25 +1429,16 @@ class MOZ_RAII CacheIRWriter : public JS
   }
   void metaClassTemplateObject(JSObject* templateObject,
                                FieldOffset classOffset) {
     writeOp(CacheOp::MetaTwoByte);
     buffer_.writeByte(uint32_t(MetaTwoByteKind::ClassTemplateObject));
     reuseStubField(classOffset);
     addStubField(uintptr_t(templateObject), StubField::Type::JSObject);
   }
-  void metaConstStringSplitData(FieldOffset strOffset, FieldOffset sepOffset,
-                                FieldOffset templateOffset) {
-    writeOp(CacheOp::MetaThreeByte);
-    buffer_.writeByte(uint32_t(MetaThreeByteKind::ConstStringSplitData));
-    reuseStubField(strOffset);
-    reuseStubField(sepOffset);
-    reuseStubField(templateOffset);
-  }
-
   void megamorphicLoadSlotResult(ObjOperandId obj, PropertyName* name,
                                  bool handleMissing) {
     writeOpWithOperandId(CacheOp::MegamorphicLoadSlotResult, obj);
     addStubField(uintptr_t(name), StubField::Type::String);
     buffer_.writeByte(uint32_t(handleMissing));
   }
   void megamorphicLoadSlotByValueResult(ObjOperandId obj, ValOperandId id,
                                         bool handleMissing) {
@@ -1743,20 +1728,16 @@ class MOZ_RAII CacheIRWriter : public JS
   void callStringConcatResult(StringOperandId lhs, StringOperandId rhs) {
     writeOpWithOperandId(CacheOp::CallStringConcatResult, lhs);
     writeOperandId(rhs);
   }
   void callStringObjectConcatResult(ValOperandId lhs, ValOperandId rhs) {
     writeOpWithOperandId(CacheOp::CallStringObjectConcatResult, lhs);
     writeOperandId(rhs);
   }
-  FieldOffset callConstStringSplitResult(ArrayObject* resultTemplate) {
-    writeOp(CacheOp::CallConstStringSplitResult);
-    return addStubField(uintptr_t(resultTemplate), StubField::Type::JSObject);
-  }
 
   void compareStringResult(uint32_t op, StringOperandId lhs,
                            StringOperandId rhs) {
     writeOpWithOperandId(CacheOp::CompareStringResult, lhs);
     writeOperandId(rhs);
     buffer_.writeByte(uint32_t(op));
   }
   void compareObjectResult(uint32_t op, ObjOperandId lhs, ObjOperandId rhs) {
@@ -2384,53 +2365,45 @@ class MOZ_RAII CallIRGenerator : public 
   JSOp op_;
   uint32_t argc_;
   HandleValue callee_;
   HandleValue thisval_;
   HandleValue newTarget_;
   HandleValueArray args_;
   PropertyTypeCheckInfo typeCheckInfo_;
   BaselineCacheIRStubKind cacheIRStubKind_;
-  bool isFirstStub_;
 
   bool getTemplateObjectForScripted(HandleFunction calleeFunc,
                                     MutableHandleObject result,
                                     bool* skipAttach);
   bool getTemplateObjectForNative(HandleFunction calleeFunc,
                                   MutableHandleObject result);
   bool getTemplateObjectForClassHook(HandleObject calleeObj,
                                      MutableHandleObject result);
 
-  // Regular stubs
   AttachDecision tryAttachArrayPush();
   AttachDecision tryAttachArrayJoin();
   AttachDecision tryAttachIsSuspendedGenerator();
   AttachDecision tryAttachFunCall();
   AttachDecision tryAttachFunApply();
-  AttachDecision tryAttachSelfHosted(HandleFunction calleeFunc);
   AttachDecision tryAttachCallScripted(HandleFunction calleeFunc);
   AttachDecision tryAttachSpecialCaseCallNative(HandleFunction calleeFunc);
   AttachDecision tryAttachCallNative(HandleFunction calleeFunc);
   AttachDecision tryAttachCallHook(HandleObject calleeObj);
 
-  // Deferred stubs
-  AttachDecision tryAttachConstStringSplit(HandleValue result,
-                                           HandleFunction calleeFunc);
-
   void trackAttached(const char* name);
 
  public:
   CallIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, JSOp op,
                   ICState::Mode mode, uint32_t argc, HandleValue callee,
                   HandleValue thisval, HandleValue newTarget,
-                  HandleValueArray args, bool isFirstStub);
+                  HandleValueArray args);
 
   AttachDecision tryAttachStub();
 
-  bool isOptimizableConstStringSplit(HandleFunction calleeFunc);
   AttachDecision tryAttachDeferredStub(HandleValue result);
 
   BaselineCacheIRStubKind cacheIRStubKind() const { return cacheIRStubKind_; }
 
   const PropertyTypeCheckInfo* typeCheckInfo() const { return &typeCheckInfo_; }
 };
 
 class MOZ_RAII CompareIRGenerator : public IRGenerator {
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -4380,18 +4380,8 @@ bool CacheIRCompiler::emitCallIsSuspende
 // This op generates no code. It is consumed by BaselineInspector.
 bool CacheIRCompiler::emitMetaTwoByte() {
   mozilla::Unused << reader.readByte();  // meta kind
   mozilla::Unused << reader.readByte();  // payload byte 1
   mozilla::Unused << reader.readByte();  // payload byte 2
 
   return true;
 }
-
-// This op generates no code. It is consumed by BaselineInspector.
-bool CacheIRCompiler::emitMetaThreeByte() {
-  mozilla::Unused << reader.readByte();  // meta kind
-  mozilla::Unused << reader.readByte();  // payload byte 1
-  mozilla::Unused << reader.readByte();  // payload byte 2
-  mozilla::Unused << reader.readByte();  // payload byte 3
-
-  return true;
-}
--- a/js/src/jit/CacheIRCompiler.h
+++ b/js/src/jit/CacheIRCompiler.h
@@ -124,17 +124,16 @@ namespace jit {
   _(MegamorphicStoreSlot)                 \
   _(MegamorphicHasPropResult)             \
   _(CallObjectHasSparseElementResult)     \
   _(CallInt32ToString)                    \
   _(CallNumberToString)                   \
   _(BooleanToString)                      \
   _(CallIsSuspendedGeneratorResult)       \
   _(MetaTwoByte)                          \
-  _(MetaThreeByte)                        \
   _(WrapResult)
 
 // [SMDDOC] CacheIR Value Representation and Tracking
 //
 // While compiling an IC stub the CacheIR compiler needs to keep track of the
 // physical location for each logical piece of data we care about, as well as
 // ensure that in the case of a stub failing, we are able to restore the input
 // state so that a subsequent stub can attempt to provide a value.
--- a/js/src/jit/IonCacheIRCompiler.cpp
+++ b/js/src/jit/IonCacheIRCompiler.cpp
@@ -1312,21 +1312,16 @@ bool IonCacheIRCompiler::emitLoadEnviron
   return true;
 }
 
 bool IonCacheIRCompiler::emitLoadStringResult() {
   JitSpew(JitSpew_Codegen, __FUNCTION__);
   MOZ_CRASH("not used in ion");
 }
 
-bool IonCacheIRCompiler::emitCallConstStringSplitResult() {
-  JitSpew(JitSpew_Codegen, __FUNCTION__);
-  MOZ_CRASH("not used in ion");
-}
-
 bool IonCacheIRCompiler::emitCompareStringResult() {
   JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
   AutoOutputRegister output(*this);
 
   Register left = allocator.useRegister(masm, reader.stringOperandId());
   Register right = allocator.useRegister(masm, reader.stringOperandId());
   JSOp op = reader.jsop();
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -1914,154 +1914,32 @@ IonBuilder::InliningResult IonBuilder::i
       MNewStringObject::New(alloc(), callInfo.getArg(0), templateObj);
   current->add(ins);
   current->push(ins);
 
   MOZ_TRY(resumeAfter(ins));
   return InliningStatus_Inlined;
 }
 
-IonBuilder::InliningResult IonBuilder::inlineConstantStringSplitString(
-    CallInfo& callInfo) {
-  if (!callInfo.getArg(0)->isConstant()) {
-    return InliningStatus_NotInlined;
-  }
-
-  if (!callInfo.getArg(1)->isConstant()) {
-    return InliningStatus_NotInlined;
-  }
-
-  MConstant* strval = callInfo.getArg(0)->toConstant();
-  if (strval->type() != MIRType::String) {
-    return InliningStatus_NotInlined;
-  }
-
-  MConstant* sepval = callInfo.getArg(1)->toConstant();
-  if (strval->type() != MIRType::String) {
-    return InliningStatus_NotInlined;
-  }
-
-  // Check if exist a template object in stub.
-  JSString* stringStr = nullptr;
-  JSString* stringSep = nullptr;
-  ArrayObject* templateObject = nullptr;
-  if (!inspector->isOptimizableConstStringSplit(pc, &stringStr, &stringSep,
-                                                &templateObject)) {
-    return InliningStatus_NotInlined;
-  }
-
-  MOZ_ASSERT(stringStr);
-  MOZ_ASSERT(stringSep);
-  MOZ_ASSERT(templateObject);
-
-  if (strval->toString() != stringStr) {
-    return InliningStatus_NotInlined;
-  }
-
-  if (sepval->toString() != stringSep) {
-    return InliningStatus_NotInlined;
-  }
-
-  // Check if |templateObject| is valid.
-  TypeSet::ObjectKey* retType = TypeSet::ObjectKey::get(templateObject);
-  if (retType->unknownProperties()) {
-    return InliningStatus_NotInlined;
-  }
-
-  HeapTypeSetKey key = retType->property(JSID_VOID);
-  if (!key.maybeTypes()) {
-    return InliningStatus_NotInlined;
-  }
-
-  if (!key.maybeTypes()->hasType(TypeSet::StringType())) {
-    return InliningStatus_NotInlined;
-  }
-
-  uint32_t initLength = templateObject->length();
-  if (templateObject->getDenseInitializedLength() != initLength) {
-    return InliningStatus_NotInlined;
-  }
-
-  Vector<MConstant*, 0, SystemAllocPolicy> arrayValues;
-  for (uint32_t i = 0; i < initLength; i++) {
-    Value str = templateObject->getDenseElement(i);
-    MOZ_ASSERT(str.toString()->isAtom());
-    MConstant* value = MConstant::New(alloc().fallible(), str, constraints());
-    if (!value) {
-      return abort(AbortReason::Alloc);
-    }
-    if (!TypeSetIncludes(key.maybeTypes(), value->type(),
-                         value->resultTypeSet())) {
-      return InliningStatus_NotInlined;
-    }
-
-    if (!arrayValues.append(value)) {
-      return abort(AbortReason::Alloc);
-    }
-  }
-  callInfo.setImplicitlyUsedUnchecked();
-
-  TemporaryTypeSet::DoubleConversion conversion =
-      getInlineReturnTypeSet()->convertDoubleElements(constraints());
-  if (conversion == TemporaryTypeSet::AlwaysConvertToDoubles) {
-    return InliningStatus_NotInlined;
-  }
-
-  MOZ_TRY(jsop_newarray(templateObject, initLength));
-
-  MDefinition* array = current->peek(-1);
-
-  if (!initLength) {
-    MOZ_TRY(resumeAfter(array->toNewArray()));
-    return InliningStatus_Inlined;
-  }
-
-  // Store all values, no need to initialize the length after each as
-  // jsop_initelem_array is doing because we do not expect to bailout
-  // because the memory is supposed to be allocated by now.
-  for (uint32_t i = 0; i < initLength; i++) {
-    if (!alloc().ensureBallast()) {
-      return abort(AbortReason::Alloc);
-    }
-
-    MConstant* value = arrayValues[i];
-    current->add(value);
-
-    MOZ_TRY(
-        initializeArrayElement(array, i, value, /* addResumePoint = */ false));
-  }
-
-  MInstruction* setLength = setInitializedLength(array, initLength);
-  MOZ_TRY(resumeAfter(setLength));
-  return InliningStatus_Inlined;
-}
-
 IonBuilder::InliningResult IonBuilder::inlineStringSplitString(
     CallInfo& callInfo) {
   MOZ_ASSERT(!callInfo.constructing());
   MOZ_ASSERT(callInfo.argc() == 2);
 
   MDefinition* strArg = callInfo.getArg(0);
   MDefinition* sepArg = callInfo.getArg(1);
 
   if (strArg->type() != MIRType::String) {
     return InliningStatus_NotInlined;
   }
 
   if (sepArg->type() != MIRType::String) {
     return InliningStatus_NotInlined;
   }
 
-  IonBuilder::InliningStatus resultConstStringSplit;
-  MOZ_TRY_VAR(resultConstStringSplit,
-              inlineConstantStringSplitString(callInfo));
-  if (resultConstStringSplit != InliningStatus_NotInlined) {
-    return resultConstStringSplit;
-  }
-
   JSContext* cx = TlsContext.get();
   ObjectGroup* group = ObjectGroupRealm::getStringSplitStringGroup(cx);
   if (!group) {
     return InliningStatus_NotInlined;
   }
 
   TypeSet::ObjectKey* retKey = TypeSet::ObjectKey::get(group);
   if (retKey->unknownProperties()) {
--- a/js/src/jit/VMFunctionList-inl.h
+++ b/js/src/jit/VMFunctionList-inl.h
@@ -65,17 +65,16 @@ namespace jit {
   _(CheckIsCallable, js::jit::CheckIsCallable)                                 \
   _(CheckOverRecursed, js::jit::CheckOverRecursed)                             \
   _(CheckOverRecursedBaseline, js::jit::CheckOverRecursedBaseline)             \
   _(CloneRegExpObject, js::CloneRegExpObject)                                  \
   _(ConcatStrings, js::ConcatStrings<CanGC>)                                   \
   _(ConvertElementsToDoubles, js::ObjectElements::ConvertElementsToDoubles)    \
   _(CopyElementsForWrite, js::NativeObject::CopyElementsForWrite)              \
   _(CopyLexicalEnvironmentObject, js::jit::CopyLexicalEnvironmentObject)       \
-  _(CopyStringSplitArray, js::jit::CopyStringSplitArray)                       \
   _(CreateAsyncFromSyncIterator, js::CreateAsyncFromSyncIterator)              \
   _(CreateDerivedTypedObj, js::jit::CreateDerivedTypedObj)                     \
   _(CreateGenerator, js::jit::CreateGenerator)                                 \
   _(CreateThis, js::jit::CreateThis)                                           \
   _(CreateThisForFunctionWithProto, js::CreateThisForFunctionWithProto)        \
   _(CreateThisWithTemplate, js::CreateThisWithTemplate)                        \
   _(DebugAfterYield, js::jit::DebugAfterYield)                                 \
   _(DebugEpilogueOnBaselineReturn, js::jit::DebugEpilogueOnBaselineReturn)     \
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -2006,29 +2006,10 @@ bool DoToNumber(JSContext* cx, HandleVal
   return ToNumber(cx, ret);
 }
 
 bool DoToNumeric(JSContext* cx, HandleValue arg, MutableHandleValue ret) {
   ret.set(arg);
   return ToNumeric(cx, ret);
 }
 
-bool CopyStringSplitArray(JSContext* cx, HandleArrayObject arr,
-                          MutableHandleValue result) {
-  MOZ_ASSERT(arr->isTenured(),
-             "ConstStringSplit needs a tenured template object");
-
-  uint32_t length = arr->getDenseInitializedLength();
-  MOZ_ASSERT(length == arr->length(),
-             "template object is a fully initialized array");
-
-  ArrayObject* nobj = NewFullyAllocatedArrayTryReuseGroup(cx, arr, length);
-  if (!nobj) {
-    return false;
-  }
-  nobj->initDenseElements(arr, 0, length);
-
-  result.setObject(*nobj);
-  return true;
-}
-
 }  // namespace jit
 }  // namespace js
--- a/js/src/jit/VMFunctions.h
+++ b/js/src/jit/VMFunctions.h
@@ -1102,19 +1102,16 @@ bool DoConcatStringObject(JSContext* cx,
 MOZ_MUST_USE bool TrySkipAwait(JSContext* cx, HandleValue val,
                                MutableHandleValue resolved);
 
 bool IsPossiblyWrappedTypedArray(JSContext* cx, JSObject* obj, bool* result);
 
 bool DoToNumber(JSContext* cx, HandleValue arg, MutableHandleValue ret);
 bool DoToNumeric(JSContext* cx, HandleValue arg, MutableHandleValue ret);
 
-bool CopyStringSplitArray(JSContext* cx, HandleArrayObject arr,
-                          MutableHandleValue result);
-
 enum class TailCallVMFunctionId;
 enum class VMFunctionId;
 
 extern const VMFunctionData& GetVMFunction(VMFunctionId id);
 extern const VMFunctionData& GetVMFunction(TailCallVMFunctionId id);
 
 }  // namespace jit
 }  // namespace js