Bug 1337773 - Use IonInIC for MIn and rename to MInCache draft
authorTed Campbell <tcampbell@mozilla.com>
Mon, 17 Apr 2017 13:31:12 -0400
changeset 572076 e370015f9ad42b1e99149d510b2e9f960468e9ea
parent 572075 a20334ff0de828cc6179c7a2caa7f9434810ee53
child 626941 e30af140603deecb7197a97ae50168fe21e6afe1
push id56986
push userbmo:tcampbell@mozilla.com
push dateWed, 03 May 2017 17:38:15 +0000
bugs1337773
milestone55.0a1
Bug 1337773 - Use IonInIC for MIn and rename to MInCache MozReview-Commit-ID: 2Nl70H4MpPa
js/src/jit/CodeGenerator.cpp
js/src/jit/CodeGenerator.h
js/src/jit/IonBuilder.cpp
js/src/jit/Lowering.cpp
js/src/jit/Lowering.h
js/src/jit/MIR.h
js/src/jit/MOpcodes.h
js/src/jit/TypePolicy.cpp
js/src/jit/shared/LIR-shared.h
js/src/jit/shared/LOpcodes-shared.h
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -11201,26 +11201,28 @@ CodeGenerator::visitClampVToUint8(LClamp
     Label fails;
     masm.clampValueToUint8(operand, input,
                            stringEntry, stringRejoin,
                            output, tempFloat, output, &fails);
 
     bailoutFrom(&fails, lir->snapshot());
 }
 
-typedef bool (*OperatorInFn)(JSContext*, HandleValue, HandleObject, bool*);
-static const VMFunction OperatorInInfo = FunctionInfo<OperatorInFn>(OperatorIn, "OperatorIn");
-
-void
-CodeGenerator::visitIn(LIn* ins)
-{
-    pushArg(ToRegister(ins->rhs()));
-    pushArg(ToValue(ins, LIn::LHS));
-
-    callVM(OperatorInInfo, ins);
+void
+CodeGenerator::visitInCache(LInCache* ins)
+{
+    LiveRegisterSet liveRegs = ins->safepoint()->liveRegs();
+
+    ConstantOrRegister key = toConstantOrRegister(ins, LInCache::LHS, ins->mir()->key()->type());
+    Register object = ToRegister(ins->rhs());
+    Register output = ToRegister(ins->output());
+    Register temp = ToRegister(ins->temp());
+
+    IonInIC cache(liveRegs, key, object, output, temp);
+    addIC(ins, allocateIC(cache));
 }
 
 typedef bool (*OperatorInIFn)(JSContext*, uint32_t, HandleObject, bool*);
 static const VMFunction OperatorInIInfo = FunctionInfo<OperatorInIFn>(OperatorInI, "OperatorInI");
 
 void
 CodeGenerator::visitInArray(LInArray* lir)
 {
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -353,17 +353,17 @@ class CodeGenerator final : public CodeG
                   JSObject* templateObject, bool saveAndRestore, Register resultreg);
     void visitRest(LRest* lir);
     void visitCallSetProperty(LCallSetProperty* ins);
     void visitCallDeleteProperty(LCallDeleteProperty* lir);
     void visitCallDeleteElement(LCallDeleteElement* lir);
     void visitBitNotV(LBitNotV* lir);
     void visitBitOpV(LBitOpV* lir);
     void emitInstanceOf(LInstruction* ins, JSObject* prototypeObject);
-    void visitIn(LIn* ins);
+    void visitInCache(LInCache* ins);
     void visitInArray(LInArray* ins);
     void visitInstanceOfO(LInstanceOfO* ins);
     void visitInstanceOfV(LInstanceOfV* ins);
     void visitCallInstanceOf(LCallInstanceOf* ins);
     void visitGetDOMProperty(LGetDOMProperty* lir);
     void visitGetDOMMemberV(LGetDOMMemberV* lir);
     void visitGetDOMMemberT(LGetDOMMemberT* lir);
     void visitSetDOMProperty(LSetDOMProperty* lir);
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -12595,27 +12595,29 @@ IonBuilder::jsop_setaliasedvar(Environme
 }
 
 AbortReasonOr<Ok>
 IonBuilder::jsop_in()
 {
     MDefinition* obj = convertUnboxedObjects(current->pop());
     MDefinition* id = current->pop();
 
-    bool emitted = false;
-
-    MOZ_TRY(inTryDense(&emitted, obj, id));
-    if (emitted)
-        return Ok();
-
-    MOZ_TRY(hasTryNotDefined(&emitted, obj, id, /* ownProperty = */ false));
-    if (emitted)
-        return Ok();
-
-    MIn* ins = MIn::New(alloc(), id, obj);
+    if (!forceInlineCaches()) {
+        bool emitted = false;
+
+        MOZ_TRY(inTryDense(&emitted, obj, id));
+        if (emitted)
+            return Ok();
+
+        MOZ_TRY(hasTryNotDefined(&emitted, obj, id, /* ownProperty = */ false));
+        if (emitted)
+            return Ok();
+    }
+
+    MInCache* ins = MInCache::New(alloc(), id, obj);
 
     current->add(ins);
     current->push(ins);
 
     return resumeAfter(ins);
 }
 
 AbortReasonOr<Ok>
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -4181,26 +4181,29 @@ LIRGenerator::visitThrow(MThrow* ins)
     MOZ_ASSERT(value->type() == MIRType::Value);
 
     LThrow* lir = new(alloc()) LThrow(useBoxAtStart(value));
     add(lir, ins);
     assignSafepoint(lir, ins);
 }
 
 void
