Bug 1629867 - Add support for LoadDenseElement to WarpCacheIRTranspiler. r=jandem
authorTom Schuster <evilpies@gmail.com>
Wed, 15 Apr 2020 15:35:58 +0000
changeset 524190 8f3a2cbbb952c9503fac159eaf12c0da951287ca
parent 524189 ce3f84d94d4d7820b150ed961aa82f0b56176bd9
child 524191 02970449a7bee151d7a2f4939369cb9bc562e4c3
push id113041
push userevilpies@gmail.com
push dateWed, 15 Apr 2020 15:59:25 +0000
treeherderautoland@706e0a08e6fa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1629867
milestone77.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 1629867 - Add support for LoadDenseElement to WarpCacheIRTranspiler. r=jandem Differential Revision: https://phabricator.services.mozilla.com/D70858
js/src/jit/WarpBuilder.cpp
js/src/jit/WarpCacheIRTranspiler.cpp
js/src/jit/WarpCacheIRTranspiler.h
js/src/jit/WarpOracle.cpp
--- a/js/src/jit/WarpBuilder.cpp
+++ b/js/src/jit/WarpBuilder.cpp
@@ -1836,16 +1836,21 @@ bool WarpBuilder::build_CallProp(Bytecod
 
 bool WarpBuilder::build_Length(BytecodeLocation loc) {
   return build_GetProp(loc);
 }
 
 bool WarpBuilder::build_GetElem(BytecodeLocation loc) {
   MDefinition* id = current->pop();
   MDefinition* val = current->pop();
+
+  if (auto* snapshot = getOpSnapshot<WarpCacheIR>(loc)) {
+    return buildCacheIR(loc, snapshot, {val, id});
+  }
+
   return buildGetPropOp(loc, val, id);
 }
 
 bool WarpBuilder::build_CallElem(BytecodeLocation loc) {
   return build_GetElem(loc);
 }
 
 bool WarpBuilder::buildSetPropOp(BytecodeLocation loc, MDefinition* obj,
--- a/js/src/jit/WarpCacheIRTranspiler.cpp
+++ b/js/src/jit/WarpCacheIRTranspiler.cpp
@@ -155,16 +155,27 @@ bool WarpCacheIRTranspiler::transpileGua
 bool WarpCacheIRTranspiler::transpile_GuardToObject() {
   return transpileGuardTo(MIRType::Object);
 }
 
 bool WarpCacheIRTranspiler::transpile_GuardToString() {
   return transpileGuardTo(MIRType::String);
 }
 
+bool WarpCacheIRTranspiler::transpile_GuardToInt32Index() {
+  ValOperandId inputId = reader.valOperandId();
+  Int32OperandId outputId = reader.int32OperandId();
+
+  MDefinition* input = getOperand(inputId);
+  auto* ins = MToNumberInt32::New(alloc(), input);
+  current->add(ins);
+
+  return defineOperand(outputId, ins);
+}
+
 bool WarpCacheIRTranspiler::transpile_LoadEnclosingEnvironment() {
   ObjOperandId inputId = reader.objOperandId();
   ObjOperandId outputId = reader.objOperandId();
 
   MDefinition* env = getOperand(inputId);
   auto* ins = MEnclosingEnvironment::New(alloc(), env);
   current->add(ins);
 
@@ -259,24 +270,52 @@ bool WarpCacheIRTranspiler::transpile_Lo
 
   auto* length = MStringLength::New(alloc(), str);
   current->add(length);
 
   setResult(length);
   return true;
 }
 
+bool WarpCacheIRTranspiler::transpile_LoadDenseElementResult() {
+  ObjOperandId objId = reader.objOperandId();
+  Int32OperandId indexId = reader.int32OperandId();
+  MDefinition* obj = getOperand(objId);
+  MDefinition* index = getOperand(indexId);
+
+  auto* elements = MElements::New(alloc(), obj);
+  current->add(elements);
+
+  auto* length = MInitializedLength::New(alloc(), elements);
+  current->add(length);
+
+  MInstruction* check = MBoundsCheck::New(alloc(), index, length);
+  current->add(check);
+
+  if (JitOptions.spectreIndexMasking) {
+    check = MSpectreMaskIndex::New(alloc(), check, length);
+    current->add(check);
+  }
+
+  bool needsHoleCheck = true;
+  bool loadDouble = false;  // TODO: Ion-only optimization.
+  auto* load =
+      MLoadElement::New(alloc(), elements, check, needsHoleCheck, loadDouble);
+  current->add(load);
+
+  setResult(load);
+  return true;
+}
+
 bool WarpCacheIRTranspiler::transpile_TypeMonitorResult() {
   MOZ_ASSERT(output_.result, "Didn't set result MDefinition");
   return true;
 }
 
-bool WarpCacheIRTranspiler::transpile_ReturnFromIC() {
-  return true;
-}
+bool WarpCacheIRTranspiler::transpile_ReturnFromIC() { return true; }
 
 bool jit::TranspileCacheIRToMIR(MIRGenerator& mirGen, MBasicBlock* current,
                                 const WarpCacheIR* snapshot,
                                 const MDefinitionStackVector& inputs,
                                 TranspilerOutput& output) {
   WarpCacheIRTranspiler transpiler(mirGen, current, snapshot, output);
   return transpiler.transpile(inputs);
 }
--- a/js/src/jit/WarpCacheIRTranspiler.h
+++ b/js/src/jit/WarpCacheIRTranspiler.h
@@ -23,23 +23,25 @@ using MDefinitionStackVector = Vector<MD
 
 // List of supported ops. Eventually we should use the full CacheIR ops list
 // instead.
 #define WARP_CACHE_IR_OPS(_)          \
   _(GuardClass)                       \
   _(GuardShape)                       \
   _(GuardToObject)                    \
   _(GuardToString)                    \
+  _(GuardToInt32Index)                \
   _(LoadEnclosingEnvironment)         \
   _(LoadDynamicSlotResult)            \
   _(LoadFixedSlotResult)              \
   _(LoadEnvironmentFixedSlotResult)   \
   _(LoadEnvironmentDynamicSlotResult) \
   _(LoadInt32ArrayLengthResult)       \
   _(LoadStringLengthResult)           \
+  _(LoadDenseElementResult)           \
   _(TypeMonitorResult)                \
   _(ReturnFromIC)
 
 // TranspilerOutput contains information from the transpiler that needs to be
 // passed back to WarpBuilder.
 struct MOZ_STACK_CLASS TranspilerOutput {
   // For ICs that return a result, this is the corresponding MIR instruction.
   MDefinition* result = nullptr;
--- a/js/src/jit/WarpOracle.cpp
+++ b/js/src/jit/WarpOracle.cpp
@@ -385,16 +385,18 @@ AbortReasonOr<WarpScriptSnapshot*> WarpO
         break;
       }
 
       case JSOp::GetName:
       case JSOp::GetGName:
       case JSOp::GetProp:
       case JSOp::CallProp:
       case JSOp::Length:
+      case JSOp::GetElem:
+      case JSOp::CallElem:
         MOZ_TRY(maybeInlineIC(opSnapshots, script, loc));
         break;
 
       case JSOp::Nop:
       case JSOp::NopDestructuring:
       case JSOp::TryDestructuring:
       case JSOp::Lineno:
       case JSOp::DebugLeaveLexicalEnv:
@@ -498,18 +500,16 @@ AbortReasonOr<WarpScriptSnapshot*> WarpO
       case JSOp::CallIgnoresRv:
       case JSOp::CallIter:
       case JSOp::FunCall:
       case JSOp::FunApply:
       case JSOp::New:
       case JSOp::SuperCall:
       case JSOp::BindName:
       case JSOp::BindGName:
-      case JSOp::GetElem:
-      case JSOp::CallElem:
       case JSOp::SetProp:
       case JSOp::StrictSetProp:
       case JSOp::SetName:
       case JSOp::StrictSetName:
       case JSOp::SetGName:
       case JSOp::StrictSetGName:
       case JSOp::InitGLexical:
       case JSOp::SetElem: