diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGVariableAccessData.h')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGVariableAccessData.h | 110 |
1 files changed, 82 insertions, 28 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGVariableAccessData.h b/Source/JavaScriptCore/dfg/DFGVariableAccessData.h index 6d8e89799..feb02472f 100644 --- a/Source/JavaScriptCore/dfg/DFGVariableAccessData.h +++ b/Source/JavaScriptCore/dfg/DFGVariableAccessData.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -46,10 +46,13 @@ public: , m_prediction(SpecNone) , m_argumentAwarePrediction(SpecNone) , m_flags(0) - , m_doubleFormatState(EmptyDoubleFormatState) , m_isCaptured(false) + , m_shouldNeverUnbox(false) , m_isArgumentsAlias(false) , m_structureCheckHoistingFailed(false) + , m_isProfitableToUnbox(false) + , m_isLoadedFrom(false) + , m_doubleFormatState(EmptyDoubleFormatState) { clearVotes(); } @@ -59,10 +62,12 @@ public: , m_prediction(SpecNone) , m_argumentAwarePrediction(SpecNone) , m_flags(0) - , m_doubleFormatState(EmptyDoubleFormatState) , m_isCaptured(isCaptured) + , m_shouldNeverUnbox(isCaptured) , m_isArgumentsAlias(false) , m_structureCheckHoistingFailed(false) + , m_isProfitableToUnbox(false) + , m_doubleFormatState(EmptyDoubleFormatState) { clearVotes(); } @@ -80,11 +85,8 @@ public: bool mergeIsCaptured(bool isCaptured) { - bool newIsCaptured = m_isCaptured | isCaptured; - if (newIsCaptured == m_isCaptured) - return false; - m_isCaptured = newIsCaptured; - return true; + return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox | isCaptured) + | checkAndSet(m_isCaptured, m_isCaptured | isCaptured); } bool isCaptured() @@ -92,15 +94,47 @@ public: return m_isCaptured; } - bool mergeStructureCheckHoistingFailed(bool failed) + bool mergeIsProfitableToUnbox(bool isProfitableToUnbox) + { + return checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox | isProfitableToUnbox); + } + + bool isProfitableToUnbox() { - bool newFailed = m_structureCheckHoistingFailed | failed; - if (newFailed == m_structureCheckHoistingFailed) + return m_isProfitableToUnbox; + } + + bool mergeShouldNeverUnbox(bool shouldNeverUnbox) + { + bool newShouldNeverUnbox = m_shouldNeverUnbox | shouldNeverUnbox; + if (newShouldNeverUnbox == m_shouldNeverUnbox) return false; - m_structureCheckHoistingFailed = newFailed; + m_shouldNeverUnbox = newShouldNeverUnbox; return true; } + // 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; + } + + // Returns true if we should be unboxing the value provided that the predictions + // and double format vote say so. This may return false even if shouldNeverUnbox() + // returns false, since this incorporates heuristics of profitability. + bool shouldUnboxIfPossible() + { + return !shouldNeverUnbox() && isProfitableToUnbox(); + } + + bool mergeStructureCheckHoistingFailed(bool failed) + { + return checkAndSet(m_structureCheckHoistingFailed, m_structureCheckHoistingFailed | failed); + } + bool structureCheckHoistingFailed() { return m_structureCheckHoistingFailed; @@ -108,11 +142,7 @@ public: bool mergeIsArgumentsAlias(bool isArgumentsAlias) { - bool newIsArgumentsAlias = m_isArgumentsAlias | isArgumentsAlias; - if (newIsArgumentsAlias == m_isArgumentsAlias) - return false; - m_isArgumentsAlias = newIsArgumentsAlias; - return true; + return checkAndSet(m_isArgumentsAlias, m_isArgumentsAlias | isArgumentsAlias); } bool isArgumentsAlias() @@ -120,6 +150,21 @@ public: return m_isArgumentsAlias; } + bool mergeIsLoadedFrom(bool isLoadedFrom) + { + return checkAndSet(m_isLoadedFrom, m_isLoadedFrom | isLoadedFrom); + } + + void setIsLoadedFrom(bool isLoadedFrom) + { + m_isLoadedFrom = isLoadedFrom; + } + + bool isLoadedFrom() + { + return m_isLoadedFrom; + } + bool predict(SpeculatedType prediction) { VariableAccessData* self = find(); @@ -177,8 +222,12 @@ public: // If the variable is not a number prediction, then this doesn't // make any sense. - if (!isNumberSpeculation(prediction())) + 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. @@ -206,13 +255,19 @@ public: bool shouldUseDoubleFormat() { ASSERT(isRoot()); - return m_doubleFormatState == UsingDoubleFormat; + 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; @@ -248,11 +303,7 @@ public: bool mergeFlags(NodeFlags newFlags) { - newFlags |= m_flags; - if (newFlags == m_flags) - return false; - m_flags = newFlags; - return true; + return checkAndSet(m_flags, m_flags | newFlags); } private: @@ -265,13 +316,16 @@ private: SpeculatedType m_prediction; SpeculatedType m_argumentAwarePrediction; NodeFlags m_flags; - - float m_votes[2]; // Used primarily for double voting but may be reused for other purposes. - DoubleFormatState m_doubleFormatState; - + bool m_isCaptured; + bool m_shouldNeverUnbox; bool m_isArgumentsAlias; bool m_structureCheckHoistingFailed; + bool m_isProfitableToUnbox; + bool m_isLoadedFrom; + + float m_votes[2]; // Used primarily for double voting but may be reused for other purposes. + DoubleFormatState m_doubleFormatState; }; } } // namespace JSC::DFG |