]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - dfg/DFGVariableAccessData.h
JavaScriptCore-7600.1.4.9.tar.gz
[apple/javascriptcore.git] / dfg / DFGVariableAccessData.h
index feb02472ff4c825d86b5944d07105ae07f81523e..cfdd2647ecaa78fff5fe12b43dfab8dbc48efd6f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef DFGVariableAccessData_h
 #define DFGVariableAccessData_h
 
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
 #include "DFGDoubleFormatState.h"
+#include "DFGFlushFormat.h"
+#include "DFGFlushedAt.h"
 #include "DFGNodeFlags.h"
 #include "Operands.h"
 #include "SpeculatedType.h"
 #include "VirtualRegister.h"
-#include <wtf/Platform.h>
 #include <wtf/UnionFind.h>
 #include <wtf/Vector.h>
 
 namespace JSC { namespace DFG {
 
+struct Node;
+
 enum DoubleBallot { VoteValue, VoteDouble };
 
 class VariableAccessData : public UnionFind<VariableAccessData> {
 public:
-    VariableAccessData()
-        : m_local(static_cast<VirtualRegister>(std::numeric_limits<int>::min()))
-        , m_prediction(SpecNone)
-        , m_argumentAwarePrediction(SpecNone)
-        , m_flags(0)
-        , m_isCaptured(false)
-        , m_shouldNeverUnbox(false)
-        , m_isArgumentsAlias(false)
-        , m_structureCheckHoistingFailed(false)
-        , m_isProfitableToUnbox(false)
-        , m_isLoadedFrom(false)
-        , m_doubleFormatState(EmptyDoubleFormatState)
-    {
-        clearVotes();
-    }
-    
-    VariableAccessData(VirtualRegister local, bool isCaptured)
-        : m_local(local)
-        , m_prediction(SpecNone)
-        , m_argumentAwarePrediction(SpecNone)
-        , m_flags(0)
-        , m_isCaptured(isCaptured)
-        , m_shouldNeverUnbox(isCaptured)
-        , m_isArgumentsAlias(false)
-        , m_structureCheckHoistingFailed(false)
-        , m_isProfitableToUnbox(false)
-        , m_doubleFormatState(EmptyDoubleFormatState)
-    {
-        clearVotes();
-    }
+    VariableAccessData();
+    VariableAccessData(VirtualRegister local, bool isCaptured);
     
     VirtualRegister local()
     {
@@ -78,16 +56,13 @@ public:
         return m_local;
     }
     
-    int operand()
+    VirtualRegister& machineLocal()
     {
-        return static_cast<int>(local());
-    }
-    
-    bool mergeIsCaptured(bool isCaptured)
-    {
-        return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox | isCaptured)
-            | checkAndSet(m_isCaptured, m_isCaptured | isCaptured);
+        ASSERT(find() == this);
+        return m_machineLocal;
     }
+
+    bool mergeIsCaptured(bool isCaptured);
     
     bool isCaptured()
     {
@@ -104,14 +79,7 @@ public:
         return m_isProfitableToUnbox;
     }
     
-    bool mergeShouldNeverUnbox(bool shouldNeverUnbox)
-    {
-        bool newShouldNeverUnbox = m_shouldNeverUnbox | shouldNeverUnbox;
-        if (newShouldNeverUnbox == m_shouldNeverUnbox)
-            return false;
-        m_shouldNeverUnbox = newShouldNeverUnbox;
-        return true;
-    }
+    bool mergeShouldNeverUnbox(bool shouldNeverUnbox);
     
     // Returns true if it would be unsound to store the value in an unboxed fashion.
     // If this returns false, it simply means that it is sound to unbox; it doesn't
@@ -135,11 +103,21 @@ public:
         return checkAndSet(m_structureCheckHoistingFailed, m_structureCheckHoistingFailed | failed);
     }
     
+    bool mergeCheckArrayHoistingFailed(bool failed)
+    {
+        return checkAndSet(m_checkArrayHoistingFailed, m_checkArrayHoistingFailed | failed);
+    }
+    
     bool structureCheckHoistingFailed()
     {
         return m_structureCheckHoistingFailed;
     }
     
+    bool checkArrayHoistingFailed()
+    {
+        return m_checkArrayHoistingFailed;
+    }
+    
     bool mergeIsArgumentsAlias(bool isArgumentsAlias)
     {
         return checkAndSet(m_isArgumentsAlias, m_isArgumentsAlias | isArgumentsAlias);
@@ -165,14 +143,7 @@ public:
         return m_isLoadedFrom;
     }
     
-    bool predict(SpeculatedType prediction)
-    {
-        VariableAccessData* self = find();
-        bool result = mergeSpeculation(self->m_prediction, prediction);
-        if (result)
-            mergeSpeculation(m_argumentAwarePrediction, m_prediction);
-        return result;
-    }
+    bool predict(SpeculatedType prediction);
     
     SpeculatedType nonUnifiedPrediction()
     {
@@ -189,10 +160,7 @@ public:
         return find()->m_argumentAwarePrediction;
     }
     
-    bool mergeArgumentAwarePrediction(SpeculatedType prediction)
-    {
-        return mergeSpeculation(find()->m_argumentAwarePrediction, prediction);
-    }
+    bool mergeArgumentAwarePrediction(SpeculatedType prediction);
     
     void clearVotes()
     {
@@ -201,10 +169,10 @@ public:
         m_votes[1] = 0;
     }
     
-    void vote(unsigned ballot)
+    void vote(unsigned ballot, float weight = 1)
     {
         ASSERT(ballot < 2);
-        m_votes[ballot]++;
+        m_votes[ballot] += weight;
     }
     
     double voteRatio()
@@ -213,39 +181,7 @@ public:
         return static_cast<double>(m_votes[1]) / m_votes[0];
     }
     
