Title: [164282] releases/WebKitGTK/webkit-2.2/Source/_javascript_Core
Revision
164282
Author
carlo...@webkit.org
Date
2014-02-18 03:39:05 -0800 (Tue, 18 Feb 2014)

Log Message

Merge r155480 - Introduce a SpecInt48 type and be more careful about what we mean by "Top" https://bugs.webkit.org/show_bug.cgi?id=121116

Reviewed by Oliver Hunt.

SpecInt48 will mean that we have something that would be a double if it was a JSValue,
but it's profitable to represent it as something other than a double.

SpecInt48AsDouble means that it has a value that could have been represented like
SpecInt48, but we're making a heuristic decision not to do it.

* bytecode/SpeculatedType.h:
(JSC::isInt48Speculation):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::::executeEffects):
(JSC::DFG::::clobberCapturedVars):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::filter):
* dfg/DFGAbstractValue.h:
(JSC::DFG::AbstractValue::makeHeapTop):
(JSC::DFG::AbstractValue::makeBytecodeTop):
(JSC::DFG::AbstractValue::isHeapTop):
(JSC::DFG::AbstractValue::heapTop):
(JSC::DFG::AbstractValue::validateType):
(JSC::DFG::AbstractValue::validate):
(JSC::DFG::AbstractValue::makeTop):
* dfg/DFGInPlaceAbstractState.cpp:
(JSC::DFG::InPlaceAbstractState::initialize):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::noticeOSREntry):
* dfg/DFGUseKind.h:
(JSC::DFG::typeFilterFor):

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/ChangeLog (164281 => 164282)


--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/ChangeLog	2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/ChangeLog	2014-02-18 11:39:05 UTC (rev 164282)
@@ -1,5 +1,40 @@
 2013-09-10  Filip Pizlo  <fpi...@apple.com>
 
+        Introduce a SpecInt48 type and be more careful about what we mean by "Top"
+        https://bugs.webkit.org/show_bug.cgi?id=121116
+
+        Reviewed by Oliver Hunt.
+        
+        SpecInt48 will mean that we have something that would be a double if it was a JSValue,
+        but it's profitable to represent it as something other than a double.
+        
+        SpecInt48AsDouble means that it has a value that could have been represented like
+        SpecInt48, but we're making a heuristic decision not to do it.
+
+        * bytecode/SpeculatedType.h:
+        (JSC::isInt48Speculation):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::::executeEffects):
+        (JSC::DFG::::clobberCapturedVars):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::filter):
+        * dfg/DFGAbstractValue.h:
+        (JSC::DFG::AbstractValue::makeHeapTop):
+        (JSC::DFG::AbstractValue::makeBytecodeTop):
+        (JSC::DFG::AbstractValue::isHeapTop):
+        (JSC::DFG::AbstractValue::heapTop):
+        (JSC::DFG::AbstractValue::validateType):
+        (JSC::DFG::AbstractValue::validate):
+        (JSC::DFG::AbstractValue::makeTop):
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::initialize):
+        * dfg/DFGJITCompiler.h:
+        (JSC::DFG::JITCompiler::noticeOSREntry):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+
+2013-09-10  Filip Pizlo  <fpi...@apple.com>
+
         SpecType should have SpecInt48AsDouble
         https://bugs.webkit.org/show_bug.cgi?id=121065
 

Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/bytecode/SpeculatedType.cpp (164281 => 164282)


--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/bytecode/SpeculatedType.cpp	2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/bytecode/SpeculatedType.cpp	2014-02-18 11:39:05 UTC (rev 164282)
@@ -166,6 +166,11 @@
         else
             isTop = false;
         
+        if (value & SpecInt48)
+            myOut.print("Int48");
+        else
+            isTop = false;
+        
         if (value & SpecNonIntAsDouble)
             myOut.print("Nonintasdouble");
         else
@@ -240,6 +245,8 @@
         return "<Int32>";
     if (isInt48AsDoubleSpeculation(prediction))
         return "<Int48AsDouble>";
+    if (isInt48Speculation(prediction))
+        return "<Int48>";
     if (isDoubleSpeculation(prediction))
         return "<Double>";
     if (isNumberSpeculation(prediction))

Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/bytecode/SpeculatedType.h (164281 => 164282)


