diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGVariableAccessData.h')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGVariableAccessData.h | 105 |
1 files changed, 92 insertions, 13 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGVariableAccessData.h b/Source/JavaScriptCore/dfg/DFGVariableAccessData.h index bd626f9fb..1d99ed516 100644 --- a/Source/JavaScriptCore/dfg/DFGVariableAccessData.h +++ b/Source/JavaScriptCore/dfg/DFGVariableAccessData.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2012 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,11 +26,14 @@ #ifndef DFGVariableAccessData_h #define DFGVariableAccessData_h -#include "DFGOperands.h" +#include "DFGDoubleFormatState.h" +#include "DFGNodeFlags.h" +#include "Operands.h" #include "PredictedType.h" #include "VirtualRegister.h" #include <wtf/Platform.h> #include <wtf/UnionFind.h> +#include <wtf/Vector.h> namespace JSC { namespace DFG { @@ -41,7 +44,9 @@ public: VariableAccessData() : m_local(static_cast<VirtualRegister>(std::numeric_limits<int>::min())) , m_prediction(PredictNone) - , m_shouldUseDoubleFormat(false) + , m_argumentAwarePrediction(PredictNone) + , m_flags(0) + , m_doubleFormatState(EmptyDoubleFormatState) { clearVotes(); } @@ -49,7 +54,9 @@ public: VariableAccessData(VirtualRegister local) : m_local(local) , m_prediction(PredictNone) - , m_shouldUseDoubleFormat(false) + , m_argumentAwarePrediction(PredictNone) + , m_flags(0) + , m_doubleFormatState(EmptyDoubleFormatState) { clearVotes(); } @@ -67,7 +74,11 @@ public: bool predict(PredictedType prediction) { - return mergePrediction(find()->m_prediction, prediction); + VariableAccessData* self = find(); + bool result = mergePrediction(self->m_prediction, prediction); + if (result) + mergePrediction(m_argumentAwarePrediction, m_prediction); + return result; } PredictedType nonUnifiedPrediction() @@ -80,6 +91,16 @@ public: return find()->m_prediction; } + PredictedType argumentAwarePrediction() + { + return find()->m_argumentAwarePrediction; + } + + bool mergeArgumentAwarePrediction(PredictedType prediction) + { + return mergePrediction(find()->m_argumentAwarePrediction, prediction); + } + void clearVotes() { ASSERT(find() == this); @@ -101,19 +122,51 @@ public: bool shouldUseDoubleFormatAccordingToVote() { + // We don't support this facility for arguments, yet. // FIXME: make this work for arguments. - return !operandIsArgument(operand()) && ((isNumberPrediction(prediction()) && doubleVoteRatio() >= Options::doubleVoteRatioForDoubleFormat) || isDoublePrediction(prediction())); + if (operandIsArgument(operand())) + return false; + + // If the variable is not a number prediction, then this doesn't + // make any sense. + if (!isNumberPrediction(prediction())) + 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 (isDoublePrediction(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 (doubleVoteRatio() >= Options::doubleVoteRatioForDoubleFormat) + return true; + + return false; + } + + DoubleFormatState doubleFormatState() + { + return find()->m_doubleFormatState; } bool shouldUseDoubleFormat() { - ASSERT(find() == this); - return m_shouldUseDoubleFormat; + ASSERT(isRoot()); + return m_doubleFormatState == UsingDoubleFormat; } bool tallyVotesForShouldUseDoubleFormat() { - ASSERT(find() == this); + ASSERT(isRoot()); + + if (m_doubleFormatState == CantUseDoubleFormat) + return false; bool newValueOfShouldUseDoubleFormat = shouldUseDoubleFormatAccordingToVote(); if (!newValueOfShouldUseDoubleFormat) { @@ -122,11 +175,35 @@ public: return false; } - if (m_shouldUseDoubleFormat) + if (m_doubleFormatState == UsingDoubleFormat) return false; - m_shouldUseDoubleFormat = true; - mergePrediction(m_prediction, PredictDouble); + return DFG::mergeDoubleFormatState(m_doubleFormatState, UsingDoubleFormat); + } + + bool mergeDoubleFormatState(DoubleFormatState doubleFormatState) + { + return DFG::mergeDoubleFormatState(find()->m_doubleFormatState, doubleFormatState); + } + + bool makePredictionForDoubleFormat() + { + ASSERT(isRoot()); + + if (m_doubleFormatState != UsingDoubleFormat) + return false; + + return mergePrediction(m_prediction, PredictDouble); + } + + NodeFlags flags() const { return m_flags; } + + bool mergeFlags(NodeFlags newFlags) + { + newFlags |= m_flags; + if (newFlags == m_flags) + return false; + m_flags = newFlags; return true; } @@ -138,9 +215,11 @@ private: VirtualRegister m_local; PredictedType m_prediction; + PredictedType m_argumentAwarePrediction; + NodeFlags m_flags; float m_votes[2]; - bool m_shouldUseDoubleFormat; + DoubleFormatState m_doubleFormatState; }; } } // namespace JSC::DFG |