OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_IC_H_ | 5 #ifndef V8_IC_H_ |
6 #define V8_IC_H_ | 6 #define V8_IC_H_ |
7 | 7 |
8 #include "src/ic/ic-state.h" | 8 #include "src/ic/ic-state.h" |
9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 void UpdateState(Handle<Object> receiver, Handle<Object> name); | 71 void UpdateState(Handle<Object> receiver, Handle<Object> name); |
72 | 72 |
73 bool IsNameCompatibleWithPrototypeFailure(Handle<Object> name); | 73 bool IsNameCompatibleWithPrototypeFailure(Handle<Object> name); |
74 void MarkPrototypeFailure(Handle<Object> name) { | 74 void MarkPrototypeFailure(Handle<Object> name) { |
75 DCHECK(IsNameCompatibleWithPrototypeFailure(name)); | 75 DCHECK(IsNameCompatibleWithPrototypeFailure(name)); |
76 old_state_ = state_; | 76 old_state_ = state_; |
77 state_ = PROTOTYPE_FAILURE; | 77 state_ = PROTOTYPE_FAILURE; |
78 } | 78 } |
79 | 79 |
80 // Clear the inline cache to initial state. | 80 // Clear the inline cache to initial state. |
81 static void Clear(Isolate* isolate, Address address, Address constant_pool); | 81 static void Clear(Isolate* isolate, Address address, |
| 82 ConstantPoolArray* constant_pool); |
82 | 83 |
83 #ifdef DEBUG | 84 #ifdef DEBUG |
84 bool IsLoadStub() const { | 85 bool IsLoadStub() const { |
85 return target()->is_load_stub() || target()->is_keyed_load_stub(); | 86 return target()->is_load_stub() || target()->is_keyed_load_stub(); |
86 } | 87 } |
87 | 88 |
88 bool IsStoreStub() const { | 89 bool IsStoreStub() const { |
89 return target()->is_store_stub() || target()->is_keyed_store_stub(); | 90 return target()->is_store_stub() || target()->is_keyed_store_stub(); |
90 } | 91 } |
91 | 92 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 void TraceIC(const char* type, Handle<Object> name); | 163 void TraceIC(const char* type, Handle<Object> name); |
163 void TraceIC(const char* type, Handle<Object> name, State old_state, | 164 void TraceIC(const char* type, Handle<Object> name, State old_state, |
164 State new_state); | 165 State new_state); |
165 | 166 |
166 MaybeHandle<Object> TypeError(MessageTemplate::Template, | 167 MaybeHandle<Object> TypeError(MessageTemplate::Template, |
167 Handle<Object> object, Handle<Object> key); | 168 Handle<Object> object, Handle<Object> key); |
168 MaybeHandle<Object> ReferenceError(Handle<Name> name); | 169 MaybeHandle<Object> ReferenceError(Handle<Name> name); |
169 | 170 |
170 // Access the target code for the given IC address. | 171 // Access the target code for the given IC address. |
171 static inline Code* GetTargetAtAddress(Address address, | 172 static inline Code* GetTargetAtAddress(Address address, |
172 Address constant_pool); | 173 ConstantPoolArray* constant_pool); |
173 static inline void SetTargetAtAddress(Address address, Code* target, | 174 static inline void SetTargetAtAddress(Address address, Code* target, |
174 Address constant_pool); | 175 ConstantPoolArray* constant_pool); |
175 static void OnTypeFeedbackChanged(Isolate* isolate, Address address, | 176 static void OnTypeFeedbackChanged(Isolate* isolate, Address address, |
176 State old_state, State new_state, | 177 State old_state, State new_state, |
177 bool target_remains_ic_stub); | 178 bool target_remains_ic_stub); |
178 // As a vector-based IC, type feedback must be updated differently. | 179 // As a vector-based IC, type feedback must be updated differently. |
179 static void OnTypeFeedbackChanged(Isolate* isolate, Code* host, | 180 static void OnTypeFeedbackChanged(Isolate* isolate, Code* host, |
180 TypeFeedbackVector* vector, State old_state, | 181 TypeFeedbackVector* vector, State old_state, |
181 State new_state); | 182 State new_state); |
182 static void PostPatching(Address address, Code* target, Code* old_target); | 183 static void PostPatching(Address address, Code* target, Code* old_target); |
183 | 184 |
184 // Compute the handler either by compiling or by retrieving a cached version. | 185 // Compute the handler either by compiling or by retrieving a cached version. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 template <class NexusClass> | 249 template <class NexusClass> |
249 NexusClass* casted_nexus() { | 250 NexusClass* casted_nexus() { |
250 return static_cast<NexusClass*>(nexus_); | 251 return static_cast<NexusClass*>(nexus_); |
251 } | 252 } |
252 FeedbackNexus* nexus() const { return nexus_; } | 253 FeedbackNexus* nexus() const { return nexus_; } |
253 | 254 |
254 inline Code* get_host(); | 255 inline Code* get_host(); |
255 | 256 |
256 private: | 257 private: |
257 inline Code* raw_target() const; | 258 inline Code* raw_target() const; |
258 inline Address constant_pool() const; | 259 inline ConstantPoolArray* constant_pool() const; |
259 inline Address raw_constant_pool() const; | 260 inline ConstantPoolArray* raw_constant_pool() const; |
260 | 261 |
261 void FindTargetMaps() { | 262 void FindTargetMaps() { |
262 if (target_maps_set_) return; | 263 if (target_maps_set_) return; |
263 target_maps_set_ = true; | 264 target_maps_set_ = true; |
264 if (UseVector()) { | 265 if (UseVector()) { |
265 nexus()->ExtractMaps(&target_maps_); | 266 nexus()->ExtractMaps(&target_maps_); |
266 } else { | 267 } else { |
267 if (state_ == MONOMORPHIC) { | 268 if (state_ == MONOMORPHIC) { |
268 Map* map = target_->FindFirstMap(); | 269 Map* map = target_->FindFirstMap(); |
269 if (map != NULL) target_maps_.Add(handle(map)); | 270 if (map != NULL) target_maps_.Add(handle(map)); |
270 } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) { | 271 } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) { |
271 target_->FindAllMaps(&target_maps_); | 272 target_->FindAllMaps(&target_maps_); |
272 } | 273 } |
273 } | 274 } |
274 } | 275 } |
275 | 276 |
276 // Frame pointer for the frame that uses (calls) the IC. | 277 // Frame pointer for the frame that uses (calls) the IC. |
277 Address fp_; | 278 Address fp_; |
278 | 279 |
279 // All access to the program counter and constant pool of an IC structure is | 280 // All access to the program counter of an IC structure is indirect |
280 // indirect to make the code GC safe. This feature is crucial since | 281 // to make the code GC safe. This feature is crucial since |
281 // GetProperty and SetProperty are called and they in turn might | 282 // GetProperty and SetProperty are called and they in turn might |
282 // invoke the garbage collector. | 283 // invoke the garbage collector. |
283 Address* pc_address_; | 284 Address* pc_address_; |
284 | 285 |
| 286 Isolate* isolate_; |
| 287 |
285 // The constant pool of the code which originally called the IC (which might | 288 // The constant pool of the code which originally called the IC (which might |
286 // be for the breakpointed copy of the original code). | 289 // be for the breakpointed copy of the original code). |
287 Address* constant_pool_address_; | 290 Handle<ConstantPoolArray> raw_constant_pool_; |
288 | |
289 Isolate* isolate_; | |
290 | 291 |
291 // The original code target that missed. | 292 // The original code target that missed. |
292 Handle<Code> target_; | 293 Handle<Code> target_; |
293 bool target_set_; | 294 bool target_set_; |
294 bool vector_set_; | 295 bool vector_set_; |
295 State old_state_; // For saving if we marked as prototype failure. | 296 State old_state_; // For saving if we marked as prototype failure. |
296 State state_; | 297 State state_; |
297 Code::Kind kind_; | 298 Code::Kind kind_; |
298 Handle<Map> receiver_map_; | 299 Handle<Map> receiver_map_; |
299 MaybeHandle<Code> maybe_handler_; | 300 MaybeHandle<Code> maybe_handler_; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 void UpdateCaches(LookupIterator* lookup); | 422 void UpdateCaches(LookupIterator* lookup); |
422 | 423 |
423 virtual Handle<Code> CompileHandler(LookupIterator* lookup, | 424 virtual Handle<Code> CompileHandler(LookupIterator* lookup, |
424 Handle<Object> unused, | 425 Handle<Object> unused, |
425 CacheHolderFlag cache_holder) override; | 426 CacheHolderFlag cache_holder) override; |
426 | 427 |
427 private: | 428 private: |
428 Handle<Code> SimpleFieldLoad(FieldIndex index); | 429 Handle<Code> SimpleFieldLoad(FieldIndex index); |
429 | 430 |
430 static void Clear(Isolate* isolate, Address address, Code* target, | 431 static void Clear(Isolate* isolate, Address address, Code* target, |
431 Address constant_pool); | 432 ConstantPoolArray* constant_pool); |
432 | 433 |
433 friend class IC; | 434 friend class IC; |
434 }; | 435 }; |
435 | 436 |
436 | 437 |
437 class KeyedLoadIC : public LoadIC { | 438 class KeyedLoadIC : public LoadIC { |
438 public: | 439 public: |
439 // ExtraICState bits (building on IC) | 440 // ExtraICState bits (building on IC) |
440 class IcCheckTypeField : public BitField<IcCheckType, 1, 1> {}; | 441 class IcCheckTypeField : public BitField<IcCheckType, 1, 1> {}; |
441 | 442 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 static Handle<Code> ChooseMegamorphicStub(Isolate* isolate); | 479 static Handle<Code> ChooseMegamorphicStub(Isolate* isolate); |
479 | 480 |
480 static void Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus); | 481 static void Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus); |
481 | 482 |
482 protected: | 483 protected: |
483 // receiver is HeapObject because it could be a String or a JSObject | 484 // receiver is HeapObject because it could be a String or a JSObject |
484 Handle<Code> LoadElementStub(Handle<HeapObject> receiver); | 485 Handle<Code> LoadElementStub(Handle<HeapObject> receiver); |
485 | 486 |
486 private: | 487 private: |
487 static void Clear(Isolate* isolate, Address address, Code* target, | 488 static void Clear(Isolate* isolate, Address address, Code* target, |
488 Address constant_pool); | 489 ConstantPoolArray* constant_pool); |
489 | 490 |
490 friend class IC; | 491 friend class IC; |
491 }; | 492 }; |
492 | 493 |
493 | 494 |
494 class StoreIC : public IC { | 495 class StoreIC : public IC { |
495 public: | 496 public: |
496 static ExtraICState ComputeExtraICState(LanguageMode flag) { | 497 static ExtraICState ComputeExtraICState(LanguageMode flag) { |
497 return StoreICState(flag).GetExtraICState(); | 498 return StoreICState(flag).GetExtraICState(); |
498 } | 499 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 void UpdateCaches(LookupIterator* lookup, Handle<Object> value, | 547 void UpdateCaches(LookupIterator* lookup, Handle<Object> value, |
547 JSReceiver::StoreFromKeyed store_mode); | 548 JSReceiver::StoreFromKeyed store_mode); |
548 virtual Handle<Code> CompileHandler(LookupIterator* lookup, | 549 virtual Handle<Code> CompileHandler(LookupIterator* lookup, |
549 Handle<Object> value, | 550 Handle<Object> value, |
550 CacheHolderFlag cache_holder) override; | 551 CacheHolderFlag cache_holder) override; |
551 | 552 |
552 private: | 553 private: |
553 inline void set_target(Code* code); | 554 inline void set_target(Code* code); |
554 | 555 |
555 static void Clear(Isolate* isolate, Address address, Code* target, | 556 static void Clear(Isolate* isolate, Address address, Code* target, |
556 Address constant_pool); | 557 ConstantPoolArray* constant_pool); |
557 | 558 |
558 friend class IC; | 559 friend class IC; |
559 }; | 560 }; |
560 | 561 |
561 | 562 |
562 enum KeyedStoreCheckMap { kDontCheckMap, kCheckMap }; | 563 enum KeyedStoreCheckMap { kDontCheckMap, kCheckMap }; |
563 | 564 |
564 | 565 |
565 enum KeyedStoreIncrementLength { kDontIncrementLength, kIncrementLength }; | 566 enum KeyedStoreIncrementLength { kDontIncrementLength, kIncrementLength }; |
566 | 567 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 } | 628 } |
628 } | 629 } |
629 | 630 |
630 Handle<Code> StoreElementStub(Handle<JSObject> receiver, | 631 Handle<Code> StoreElementStub(Handle<JSObject> receiver, |
631 KeyedAccessStoreMode store_mode); | 632 KeyedAccessStoreMode store_mode); |
632 | 633 |
633 private: | 634 private: |
634 inline void set_target(Code* code); | 635 inline void set_target(Code* code); |
635 | 636 |
636 static void Clear(Isolate* isolate, Address address, Code* target, | 637 static void Clear(Isolate* isolate, Address address, Code* target, |
637 Address constant_pool); | 638 ConstantPoolArray* constant_pool); |
638 | 639 |
639 KeyedAccessStoreMode GetStoreMode(Handle<JSObject> receiver, | 640 KeyedAccessStoreMode GetStoreMode(Handle<JSObject> receiver, |
640 Handle<Object> key, Handle<Object> value); | 641 Handle<Object> key, Handle<Object> value); |
641 | 642 |
642 Handle<Map> ComputeTransitionedMap(Handle<Map> map, | 643 Handle<Map> ComputeTransitionedMap(Handle<Map> map, |
643 KeyedAccessStoreMode store_mode); | 644 KeyedAccessStoreMode store_mode); |
644 | 645 |
645 friend class IC; | 646 friend class IC; |
646 }; | 647 }; |
647 | 648 |
(...skipping 30 matching lines...) Expand all Loading... |
678 private: | 679 private: |
679 static bool HasInlinedSmiCode(Address address); | 680 static bool HasInlinedSmiCode(Address address); |
680 | 681 |
681 bool strict() const { return op_ == Token::EQ_STRICT; } | 682 bool strict() const { return op_ == Token::EQ_STRICT; } |
682 Condition GetCondition() const { return ComputeCondition(op_); } | 683 Condition GetCondition() const { return ComputeCondition(op_); } |
683 | 684 |
684 static Code* GetRawUninitialized(Isolate* isolate, Token::Value op, | 685 static Code* GetRawUninitialized(Isolate* isolate, Token::Value op, |
685 bool strong); | 686 bool strong); |
686 | 687 |
687 static void Clear(Isolate* isolate, Address address, Code* target, | 688 static void Clear(Isolate* isolate, Address address, Code* target, |
688 Address constant_pool); | 689 ConstantPoolArray* constant_pool); |
689 | 690 |
690 Token::Value op_; | 691 Token::Value op_; |
691 | 692 |
692 friend class IC; | 693 friend class IC; |
693 }; | 694 }; |
694 | 695 |
695 | 696 |
696 class CompareNilIC : public IC { | 697 class CompareNilIC : public IC { |
697 public: | 698 public: |
698 explicit CompareNilIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {} | 699 explicit CompareNilIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {} |
699 | 700 |
700 Handle<Object> CompareNil(Handle<Object> object); | 701 Handle<Object> CompareNil(Handle<Object> object); |
701 | 702 |
702 static Handle<Code> GetUninitialized(); | 703 static Handle<Code> GetUninitialized(); |
703 | 704 |
704 static void Clear(Address address, Code* target, Address constant_pool); | 705 static void Clear(Address address, Code* target, |
| 706 ConstantPoolArray* constant_pool); |
705 | 707 |
706 static Handle<Object> DoCompareNilSlow(Isolate* isolate, NilValue nil, | 708 static Handle<Object> DoCompareNilSlow(Isolate* isolate, NilValue nil, |
707 Handle<Object> object); | 709 Handle<Object> object); |
708 }; | 710 }; |
709 | 711 |
710 | 712 |
711 class ToBooleanIC : public IC { | 713 class ToBooleanIC : public IC { |
712 public: | 714 public: |
713 explicit ToBooleanIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {} | 715 explicit ToBooleanIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {} |
714 | 716 |
(...skipping 21 matching lines...) Expand all Loading... |
736 | 738 |
737 // Support functions for interceptor handlers. | 739 // Support functions for interceptor handlers. |
738 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly); | 740 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly); |
739 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptor); | 741 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptor); |
740 DECLARE_RUNTIME_FUNCTION(LoadElementWithInterceptor); | 742 DECLARE_RUNTIME_FUNCTION(LoadElementWithInterceptor); |
741 DECLARE_RUNTIME_FUNCTION(StorePropertyWithInterceptor); | 743 DECLARE_RUNTIME_FUNCTION(StorePropertyWithInterceptor); |
742 } | 744 } |
743 } // namespace v8::internal | 745 } // namespace v8::internal |
744 | 746 |
745 #endif // V8_IC_H_ | 747 #endif // V8_IC_H_ |
OLD | NEW |