Title: [184540] trunk/Source/_javascript_Core
Revision
184540
Author
[email protected]
Date
2015-05-18 19:30:00 -0700 (Mon, 18 May 2015)

Log Message

Add SpecBoolInt32 type that means "I'm an int and I'm either 0 or 1"
https://bugs.webkit.org/show_bug.cgi?id=145137

Reviewed by Benjamin Poulain.
        
It's super useful to know if an integer value could be either zero or one. We have an
immediate need for this because of Int32|Boolean uses, where knowing that the Int32 is
either 0 or 1 means that there is no actual polymorphism if you just look at the low bit
(1 behaves like true, 0 behaves like false, and the low bit of 1|true is 1, and the low
bit of 0|false is 0).
        
We do this by splitting the SpecInt32 type into SpecBoolInt32 and SpecNonBoolInt32. This
change doesn't have any effect on behavior, yet. But it does give us the ability to
predict and prove when values are SpecBoolInt32; it's just we don't leverage this yet.
        
This is perf-neutral.

* bytecode/SpeculatedType.cpp:
(JSC::dumpSpeculation):
(JSC::speculationToAbbreviatedString):
(JSC::speculationFromValue):
* bytecode/SpeculatedType.h:
(JSC::isStringOrStringObjectSpeculation):
(JSC::isBoolInt32Speculation):
(JSC::isInt32Speculation):
(JSC::isInt32OrBooleanSpeculation):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (184539 => 184540)


--- trunk/Source/_javascript_Core/ChangeLog	2015-05-19 02:02:10 UTC (rev 184539)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-05-19 02:30:00 UTC (rev 184540)
@@ -1,3 +1,34 @@
+2015-05-18  Filip Pizlo  <[email protected]>
+
+        Add SpecBoolInt32 type that means "I'm an int and I'm either 0 or 1"
+        https://bugs.webkit.org/show_bug.cgi?id=145137
+
+        Reviewed by Benjamin Poulain.
+        
+        It's super useful to know if an integer value could be either zero or one. We have an
+        immediate need for this because of Int32|Boolean uses, where knowing that the Int32 is
+        either 0 or 1 means that there is no actual polymorphism if you just look at the low bit
+        (1 behaves like true, 0 behaves like false, and the low bit of 1|true is 1, and the low
+        bit of 0|false is 0).
+        
+        We do this by splitting the SpecInt32 type into SpecBoolInt32 and SpecNonBoolInt32. This
+        change doesn't have any effect on behavior, yet. But it does give us the ability to
+        predict and prove when values are SpecBoolInt32; it's just we don't leverage this yet.
+        
+        This is perf-neutral.
+
+        * bytecode/SpeculatedType.cpp:
+        (JSC::dumpSpeculation):
+        (JSC::speculationToAbbreviatedString):
+        (JSC::speculationFromValue):
+        * bytecode/SpeculatedType.h:
+        (JSC::isStringOrStringObjectSpeculation):
+        (JSC::isBoolInt32Speculation):
+        (JSC::isInt32Speculation):
+        (JSC::isInt32OrBooleanSpeculation):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+
 2015-05-18  Michael Catanzaro  <[email protected]>
 
         [CMake] Ignore warnings in system headers

Modified: trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp (184539 => 184540)


--- trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp	2015-05-19 02:02:10 UTC (rev 184539)
+++ trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp	2015-05-19 02:30:00 UTC (rev 184540)
@@ -163,10 +163,19 @@
             isTop = false;
     }
     
-    if (value & SpecInt32)
+    if (value == SpecInt32)
         myOut.print("Int32");
-    else
-        isTop = false;
+    else {
+        if (value & SpecBoolInt32)
+            myOut.print("Boolint32");
+        else
+            isTop = false;
+        
+        if (value & SpecNonBoolInt32)
+            myOut.print("Nonboolint32");
+        else
+            isTop = false;
+    }
     
     if (value & SpecInt52)
         myOut.print("Int52");
@@ -254,6 +263,8 @@
         return "<Object>";
     if (isCellSpeculation(prediction))
         return "<Cell>";
+    if (isBoolInt32Speculation(prediction))
+        return "<BoolInt32>";
     if (isInt32Speculation(prediction))
         return "<Int32>";
     if (isInt52AsDoubleSpeculation(prediction))
