Bug 1334187 - Port In_Dense from BaselineIC to CacheIR. r?jandem draft
authorTed Campbell <tcampbell@mozilla.com>
Thu, 26 Jan 2017 22:47:44 -0500
changeset 467387 642336a7637df744a750faac3f17c8ecd761a48d
parent 467386 5e7381be8252e402be6753193141977d84aafbdb
child 543677 03fd8b37f874aebd2c7e4fd72765780113057e29
push id43164
push userbmo:tcampbell@mozilla.com
push dateFri, 27 Jan 2017 19:27:17 +0000
reviewersjandem
bugs1334187
milestone54.0a1
Bug 1334187 - Port In_Dense from BaselineIC to CacheIR. r?jandem
js/src/jit/BaselineIC.cpp
js/src/jit/BaselineIC.h
js/src/jit/BaselineICList.h
js/src/jit/CacheIR.cpp
js/src/jit/CacheIR.h
js/src/jit/SharedIC.cpp
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -870,24 +870,16 @@ TypedThingRequiresFloatingPoint(JSObject
 {
     Scalar::Type type = TypedThingElementType(obj);
     return type == Scalar::Uint32 ||
            type == Scalar::Float32 ||
            type == Scalar::Float64;
 }
 
 static bool
-IsNativeDenseElementAccess(HandleObject obj, HandleValue key)
-{
-    if (obj->isNative() && key.isInt32() && key.toInt32() >= 0 && !obj->is<TypedArrayObject>())
-        return true;
-    return false;
-}
-
-static bool
 IsNativeOrUnboxedDenseElementAccess(HandleObject obj, HandleValue key)
 {
     if (!obj->isNative() && !obj->is<UnboxedArrayObject>())
         return false;
     if (key.isInt32() && key.toInt32() >= 0 && !obj->is<TypedArrayObject>())
         return true;
     return false;
 }
@@ -1995,36 +1987,16 @@ ICSetElem_TypedArray::Compiler::generate
     return true;
 }
 
 //
 // In_Fallback
 //
 
 static bool
