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.h166
1 files changed, 166 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/bytecode/ValueProfile.h b/Source/JavaScriptCore/bytecode/ValueProfile.h
new file mode 100644
index 000000000..02a1d6bf9
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/ValueProfile.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ValueProfile_h
+#define ValueProfile_h
+
+#include "JSArray.h"
+#include "PredictedType.h"
+#include "Structure.h"
+#include "WriteBarrier.h"
+
+namespace JSC {
+
+#if ENABLE(VALUE_PROFILER)
+struct ValueProfile {
+ static const unsigned logNumberOfBuckets = 0; // 1 bucket
+ static const unsigned numberOfBuckets = 1 << logNumberOfBuckets;
+ static const unsigned numberOfSpecFailBuckets = 1;
+ static const unsigned bucketIndexMask = numberOfBuckets - 1;
+ static const unsigned totalNumberOfBuckets = numberOfBuckets + numberOfSpecFailBuckets;
+
+ ValueProfile()
+ : m_bytecodeOffset(-1)
+ , m_prediction(PredictNone)
+ , m_numberOfSamplesInPrediction(0)
+ {
+ for (unsigned i = 0; i < totalNumberOfBuckets; ++i)
+ m_buckets[i] = JSValue::encode(JSValue());
+ }
+
+ ValueProfile(int bytecodeOffset)
+ : m_bytecodeOffset(bytecodeOffset)
+ , m_prediction(PredictNone)
+ , m_numberOfSamplesInPrediction(0)
+ {
+ for (unsigned i = 0; i < totalNumberOfBuckets; ++i)
+ m_buckets[i] = JSValue::encode(JSValue());
+ }
+
+ EncodedJSValue* specFailBucket(unsigned i)
+ {
+ ASSERT(numberOfBuckets + i < totalNumberOfBuckets);
+ return m_buckets + numberOfBuckets + i;
+ }
+
+ const ClassInfo* classInfo(unsigned bucket) const
+ {
+ JSValue value = JSValue::decode(m_buckets[bucket]);
+ if (!!value) {
+ if (!value.isCell())
+ return 0;
+ return value.asCell()->structure()->classInfo();
+ }
+ return 0;
+ }
+
+ unsigned numberOfSamples() const
+ {
+ unsigned result = 0;
+ for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
+ if (!!JSValue::decode(m_buckets[i]))
+ result++;
+ }
+ return result;
+ }
+
+ unsigned totalNumberOfSamples() const
+ {
+ return numberOfSamples() + m_numberOfSamplesInPrediction;
+ }
+
+ bool isLive() const
+ {
+ for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
+ if (!!JSValue::decode(m_buckets[i]))
+ return true;
+ }
+ return false;
+ }
+
+#ifndef NDEBUG
+ void dump(FILE* out)
+ {
+ fprintf(out,
+ "samples = %u, prediction = %s",
+ totalNumberOfSamples(),
+ predictionToString(m_prediction));
+ bool first = true;
+ for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
+ JSValue value = JSValue::decode(m_buckets[i]);
+ if (!!value) {
+ if (first) {
+ fprintf(out, ": ");
+ first = false;
+ } else
+ fprintf(out, ", ");
+ fprintf(out, "%s", value.description());
+ }
+ }
+ }
+#endif
+
+ // Updates the prediction and returns the new one.
+ PredictedType computeUpdatedPrediction();
+
+ int m_bytecodeOffset; // -1 for prologue
+
+ PredictedType m_prediction;
+ unsigned m_numberOfSamplesInPrediction;
+
+ EncodedJSValue m_buckets[totalNumberOfBuckets];
+};
+
+inline int getValueProfileBytecodeOffset(ValueProfile* valueProfile)
+{
+ return valueProfile->m_bytecodeOffset;
+}
+
+// This is a mini value profile to catch pathologies. It is a counter that gets
+// incremented when we take the slow path on any instruction.
+struct RareCaseProfile {
+ RareCaseProfile(int bytecodeOffset)
+ : m_bytecodeOffset(bytecodeOffset)
+ , m_counter(0)
+ {
+ }
+
+ int m_bytecodeOffset;
+ uint32_t m_counter;
+};
+
+inline int getRareCaseProfileBytecodeOffset(RareCaseProfile* rareCaseProfile)
+{
+ return rareCaseProfile->m_bytecodeOffset;
+}
+#endif
+
+}
+
+#endif
+