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/macro-assembler.h" | 8 #include "src/macro-assembler.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 virtual ~IC() {} | 69 virtual ~IC() {} |
70 | 70 |
71 State state() const { return state_; } | 71 State state() const { return state_; } |
72 inline Address address() const; | 72 inline Address address() const; |
73 | 73 |
74 // Compute the current IC state based on the target stub, receiver and name. | 74 // Compute the current IC state based on the target stub, receiver and name. |
75 void UpdateState(Handle<Object> receiver, Handle<Object> name); | 75 void UpdateState(Handle<Object> receiver, Handle<Object> name); |
76 | 76 |
77 bool IsNameCompatibleWithPrototypeFailure(Handle<Object> name); | 77 bool IsNameCompatibleWithPrototypeFailure(Handle<Object> name); |
78 void MarkPrototypeFailure(Handle<Object> name) { | 78 void MarkPrototypeFailure(Handle<Object> name) { |
79 ASSERT(IsNameCompatibleWithPrototypeFailure(name)); | 79 DCHECK(IsNameCompatibleWithPrototypeFailure(name)); |
80 state_ = PROTOTYPE_FAILURE; | 80 state_ = PROTOTYPE_FAILURE; |
81 } | 81 } |
82 | 82 |
83 // If the stub contains weak maps then this function adds the stub to | 83 // If the stub contains weak maps then this function adds the stub to |
84 // the dependent code array of each weak map. | 84 // the dependent code array of each weak map. |
85 static void RegisterWeakMapDependency(Handle<Code> stub); | 85 static void RegisterWeakMapDependency(Handle<Code> stub); |
86 | 86 |
87 // This function is called when a weak map in the stub is dying, | 87 // This function is called when a weak map in the stub is dying, |
88 // invalidates the stub by setting maps in it to undefined. | 88 // invalidates the stub by setting maps in it to undefined. |
89 static void InvalidateMaps(Code* stub); | 89 static void InvalidateMaps(Code* stub); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 void UpdateMonomorphicIC(Handle<Code> handler, Handle<String> name); | 205 void UpdateMonomorphicIC(Handle<Code> handler, Handle<String> name); |
206 bool UpdatePolymorphicIC(Handle<String> name, Handle<Code> code); | 206 bool UpdatePolymorphicIC(Handle<String> name, Handle<Code> code); |
207 void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code); | 207 void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code); |
208 | 208 |
209 void CopyICToMegamorphicCache(Handle<String> name); | 209 void CopyICToMegamorphicCache(Handle<String> name); |
210 bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map); | 210 bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map); |
211 void PatchCache(Handle<String> name, Handle<Code> code); | 211 void PatchCache(Handle<String> name, Handle<Code> code); |
212 Code::Kind kind() const { return kind_; } | 212 Code::Kind kind() const { return kind_; } |
213 Code::Kind handler_kind() const { | 213 Code::Kind handler_kind() const { |
214 if (kind_ == Code::KEYED_LOAD_IC) return Code::LOAD_IC; | 214 if (kind_ == Code::KEYED_LOAD_IC) return Code::LOAD_IC; |
215 ASSERT(kind_ == Code::LOAD_IC || kind_ == Code::STORE_IC || | 215 DCHECK(kind_ == Code::LOAD_IC || kind_ == Code::STORE_IC || |
216 kind_ == Code::KEYED_STORE_IC); | 216 kind_ == Code::KEYED_STORE_IC); |
217 return kind_; | 217 return kind_; |
218 } | 218 } |
219 virtual Handle<Code> megamorphic_stub() { | 219 virtual Handle<Code> megamorphic_stub() { |
220 UNREACHABLE(); | 220 UNREACHABLE(); |
221 return Handle<Code>::null(); | 221 return Handle<Code>::null(); |
222 } | 222 } |
223 | 223 |
224 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, | 224 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, |
225 Handle<String> name); | 225 Handle<String> name); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 static ContextualMode GetContextualMode(ExtraICState state) { | 426 static ContextualMode GetContextualMode(ExtraICState state) { |
427 return State(state).contextual_mode(); | 427 return State(state).contextual_mode(); |
428 } | 428 } |
429 | 429 |
430 ContextualMode contextual_mode() const { | 430 ContextualMode contextual_mode() const { |
431 return GetContextualMode(extra_ic_state()); | 431 return GetContextualMode(extra_ic_state()); |
432 } | 432 } |
433 | 433 |
434 explicit LoadIC(FrameDepth depth, Isolate* isolate) | 434 explicit LoadIC(FrameDepth depth, Isolate* isolate) |
435 : IC(depth, isolate) { | 435 : IC(depth, isolate) { |
436 ASSERT(IsLoadStub()); | 436 DCHECK(IsLoadStub()); |
437 } | 437 } |
438 | 438 |
439 // Returns if this IC is for contextual (no explicit receiver) | 439 // Returns if this IC is for contextual (no explicit receiver) |
440 // access to properties. | 440 // access to properties. |
441 bool IsUndeclaredGlobal(Handle<Object> receiver) { | 441 bool IsUndeclaredGlobal(Handle<Object> receiver) { |
442 if (receiver->IsGlobalObject()) { | 442 if (receiver->IsGlobalObject()) { |
443 return contextual_mode() == CONTEXTUAL; | 443 return contextual_mode() == CONTEXTUAL; |
444 } else { | 444 } else { |
445 ASSERT(contextual_mode() != CONTEXTUAL); | 445 DCHECK(contextual_mode() != CONTEXTUAL); |
446 return false; | 446 return false; |
447 } | 447 } |
448 } | 448 } |
449 | 449 |
450 // Code generator routines. | 450 // Code generator routines. |
451 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 451 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } |
452 static void GeneratePreMonomorphic(MacroAssembler* masm) { | 452 static void GeneratePreMonomorphic(MacroAssembler* masm) { |
453 GenerateMiss(masm); | 453 GenerateMiss(masm); |
454 } | 454 } |
455 static void GenerateMiss(MacroAssembler* masm); | 455 static void GenerateMiss(MacroAssembler* masm); |
456 static void GenerateMegamorphic(MacroAssembler* masm); | 456 static void GenerateMegamorphic(MacroAssembler* masm); |
457 static void GenerateNormal(MacroAssembler* masm); | 457 static void GenerateNormal(MacroAssembler* masm); |
458 static void GenerateRuntimeGetProperty(MacroAssembler* masm); | 458 static void GenerateRuntimeGetProperty(MacroAssembler* masm); |
459 | 459 |
460 static Handle<Code> initialize_stub(Isolate* isolate, | 460 static Handle<Code> initialize_stub(Isolate* isolate, |
461 ExtraICState extra_state); | 461 ExtraICState extra_state); |
462 | 462 |
463 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, | 463 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, |
464 Handle<String> name); | 464 Handle<String> name); |
465 | 465 |
466 protected: | 466 protected: |
467 void set_target(Code* code) { | 467 void set_target(Code* code) { |
468 // The contextual mode must be preserved across IC patching. | 468 // The contextual mode must be preserved across IC patching. |
469 ASSERT(GetContextualMode(code->extra_ic_state()) == | 469 DCHECK(GetContextualMode(code->extra_ic_state()) == |
470 GetContextualMode(target()->extra_ic_state())); | 470 GetContextualMode(target()->extra_ic_state())); |
471 | 471 |
472 IC::set_target(code); | 472 IC::set_target(code); |
473 } | 473 } |
474 | 474 |
475 Handle<Code> slow_stub() const { | 475 Handle<Code> slow_stub() const { |
476 if (kind() == Code::LOAD_IC) { | 476 if (kind() == Code::LOAD_IC) { |
477 return isolate()->builtins()->LoadIC_Slow(); | 477 return isolate()->builtins()->LoadIC_Slow(); |
478 } else { | 478 } else { |
479 ASSERT_EQ(Code::KEYED_LOAD_IC, kind()); | 479 DCHECK_EQ(Code::KEYED_LOAD_IC, kind()); |
480 return isolate()->builtins()->KeyedLoadIC_Slow(); | 480 return isolate()->builtins()->KeyedLoadIC_Slow(); |
481 } | 481 } |
482 } | 482 } |
483 | 483 |
484 virtual Handle<Code> megamorphic_stub(); | 484 virtual Handle<Code> megamorphic_stub(); |
485 | 485 |
486 // Update the inline cache and the global stub cache based on the | 486 // Update the inline cache and the global stub cache based on the |
487 // lookup result. | 487 // lookup result. |
488 void UpdateCaches(LookupIterator* lookup, Handle<Object> object, | 488 void UpdateCaches(LookupIterator* lookup, Handle<Object> object, |
489 Handle<String> name); | 489 Handle<String> name); |
(...skipping 17 matching lines...) Expand all Loading... |
507 ConstantPoolArray* constant_pool); | 507 ConstantPoolArray* constant_pool); |
508 | 508 |
509 friend class IC; | 509 friend class IC; |
510 }; | 510 }; |
511 | 511 |
512 | 512 |
513 class KeyedLoadIC: public LoadIC { | 513 class KeyedLoadIC: public LoadIC { |
514 public: | 514 public: |
515 explicit KeyedLoadIC(FrameDepth depth, Isolate* isolate) | 515 explicit KeyedLoadIC(FrameDepth depth, Isolate* isolate) |
516 : LoadIC(depth, isolate) { | 516 : LoadIC(depth, isolate) { |
517 ASSERT(target()->is_keyed_load_stub()); | 517 DCHECK(target()->is_keyed_load_stub()); |
518 } | 518 } |
519 | 519 |
520 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, | 520 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, |
521 Handle<Object> key); | 521 Handle<Object> key); |
522 | 522 |
523 // Code generator routines. | 523 // Code generator routines. |
524 static void GenerateMiss(MacroAssembler* masm); | 524 static void GenerateMiss(MacroAssembler* masm); |
525 static void GenerateRuntimeGetProperty(MacroAssembler* masm); | 525 static void GenerateRuntimeGetProperty(MacroAssembler* masm); |
526 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 526 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } |
527 static void GeneratePreMonomorphic(MacroAssembler* masm) { | 527 static void GeneratePreMonomorphic(MacroAssembler* masm) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 kNameIndex, | 589 kNameIndex, |
590 kValueIndex, | 590 kValueIndex, |
591 kParameterCount | 591 kParameterCount |
592 }; | 592 }; |
593 static const Register ReceiverRegister(); | 593 static const Register ReceiverRegister(); |
594 static const Register NameRegister(); | 594 static const Register NameRegister(); |
595 static const Register ValueRegister(); | 595 static const Register ValueRegister(); |
596 | 596 |
597 StoreIC(FrameDepth depth, Isolate* isolate) | 597 StoreIC(FrameDepth depth, Isolate* isolate) |
598 : IC(depth, isolate) { | 598 : IC(depth, isolate) { |
599 ASSERT(IsStoreStub()); | 599 DCHECK(IsStoreStub()); |
600 } | 600 } |
601 | 601 |
602 StrictMode strict_mode() const { | 602 StrictMode strict_mode() const { |
603 return StrictModeState::decode(extra_ic_state()); | 603 return StrictModeState::decode(extra_ic_state()); |
604 } | 604 } |
605 | 605 |
606 // Code generators for stub routines. Only called once at startup. | 606 // Code generators for stub routines. Only called once at startup. |
607 static void GenerateSlow(MacroAssembler* masm); | 607 static void GenerateSlow(MacroAssembler* masm); |
608 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 608 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } |
609 static void GeneratePreMonomorphic(MacroAssembler* masm) { | 609 static void GeneratePreMonomorphic(MacroAssembler* masm) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 Handle<Object> value); | 650 Handle<Object> value); |
651 virtual Handle<Code> CompileStoreHandler(LookupResult* lookup, | 651 virtual Handle<Code> CompileStoreHandler(LookupResult* lookup, |
652 Handle<Object> object, | 652 Handle<Object> object, |
653 Handle<String> name, | 653 Handle<String> name, |
654 Handle<Object> value, | 654 Handle<Object> value, |
655 CacheHolderFlag cache_holder); | 655 CacheHolderFlag cache_holder); |
656 | 656 |
657 private: | 657 private: |
658 void set_target(Code* code) { | 658 void set_target(Code* code) { |
659 // Strict mode must be preserved across IC patching. | 659 // Strict mode must be preserved across IC patching. |
660 ASSERT(GetStrictMode(code->extra_ic_state()) == | 660 DCHECK(GetStrictMode(code->extra_ic_state()) == |
661 GetStrictMode(target()->extra_ic_state())); | 661 GetStrictMode(target()->extra_ic_state())); |
662 IC::set_target(code); | 662 IC::set_target(code); |
663 } | 663 } |
664 | 664 |
665 static void Clear(Isolate* isolate, | 665 static void Clear(Isolate* isolate, |
666 Address address, | 666 Address address, |
667 Code* target, | 667 Code* target, |
668 ConstantPoolArray* constant_pool); | 668 ConstantPoolArray* constant_pool); |
669 | 669 |
670 friend class IC; | 670 friend class IC; |
(...skipping 30 matching lines...) Expand all Loading... |
701 return ExtraICStateKeyedAccessStoreMode::decode(extra_state); | 701 return ExtraICStateKeyedAccessStoreMode::decode(extra_state); |
702 } | 702 } |
703 | 703 |
704 // The map register isn't part of the normal call specification, but | 704 // The map register isn't part of the normal call specification, but |
705 // ElementsTransitionAndStoreStub, used in polymorphic keyed store | 705 // ElementsTransitionAndStoreStub, used in polymorphic keyed store |
706 // stub implementations requires it to be initialized. | 706 // stub implementations requires it to be initialized. |
707 static const Register MapRegister(); | 707 static const Register MapRegister(); |
708 | 708 |
709 KeyedStoreIC(FrameDepth depth, Isolate* isolate) | 709 KeyedStoreIC(FrameDepth depth, Isolate* isolate) |
710 : StoreIC(depth, isolate) { | 710 : StoreIC(depth, isolate) { |
711 ASSERT(target()->is_keyed_store_stub()); | 711 DCHECK(target()->is_keyed_store_stub()); |
712 } | 712 } |
713 | 713 |
714 MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Object> object, | 714 MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Object> object, |
715 Handle<Object> name, | 715 Handle<Object> name, |
716 Handle<Object> value); | 716 Handle<Object> value); |
717 | 717 |
718 // Code generators for stub routines. Only called once at startup. | 718 // Code generators for stub routines. Only called once at startup. |
719 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 719 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } |
720 static void GeneratePreMonomorphic(MacroAssembler* masm) { | 720 static void GeneratePreMonomorphic(MacroAssembler* masm) { |
721 GenerateMiss(masm); | 721 GenerateMiss(masm); |
(...skipping 27 matching lines...) Expand all Loading... |
749 return isolate()->builtins()->KeyedStoreIC_Generic(); | 749 return isolate()->builtins()->KeyedStoreIC_Generic(); |
750 } | 750 } |
751 } | 751 } |
752 | 752 |
753 Handle<Code> StoreElementStub(Handle<JSObject> receiver, | 753 Handle<Code> StoreElementStub(Handle<JSObject> receiver, |
754 KeyedAccessStoreMode store_mode); | 754 KeyedAccessStoreMode store_mode); |
755 | 755 |
756 private: | 756 private: |
757 void set_target(Code* code) { | 757 void set_target(Code* code) { |
758 // Strict mode must be preserved across IC patching. | 758 // Strict mode must be preserved across IC patching. |
759 ASSERT(GetStrictMode(code->extra_ic_state()) == strict_mode()); | 759 DCHECK(GetStrictMode(code->extra_ic_state()) == strict_mode()); |
760 IC::set_target(code); | 760 IC::set_target(code); |
761 } | 761 } |
762 | 762 |
763 // Stub accessors. | 763 // Stub accessors. |
764 virtual Handle<Code> generic_stub() const { | 764 virtual Handle<Code> generic_stub() const { |
765 if (strict_mode() == STRICT) { | 765 if (strict_mode() == STRICT) { |
766 return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); | 766 return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); |
767 } else { | 767 } else { |
768 return isolate()->builtins()->KeyedStoreIC_Generic(); | 768 return isolate()->builtins()->KeyedStoreIC_Generic(); |
769 } | 769 } |
(...skipping 25 matching lines...) Expand all Loading... |
795 // Type Recording BinaryOpIC, that records the types of the inputs and outputs. | 795 // Type Recording BinaryOpIC, that records the types of the inputs and outputs. |
796 class BinaryOpIC: public IC { | 796 class BinaryOpIC: public IC { |
797 public: | 797 public: |
798 class State V8_FINAL BASE_EMBEDDED { | 798 class State V8_FINAL BASE_EMBEDDED { |
799 public: | 799 public: |
800 State(Isolate* isolate, ExtraICState extra_ic_state); | 800 State(Isolate* isolate, ExtraICState extra_ic_state); |
801 | 801 |
802 State(Isolate* isolate, Token::Value op, OverwriteMode mode) | 802 State(Isolate* isolate, Token::Value op, OverwriteMode mode) |
803 : op_(op), mode_(mode), left_kind_(NONE), right_kind_(NONE), | 803 : op_(op), mode_(mode), left_kind_(NONE), right_kind_(NONE), |
804 result_kind_(NONE), isolate_(isolate) { | 804 result_kind_(NONE), isolate_(isolate) { |
805 ASSERT_LE(FIRST_TOKEN, op); | 805 DCHECK_LE(FIRST_TOKEN, op); |
806 ASSERT_LE(op, LAST_TOKEN); | 806 DCHECK_LE(op, LAST_TOKEN); |
807 } | 807 } |
808 | 808 |
809 InlineCacheState GetICState() const { | 809 InlineCacheState GetICState() const { |
810 if (Max(left_kind_, right_kind_) == NONE) { | 810 if (Max(left_kind_, right_kind_) == NONE) { |
811 return ::v8::internal::UNINITIALIZED; | 811 return ::v8::internal::UNINITIALIZED; |
812 } | 812 } |
813 if (Max(left_kind_, right_kind_) == GENERIC) { | 813 if (Max(left_kind_, right_kind_) == GENERIC) { |
814 return ::v8::internal::MEGAMORPHIC; | 814 return ::v8::internal::MEGAMORPHIC; |
815 } | 815 } |
816 if (Min(left_kind_, right_kind_) == GENERIC) { | 816 if (Min(left_kind_, right_kind_) == GENERIC) { |
(...skipping 11 matching lines...) Expand all Loading... |
828 return (result_kind_ > SMI && result_kind_ <= NUMBER) && | 828 return (result_kind_ > SMI && result_kind_ <= NUMBER) && |
829 ((mode_ == OVERWRITE_LEFT && | 829 ((mode_ == OVERWRITE_LEFT && |
830 left_kind_ > SMI && left_kind_ <= NUMBER) || | 830 left_kind_ > SMI && left_kind_ <= NUMBER) || |
831 (mode_ == OVERWRITE_RIGHT && | 831 (mode_ == OVERWRITE_RIGHT && |
832 right_kind_ > SMI && right_kind_ <= NUMBER)); | 832 right_kind_ > SMI && right_kind_ <= NUMBER)); |
833 } | 833 } |
834 | 834 |
835 // Returns true if the IC _could_ create allocation mementos. | 835 // Returns true if the IC _could_ create allocation mementos. |
836 bool CouldCreateAllocationMementos() const { | 836 bool CouldCreateAllocationMementos() const { |
837 if (left_kind_ == STRING || right_kind_ == STRING) { | 837 if (left_kind_ == STRING || right_kind_ == STRING) { |
838 ASSERT_EQ(Token::ADD, op_); | 838 DCHECK_EQ(Token::ADD, op_); |
839 return true; | 839 return true; |
840 } | 840 } |
841 return false; | 841 return false; |
842 } | 842 } |
843 | 843 |
844 // Returns true if the IC _should_ create allocation mementos. | 844 // Returns true if the IC _should_ create allocation mementos. |
845 bool ShouldCreateAllocationMementos() const { | 845 bool ShouldCreateAllocationMementos() const { |
846 return FLAG_allocation_site_pretenuring && | 846 return FLAG_allocation_site_pretenuring && |
847 CouldCreateAllocationMementos(); | 847 CouldCreateAllocationMementos(); |
848 } | 848 } |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 DECLARE_RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss); | 1032 DECLARE_RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss); |
1033 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_Miss); | 1033 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_Miss); |
1034 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite); | 1034 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite); |
1035 DECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss); | 1035 DECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss); |
1036 DECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss); | 1036 DECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss); |
1037 | 1037 |
1038 | 1038 |
1039 } } // namespace v8::internal | 1039 } } // namespace v8::internal |
1040 | 1040 |
1041 #endif // V8_IC_H_ | 1041 #endif // V8_IC_H_ |
OLD | NEW |