summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGVariableAccessData.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGVariableAccessData.h')
-rw-r--r--Source/JavaScriptCore/dfg/DFGVariableAccessData.h110
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