--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/bytecode/SpeculatedType.h	2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/bytecode/SpeculatedType.h	2014-02-18 11:39:05 UTC (rev 164282)
@@ -62,19 +62,21 @@
 static const SpeculatedType SpecCellOther         = 0x00040000; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString.
 static const SpeculatedType SpecCell              = 0x0007ffff; // It's definitely a JSCell.
 static const SpeculatedType SpecInt32             = 0x00800000; // It's definitely an Int32.
-static const SpeculatedType SpecInt48AsDouble     = 0x01000000; // It's definitely an Int48 and it's inside a double.
-static const SpeculatedType SpecInteger           = 0x01800000; // It's definitely some kind of integer.
-static const SpeculatedType SpecNonIntAsDouble    = 0x02000000; // It's definitely not an Int48 but it's a real number and it's a double.
-static const SpeculatedType SpecDoubleReal        = 0x03000000; // It's definitely a non-NaN double.
-static const SpeculatedType SpecDoubleNaN         = 0x04000000; // It's definitely a NaN.
-static const SpeculatedType SpecDouble            = 0x07000000; // It's either a non-NaN or a NaN double.
-static const SpeculatedType SpecRealNumber        = 0x03800000; // It's either an Int32 or a DoubleReal.
-static const SpeculatedType SpecNumber            = 0x07800000; // It's either an Int32 or a Double.
-static const SpeculatedType SpecBoolean           = 0x08000000; // It's definitely a Boolean.
-static const SpeculatedType SpecOther             = 0x10000000; // It's definitely none of the above.
-static const SpeculatedType SpecTop               = 0x1fffffff; // It can be any of the above.
-static const SpeculatedType SpecEmpty             = 0x20000000; // It's definitely an empty value marker.
-static const SpeculatedType SpecEmptyOrTop        = 0x3fffffff; // It can be any of the above.
+static const SpeculatedType SpecInt48             = 0x01000000; // It's definitely an Int48, it's inside a double, but it doesn't need to be.
+static const SpeculatedType SpecInt48AsDouble     = 0x02000000; // It's definitely an Int48 and it's inside a double.
+static const SpeculatedType SpecInteger           = 0x03800000; // It's definitely some kind of integer.
+static const SpeculatedType SpecNonIntAsDouble    = 0x04000000; // It's definitely not an Int48 but it's a real number and it's a double.
+static const SpeculatedType SpecDoubleReal        = 0x07000000; // It's definitely a non-NaN double.
+static const SpeculatedType SpecDoubleNaN         = 0x08000000; // It's definitely a NaN.
+static const SpeculatedType SpecDouble            = 0x0f000000; // It's either a non-NaN or a NaN double.
+static const SpeculatedType SpecRealNumber        = 0x07800000; // It's either an Int32 or a DoubleReal.
+static const SpeculatedType SpecNumber            = 0x0f800000; // It's either an Int32 or a Double.
+static const SpeculatedType SpecBoolean           = 0x10000000; // It's definitely a Boolean.
+static const SpeculatedType SpecOther             = 0x20000000; // It's definitely none of the above.
+static const SpeculatedType SpecHeapTop           = 0x3fffffff; // It can be any of the above.
+static const SpeculatedType SpecEmpty             = 0x40000000; // It's definitely an empty value marker.
+static const SpeculatedType SpecBytecodeTop       = 0x7fffffff; // It can be any of the above.
+static const SpeculatedType SpecFullTop           = 0x7fffffff; // It can be any of the above plus anything the DFG chooses.
 
 typedef bool (*SpeculatedTypeChecker)(SpeculatedType);
 
@@ -245,6 +247,11 @@
     return isInt32Speculation(value & ~SpecOther);
 }
 