-LIRGenerator::visitIn(MIn* ins)
+LIRGenerator::visitInCache(MInCache* ins)
 {
     MDefinition* lhs = ins->lhs();
     MDefinition* rhs = ins->rhs();
 
-    MOZ_ASSERT(lhs->type() == MIRType::Value);
+    MOZ_ASSERT(lhs->type() == MIRType::String ||
+               lhs->type() == MIRType::Symbol ||
+               lhs->type() == MIRType::Int32 ||
+               lhs->type() == MIRType::Value);
     MOZ_ASSERT(rhs->type() == MIRType::Object);
 
-    LIn* lir = new(alloc()) LIn(useBoxAtStart(lhs), useRegisterAtStart(rhs));
-    defineReturn(lir, ins);
+    LInCache* lir = new(alloc()) LInCache(useBoxOrTyped(lhs), useRegister(rhs), temp());
+    define(lir, ins);
     assignSafepoint(lir, ins);
 }
 
 void
 LIRGenerator::visitHasOwnCache(MHasOwnCache* ins)
 {
     MDefinition* value = ins->value();
     MOZ_ASSERT(value->type() == MIRType::Object || value->type() == MIRType::Value);
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -281,17 +281,17 @@ class LIRGenerator : public LIRGenerator
     void visitIteratorEnd(MIteratorEnd* ins);
     void visitStringLength(MStringLength* ins);
     void visitArgumentsLength(MArgumentsLength* ins);
     void visitGetFrameArgument(MGetFrameArgument* ins);
     void visitSetFrameArgument(MSetFrameArgument* ins);
     void visitRunOncePrologue(MRunOncePrologue* ins);
     void visitRest(MRest* ins);
     void visitThrow(MThrow* ins);
-    void visitIn(MIn* ins);
+    void visitInCache(MInCache* ins);
     void visitInArray(MInArray* ins);
     void visitHasOwnCache(MHasOwnCache* ins);
     void visitInstanceOf(MInstanceOf* ins);
     void visitCallInstanceOf(MCallInstanceOf* ins);
     void visitIsCallable(MIsCallable* ins);
     void visitIsConstructor(MIsConstructor* ins);
     void visitIsObject(MIsObject* ins);
     void visitHasClass(MHasClass* ins);
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -12484,34 +12484,31 @@ class MIteratorEnd
 
   public:
     INSTRUCTION_HEADER(IteratorEnd)
     TRIVIAL_NEW_WRAPPERS
     NAMED_OPERANDS((0, iterator))
 
 };
 
-// Implementation for 'in' operator.
-class MIn
+// Implementation for 'in' operator using instruction cache
+class MInCache
   : public MBinaryInstruction,
