OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_TYPE_FEEDBACK_VECTOR_H_ | 5 #ifndef V8_TYPE_FEEDBACK_VECTOR_H_ |
6 #define V8_TYPE_FEEDBACK_VECTOR_H_ | 6 #define V8_TYPE_FEEDBACK_VECTOR_H_ |
7 | 7 |
8 #include "src/checks.h" | 8 #include "src/checks.h" |
9 #include "src/elements-kind.h" | 9 #include "src/elements-kind.h" |
10 #include "src/heap/heap.h" | 10 #include "src/heap/heap.h" |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 }; | 166 }; |
167 | 167 |
168 static const int kVectorICKindBits = 2; | 168 static const int kVectorICKindBits = 2; |
169 static VectorICKind FromCodeKind(Code::Kind kind); | 169 static VectorICKind FromCodeKind(Code::Kind kind); |
170 static Code::Kind FromVectorICKind(VectorICKind kind); | 170 static Code::Kind FromVectorICKind(VectorICKind kind); |
171 typedef BitSetComputer<VectorICKind, kVectorICKindBits, kSmiValueSize, | 171 typedef BitSetComputer<VectorICKind, kVectorICKindBits, kSmiValueSize, |
172 uint32_t> VectorICComputer; | 172 uint32_t> VectorICComputer; |
173 | 173 |
174 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector); | 174 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector); |
175 }; | 175 }; |
176 | |
177 | |
178 // A FeedbackNexus is the combination of a TypeFeedbackVector and a slot. | |
179 // Derived classes customize the update and retrieval of feedback. | |
180 class FeedbackNexus { | |
181 public: | |
182 FeedbackNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) | |
183 : vector_handle_(vector), use_handle_(true), slot_(slot) {} | |
184 FeedbackNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) | |
185 : vector_(vector), use_handle_(false), slot_(slot) {} | |
186 virtual ~FeedbackNexus() {} | |
187 | |
188 Handle<TypeFeedbackVector> vector_handle() const { | |
189 DCHECK(use_handle_); | |
190 return vector_handle_; | |
191 } | |
192 TypeFeedbackVector* vector() const { | |
193 return use_handle_ ? *vector_handle_ : vector_; | |
194 } | |
195 FeedbackVectorICSlot slot() const { return slot_; } | |
196 | |
197 InlineCacheState ic_state() const { return StateFromFeedback(); } | |
198 Map* FindFirstMap() const { | |
199 MapHandleList maps; | |
200 ExtractMaps(&maps); | |
201 if (maps.length() > 0) return *maps.at(0); | |
202 return NULL; | |
203 } | |
204 | |
205 virtual InlineCacheState StateFromFeedback() const = 0; | |
206 virtual int ExtractMaps(MapHandleList* maps) const = 0; | |
207 virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const = 0; | |
208 virtual bool FindHandlers(CodeHandleList* code_list, int length = -1) const { | |
209 return length == 0; | |
210 } | |
211 virtual Name* FindFirstName() const { return NULL; } | |
212 | |
213 Object* GetFeedback() const { return vector()->Get(slot()); } | |
214 | |
215 protected: | |
216 Isolate* GetIsolate() const { return vector()->GetIsolate(); } | |
217 | |
218 void SetFeedback(Object* feedback, | |
219 WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { | |
220 vector()->Set(slot(), feedback, mode); | |
221 } | |
222 | |
223 Handle<FixedArray> EnsureArrayOfSize(int length); | |
224 void InstallHandlers(int start_index, TypeHandleList* types, | |
225 CodeHandleList* handlers); | |
226 int ExtractMaps(int start_index, MapHandleList* maps) const; | |
227 MaybeHandle<Code> FindHandlerForMap(int start_index, Handle<Map> map) const; | |
228 bool FindHandlers(int start_index, CodeHandleList* code_list, | |
229 int length) const; | |
230 | |
231 private: | |
232 // The reason for the union is that we can use handles during IC miss, | |
233 // but not during GC when we clear ICs. If you have a handle to the | |
234 // vector that is better because more operations can be done, like | |
235 // allocation. | |
236 union { | |
237 Handle<TypeFeedbackVector> vector_handle_; | |
238 TypeFeedbackVector* vector_; | |
239 }; | |
240 bool use_handle_; | |
241 FeedbackVectorICSlot slot_; | |
242 }; | |
243 | |
244 | |
245 class CallICNexus : public FeedbackNexus { | |
246 public: | |
247 CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) | |
248 : FeedbackNexus(vector, slot) { | |
249 DCHECK(vector->GetKind(slot) == Code::CALL_IC); | |
250 } | |
251 CallICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) | |
252 : FeedbackNexus(vector, slot) { | |
253 DCHECK(vector->GetKind(slot) == Code::CALL_IC); | |
254 } | |
255 | |
256 void ConfigureUninitialized(); | |
257 void ConfigureGeneric(); | |
258 void ConfigureMonomorphicArray(); | |
259 void ConfigureMonomorphic(Handle<JSFunction> function); | |
260 | |
261 virtual InlineCacheState StateFromFeedback() const OVERRIDE; | |
262 | |
263 virtual int ExtractMaps(MapHandleList* maps) const OVERRIDE { | |
264 // CallICs don't record map feedback. | |
265 return 0; | |
266 } | |
267 virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE { | |
268 return MaybeHandle<Code>(); | |
269 } | |
270 virtual bool FindHandlers(CodeHandleList* code_list, | |
271 int length = -1) const OVERRIDE { | |
272 return length == 0; | |
273 } | |
274 }; | |
275 } | 176 } |
276 } // namespace v8::internal | 177 } // namespace v8::internal |
277 | 178 |
278 #endif // V8_TRANSITIONS_H_ | 179 #endif // V8_TRANSITIONS_H_ |
OLD | NEW |