Bug 1341261: [Part 2] Implement GuardTagNotEqual r=tcampbell
authorMatthew Gaudet <mgaudet@mozilla.com>
Thu, 22 Feb 2018 13:19:21 -0500
changeset 761246 74bdd1f7a2f17d86b5d6176c5718c2ac8cfe5f8d
parent 761245 38f4d206e39e67ade4764f3bff55d45962e62e64
child 761247 591a2c93a43e59ef7cf6d5fe86268a1e8315f1f1
push id100926
push userrwood@mozilla.com
push dateWed, 28 Feb 2018 21:51:29 +0000
reviewerstcampbell
bugs1341261
milestone60.0a1
Bug 1341261: [Part 2] Implement GuardTagNotEqual r=tcampbell Does a tag compare on two types; fails for number tags
js/src/jit/CacheIR.h
js/src/jit/CacheIRCompiler.cpp
js/src/jit/CacheIRCompiler.h
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -204,16 +204,17 @@ extern const char* CacheKindNames[];
     _(GuardNoDenseElements)               \
     _(GuardNoUnboxedExpando)              \
     _(GuardAndLoadUnboxedExpando)         \
     _(GuardAndGetIndexFromString)         \
     _(GuardAndGetIterator)                \
     _(GuardHasGetterSetter)               \
     _(GuardGroupHasUnanalyzedNewScript)   \
     _(GuardIndexIsNonNegative)            \
+    _(GuardTagNotEqual)                   \
     _(GuardXrayExpandoShapeAndDefaultProto) \
     _(GuardFunctionPrototype)             \
     _(LoadStackValue)                     \
     _(LoadObject)                         \
     _(LoadProto)                          \
     _(LoadEnclosingEnvironment)           \
     _(LoadWrapperTarget)                  \
     _(LoadValueTag)                       \
@@ -699,16 +700,20 @@ class MOZ_RAII CacheIRWriter : public JS
     void guardGroupHasUnanalyzedNewScript(ObjectGroup* group) {
         writeOp(CacheOp::GuardGroupHasUnanalyzedNewScript);
         addStubField(uintptr_t(group), StubField::Type::ObjectGroup);
     }
 
     void guardIndexIsNonNegative(Int32OperandId index) {
         writeOpWithOperandId(CacheOp::GuardIndexIsNonNegative, index);
     }
+    void guardTagNotEqual(ValueTagOperandId lhs, ValueTagOperandId rhs) {
+        writeOpWithOperandId(CacheOp::GuardTagNotEqual, lhs);
+        writeOperandId(rhs);
+    }
 
     void loadFrameCalleeResult() {
         writeOp(CacheOp::LoadFrameCalleeResult);
     }
     void loadFrameNumActualArgsResult() {
         writeOp(CacheOp::LoadFrameNumActualArgsResult);
     }
     void loadFrameArgumentResult(Int32OperandId index) {
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -1983,16 +1983,38 @@ CacheIRCompiler::emitGuardIndexIsNonNega
     if (!addFailurePath(&failure))
         return false;
 
     masm.branch32(Assembler::LessThan, index, Imm32(0), failure->label());
     return true;
 }
 
 bool
+CacheIRCompiler::emitGuardTagNotEqual()
+{
+    Register lhs = allocator.useRegister(masm, reader.valueTagOperandId());
+    Register rhs = allocator.useRegister(masm, reader.valueTagOperandId());
+
+    FailurePath* failure;
+    if (!addFailurePath(&failure))
+        return false;
+
+    Label done;
+    masm.branch32(Assembler::Equal, lhs, rhs, failure->label());
+
+    // If both lhs and rhs are numbers, can't use tag comparison to do inequality comparison
+    masm.branchTestNumber(Assembler::NotEqual, lhs, &done);
+    masm.branchTestNumber(Assembler::NotEqual, rhs, &done);
+    masm.jump(failure->label());
+
+    masm.bind(&done);
+    return true;
+}
+
+bool
 CacheIRCompiler::emitLoadDenseElementHoleResult()
 {
     AutoOutputRegister output(*this);
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     Register index = allocator.useRegister(masm, reader.int32OperandId());
     AutoScratchRegister scratch1(allocator, masm);
     AutoScratchRegisterMaybeOutput scratch2(allocator, masm, output);
 
--- a/js/src/jit/CacheIRCompiler.h
+++ b/js/src/jit/CacheIRCompiler.h
@@ -31,16 +31,17 @@ namespace jit {
     _(GuardSpecificInt32Immediate)        \
     _(GuardMagicValue)                    \
     _(GuardNoUnboxedExpando)              \
     _(GuardAndLoadUnboxedExpando)         \
     _(GuardNoDetachedTypedObjects)        \
     _(GuardNoDenseElements)               \
     _(GuardAndGetIndexFromString)         \
     _(GuardIndexIsNonNegative)            \
+    _(GuardTagNotEqual)                   \
     _(LoadProto)                          \
     _(LoadEnclosingEnvironment)           \
     _(LoadWrapperTarget)                  \
     _(LoadValueTag)                       \
     _(LoadDOMExpandoValue)                \
     _(LoadDOMExpandoValueIgnoreGeneration)\
     _(LoadUndefinedResult)                \
     _(LoadBooleanResult)                  \