-    public MixPolicy<BoxPolicy<0>, ObjectPolicy<1> >::Data
-{
-    MIn(MDefinition* key, MDefinition* obj)
+    public MixPolicy<CacheIdPolicy<0>, ObjectPolicy<1> >::Data
+{
+    MInCache(MDefinition* key, MDefinition* obj)
       : MBinaryInstruction(key, obj)
     {
         setResultType(MIRType::Boolean);
     }
 
   public:
-    INSTRUCTION_HEADER(In)
-    TRIVIAL_NEW_WRAPPERS
-
-    bool possiblyCalls() const override {
-        return true;
-    }
+    INSTRUCTION_HEADER(InCache)
+    TRIVIAL_NEW_WRAPPERS
+    NAMED_OPERANDS((0, key), (1, object))
 };
 
 
 // Test whether the index is in the array bounds or a hole.
 class MInArray
   : public MQuaternaryInstruction,
     public ObjectPolicy<3>::Data
 {
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -261,17 +261,17 @@ namespace jit {
     _(GetFrameArgument)                                                     \
     _(SetFrameArgument)                                                     \
     _(RunOncePrologue)                                                      \
     _(Rest)                                                                 \
     _(Floor)                                                                \
     _(Ceil)                                                                 \
     _(Round)                                                                \
     _(NearbyInt)                                                            \
-    _(In)                                                                   \
+    _(InCache)                                                              \
     _(HasOwnCache)                                                          \
     _(InstanceOf)                                                           \
     _(CallInstanceOf)                                                       \
     _(InterruptCheck)                                                       \
     _(GetDOMProperty)                                                       \
     _(GetDOMMember)                                                         \
     _(SetDOMProperty)                                                       \
     _(IsConstructor)                                                        \
--- a/js/src/jit/TypePolicy.cpp
+++ b/js/src/jit/TypePolicy.cpp
@@ -668,16 +668,17 @@ CacheIdPolicy<Op>::staticAdjustInputs(Te
       case MIRType::String:
       case MIRType::Symbol:
         return true;
       default:
         return BoxPolicy<Op>::staticAdjustInputs(alloc, ins);
     }
 }
 
+template bool CacheIdPolicy<0>::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins);
 template bool CacheIdPolicy<1>::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins);
 
 bool
 ToDoublePolicy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins)
 {
     MOZ_ASSERT(ins->isToDouble() || ins->isToFloat32());
 
     MDefinition* in = ins->getOperand(0);
@@ -1245,16 +1246,17 @@ FilterTypeSetPolicy::adjustInputs(TempAl
     _(Mix4Policy<SimdScalarPolicy<0>, SimdScalarPolicy<1>, SimdScalarPolicy<2>, SimdScalarPolicy<3> >) \
     _(MixPolicy<BoxPolicy<0>, ObjectPolicy<1> >)                        \
     _(MixPolicy<ConvertToStringPolicy<0>, ConvertToStringPolicy<1> >)   \
     _(MixPolicy<ConvertToStringPolicy<0>, ObjectPolicy<1> >)            \
     _(MixPolicy<DoublePolicy<0>, DoublePolicy<1> >)                     \
     _(MixPolicy<IntPolicy<0>, IntPolicy<1> >)                           \
     _(MixPolicy<ObjectPolicy<0>, BoxPolicy<1> >)                        \
     _(MixPolicy<BoxExceptPolicy<0, MIRType::Object>, CacheIdPolicy<1>>) \
+    _(MixPolicy<CacheIdPolicy<0>, ObjectPolicy<1> >)                    \
     _(MixPolicy<ObjectPolicy<0>, ConvertToStringPolicy<1> >)            \
     _(MixPolicy<ObjectPolicy<0>, IntPolicy<1> >)                        \
     _(MixPolicy<ObjectPolicy<0>, IntPolicy<2> >)                        \
     _(MixPolicy<ObjectPolicy<0>, NoFloatPolicy<1> >)                    \
     _(MixPolicy<ObjectPolicy<0>, NoFloatPolicy<2> >)                    \
     _(MixPolicy<ObjectPolicy<0>, NoFloatPolicy<3> >)                    \
     _(MixPolicy<ObjectPolicy<0>, ObjectPolicy<1> >)                     \
     _(MixPolicy<ObjectPolicy<0>, StringPolicy<1> >)                     \
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -7848,31 +7848,38 @@ class LGuardSharedTypedArray : public LI
     const MGuardSharedTypedArray* mir() const {
         return mir_->toGuardSharedTypedArray();
     }
     const LDefinition* tempInt() {
         return getTemp(0);
     }
 };
 
-class LIn : public LCallInstructionHelper<1, BOX_PIECES+1, 0>
-{
-  public:
-    LIR_HEADER(In)
-    LIn(const LBoxAllocation& lhs, const LAllocation& rhs) {
+class LInCache : public LInstructionHelper<1, BOX_PIECES+1, 1>
+{
+  public:
+    LIR_HEADER(InCache)
+    LInCache(const LBoxAllocation& lhs, const LAllocation& rhs, const LDefinition& temp) {
         setBoxOperand(LHS, lhs);
         setOperand(RHS, rhs);
+        setTemp(0, temp);
     }
 
     const LAllocation* lhs() {
         return getOperand(LHS);
     }
     const LAllocation* rhs() {
         return getOperand(RHS);
     }
+    const LDefinition* temp() {
+        return getTemp(0);
+    }
+    const MInCache* mir() const {
+        return mir_->toInCache();
+    }
 
     static const size_t LHS = 0;
     static const size_t RHS = BOX_PIECES;
 };
 
 class LHasOwnCache : public LInstructionHelper<1, 2 * BOX_PIECES, 0>
 {
   public:
--- a/js/src/jit/shared/LOpcodes-shared.h
+++ b/js/src/jit/shared/LOpcodes-shared.h
@@ -370,17 +370,17 @@
     _(Floor)                        \
     _(FloorF)                       \
     _(Ceil)                         \
     _(CeilF)                        \
     _(Round)                        \
     _(RoundF)                       \
     _(NearbyInt)                    \
     _(NearbyIntF)                   \
-    _(In)                           \
+    _(InCache)                      \
     _(InArray)                      \
     _(HasOwnCache)                  \
     _(InstanceOfO)                  \
     _(InstanceOfV)                  \
     _(CallInstanceOf)               \
     _(InterruptCheck)               \
     _(Rotate)                       \
     _(RotateI64)                    \