@@ -363,8 +374,11 @@
 {
     if (value.isEmpty())
         return SpecEmpty;
-    if (value.isInt32())
-        return SpecInt32;
+    if (value.isInt32()) {
+        if (value.asInt32() & ~1)
+            return SpecNonBoolInt32;
+        return SpecBoolInt32;
+    }
     if (value.isDouble()) {
         double number = value.asNumber();
         if (number != number)

Modified: trunk/Source/_javascript_Core/bytecode/SpeculatedType.h (184539 => 184540)


--- trunk/Source/_javascript_Core/bytecode/SpeculatedType.h	2015-05-19 02:02:10 UTC (rev 184539)
+++ trunk/Source/_javascript_Core/bytecode/SpeculatedType.h	2015-05-19 02:30:00 UTC (rev 184540)
@@ -63,11 +63,13 @@
 static const SpeculatedType SpecSymbol             = 0x00040000; // It's definitely a Symbol.
 static const SpeculatedType SpecCellOther          = 0x00080000; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString or a Symbol. FIXME: This shouldn't be part of heap-top or bytecode-top. https://bugs.webkit.org/show_bug.cgi?id=133078
 static const SpeculatedType SpecCell               = 0x000fffff; // It's definitely a JSCell.
-static const SpeculatedType SpecInt32              = 0x00200000; // It's definitely an Int32.
+static const SpeculatedType SpecBoolInt32          = 0x00100000; // It's definitely an Int32 with value 0 or 1.
+static const SpeculatedType SpecNonBoolInt32       = 0x00200000; // It's definitely an Int32 with value other than 0 or 1.
+static const SpeculatedType SpecInt32              = 0x00300000; // It's definitely an Int32.
 static const SpeculatedType SpecInt52              = 0x00400000; // It's definitely an Int52 and we intend it to unbox it.
-static const SpeculatedType SpecMachineInt         = 0x00600000; // It's something that we can do machine int arithmetic on.
+static const SpeculatedType SpecMachineInt         = 0x00700000; // It's something that we can do machine int arithmetic on.
 static const SpeculatedType SpecInt52AsDouble      = 0x00800000; // It's definitely an Int52 and it's inside a double.
-static const SpeculatedType SpecInteger            = 0x00e00000; // It's definitely some kind of integer.
+static const SpeculatedType SpecInteger            = 0x00f00000; // It's definitely some kind of integer.
 static const SpeculatedType SpecNonIntAsDouble     = 0x01000000; // It's definitely not an Int52 but it's a real number and it's a double.
 static const SpeculatedType SpecDoubleReal         = 0x01800000; // It's definitely a non-NaN double.
 static const SpeculatedType SpecDoublePureNaN      = 0x02000000; // It's definitely a NaN that is sae to tag (i.e. pure).
@@ -75,10 +77,10 @@
 static const SpeculatedType SpecDoubleNaN          = 0x06000000; // It's definitely some kind of NaN.
 static const SpeculatedType SpecBytecodeDouble     = 0x03800000; // It's either a non-NaN or a NaN double, but it's definitely not impure NaN.
 static const SpeculatedType SpecFullDouble         = 0x07800000; // It's either a non-NaN or a NaN double.
-static const SpeculatedType SpecBytecodeRealNumber = 0x01a00000; // It's either an Int32 or a DoubleReal.
-static const SpeculatedType SpecFullRealNumber     = 0x01e00000; // It's either an Int32 or a DoubleReal, or a Int52.
-static const SpeculatedType SpecBytecodeNumber     = 0x03a00000; // It's either an Int32 or a Double, and the Double cannot be an impure NaN.
-static const SpeculatedType SpecFullNumber         = 0x07e00000; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN.
+static const SpeculatedType SpecBytecodeRealNumber = 0x01b00000; // It's either an Int32 or a DoubleReal.
+static const SpeculatedType SpecFullRealNumber     = 0x01f00000; // It's either an Int32 or a DoubleReal, or a Int52.
+static const SpeculatedType SpecBytecodeNumber     = 0x03b00000; // It's either an Int32 or a Double, and the Double cannot be an impure NaN.
+static const SpeculatedType SpecFullNumber         = 0x07f00000; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN.
 static const SpeculatedType SpecBoolean            = 0x10000000; // It's definitely a Boolean.
 static const SpeculatedType SpecOther              = 0x20000000; // It's definitely either Null or Undefined.
 static const SpeculatedType SpecMisc               = 0x30000000; // It's definitely either a boolean, Null, or Undefined.
@@ -262,9 +264,14 @@
     return !!value && !(value & ~(SpecString | SpecStringObject));
 }
 
+inline bool isBoolInt32Speculation(SpeculatedType value)
+{
+    return value == SpecBoolInt32;
+}
+
 inline bool isInt32Speculation(SpeculatedType value)
 {
-    return value == SpecInt32;
+    return value && !(value & ~SpecInt32);
 }
 
 inline bool isInt32OrBooleanSpeculation(SpeculatedType value)

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (184539 => 184540)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2015-05-19 02:02:10 UTC (rev 184539)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2015-05-19 02:30:00 UTC (rev 184540)
@@ -257,6 +257,14 @@
             }
             break;
         }
+        
+        if (node->op() == BitAnd
+            && (isBoolInt32Speculation(forNode(node->child1()).m_type) ||
+                isBoolInt32Speculation(forNode(node->child2()).m_type))) {
+            forNode(node).setType(SpecBoolInt32);
+            break;
+        }
+        
         forNode(node).setType(SpecInt32);
         break;
     }
@@ -297,7 +305,7 @@
         if (node->child1().useKind() == UntypedUse && !(value.m_type & ~SpecBoolean))
             m_state.setFoundConstants(true);
         if (value.m_type & SpecBoolean) {
-            value.merge(SpecInt32);
+            value.merge(SpecBoolInt32);
             value.filter(~SpecBoolean);
         }
         break;
@@ -337,6 +345,11 @@
             }
         }
         
+        if (isBooleanSpeculation(forNode(node->child1()).m_type)) {
+            forNode(node).setType(SpecBoolInt32);
+            break;
+        }
+        
         forNode(node).setType(SpecInt32);
         break;
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to