~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/JavaScriptCore/bytecode/ValueProfile.h

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions
 
6
 * are met:
 
7
 *
 
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.
 
16
 *
 
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.
 
27
 */
 
28
 
 
29
#ifndef ValueProfile_h
 
30
#define ValueProfile_h
 
31
 
 
32
#include <wtf/Platform.h>
 
33
 
 
34
#if ENABLE(VALUE_PROFILER)
 
35
 
 
36
#include "Heap.h"
 
37
#include "JSArray.h"
 
38
#include "SpeculatedType.h"
 
39
#include "Structure.h"
 
40
#include "WriteBarrier.h"
 
41
#include <wtf/PrintStream.h>
 
42
 
 
43
namespace JSC {
 
44
 
 
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;
 
51
    
 
52
    ValueProfileBase()
 
53
        : m_bytecodeOffset(-1)
 
54
        , m_prediction(SpecNone)
 
55
        , m_numberOfSamplesInPrediction(0)
 
56
        , m_singletonValueIsTop(false)
 
57
    {
 
58
        for (unsigned i = 0; i < totalNumberOfBuckets; ++i)
 
59
            m_buckets[i] = JSValue::encode(JSValue());
 
60
    }
 
61
    
 
62
    ValueProfileBase(int bytecodeOffset)
 
63
        : m_bytecodeOffset(bytecodeOffset)
 
64
        , m_prediction(SpecNone)
 
65
        , m_numberOfSamplesInPrediction(0)
 
66
        , m_singletonValueIsTop(false)
 
67
    {
 
68
        for (unsigned i = 0; i < totalNumberOfBuckets; ++i)
 
69
            m_buckets[i] = JSValue::encode(JSValue());
 
70
    }
 
71
    
 
72
    EncodedJSValue* specFailBucket(unsigned i)
 
73
    {
 
74
        ASSERT(numberOfBuckets + i < totalNumberOfBuckets);
 
75
        return m_buckets + numberOfBuckets + i;
 
76
    }
 
77
    
 
78
    const ClassInfo* classInfo(unsigned bucket) const
 
79
    {
 
80
        JSValue value = JSValue::decode(m_buckets[bucket]);
 
81
        if (!!value) {
 
82
            if (!value.isCell())
 
83
                return 0;
 
84
            return value.asCell()->structure()->classInfo();
 
85
        }
 
86
        return 0;
 
87
    }
 
88
    
 
89
    unsigned numberOfSamples() const
 
90
    {
 
91
        unsigned result = 0;
 
92
        for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
 
93
            if (!!JSValue::decode(m_buckets[i]))
 
94
                result++;
 
95
        }
 
96
        return result;
 
97
    }
 
98
    
 
99
    unsigned totalNumberOfSamples() const
 
100
    {
 
101
        return numberOfSamples() + m_numberOfSamplesInPrediction;
 
102
    }
 
103
    
 
104
    bool isLive() const
 
105
    {
 
106
        for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
 
107
            if (!!JSValue::decode(m_buckets[i]))
 
108
                return true;
 
109
        }
 
110
        return false;
 
111
    }
 
112
    
 
113
    void dump(PrintStream& out)
 
114
    {
 
115
        out.print("samples = ", totalNumberOfSamples(), " prediction = ", SpeculationDump(m_prediction));
 
116
        out.printf(", value = ");
 
117
        if (m_singletonValueIsTop)
 
118
            out.printf("TOP");
 
119
        else
 
120
            out.printf("%s", m_singletonValue.description());
 
121
        bool first = true;
 
122
        for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
 
123
            JSValue value = JSValue::decode(m_buckets[i]);
 
124
            if (!!value) {
 
125
                if (first) {
 
126
                    out.printf(": ");
 
127
                    first = false;
 
128
                } else
 
129
                    out.printf(", ");
 
130
                out.printf("%s", value.description());
 
131
            }
 
132
        }
 
133
    }
 
