Bug 1688033: Add support for LoadArgumentsObjArg r=jandem
authorIain Ireland <iireland@mozilla.com>
Tue, 02 Feb 2021 00:27:40 +0000
changeset 565562 57bcdf857d44b8c95dc8b9382a6e0ab7c2b52e4f
parent 565561 ec8cf08562a3bd8dfdf8920fca8a965431fbd93c
child 565563 06775794753816195cc8077ad8894377449b628a
push id38162
push usernerli@mozilla.com
push dateTue, 02 Feb 2021 09:51:07 +0000
treeherdermozilla-central@57bcdf857d44 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1688033
milestone87.0a1
first release with
nightly linux32
57bcdf857d44 / 87.0a1 / 20210202095107 / files
nightly linux64
57bcdf857d44 / 87.0a1 / 20210202095107 / files
nightly mac
57bcdf857d44 / 87.0a1 / 20210202095107 / files
nightly win32
57bcdf857d44 / 87.0a1 / 20210202095107 / files
nightly win64
57bcdf857d44 / 87.0a1 / 20210202095107 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1688033: Add support for LoadArgumentsObjArg r=jandem This adds support for `arguments[i]`. It is based directly on WarpCacheIRTranspiler::emitLoadFrameArgumentResult. If this bounds check fails, then baseline will attach a new stub in tryAttachGenericElement, preventing a bailout loop. We could also disable scalar replacement of arguments immediately, using a special BailoutKind. Depends on D103111 Differential Revision: https://phabricator.services.mozilla.com/D103112
js/src/jit/ScalarReplacement.cpp
--- a/js/src/jit/ScalarReplacement.cpp
+++ b/js/src/jit/ScalarReplacement.cpp
@@ -1247,16 +1247,17 @@ static bool IsArgumentsObjectEscaped(MIn
           return true;
         }
         break;
       }
 
       // This is a replaceable consumer.
       case MDefinition::Opcode::ArgumentsObjectLength:
       case MDefinition::Opcode::GetArgumentsObjectArg:
+      case MDefinition::Opcode::LoadArgumentsObjectArg:
         break;
 
       default:
         JitSpewDef(JitSpew_Escape, "is escaped by\n", def);
         return true;
     }
   }
 
@@ -1269,16 +1270,17 @@ class ArgumentsReplacer : public MDefini
   MIRGenerator* mir_;
   MIRGraph& graph_;
   MInstruction* args_;
 
   TempAllocator& alloc() { return graph_.alloc(); }
 
   void visitGuardToClass(MGuardToClass* ins);
   void visitGetArgumentsObjectArg(MGetArgumentsObjectArg* ins);
+  void visitLoadArgumentsObjectArg(MLoadArgumentsObjectArg* ins);
   void visitArgumentsObjectLength(MArgumentsObjectLength* ins);
 
  public:
   ArgumentsReplacer(MIRGenerator* mir, MIRGraph& graph, MInstruction* args)
       : mir_(mir), graph_(graph), args_(args) {
     MOZ_ASSERT(IsOptimizableArgumentsInstruction(args_));
   }
 
@@ -1351,16 +1353,47 @@ void ArgumentsReplacer::visitGetArgument
   auto* loadArg = MGetFrameArgument::New(alloc(), index);
   ins->block()->insertBefore(ins, loadArg);
   ins->replaceAllUsesWith(loadArg);
 
   // Remove original instruction.
   ins->block()->discard(ins);
 }
 
+void ArgumentsReplacer::visitLoadArgumentsObjectArg(
+    MLoadArgumentsObjectArg* ins) {
+  // There is only one possible arguments object.
+  // TODO: support inlining.
+  MOZ_ASSERT(ins->getArgsObject() == args_);
+
+  MDefinition* index = ins->index();
+
+  // Insert bounds check.
+  auto* length = MArgumentsLength::New(alloc());
+  ins->block()->insertBefore(ins, length);
+
+  MInstruction* check = MBoundsCheck::New(alloc(), index, length);
+  ins->block()->insertBefore(ins, check);
+
+  // TODO: Set special bailout kind?
+  check->setBailoutKind(ins->bailoutKind());
+
+  if (JitOptions.spectreIndexMasking) {
+    check = MSpectreMaskIndex::New(alloc(), check, length);
+    ins->block()->insertBefore(ins, check);
+  }
+
+  auto* loadArg = MGetFrameArgument::New(alloc(), check);
+  ins->block()->insertBefore(ins, loadArg);
+  ins->replaceAllUsesWith(loadArg);
+
+  // Remove original instruction.
+  ins->block()->discard(ins);
+}
+
 void ArgumentsReplacer::visitArgumentsObjectLength(
     MArgumentsObjectLength* ins) {
   // There is only one possible arguments object.
   // TODO: support inlining.
   MOZ_ASSERT(ins->getArgsObject() == args_);
 
   auto* length = MArgumentsLength::New(alloc());
   ins->block()->insertBefore(ins, length);