-TryAttachDenseInStub(JSContext* cx, HandleScript outerScript, ICIn_Fallback* stub,
-                     HandleValue key, HandleObject obj, bool* attached)
-{
-    MOZ_ASSERT(!*attached);
-
-    if (!IsNativeDenseElementAccess(obj, key))
-        return true;
-
-    JitSpew(JitSpew_BaselineIC, "  Generating In(Native[Int32] dense) stub");
-    ICIn_Dense::Compiler compiler(cx, obj->as<NativeObject>().lastProperty());
-    ICStub* denseStub = compiler.getStub(compiler.getStubSpace(outerScript));
-    if (!denseStub)
-        return false;
-
-    *attached = true;
-    stub->addNewStub(denseStub);
-    return true;
-}
-
-static bool
 TryAttachNativeInStub(JSContext* cx, HandleScript outerScript, ICIn_Fallback* stub,
                       HandleValue key, HandleObject obj, bool* attached)
 {
     MOZ_ASSERT(!*attached);
 
     RootedId id(cx);
     if (!IsOptimizableElementPropertyName(cx, key, &id))
         return true;
@@ -2141,20 +2113,16 @@ DoInFallback(JSContext* cx, BaselineFram
 
     if (attached)
         return true;
 
     if (obj->isNative()) {
         RootedScript script(cx, frame->script());
         bool attached = false;
         if (cond) {
-            if (!TryAttachDenseInStub(cx, script, stub, key, obj, &attached))
-                return false;
-            if (attached)
-                return true;
             if (!TryAttachNativeInStub(cx, script, stub, key, obj, &attached))
                 return false;
             if (attached)
                 return true;
         } else {
             if (!TryAttachNativeInDoesNotExistStub(cx, script, stub, key, obj, &attached))
                 return false;
             if (attached)
@@ -2321,57 +2289,16 @@ ICInNativeDoesNotExistCompiler::generate
 
     masm.bind(&failurePopR0Scratch);
     masm.pop(R0.scratchReg());
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
 }
 
-bool
-ICIn_Dense::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-
-    masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
-    masm.branchTestObject(Assembler::NotEqual, R1, &failure);
-
-    AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
-    Register scratch = regs.takeAny();
-
-    // Unbox and shape guard object.
-    Register obj = masm.extractObject(R1, ExtractTemp0);
-    masm.loadPtr(Address(ICStubReg, ICIn_Dense::offsetOfShape()), scratch);
-    masm.branchTestObjShape(Assembler::NotEqual, obj, scratch, &failure);
-
-    // Load obj->elements.
-    masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch);
-
-    // Unbox key and bounds check.
-    Address initLength(scratch, ObjectElements::offsetOfInitializedLength());
-    Register key = masm.extractInt32(R0, ExtractTemp0);
-    masm.branch32(Assembler::BelowOrEqual, initLength, key, &failure);
-
-    // Hole check.
-    JS_STATIC_ASSERT(sizeof(Value) == 8);
-    BaseIndex element(scratch, key, TimesEight);
-    masm.branchTestMagic(Assembler::Equal, element, &failure);
-
-    masm.moveValue(BooleanValue(true), R0);
-
-    EmitReturnFromIC(masm);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
 static bool
 DoGetNameFallback(JSContext* cx, BaselineFrame* frame, ICGetName_Fallback* stub_,
                   HandleObject envChain, MutableHandleValue res)
 {
     SharedStubInfo info(cx, frame, stub_->icEntry());
 
     // This fallback stub may trigger debug mode toggling.
     DebugModeOSRVolatileStub<ICGetName_Fallback*> stub(frame, stub_);
@@ -5972,21 +5899,16 @@ ICInNativeDoesNotExistCompiler::ICInNati
   : ICStubCompiler(cx, ICStub::In_NativeDoesNotExist, Engine::Baseline),
     obj_(cx, obj),
     name_(cx, name),
     protoChainDepth_(protoChainDepth)
 {
     MOZ_ASSERT(protoChainDepth_ <= ICIn_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH);
 }
 
-ICIn_Dense::ICIn_Dense(JitCode* stubCode, HandleShape shape)
-  : ICStub(In_Dense, stubCode),
-    shape_(shape)
-{ }
-
 
 ICGetIntrinsic_Constant::ICGetIntrinsic_Constant(JitCode* stubCode, const Value& value)
   : ICStub(GetIntrinsic_Constant, stubCode),
     value_(value)
 { }
 
 ICGetIntrinsic_Constant::~ICGetIntrinsic_Constant()
 { }
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -894,50 +894,16 @@ class ICInNativeDoesNotExistCompiler : p
     template <size_t ProtoChainDepth>
     ICStub* getStubSpecific(ICStubSpace* space, Handle<ShapeVector> shapes) {
         return newStub<ICIn_NativeDoesNotExistImpl<ProtoChainDepth>>(space, getStubCode(), shapes,
                                                                      name_);}
 
     ICStub* getStub(ICStubSpace* space);
 };
 
-class ICIn_Dense : public ICStub
-{
-    friend class ICStubSpace;
-
-    GCPtrShape shape_;
-
-    ICIn_Dense(JitCode* stubCode, HandleShape shape);
-
-  public:
-    GCPtrShape& shape() {
-        return shape_;
-    }
-    static size_t offsetOfShape() {
-        return offsetof(ICIn_Dense, shape_);
-    }
-
-    class Compiler : public ICStubCompiler {
-      RootedShape shape_;
-
-      protected:
-        MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm);
-
-      public:
-        Compiler(JSContext* cx, Shape* shape)
-          : ICStubCompiler(cx, ICStub::In_Dense, Engine::Baseline),
-            shape_(cx, shape)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            return newStub<ICIn_Dense>(space, getStubCode(), shape_);
-        }
-    };
-};
-
 // GetName
 //      JSOP_GETNAME
 //      JSOP_GETGNAME
 class ICGetName_Fallback : public ICMonitoredFallbackStub
 {
     friend class ICStubSpace;
 
     explicit ICGetName_Fallback(JitCode* stubCode)
--- a/js/src/jit/BaselineICList.h
+++ b/js/src/jit/BaselineICList.h
@@ -54,17 +54,16 @@ namespace jit {
     _(SetElem_DenseOrUnboxedArray)               \
     _(SetElem_DenseOrUnboxedArrayAdd)            \
     _(SetElem_TypedArray)                        \
                                                  \
     _(In_Fallback)                               \
     _(In_Native)                                 \
     _(In_NativePrototype)                        \
     _(In_NativeDoesNotExist)                     \
-    _(In_Dense)                                  \
                                                  \
     _(GetName_Fallback)                          \
                                                  \
     _(BindName_Fallback)                         \
                                                  \
     _(GetIntrinsic_Fallback)                     \
     _(GetIntrinsic_Constant)                     \
                                                  \
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -1539,27 +1539,59 @@ GetNameIRGenerator::tryAttachEnvironment
         size_t dynamicSlotOffset = holder->dynamicSlotIndex(shape->slot()) * sizeof(Value);
         writer.loadEnvironmentDynamicSlotResult(lastObjId, dynamicSlotOffset);
     }
 
     writer.typeMonitorResult();
     return true;
 }
 
