Bug 1341087 - Implement bitwise symbol equality comparison in Ion. r=h4writer
authorTom Schuster <evilpies@gmail.com>
Tue, 21 Feb 2017 14:24:10 +0100
changeset 343976 f0e0d480f660c02bdd40c3d26a635a51fe03de75
parent 343975 2a9f1f1516ec266eb29fc7bc268b5805dd42437c
child 343977 1de8a2485e15aed6455d399680dc18846b65e4e1
push id87237
push userevilpies@gmail.com
push dateTue, 21 Feb 2017 13:24:28 +0000
treeherdermozilla-inbound@1de8a2485e15 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersh4writer
bugs1341087
milestone54.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 1341087 - Implement bitwise symbol equality comparison in Ion. r=h4writer
js/src/jit-test/tests/symbol-equality.js
js/src/jit/IonBuilder.cpp
--- a/js/src/jit-test/tests/symbol-equality.js
+++ b/js/src/jit-test/tests/symbol-equality.js
@@ -14,10 +14,28 @@ function simpleEquality() {
 function equalOperands() {
     for (var i = 0; i < 150; i++) {
         var x = Symbol();
         assertEq(x === x, true);
         assertEq(x !== x, false);
     }
 }
 
+function bitwiseCompare() {
+    var ar = [true, false, Symbol(), null, undefined];
+    var s = Symbol();
+    ar.push(s);
+
+    for (var i = 0; i < 150; i++) {
+        for (var j = 0; j < ar.length; j++) {
+            var equal = (j == ar.indexOf(s));
+
+            assertEq(ar[j] === s, equal);
+            assertEq(ar[j] !== s, !equal);
+            assertEq(ar[j] == s, equal);
+            assertEq(ar[j] != s, !equal);
+        }
+    }
+}
+
 equalOperands();
 simpleEquality();
+bitwiseCompare();
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -5529,19 +5529,18 @@ IonBuilder::jsop_compare(JSOp op, MDefin
 
     trackOptimizationSuccess();
     return Ok();
 }
 
 static bool
 ObjectOrSimplePrimitive(MDefinition* op)
 {
-    // Return true if op is either undefined/null/boolean/int32 or an object.
+    // Return true if op is either undefined/null/boolean/int32/symbol or an object.
     return !op->mightBeType(MIRType::String)
-        && !op->mightBeType(MIRType::Symbol)
         && !op->mightBeType(MIRType::Double)
         && !op->mightBeType(MIRType::Float32)
         && !op->mightBeType(MIRType::MagicOptimizedArguments)
         && !op->mightBeType(MIRType::MagicHole)
         && !op->mightBeType(MIRType::MagicIsConstructing);
 }
 
 AbortReasonOr<Ok>
@@ -5590,24 +5589,24 @@ AbortReasonOr<Ok>
 IonBuilder::compareTryBitwise(bool* emitted, JSOp op, MDefinition* left, MDefinition* right)
 {
     MOZ_ASSERT(*emitted == false);
     trackOptimizationAttempt(TrackedStrategy::Compare_Bitwise);
 
     // Try to emit a bitwise compare. Check if a bitwise compare equals the wanted
     // result for all observed operand types.
 
-    // Onlye allow loose and strict equality.
+    // Only allow loose and strict equality.
     if (op != JSOP_EQ && op != JSOP_NE && op != JSOP_STRICTEQ && op != JSOP_STRICTNE) {
         trackOptimizationOutcome(TrackedOutcome::RelationalCompare);
         return Ok();
     }
 
     // Only primitive (not double/string) or objects are supported.
-    // I.e. Undefined/Null/Boolean/Int32 and Object
+    // I.e. Undefined/Null/Boolean/Int32/Symbol and Object
     if (!ObjectOrSimplePrimitive(left) || !ObjectOrSimplePrimitive(right)) {
         trackOptimizationOutcome(TrackedOutcome::OperandTypeNotBitwiseComparable);
         return Ok();
     }
 
     // Objects that emulate undefined are not supported.
     if (left->maybeEmulatesUndefined(constraints()) ||
         right->maybeEmulatesUndefined(constraints()))
@@ -5633,20 +5632,24 @@ IonBuilder::compareTryBitwise(bool* emit
         // because tag is different, but value can be the same (1 == true).
         if ((left->mightBeType(MIRType::Int32) && right->mightBeType(MIRType::Boolean)) ||
             (left->mightBeType(MIRType::Boolean) && right->mightBeType(MIRType::Int32)))
         {
             trackOptimizationOutcome(TrackedOutcome::LoosyInt32BooleanCompare);
             return Ok();
         }
 
-        // For loosy comparison of an object with a Boolean/Number/String
+        // For loosy comparison of an object with a Boolean/Number/String/Symbol
         // the valueOf the object is taken. Therefore not supported.
-        bool simpleLHS = left->mightBeType(MIRType::Boolean) || left->mightBeType(MIRType::Int32);
-        bool simpleRHS = right->mightBeType(MIRType::Boolean) || right->mightBeType(MIRType::Int32);
+        bool simpleLHS = left->mightBeType(MIRType::Boolean) ||
+                         left->mightBeType(MIRType::Int32) ||
+                         left->mightBeType(MIRType::Symbol);
+        bool simpleRHS = right->mightBeType(MIRType::Boolean) ||
+                         right->mightBeType(MIRType::Int32) ||
+                         right->mightBeType(MIRType::Symbol);
         if ((left->mightBeType(MIRType::Object) && simpleRHS) ||
             (right->mightBeType(MIRType::Object) && simpleLHS))
         {
             trackOptimizationOutcome(TrackedOutcome::CallsValueOf);
             return Ok();
         }
     }