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), vector_(NULL), slot_(slot) {} |
| 184 FeedbackNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) |
| 185 : vector_(vector), slot_(slot) {} |
| 186 virtual ~FeedbackNexus() {} |
| 187 |
| 188 Handle<TypeFeedbackVector> vector_handle() const { |
| 189 DCHECK(vector_ == NULL); |
| 190 return vector_handle_; |
| 191 } |
| 192 TypeFeedbackVector* vector() const { |
| 193 return vector_handle_.is_null() ? vector_ : *vector_handle_; |
| 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 having a vector handle and a raw pointer is that we can and |
| 233 // should use handles during IC miss, but not during GC when we clear ICs. If |
| 234 // you have a handle to the vector that is better because more operations can |
| 235 // be done, like allocation. |
| 236 Handle<TypeFeedbackVector> vector_handle_; |
| 237 TypeFeedbackVector* vector_; |
| 238 FeedbackVectorICSlot slot_; |
| 239 }; |
| 240 |
| 241 |
| 242 class CallICNexus : public FeedbackNexus { |
| 243 public: |
| 244 CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) |
| 245 : FeedbackNexus(vector, slot) { |
| 246 DCHECK(vector->GetKind(slot) == Code::CALL_IC); |
| 247 } |
| 248 CallICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) |
| 249 : FeedbackNexus(vector, slot) { |
| 250 DCHECK(vector->GetKind(slot) == Code::CALL_IC); |
| 251 } |
| 252 |
| 253 void ConfigureUninitialized(); |
| 254 void ConfigureGeneric(); |
| 255 void ConfigureMonomorphicArray(); |
| 256 void ConfigureMonomorphic(Handle<JSFunction> function); |
| 257 |
| 258 virtual InlineCacheState StateFromFeedback() const OVERRIDE; |
| 259 |
| 260 virtual int ExtractMaps(MapHandleList* maps) const OVERRIDE { |
| 261 // CallICs don't record map feedback. |
| 262 return 0; |
| 263 } |
| 264 virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE { |
| 265 return MaybeHandle<Code>(); |
| 266 } |
| 267 virtual bool FindHandlers(CodeHandleList* code_list, |
| 268 int length = -1) const OVERRIDE { |
| 269 return length == 0; |
| 270 } |
| 271 }; |
176 } | 272 } |
177 } // namespace v8::internal | 273 } // namespace v8::internal |
178 | 274 |
179 #endif // V8_TRANSITIONS_H_ | 275 #endif // V8_TRANSITIONS_H_ |
OLD | NEW |