]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - dfg/DFGEdge.h
JavaScriptCore-7600.1.4.9.tar.gz
[apple/javascriptcore.git] / dfg / DFGEdge.h
index eb835b0508a8a9c3709cda42a622e2e0a633dd4c..4ceda0cbaa733bac78e4043dd8a41b11a732dee2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 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
@@ -26,8 +26,6 @@
 #ifndef DFGEdge_h
 #define DFGEdge_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(DFG_JIT)
 
 #include "DFGCommon.h"
@@ -39,12 +37,12 @@ class AdjacencyList;
 
 class Edge {
 public:
-    explicit Edge(Node* node = 0, UseKind useKind = UntypedUse, ProofStatus proofStatus = NeedsCheck)
+    explicit Edge(Node* node = 0, UseKind useKind = UntypedUse, ProofStatus proofStatus = NeedsCheck, KillStatus killStatus = DoesNotKill)
 #if USE(JSVALUE64)
-        : m_encodedWord(makeWord(node, useKind, proofStatus))
+        : m_encodedWord(makeWord(node, useKind, proofStatus, killStatus))
 #else
         : m_node(node)
-        , m_encodedWord(makeWord(useKind, proofStatus))
+        , m_encodedWord(makeWord(useKind, proofStatus, killStatus))
 #endif
     {
     }
@@ -61,7 +59,7 @@ public:
     void setNode(Node* node)
     {
 #if USE(JSVALUE64)
-        m_encodedWord = makeWord(node, useKind(), proofStatus());
+        m_encodedWord = makeWord(node, useKind(), proofStatus(), killStatus());
 #else
         m_node = node;
 #endif
@@ -71,9 +69,9 @@ public:
     {
 #if USE(JSVALUE64)
         unsigned masked = m_encodedWord & (((1 << shift()) - 1));
-        unsigned shifted = masked >> 1;
+        unsigned shifted = masked >> 2;
 #else
-        unsigned shifted = static_cast<UseKind>(m_encodedWord) >> 1;
+        unsigned shifted = static_cast<UseKind>(m_encodedWord) >> 2;
 #endif
         ASSERT(shifted < static_cast<unsigned>(LastUseKind));
         UseKind result = static_cast<UseKind>(shifted);
@@ -89,9 +87,9 @@ public:
     {
         ASSERT(node());
 #if USE(JSVALUE64)
-        m_encodedWord = makeWord(node(), useKind, proofStatus());
+        m_encodedWord = makeWord(node(), useKind, proofStatus(), killStatus());
 #else
-        m_encodedWord = makeWord(useKind, proofStatus());
+        m_encodedWord = makeWord(useKind, proofStatus(), killStatus());
 #endif
     }
     
@@ -108,9 +106,9 @@ public:
     {
         ASSERT(node());
 #if USE(JSVALUE64)
-        m_encodedWord = makeWord(node(), useKind(), proofStatus);
+        m_encodedWord = makeWord(node(), useKind(), proofStatus, killStatus());
 #else
-        m_encodedWord = makeWord(useKind(), proofStatus);
+        m_encodedWord = makeWord(useKind(), proofStatus, killStatus());
 #endif
     }
     bool isProved() const
@@ -122,7 +120,48 @@ public:
         return proofStatus() == NeedsCheck;
     }
     
+    bool willNotHaveCheck() const
+    {
+        return isProved() || shouldNotHaveTypeCheck(useKind());
+    }
+    bool willHaveCheck() const
+    {
+        return !willNotHaveCheck();
+    }
+    
+    KillStatus killStatusUnchecked() const
+    {
+        return killStatusForDoesKill(m_encodedWord & 2);
+    }
+    KillStatus killStatus() const
+    {
+        ASSERT(node());
+        return killStatusUnchecked();
+    }
+    void setKillStatus(KillStatus killStatus)
+    {
+        ASSERT(node());
+#if USE(JSVALUE64)
+        m_encodedWord = makeWord(node(), useKind(), proofStatus(), killStatus);
+#else
+        m_encodedWord = makeWord(useKind(), proofStatus(), killStatus);
+#endif
+    }
+    bool doesKill() const { return DFG::doesKill(killStatus()); }
+    bool doesNotKill() const { return !doesKill(); }
+    
     bool isSet() const { return !!node(); }
+
+    Edge sanitized() const
+    {
+        Edge result = *this;
+#if USE(JSVALUE64)
+        result.m_encodedWord = makeWord(node(), useKindUnchecked(), NeedsCheck, DoesNotKill);
+#else
+        result.m_encodedWord = makeWord(useKindUnchecked(), NeedsCheck, DoesNotKill);
+#endif
+        return result;
+    }
     
     typedef void* Edge::*UnspecifiedBoolType;
     operator UnspecifiedBoolType*() const { return reinterpret_cast<UnspecifiedBoolType*>(isSet()); }
@@ -143,27 +182,36 @@ public:
     }
     
     void dump(PrintStream&) const;
+    
+    unsigned hash() const
+    {
+#if USE(JSVALUE64)
+        return IntHash<uintptr_t>::hash(m_encodedWord);
+#else
+        return PtrHash<Node*>::hash(m_node) + m_encodedWord;
+#endif
+    }
 
 private:
     friend class AdjacencyList;
     
 #if USE(JSVALUE64)
-    static uint32_t shift() { return 6; }
+    static uint32_t shift() { return 7; }
     
-    static uintptr_t makeWord(Node* node, UseKind useKind, ProofStatus proofStatus)
+    static uintptr_t makeWord(Node* node, UseKind useKind, ProofStatus proofStatus, KillStatus killStatus)
     {
         ASSERT(sizeof(node) == 8);
         uintptr_t shiftedValue = bitwise_cast<uintptr_t>(node) << shift();
         ASSERT((shiftedValue >> shift()) == bitwise_cast<uintptr_t>(node));
         ASSERT(useKind >= 0 && useKind < LastUseKind);
-        ASSERT((static_cast<uintptr_t>(LastUseKind) << 1) <= (static_cast<uintptr_t>(1) << shift()));
-        return shiftedValue | (static_cast<uintptr_t>(useKind) << 1) | DFG::isProved(proofStatus);
+        ASSERT((static_cast<uintptr_t>(LastUseKind) << 2) <= (static_cast<uintptr_t>(2) << shift()));
+        return shiftedValue | (static_cast<uintptr_t>(useKind) << 2) | (DFG::doesKill(killStatus) << 1) | DFG::isProved(proofStatus);
     }
     
 #else
-    static uintptr_t makeWord(UseKind useKind, ProofStatus proofStatus)
+    static uintptr_t makeWord(UseKind useKind, ProofStatus proofStatus, KillStatus killStatus)
     {
-        return (static_cast<uintptr_t>(useKind) << 1) | DFG::isProved(proofStatus);
+        return (static_cast<uintptr_t>(useKind) << 2) | (DFG::doesKill(killStatus) << 1) | DFG::isProved(proofStatus);
     }
     
     Node* m_node;