-    bool shouldUseDoubleFormatAccordingToVote()
-    {
-        // We don't support this facility for arguments, yet.
-        // FIXME: make this work for arguments.
-        if (operandIsArgument(operand()))
-            return false;
-        
-        // If the variable is not a number prediction, then this doesn't
-        // make any sense.
-        if (!isNumberSpeculation(prediction())) {
-            // FIXME: we may end up forcing a local in inlined argument position to be a double even
-            // if it is sometimes not even numeric, since this never signals the fact that it doesn't
-            // want doubles. https://bugs.webkit.org/show_bug.cgi?id=109511
-            return false;
-        }
-        
-        // If the variable is predicted to hold only doubles, then it's a
-        // no-brainer: it should be formatted as a double.
-        if (isDoubleSpeculation(prediction()))
-            return true;
-        
-        // If the variable is known to be used as an integer, then be safe -
-        // don't force it to be a double.
-        if (flags() & NodeUsedAsInt)
-            return false;
-        
-        // If the variable has been voted to become a double, then make it a
-        // double.
-        if (voteRatio() >= Options::doubleVoteRatioForDoubleFormat())
-            return true;
-        
-        return false;
-    }
+    bool shouldUseDoubleFormatAccordingToVote();
     
     DoubleFormatState doubleFormatState()
     {
@@ -261,43 +197,11 @@ public:
         return doubleState && isProfitableToUnbox();
     }
     
-    bool tallyVotesForShouldUseDoubleFormat()
-    {
-        ASSERT(isRoot());
-        
-        if (operandIsArgument(local()) || shouldNeverUnbox())
-            return DFG::mergeDoubleFormatState(m_doubleFormatState, NotUsingDoubleFormat);
-        
-        if (m_doubleFormatState == CantUseDoubleFormat)
-            return false;
-        
-        bool newValueOfShouldUseDoubleFormat = shouldUseDoubleFormatAccordingToVote();
-        if (!newValueOfShouldUseDoubleFormat) {
-            // We monotonically convert to double. Hence, if the fixpoint leads us to conclude that we should
-            // switch back to int, we instead ignore this and stick with double.
-            return false;
-        }
-        
-        if (m_doubleFormatState == UsingDoubleFormat)
-            return false;
-        
-        return DFG::mergeDoubleFormatState(m_doubleFormatState, UsingDoubleFormat);
-    }
+    bool tallyVotesForShouldUseDoubleFormat();
     
-    bool mergeDoubleFormatState(DoubleFormatState doubleFormatState)
-    {
-        return DFG::mergeDoubleFormatState(find()->m_doubleFormatState, doubleFormatState);
-    }
+    bool mergeDoubleFormatState(DoubleFormatState);
     
-    bool makePredictionForDoubleFormat()
-    {
-        ASSERT(isRoot());
-        
-        if (m_doubleFormatState != UsingDoubleFormat)
-            return false;
-        
-        return mergeSpeculation(m_prediction, SpecDouble);
-    }
+    bool makePredictionForDoubleFormat();
     
     NodeFlags flags() const { return m_flags; }
     
@@ -306,13 +210,25 @@ public:
         return checkAndSet(m_flags, m_flags | newFlags);
     }
     
+    FlushFormat flushFormat();
+    
+    bool couldRepresentInt52();
+    
+    FlushedAt flushedAt()
+    {
+        return FlushedAt(flushFormat(), machineLocal());
+    }
+
 private:
+    bool couldRepresentInt52Impl();
+    
     // This is slightly space-inefficient, since anything we're unified with
     // will have the same operand and should have the same prediction. But
     // putting them here simplifies the code, and we don't expect DFG space
     // usage for variable access nodes do be significant.
 
     VirtualRegister m_local;
+    VirtualRegister m_machineLocal;
     SpeculatedType m_prediction;
     SpeculatedType m_argumentAwarePrediction;
     NodeFlags m_flags;
@@ -321,6 +237,7 @@ private:
     bool m_shouldNeverUnbox;
     bool m_isArgumentsAlias;
     bool m_structureCheckHoistingFailed;
+    bool m_checkArrayHoistingFailed;
     bool m_isProfitableToUnbox;
     bool m_isLoadedFrom;
 
@@ -330,4 +247,6 @@ private:
 
 } } // namespace JSC::DFG
 
+#endif // ENABLE(DFG_JIT)
+
 #endif // DFGVariableAccessData_h