summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode/ValueProfile.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/bytecode/ValueProfile.h')
-rw-r--r--Source/JavaScriptCore/bytecode/ValueProfile.h107
1 files changed, 66 insertions, 41 deletions
diff --git a/Source/JavaScriptCore/bytecode/ValueProfile.h b/Source/JavaScriptCore/bytecode/ValueProfile.h
index 028c1f696..48b47da7c 100644
--- a/Source/JavaScriptCore/bytecode/ValueProfile.h
+++ b/Source/JavaScriptCore/bytecode/ValueProfile.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
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -29,10 +29,7 @@
#ifndef ValueProfile_h
#define ValueProfile_h
-#include <wtf/Platform.h>
-
-#if ENABLE(VALUE_PROFILER)
-
+#include "ConcurrentJITLock.h"
#include "Heap.h"
#include "JSArray.h"
#include "SpeculatedType.h"
@@ -54,7 +51,6 @@ struct ValueProfileBase {
: m_bytecodeOffset(-1)
, m_prediction(SpecNone)
, m_numberOfSamplesInPrediction(0)
- , m_singletonValueIsTop(false)
{
for (unsigned i = 0; i < totalNumberOfBuckets; ++i)
m_buckets[i] = JSValue::encode(JSValue());
@@ -64,7 +60,6 @@ struct ValueProfileBase {
: m_bytecodeOffset(bytecodeOffset)
, m_prediction(SpecNone)
, m_numberOfSamplesInPrediction(0)
- , m_singletonValueIsTop(false)
{
for (unsigned i = 0; i < totalNumberOfBuckets; ++i)
m_buckets[i] = JSValue::encode(JSValue());
@@ -111,28 +106,18 @@ struct ValueProfileBase {
return false;
}
- CString briefDescription()
+ CString briefDescription(const ConcurrentJITLocker& locker)
{
- computeUpdatedPrediction();
+ computeUpdatedPrediction(locker);
StringPrintStream out;
-
- if (m_singletonValueIsTop)
- out.print("predicting ", SpeculationDump(m_prediction));
- else if (m_singletonValue)
- out.print("predicting ", m_singletonValue);
-
+ out.print("predicting ", SpeculationDump(m_prediction));
return out.toCString();
}
void dump(PrintStream& out)
{
out.print("samples = ", totalNumberOfSamples(), " prediction = ", SpeculationDump(m_prediction));
- out.printf(", value = ");
- if (m_singletonValueIsTop)
- out.printf("TOP");
- else
- out.print(m_singletonValue);
bool first = true;
for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
JSValue value = JSValue::decode(m_buckets[i]);
@@ -147,8 +132,9 @@ struct ValueProfileBase {
}
}
- // Updates the prediction and returns the new one.
- SpeculatedType computeUpdatedPrediction(OperationInProgress operation = NoOperation)
+ // Updates the prediction and returns the new one. Never call this from any thread
+ // that isn't executing the code.
+ SpeculatedType computeUpdatedPrediction(const ConcurrentJITLocker&)
{
for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
JSValue value = JSValue::decode(m_buckets[i]);
@@ -158,23 +144,9 @@ struct ValueProfileBase {
m_numberOfSamplesInPrediction++;
mergeSpeculation(m_prediction, speculationFromValue(value));
- if (!m_singletonValueIsTop && !!value) {
- if (!m_singletonValue)
- m_singletonValue = value;
- else if (m_singletonValue != value)
- m_singletonValueIsTop = true;
- }
-
m_buckets[i] = JSValue::encode(JSValue());
}
- if (operation == Collection
- && !m_singletonValueIsTop
- && !!m_singletonValue
- && m_singletonValue.isCell()
- && !Heap::isMarked(m_singletonValue.asCell()))
- m_singletonValueIsTop = true;
-
return m_prediction;
}
@@ -183,9 +155,6 @@ struct ValueProfileBase {
SpeculatedType m_prediction;
unsigned m_numberOfSamplesInPrediction;
- bool m_singletonValueIsTop;
- JSValue m_singletonValue;
-
EncodedJSValue m_buckets[totalNumberOfBuckets];
};
@@ -237,9 +206,65 @@ inline int getRareCaseProfileBytecodeOffset(RareCaseProfile* rareCaseProfile)
return rareCaseProfile->m_bytecodeOffset;
}
+struct ResultProfile {
+private:
+ static const int numberOfFlagBits = 5;
+
+public:
+ ResultProfile(int bytecodeOffset)
+ : m_bytecodeOffsetAndFlags(bytecodeOffset << numberOfFlagBits)
+ {
+ ASSERT(((bytecodeOffset << numberOfFlagBits) >> numberOfFlagBits) == bytecodeOffset);
+ }
+
+ enum ObservedResults {
+ NonNegZeroDouble = 1 << 0,
+ NegZeroDouble = 1 << 1,
+ NonNumber = 1 << 2,
+ Int32Overflow = 1 << 3,
+ Int52Overflow = 1 << 4,
+ };
+
+ int bytecodeOffset() const { return m_bytecodeOffsetAndFlags >> numberOfFlagBits; }
+ unsigned specialFastPathCount() const { return m_specialFastPathCount; }
+
+ bool didObserveNonInt32() const { return hasBits(NonNegZeroDouble | NegZeroDouble | NonNumber); }
+ bool didObserveDouble() const { return hasBits(NonNegZeroDouble | NegZeroDouble); }
+ bool didObserveNonNegZeroDouble() const { return hasBits(NonNegZeroDouble); }
+ bool didObserveNegZeroDouble() const { return hasBits(NegZeroDouble); }
+ bool didObserveNonNumber() const { return hasBits(NonNumber); }
+ bool didObserveInt32Overflow() const { return hasBits(Int32Overflow); }
+ bool didObserveInt52Overflow() const { return hasBits(Int52Overflow); }
+
+ void setObservedNonNegZeroDouble() { setBit(NonNegZeroDouble); }
+ void setObservedNegZeroDouble() { setBit(NegZeroDouble); }
+ void setObservedNonNumber() { setBit(NonNumber); }
+ void setObservedInt32Overflow() { setBit(Int32Overflow); }
+ void setObservedInt52Overflow() { setBit(Int52Overflow); }
+
+ void* addressOfFlags() { return &m_bytecodeOffsetAndFlags; }
+ void* addressOfSpecialFastPathCount() { return &m_specialFastPathCount; }
+
+private:
+ bool hasBits(int mask) const { return m_bytecodeOffsetAndFlags & mask; }
+ void setBit(int mask) { m_bytecodeOffsetAndFlags |= mask; }
+
+ int m_bytecodeOffsetAndFlags;
+ unsigned m_specialFastPathCount { 0 };
+};
+
+inline int getResultProfileBytecodeOffset(ResultProfile* profile)
+{
+ return profile->bytecodeOffset();
+}
+
} // namespace JSC
-#endif // ENABLE(VALUE_PROFILER)
+namespace WTF {
+
+void printInternal(PrintStream&, const JSC::ResultProfile&);
+
+} // namespace WTF
#endif // ValueProfile_h