134
    
 
135
    // Updates the prediction and returns the new one.
 
136
    SpeculatedType computeUpdatedPrediction(OperationInProgress operation = NoOperation)
 
137
    {
 
138
        for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
 
139
            JSValue value = JSValue::decode(m_buckets[i]);
 
140
            if (!value)
 
141
                continue;
 
142
            
 
143
            m_numberOfSamplesInPrediction++;
 
144
            mergeSpeculation(m_prediction, speculationFromValue(value));
 
145
            
 
146
            if (!m_singletonValueIsTop && !!value) {
 
147
                if (!m_singletonValue)
 
148
                    m_singletonValue = value;
 
149
                else if (m_singletonValue != value)
 
150
                    m_singletonValueIsTop = true;
 
151
            }
 
152
            
 
153
            m_buckets[i] = JSValue::encode(JSValue());
 
154
        }
 
155
        
 
156
        if (operation == Collection
 
157
            && !m_singletonValueIsTop
 
158
            && !!m_singletonValue
 
159
            && m_singletonValue.isCell()
 
160
            && !Heap::isMarked(m_singletonValue.asCell()))
 
161
            m_singletonValueIsTop = true;
 
162
            
 
163
        return m_prediction;
 
164
    }
 
165
    
 
166
    int m_bytecodeOffset; // -1 for prologue
 
167
    
 
168
    SpeculatedType m_prediction;
 
169
    unsigned m_numberOfSamplesInPrediction;
 
170
    
 
171
    bool m_singletonValueIsTop;
 
172
    JSValue m_singletonValue;
 
173
 
 
174
    EncodedJSValue m_buckets[totalNumberOfBuckets];
 
175
};
 
176
 
 
177
struct MinimalValueProfile : public ValueProfileBase<0> {
 
178
    MinimalValueProfile(): ValueProfileBase<0>() { }
 
179
    MinimalValueProfile(int bytecodeOffset): ValueProfileBase<0>(bytecodeOffset) { }
 
180
};
 
181
 
 
182
template<unsigned logNumberOfBucketsArgument>
 
183
struct ValueProfileWithLogNumberOfBuckets : public ValueProfileBase<1 << logNumberOfBucketsArgument> {
 
184
    static const unsigned logNumberOfBuckets = logNumberOfBucketsArgument;
 
185
    
 
186
    ValueProfileWithLogNumberOfBuckets()
 
187
        : ValueProfileBase<1 << logNumberOfBucketsArgument>()
 
188
    {
 
189
    }
 
190
    ValueProfileWithLogNumberOfBuckets(int bytecodeOffset)
 
191
        : ValueProfileBase<1 << logNumberOfBucketsArgument>(bytecodeOffset)
 
192
    {
 
193
    }
 
194
};
 
195
 
 
196
struct ValueProfile : public ValueProfileWithLogNumberOfBuckets<0> {
 
197
    ValueProfile(): ValueProfileWithLogNumberOfBuckets<0>() { }
 
198
    ValueProfile(int bytecodeOffset): ValueProfileWithLogNumberOfBuckets<0>(bytecodeOffset) { }
 
199
};
 
200
 
 
201
template<typename T>
 
202
inline int getValueProfileBytecodeOffset(T* valueProfile)
 
203
{
 
204
    return valueProfile->m_bytecodeOffset;
 
205
}
 
206
 
 
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)
 
212
        , m_counter(0)
 
213
    {
 
214
    }
 
215
    
 
216
    int m_bytecodeOffset;
 
217
    uint32_t m_counter;
 
218
};
 
219
 
 
220
inline int getRareCaseProfileBytecodeOffset(RareCaseProfile* rareCaseProfile)
 
221
{
 
222
    return rareCaseProfile->m_bytecodeOffset;
 
223
}
 
224
 
 
225
} // namespace JSC
 
226
 
 
227
#endif // ENABLE(VALUE_PROFILER)
 
228
 
 
229
#endif // ValueProfile_h
 
230