+static bool
+IsNativeDenseElementAccess(HandleObject obj, HandleValue key)
+{
+    if (obj->isNative() && key.isInt32() && key.toInt32() >= 0 && !obj->is<TypedArrayObject>())
+        return true;
+    return false;
+}
+
 InIRGenerator::InIRGenerator(JSContext* cx, jsbytecode* pc,
                              HandleValue key, HandleObject obj)
   : IRGenerator(cx, pc, CacheKind::In),
     key_(key), obj_(obj)
 { }
 
 bool
+InIRGenerator::tryAttachDenseIn(HandleValue key, ValOperandId keyId,
+                                HandleObject obj, ObjOperandId objId)
+{
+    if (!IsNativeDenseElementAccess(obj, key))
+        return false;
+
+    Int32OperandId indexId = writer.guardIsInt32Index(keyId);
+
+    writer.guardShape(objId, obj->as<NativeObject>().lastProperty());
+    writer.loadDenseElementExistsResult(objId, indexId);
+    writer.returnFromIC();
+    return true;
+}
+
+bool
 InIRGenerator::tryAttachStub()
 {
     MOZ_ASSERT(cacheKind_ == CacheKind::In);
 
+    AutoAssertNoPendingException aanpe(cx_);
+
+    ValOperandId keyId(writer.setInputOperandId(0));
+    ValOperandId valId(writer.setInputOperandId(1));
+    ObjOperandId objId = writer.guardIsObject(valId);
+
+    if (tryAttachDenseIn(key_, keyId, obj_, objId))
+        return true;
+
     return false;
 }
 
 bool
 IRGenerator::maybeGuardInt32Index(const Value& index, ValOperandId indexId,
                                   uint32_t* int32Index, Int32OperandId* int32IndexId)
 {
     if (index.isNumber()) {
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -963,16 +963,19 @@ class MOZ_RAII SetPropIRGenerator : publ
 };
 
 // InIRGenerator generates CacheIR for a In IC.
 class MOZ_RAII InIRGenerator : public IRGenerator
 {
     HandleValue key_;
     HandleObject obj_;
 
+    bool tryAttachDenseIn(HandleValue key, ValOperandId keyId,
+                          HandleObject obj, ObjOperandId objId);
+
   public:
     InIRGenerator(JSContext* cx, jsbytecode* pc,
                   HandleValue key, HandleObject obj);
 
     bool tryAttachStub();
 };
 
 } // namespace jit
--- a/js/src/jit/SharedIC.cpp
+++ b/js/src/jit/SharedIC.cpp
@@ -341,21 +341,16 @@ ICStub::trace(JSTracer* trc)
           case 5: inStub->toImpl<5>()->traceShapes(trc); break;
           case 6: inStub->toImpl<6>()->traceShapes(trc); break;
           case 7: inStub->toImpl<7>()->traceShapes(trc); break;
           case 8: inStub->toImpl<8>()->traceShapes(trc); break;
           default: MOZ_CRASH("Invalid proto stub.");
         }
         break;
       }
-      case ICStub::In_Dense: {
-        ICIn_Dense* inStub = toIn_Dense();
-        TraceEdge(trc, &inStub->shape(), "baseline-in-dense-shape");
-        break;
-      }
       case ICStub::GetIntrinsic_Constant: {
         ICGetIntrinsic_Constant* constantStub = toGetIntrinsic_Constant();
         TraceEdge(trc, &constantStub->value(), "baseline-getintrinsic-constant-value");
         break;
       }
       case ICStub::SetProp_NativeAdd: {
         ICSetProp_NativeAdd* propStub = toSetProp_NativeAdd();
         TraceEdge(trc, &propStub->group(), "baseline-setpropnativeadd-stub-group");