+inline bool isInt48Speculation(SpeculatedType value)
+{
+    return value == SpecInt48;
+}
+
 inline bool isInt48AsDoubleSpeculation(SpeculatedType value)
 {
     return value == SpecInt48AsDouble;

Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (164281 => 164282)


--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2014-02-18 11:39:05 UTC (rev 164282)
@@ -143,7 +143,7 @@
         ASSERT(m_graph.m_form == SSA);
         VariableAccessData* variable = node->variableAccessData();
         AbstractValue& value = m_state.variables().operand(variable->local());
-        ASSERT(value.isTop());
+        ASSERT(value.isHeapTop());
         FiltrationResult result =
             value.filter(typeFilterFor(useKindFor(variable->flushFormat())));
         ASSERT_UNUSED(result, result == FiltrationOK);
@@ -772,7 +772,7 @@
             break;
         case Array::Generic:
             clobberWorld(node->codeOrigin, clobberLimit);
-            forNode(node).makeTop();
+            forNode(node).makeHeapTop();
             break;
         case Array::String:
             if (node->arrayMode().isOutOfBounds()) {
@@ -787,24 +787,24 @@
                 // so we're going with TOP for now. The same thing applies to
                 // clobbering the world.
                 clobberWorld(node->codeOrigin, clobberLimit);
-                forNode(node).makeTop();
+                forNode(node).makeHeapTop();
             } else
                 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
             break;
         case Array::Arguments:
-            forNode(node).makeTop();
+            forNode(node).makeHeapTop();
             break;
         case Array::Int32:
             if (node->arrayMode().isOutOfBounds()) {
                 clobberWorld(node->codeOrigin, clobberLimit);
-                forNode(node).makeTop();
+                forNode(node).makeHeapTop();
             } else
                 forNode(node).setType(SpecInt32);
             break;
         case Array::Double:
             if (node->arrayMode().isOutOfBounds()) {
                 clobberWorld(node->codeOrigin, clobberLimit);
-                forNode(node).makeTop();
+                forNode(node).makeHeapTop();
             } else if (node->arrayMode().isSaneChain())
                 forNode(node).setType(SpecDouble);
             else
@@ -815,7 +815,7 @@
         case Array::SlowPutArrayStorage:
             if (node->arrayMode().isOutOfBounds())
                 clobberWorld(node->codeOrigin, clobberLimit);
-            forNode(node).makeTop();
+            forNode(node).makeHeapTop();
             break;
         case Array::Int8Array:
             forNode(node).setType(SpecInt32);
@@ -896,11 +896,11 @@
     case ArrayPop:
         node->setCanExit(true);
         clobberWorld(node->codeOrigin, clobberLimit);
-        forNode(node).makeTop();
+        forNode(node).makeHeapTop();
         break;
             
     case RegExpExec:
-        forNode(node).makeTop();
+        forNode(node).makeHeapTop();
         break;
 
     case RegExpTest:
@@ -983,7 +983,7 @@
         
         SpeculatedType type = source.m_type;
         if (type & ~(SpecNumber | SpecString | SpecBoolean))
-            type = (SpecTop & ~SpecCell) | SpecString;
+            type = (SpecHeapTop & ~SpecCell) | SpecString;
 
         destination.setType(type);
         if (destination.isClear())
@@ -1138,7 +1138,7 @@
         clobberWorld(node->codeOrigin, clobberLimit);
         // We currently make no guarantee about what this returns because it does not
         // speculate that the length property is actually a length.
-        forNode(node).makeTop();
+        forNode(node).makeHeapTop();
         break;
         
     case GetMyArgumentByVal:
@@ -1146,7 +1146,7 @@
         // We know that this executable does not escape its arguments, so we can optimize
         // the arguments a bit. Note that this ends up being further optimized by the
         // ArgumentsSimplificationPhase.
-        forNode(node).makeTop();
+        forNode(node).makeHeapTop();
         break;
         
     case GetMyArgumentByValSafe:
@@ -1155,7 +1155,7 @@
         // a getter. We don't speculate against this.
         clobberWorld(node->codeOrigin, clobberLimit);
         // And the result is unknown.
-        forNode(node).makeTop();
+        forNode(node).makeHeapTop();
         break;
         
     case NewFunction: {
@@ -1206,7 +1206,7 @@
         break;
 
     case GetClosureVar:
-        forNode(node).makeTop();
+        forNode(node).makeHeapTop();
         break;
             
     case PutClosureVar:
@@ -1234,7 +1234,7 @@
                     if (status.specificValue())
                         forNode(node).set(m_graph, status.specificValue());
                     else
-                        forNode(node).makeTop();
+                        forNode(node).makeHeapTop();
                     filter(node->child1(), status.structureSet());
                     
                     m_state.setFoundConstants(true);
@@ -1243,7 +1243,7 @@
             }
         }
         clobberWorld(node->codeOrigin, clobberLimit);
