]>
Commit | Line | Data |
---|---|---|
6fe7ccc8 | 1 | /* |
81345200 | 2 | * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved. |
6fe7ccc8 A |
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. | |
81345200 | 13 | * 3. Neither the name of Apple Inc. ("Apple") nor the names of |
6fe7ccc8 A |
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 | ||
81345200 | 32 | #include "ConcurrentJITLock.h" |
93a37866 | 33 | #include "Heap.h" |
6fe7ccc8 | 34 | #include "JSArray.h" |
93a37866 | 35 | #include "SpeculatedType.h" |
6fe7ccc8 A |
36 | #include "Structure.h" |
37 | #include "WriteBarrier.h" | |
93a37866 A |
38 | #include <wtf/PrintStream.h> |
39 | #include <wtf/StringPrintStream.h> | |
6fe7ccc8 A |
40 | |
41 | namespace JSC { | |
42 | ||
43 | template<unsigned numberOfBucketsArgument> | |
44 | struct ValueProfileBase { | |
45 | static const unsigned numberOfBuckets = numberOfBucketsArgument; | |
46 | static const unsigned numberOfSpecFailBuckets = 1; | |
47 | static const unsigned bucketIndexMask = numberOfBuckets - 1; | |
48 | static const unsigned totalNumberOfBuckets = numberOfBuckets + numberOfSpecFailBuckets; | |
49 | ||
50 | ValueProfileBase() | |
51 | : m_bytecodeOffset(-1) | |
93a37866 | 52 | , m_prediction(SpecNone) |
6fe7ccc8 A |
53 | , m_numberOfSamplesInPrediction(0) |
54 | { | |
55 | for (unsigned i = 0; i < totalNumberOfBuckets; ++i) | |
56 | m_buckets[i] = JSValue::encode(JSValue()); | |
57 | } | |
58 | ||
59 | ValueProfileBase(int bytecodeOffset) | |
60 | : m_bytecodeOffset(bytecodeOffset) | |
93a37866 | 61 | , m_prediction(SpecNone) |
6fe7ccc8 A |
62 | , m_numberOfSamplesInPrediction(0) |
63 | { | |
64 | for (unsigned i = 0; i < totalNumberOfBuckets; ++i) | |
65 | m_buckets[i] = JSValue::encode(JSValue()); | |
66 | } | |
67 | ||
68 | EncodedJSValue* specFailBucket(unsigned i) | |
69 | { | |
70 | ASSERT(numberOfBuckets + i < totalNumberOfBuckets); | |
71 | return m_buckets + numberOfBuckets + i; | |
72 | } | |
73 | ||
74 | const ClassInfo* classInfo(unsigned bucket) const | |
75 | { | |
76 | JSValue value = JSValue::decode(m_buckets[bucket]); | |
77 | if (!!value) { | |
78 | if (!value.isCell()) | |
79 | return 0; | |
80 | return value.asCell()->structure()->classInfo(); | |
81 | } | |
82 | return 0; | |
83 | } | |
84 | ||
85 | unsigned numberOfSamples() const | |
86 | { | |
87 | unsigned result = 0; | |
88 | for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { | |
89 | if (!!JSValue::decode(m_buckets[i])) | |
90 | result++; | |
91 | } | |
92 | return result; | |
93 | } | |
94 | ||
95 | unsigned totalNumberOfSamples() const | |
96 | { | |
97 | return numberOfSamples() + m_numberOfSamplesInPrediction; | |
98 | } | |
99 | ||
100 | bool isLive() const | |
101 | { | |
102 | for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { | |
103 | if (!!JSValue::decode(m_buckets[i])) | |
104 | return true; | |
105 | } | |
106 | return false; | |
107 | } | |
108 | ||
81345200 | 109 | CString briefDescription(const ConcurrentJITLocker& locker) |
6fe7ccc8 | 110 | { |
81345200 | 111 | computeUpdatedPrediction(locker); |
93a37866 A |
112 | |
113 | StringPrintStream out; | |
81345200 | 114 | out.print("predicting ", SpeculationDump(m_prediction)); |
93a37866 A |
115 | return out.toCString(); |
116 | } | |
117 | ||
118 | void dump(PrintStream& out) | |
119 | { | |
120 | out.print("samples = ", totalNumberOfSamples(), " prediction = ", SpeculationDump(m_prediction)); | |
6fe7ccc8 A |
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) { | |
93a37866 | 126 | out.printf(": "); |
6fe7ccc8 A |
127 | first = false; |
128 | } else | |
93a37866 A |
129 | out.printf(", "); |
130 | out.print(value); | |
6fe7ccc8 A |
131 | } |
132 | } | |
133 | } | |
134 | ||
81345200 A |
135 | // Updates the prediction and returns the new one. Never call this from any thread |
136 | // that isn't executing the code. | |
137 | SpeculatedType computeUpdatedPrediction(const ConcurrentJITLocker&) | |
6fe7ccc8 A |
138 | { |
139 | for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { | |
140 | JSValue value = JSValue::decode(m_buckets[i]); | |
141 | if (!value) | |
142 | continue; | |
143 | ||
144 | m_numberOfSamplesInPrediction++; | |
93a37866 A |
145 | mergeSpeculation(m_prediction, speculationFromValue(value)); |
146 | ||
6fe7ccc8 A |
147 | m_buckets[i] = JSValue::encode(JSValue()); |
148 | } | |
149 | ||
150 | return m_prediction; | |
151 | } | |
152 | ||
153 | int m_bytecodeOffset; // -1 for prologue | |
154 | ||
93a37866 | 155 | SpeculatedType m_prediction; |
6fe7ccc8 A |
156 | unsigned m_numberOfSamplesInPrediction; |
157 | ||
158 | EncodedJSValue m_buckets[totalNumberOfBuckets]; | |
159 | }; | |
160 | ||
161 | struct MinimalValueProfile : public ValueProfileBase<0> { | |
162 | MinimalValueProfile(): ValueProfileBase<0>() { } | |
163 | MinimalValueProfile(int bytecodeOffset): ValueProfileBase<0>(bytecodeOffset) { } | |
164 | }; | |
165 | ||
166 | template<unsigned logNumberOfBucketsArgument> | |
167 | struct ValueProfileWithLogNumberOfBuckets : public ValueProfileBase<1 << logNumberOfBucketsArgument> { | |
168 | static const unsigned logNumberOfBuckets = logNumberOfBucketsArgument; | |
169 | ||
170 | ValueProfileWithLogNumberOfBuckets() | |
171 | : ValueProfileBase<1 << logNumberOfBucketsArgument>() | |
172 | { | |
173 | } | |
174 | ValueProfileWithLogNumberOfBuckets(int bytecodeOffset) | |
175 | : ValueProfileBase<1 << logNumberOfBucketsArgument>(bytecodeOffset) | |
176 | { | |
177 | } | |
178 | }; | |
179 | ||
180 | struct ValueProfile : public ValueProfileWithLogNumberOfBuckets<0> { | |
181 | ValueProfile(): ValueProfileWithLogNumberOfBuckets<0>() { } | |
182 | ValueProfile(int bytecodeOffset): ValueProfileWithLogNumberOfBuckets<0>(bytecodeOffset) { } | |
183 | }; | |
184 | ||
185 | template<typename T> | |
186 | inline int getValueProfileBytecodeOffset(T* valueProfile) | |
187 | { | |
188 | return valueProfile->m_bytecodeOffset; | |
189 | } | |
190 | ||
191 | // This is a mini value profile to catch pathologies. It is a counter that gets | |
192 | // incremented when we take the slow path on any instruction. | |
193 | struct RareCaseProfile { | |
194 | RareCaseProfile(int bytecodeOffset) | |
195 | : m_bytecodeOffset(bytecodeOffset) | |
196 | , m_counter(0) | |
197 | { | |
198 | } | |
199 | ||
200 | int m_bytecodeOffset; | |
201 | uint32_t m_counter; | |
202 | }; | |
203 | ||
204 | inline int getRareCaseProfileBytecodeOffset(RareCaseProfile* rareCaseProfile) | |
205 | { | |
206 | return rareCaseProfile->m_bytecodeOffset; | |
207 | } | |
208 | ||
209 | } // namespace JSC | |
210 | ||
6fe7ccc8 A |
211 | #endif // ValueProfile_h |
212 |