diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGEdge.h')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGEdge.h | 92 |
1 files changed, 67 insertions, 25 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGEdge.h b/Source/JavaScriptCore/dfg/DFGEdge.h index eb835b050..3dec1893f 100644 --- a/Source/JavaScriptCore/dfg/DFGEdge.h +++ b/Source/JavaScriptCore/dfg/DFGEdge.h @@ -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,26 +106,61 @@ 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 { return proofStatus() == IsProved; } - bool needsCheck() const + + bool willNotHaveCheck() const { - return proofStatus() == NeedsCheck; + return isProved() || shouldNotHaveTypeCheck(useKind()); + } + bool willHaveCheck() const + { + return !willNotHaveCheck(); } - bool isSet() const { return !!node(); } - - typedef void* Edge::*UnspecifiedBoolType; - operator UnspecifiedBoolType*() const { return reinterpret_cast<UnspecifiedBoolType*>(isSet()); } + 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; + } + bool operator!() const { return !isSet(); } + explicit operator bool() const { return isSet(); } bool operator==(Edge other) const { @@ -143,27 +176,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) | static_cast<uintptr_t>(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) | static_cast<uintptr_t>(DFG::isProved(proofStatus)); } Node* m_node; |