2
* Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14
* its contributors may be used to endorse or promote products derived
15
* from this software without specific prior written permission.
17
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
#ifndef ValueProfile_h
30
#define ValueProfile_h
32
#include <wtf/Platform.h>
34
#if ENABLE(VALUE_PROFILER)
38
#include "SpeculatedType.h"
39
#include "Structure.h"
40
#include "WriteBarrier.h"
41
#include <wtf/PrintStream.h>
45
template<unsigned numberOfBucketsArgument>
46
struct ValueProfileBase {
47
static const unsigned numberOfBuckets = numberOfBucketsArgument;
48
static const unsigned numberOfSpecFailBuckets = 1;
49
static const unsigned bucketIndexMask = numberOfBuckets - 1;
50
static const unsigned totalNumberOfBuckets = numberOfBuckets + numberOfSpecFailBuckets;
53
: m_bytecodeOffset(-1)
54
, m_prediction(SpecNone)
55
, m_numberOfSamplesInPrediction(0)
56
, m_singletonValueIsTop(false)
58
for (unsigned i = 0; i < totalNumberOfBuckets; ++i)
59
m_buckets[i] = JSValue::encode(JSValue());
62
ValueProfileBase(int bytecodeOffset)
63
: m_bytecodeOffset(bytecodeOffset)
64
, m_prediction(SpecNone)
65
, m_numberOfSamplesInPrediction(0)
66
, m_singletonValueIsTop(false)
68
for (unsigned i = 0; i < totalNumberOfBuckets; ++i)
69
m_buckets[i] = JSValue::encode(JSValue());
72
EncodedJSValue* specFailBucket(unsigned i)
74
ASSERT(numberOfBuckets + i < totalNumberOfBuckets);
75
return m_buckets + numberOfBuckets + i;
78
const ClassInfo* classInfo(unsigned bucket) const
80
JSValue value = JSValue::decode(m_buckets[bucket]);
84
return value.asCell()->structure()->classInfo();
89
unsigned numberOfSamples() const
92
for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
93
if (!!JSValue::decode(m_buckets[i]))
99
unsigned totalNumberOfSamples() const
101
return numberOfSamples() + m_numberOfSamplesInPrediction;
106
for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
107
if (!!JSValue::decode(m_buckets[i]))
113
void dump(PrintStream& out)
115
out.print("samples = ", totalNumberOfSamples(), " prediction = ", SpeculationDump(m_prediction));
116
out.printf(", value = ");
117
if (m_singletonValueIsTop)
120
out.printf("%s", m_singletonValue.description());
122
for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
123
JSValue value = JSValue::decode(m_buckets[i]);
130
out.printf("%s", value.description());
135
// Updates the prediction and returns the new one.
136
SpeculatedType computeUpdatedPrediction(OperationInProgress operation = NoOperation)
138
for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
139
JSValue value = JSValue::decode(m_buckets[i]);
143
m_numberOfSamplesInPrediction++;
144
mergeSpeculation(m_prediction, speculationFromValue(value));
146
if (!m_singletonValueIsTop && !!value) {
147
if (!m_singletonValue)
148
m_singletonValue = value;
149
else if (m_singletonValue != value)
150
m_singletonValueIsTop = true;
153
m_buckets[i] = JSValue::encode(JSValue());
156
if (operation == Collection
157
&& !m_singletonValueIsTop
158
&& !!m_singletonValue
159
&& m_singletonValue.isCell()
160
&& !Heap::isMarked(m_singletonValue.asCell()))
161
m_singletonValueIsTop = true;
166
int m_bytecodeOffset; // -1 for prologue
168
SpeculatedType m_prediction;
169
unsigned m_numberOfSamplesInPrediction;
171
bool m_singletonValueIsTop;
172
JSValue m_singletonValue;
174
EncodedJSValue m_buckets[totalNumberOfBuckets];
177
struct MinimalValueProfile : public ValueProfileBase<0> {
178
MinimalValueProfile(): ValueProfileBase<0>() { }
179
MinimalValueProfile(int bytecodeOffset): ValueProfileBase<0>(bytecodeOffset) { }
182
template<unsigned logNumberOfBucketsArgument>
183
struct ValueProfileWithLogNumberOfBuckets : public ValueProfileBase<1 << logNumberOfBucketsArgument> {
184
static const unsigned logNumberOfBuckets = logNumberOfBucketsArgument;
186
ValueProfileWithLogNumberOfBuckets()
187
: ValueProfileBase<1 << logNumberOfBucketsArgument>()
190
ValueProfileWithLogNumberOfBuckets(int bytecodeOffset)
191
: ValueProfileBase<1 << logNumberOfBucketsArgument>(bytecodeOffset)
196
struct ValueProfile : public ValueProfileWithLogNumberOfBuckets<0> {
197
ValueProfile(): ValueProfileWithLogNumberOfBuckets<0>() { }
198
ValueProfile(int bytecodeOffset): ValueProfileWithLogNumberOfBuckets<0>(bytecodeOffset) { }
202
inline int getValueProfileBytecodeOffset(T* valueProfile)
204
return valueProfile->m_bytecodeOffset;
207
// This is a mini value profile to catch pathologies. It is a counter that gets
208
// incremented when we take the slow path on any instruction.
209
struct RareCaseProfile {
210
RareCaseProfile(int bytecodeOffset)
211
: m_bytecodeOffset(bytecodeOffset)
216
int m_bytecodeOffset;
220
inline int getRareCaseProfileBytecodeOffset(RareCaseProfile* rareCaseProfile)
222
return rareCaseProfile->m_bytecodeOffset;
227
#endif // ENABLE(VALUE_PROFILER)
229
#endif // ValueProfile_h