| 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 |