-        forNode(node).makeTop();
+        forNode(node).makeHeapTop();
         break;
             
     case GetArrayLength:
@@ -1401,7 +1401,7 @@
     }
         
     case GetByOffset: {
-        forNode(node).makeTop();
+        forNode(node).makeHeapTop();
         break;
     }
             
@@ -1456,7 +1456,7 @@
         break;
             
     case GetGlobalVar:
-        forNode(node).makeTop();
+        forNode(node).makeHeapTop();
         break;
         
     case GlobalVarWatchpoint:
@@ -1500,7 +1500,7 @@
     case Construct:
         node->setCanExit(true);
         clobberWorld(node->codeOrigin, clobberLimit);
-        forNode(node).makeTop();
+        forNode(node).makeHeapTop();
         break;
 
     case ForceOSRExit:
@@ -1572,18 +1572,18 @@
         for (size_t i = capturedVars.size(); i--;) {
             if (!capturedVars.quickGet(i))
                 continue;
-            m_state.variables().local(i).makeTop();
+            m_state.variables().local(i).makeHeapTop();
         }
     } else {
         for (size_t i = m_codeBlock->m_numVars; i--;) {
             if (m_codeBlock->isCaptured(i))
-                m_state.variables().local(i).makeTop();
+                m_state.variables().local(i).makeHeapTop();
         }
     }
 
     for (size_t i = m_state.variables().numberOfArguments(); i--;) {
         if (m_codeBlock->isCaptured(argumentToOperand(i)))
-            m_state.variables().argument(i).makeTop();
+            m_state.variables().argument(i).makeHeapTop();
     }
 }
 

Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractValue.cpp (164281 => 164282)


