diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGVariableAccessData.h')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGVariableAccessData.h | 196 |
1 files changed, 47 insertions, 149 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGVariableAccessData.h b/Source/JavaScriptCore/dfg/DFGVariableAccessData.h index feb02472f..0f817561c 100644 --- a/Source/JavaScriptCore/dfg/DFGVariableAccessData.h +++ b/Source/JavaScriptCore/dfg/DFGVariableAccessData.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2011-2015 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,51 +26,29 @@ #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); VirtualRegister local() { @@ -78,25 +56,15 @@ public: return m_local; } - int operand() - { - return static_cast<int>(local()); - } - - bool mergeIsCaptured(bool isCaptured) - { - return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox | isCaptured) - | checkAndSet(m_isCaptured, m_isCaptured | isCaptured); - } - - bool isCaptured() + VirtualRegister& machineLocal() { - return m_isCaptured; + ASSERT(find() == this); + return m_machineLocal; } - + bool mergeIsProfitableToUnbox(bool isProfitableToUnbox) { - return checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox | isProfitableToUnbox); + return checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox || isProfitableToUnbox); } bool isProfitableToUnbox() @@ -104,21 +72,13 @@ 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 // mean that we have actually done so. bool shouldNeverUnbox() { - ASSERT(!(m_isCaptured && !m_shouldNeverUnbox)); return m_shouldNeverUnbox; } @@ -132,27 +92,27 @@ public: bool mergeStructureCheckHoistingFailed(bool failed) { - return checkAndSet(m_structureCheckHoistingFailed, m_structureCheckHoistingFailed | failed); + return checkAndSet(m_structureCheckHoistingFailed, m_structureCheckHoistingFailed || failed); } - bool structureCheckHoistingFailed() + bool mergeCheckArrayHoistingFailed(bool failed) { - return m_structureCheckHoistingFailed; + return checkAndSet(m_checkArrayHoistingFailed, m_checkArrayHoistingFailed || failed); } - bool mergeIsArgumentsAlias(bool isArgumentsAlias) + bool structureCheckHoistingFailed() { - return checkAndSet(m_isArgumentsAlias, m_isArgumentsAlias | isArgumentsAlias); + return m_structureCheckHoistingFailed; } - bool isArgumentsAlias() + bool checkArrayHoistingFailed() { - return m_isArgumentsAlias; + return m_checkArrayHoistingFailed; } bool mergeIsLoadedFrom(bool isLoadedFrom) { - return checkAndSet(m_isLoadedFrom, m_isLoadedFrom | isLoadedFrom); + return checkAndSet(m_isLoadedFrom, m_isLoadedFrom || isLoadedFrom); } void setIsLoadedFrom(bool isLoadedFrom) @@ -165,14 +125,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 +142,7 @@ public: return find()->m_argumentAwarePrediction; } - bool mergeArgumentAwarePrediction(SpeculatedType prediction) - { - return mergeSpeculation(find()->m_argumentAwarePrediction, prediction); - } + bool mergeArgumentAwarePrediction(SpeculatedType prediction); void clearVotes() { @@ -201,10 +151,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 +163,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() { @@ -257,47 +175,14 @@ public: ASSERT(isRoot()); bool doubleState = m_doubleFormatState == UsingDoubleFormat; ASSERT(!(doubleState && shouldNeverUnbox())); - ASSERT(!(doubleState && isCaptured())); 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,21 +191,32 @@ 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; - bool m_isCaptured; bool m_shouldNeverUnbox; - bool m_isArgumentsAlias; bool m_structureCheckHoistingFailed; + bool m_checkArrayHoistingFailed; bool m_isProfitableToUnbox; bool m_isLoadedFrom; @@ -330,4 +226,6 @@ private: } } // namespace JSC::DFG +#endif // ENABLE(DFG_JIT) + #endif // DFGVariableAccessData_h |