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