--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractValue.cpp	2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractValue.cpp	2014-02-18 11:39:05 UTC (rev 164282)
@@ -125,12 +125,9 @@
 
 FiltrationResult AbstractValue::filter(SpeculatedType type)
 {
-    if (isClear())
+    if ((m_type & type) == m_type)
         return FiltrationOK;
     
-    if (type == SpecTop)
-        return isClear() ? Contradiction : FiltrationOK;
-    
     m_type &= type;
     
     // It's possible that prior to this filter() call we had, say, (Final, TOP), and

Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractValue.h (164281 => 164282)


--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractValue.h	2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGAbstractValue.h	2014-02-18 11:39:05 UTC (rev 164282)
@@ -62,16 +62,16 @@
     bool isClear() const { return m_type == SpecNone; }
     bool operator!() const { return isClear(); }
     
-    void makeTop()
+    void makeHeapTop()
     {
-        m_type |= SpecTop; // The state may have included SpecEmpty, in which case we want this to become SpecEmptyOrTop.
-        m_arrayModes = ALL_ARRAY_MODES;
-        m_currentKnownStructure.makeTop();
-        m_futurePossibleStructure.makeTop();
-        m_value = JSValue();
-        checkConsistency();
+        makeTop(SpecHeapTop);
     }
     
+    void makeBytecodeTop()
+    {
+        makeTop(SpecBytecodeTop);
+    }
+    
     void clobberStructures()
     {
         if (m_type & SpecCell) {
@@ -89,9 +89,9 @@
         m_value = JSValue();
     }
     
-    bool isTop() const
+    bool isHeapTop() const
     {
-        return m_type == SpecTop && m_currentKnownStructure.isTop() && m_futurePossibleStructure.isTop();
+        return (m_type | SpecHeapTop) == m_type && m_currentKnownStructure.isTop() && m_futurePossibleStructure.isTop();
     }
     
     bool valueIsTop() const
@@ -104,10 +104,10 @@
         return m_value;
     }
     
-    static AbstractValue top()
+    static AbstractValue heapTop()
     {
         AbstractValue result;
-        result.makeTop();
+        result.makeHeapTop();
         return result;
     }
     
@@ -195,7 +195,7 @@
     
     bool validateType(JSValue value) const
     {
-        if (isTop())
+        if (isHeapTop())
             return true;
         
         if (mergeSpeculations(m_type, speculationFromValue(value)) != m_type)
@@ -211,7 +211,7 @@
     
     bool validate(JSValue value) const
     {
-        if (isTop())
+        if (isHeapTop())
             return true;
         
         if (!!m_value && m_value != value)
@@ -363,6 +363,16 @@
         m_arrayModes = ALL_ARRAY_MODES;
     }
     
+    void makeTop(SpeculatedType top)
+    {
+        m_type |= top;
+        m_arrayModes = ALL_ARRAY_MODES;
+        m_currentKnownStructure.makeTop();
+        m_futurePossibleStructure.makeTop();
+        m_value = JSValue();
+        checkConsistency();
+    }
+    
     void setFuturePossibleStructure(Graph&, Structure* structure);
 
     void filterValueByType();

Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp (164281 => 164282)


--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp	2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp	2014-02-18 11:39:05 UTC (rev 164282)
@@ -108,14 +108,14 @@
     root->cfaFoundConstants = false;
     for (size_t i = 0; i < root->valuesAtHead.numberOfArguments(); ++i) {
         if (m_graph.m_form == SSA) {
-            root->valuesAtHead.argument(i).makeTop();
+            root->valuesAtHead.argument(i).makeHeapTop();
             continue;
         }
         
         Node* node = root->variablesAtHead.argument(i);
         ASSERT(node->op() == SetArgument);
         if (!node->variableAccessData()->shouldUnboxIfPossible()) {
-            root->valuesAtHead.argument(i).makeTop();
+            root->valuesAtHead.argument(i).makeHeapTop();
             continue;
         }
         
@@ -128,14 +128,12 @@
         else if (isCellSpeculation(prediction))
             root->valuesAtHead.argument(i).setType(SpecCell);
         else
-            root->valuesAtHead.argument(i).makeTop();
-        
-        root->valuesAtTail.argument(i).clear();
+            root->valuesAtHead.argument(i).makeHeapTop();
     }
     for (size_t i = 0; i < root->valuesAtHead.numberOfLocals(); ++i) {
         Node* node = root->variablesAtHead.local(i);
         if (node && node->variableAccessData()->isCaptured())
-            root->valuesAtHead.local(i).makeTop();
+            root->valuesAtHead.local(i).makeHeapTop();
         else
             root->valuesAtHead.local(i).clear();
         root->valuesAtTail.local(i).clear();

Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGJITCompiler.h (164281 => 164282)


--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGJITCompiler.h	2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGJITCompiler.h	2014-02-18 11:39:05 UTC (rev 164282)
@@ -445,12 +445,12 @@
         for (size_t argument = 0; argument < basicBlock.variablesAtHead.numberOfArguments(); ++argument) {
             Node* node = basicBlock.variablesAtHead.argument(argument);
             if (!node || !node->shouldGenerate())
-                entry->m_expectedValues.argument(argument).makeTop();
+                entry->m_expectedValues.argument(argument).makeHeapTop();
         }
         for (size_t local = 0; local < basicBlock.variablesAtHead.numberOfLocals(); ++local) {
             Node* node = basicBlock.variablesAtHead.local(local);
             if (!node || !node->shouldGenerate())
-                entry->m_expectedValues.local(local).makeTop();
+                entry->m_expectedValues.local(local).makeHeapTop();
             else if (node->variableAccessData()->shouldUseDoubleFormat())
                 entry->m_localsForcedDouble.set(local);
         }

Modified: releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGUseKind.h (164281 => 164282)


--- releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGUseKind.h	2014-02-18 11:38:05 UTC (rev 164281)
+++ releases/WebKitGTK/webkit-2.2/Source/_javascript_Core/dfg/DFGUseKind.h	2014-02-18 11:39:05 UTC (rev 164282)
@@ -62,7 +62,7 @@
 {
     switch (useKind) {
     case UntypedUse:
-        return SpecEmptyOrTop; // TOP isn't good enough; untyped uses may use the normally unseen empty value, in the case of lazy registers.
+        return SpecFullTop;
     case Int32Use:
     case KnownInt32Use:
         return SpecInt32;
@@ -97,7 +97,7 @@
         return SpecOther;
     default:
         RELEASE_ASSERT_NOT_REACHED();
-        return SpecTop;
+        return SpecFullTop;
     }
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to