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_DEOPTIMIZER_H_ | 5 #ifndef V8_DEOPTIMIZER_H_ |
6 #define V8_DEOPTIMIZER_H_ | 6 #define V8_DEOPTIMIZER_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
10 | 10 |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 | 14 |
15 class FrameDescription; | 15 class FrameDescription; |
16 class TranslationIterator; | 16 class TranslationIterator; |
17 class DeoptimizedFrameInfo; | 17 class DeoptimizedFrameInfo; |
18 class TranslatedState; | 18 class TranslatedState; |
19 class RegisterValues; | 19 class RegisterValues; |
20 | 20 |
21 class TranslatedValue { | 21 class TranslatedValue { |
22 public: | 22 public: |
23 // Allocation-less getter of the value. | 23 // Allocation-less getter of the value. |
24 // Returns heap()->arguments_marker() if allocation would be | 24 // Returns heap()->arguments_marker() if allocation would be |
25 // necessary to get the value. | 25 // necessary to get the value. |
26 Object* GetRawValue() const; | 26 Object* GetRawValue() const; |
27 Handle<Object> GetValue(); | 27 Handle<Object> GetValue(); |
28 | 28 |
29 bool IsMaterializedObject() const; | 29 bool IsMaterializedObject() const; |
| 30 bool IsMaterializableByDebugger() const; |
30 | 31 |
31 private: | 32 private: |
32 friend class TranslatedState; | 33 friend class TranslatedState; |
33 friend class TranslatedFrame; | 34 friend class TranslatedFrame; |
34 | 35 |
35 enum Kind { | 36 enum Kind { |
36 kInvalid, | 37 kInvalid, |
37 kTagged, | 38 kTagged, |
38 kInt32, | 39 kInt32, |
39 kUInt32, | 40 kUInt32, |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 static void VisitAllOptimizedFunctions( | 502 static void VisitAllOptimizedFunctions( |
502 Isolate* isolate, OptimizedFunctionVisitor* visitor); | 503 Isolate* isolate, OptimizedFunctionVisitor* visitor); |
503 | 504 |
504 // The size in bytes of the code required at a lazy deopt patch site. | 505 // The size in bytes of the code required at a lazy deopt patch site. |
505 static int patch_size(); | 506 static int patch_size(); |
506 | 507 |
507 ~Deoptimizer(); | 508 ~Deoptimizer(); |
508 | 509 |
509 void MaterializeHeapObjects(JavaScriptFrameIterator* it); | 510 void MaterializeHeapObjects(JavaScriptFrameIterator* it); |
510 | 511 |
511 void MaterializeHeapNumbersForDebuggerInspectableFrame( | |
512 int frame_index, int parameter_count, int expression_count, | |
513 DeoptimizedFrameInfo* info); | |
514 | |
515 static void ComputeOutputFrames(Deoptimizer* deoptimizer); | 512 static void ComputeOutputFrames(Deoptimizer* deoptimizer); |
516 | 513 |
517 | 514 |
518 enum GetEntryMode { | 515 enum GetEntryMode { |
519 CALCULATE_ENTRY_ADDRESS, | 516 CALCULATE_ENTRY_ADDRESS, |
520 ENSURE_ENTRY_CODE | 517 ENSURE_ENTRY_CODE |
521 }; | 518 }; |
522 | 519 |
523 | 520 |
524 static Address GetDeoptimizationEntry( | 521 static Address GetDeoptimizationEntry( |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 static void DeoptimizeMarkedCodeForContext(Context* native_context); | 635 static void DeoptimizeMarkedCodeForContext(Context* native_context); |
639 | 636 |
640 // Patch the given code so that it will deoptimize itself. | 637 // Patch the given code so that it will deoptimize itself. |
641 static void PatchCodeForDeoptimization(Isolate* isolate, Code* code); | 638 static void PatchCodeForDeoptimization(Isolate* isolate, Code* code); |
642 | 639 |
643 // Searches the list of known deoptimizing code for a Code object | 640 // Searches the list of known deoptimizing code for a Code object |
644 // containing the given address (which is supposedly faster than | 641 // containing the given address (which is supposedly faster than |
645 // searching all code objects). | 642 // searching all code objects). |
646 Code* FindDeoptimizingCode(Address addr); | 643 Code* FindDeoptimizingCode(Address addr); |
647 | 644 |
648 // Fill the input from from a JavaScript frame. This is used when | |
649 // the debugger needs to inspect an optimized frame. For normal | |
650 // deoptimizations the input frame is filled in generated code. | |
651 void FillInputFrame(Address tos, JavaScriptFrame* frame); | |
652 | |
653 // Fill the given output frame's registers to contain the failure handler | 645 // Fill the given output frame's registers to contain the failure handler |
654 // address and the number of parameters for a stub failure trampoline. | 646 // address and the number of parameters for a stub failure trampoline. |
655 void SetPlatformCompiledStubRegisters(FrameDescription* output_frame, | 647 void SetPlatformCompiledStubRegisters(FrameDescription* output_frame, |
656 CodeStubDescriptor* desc); | 648 CodeStubDescriptor* desc); |
657 | 649 |
658 // Fill the given output frame's double registers with the original values | 650 // Fill the given output frame's double registers with the original values |
659 // from the input frame's double registers. | 651 // from the input frame's double registers. |
660 void CopyDoubleRegisters(FrameDescription* output_frame); | 652 void CopyDoubleRegisters(FrameDescription* output_frame); |
661 | 653 |
662 // Determines whether the input frame contains alignment padding by looking | 654 // Determines whether the input frame contains alignment padding by looking |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 double_registers_[n] = value; | 729 double_registers_[n] = value; |
738 } | 730 } |
739 | 731 |
740 intptr_t registers_[Register::kNumRegisters]; | 732 intptr_t registers_[Register::kNumRegisters]; |
741 double double_registers_[DoubleRegister::kMaxNumRegisters]; | 733 double double_registers_[DoubleRegister::kMaxNumRegisters]; |
742 }; | 734 }; |
743 | 735 |
744 | 736 |
745 class FrameDescription { | 737 class FrameDescription { |
746 public: | 738 public: |
747 FrameDescription(uint32_t frame_size, | 739 explicit FrameDescription(uint32_t frame_size, int parameter_count = 0); |
748 JSFunction* function); | |
749 | 740 |
750 void* operator new(size_t size, uint32_t frame_size) { | 741 void* operator new(size_t size, uint32_t frame_size) { |
751 // Subtracts kPointerSize, as the member frame_content_ already supplies | 742 // Subtracts kPointerSize, as the member frame_content_ already supplies |
752 // the first element of the area to store the frame. | 743 // the first element of the area to store the frame. |
753 return malloc(size + frame_size - kPointerSize); | 744 return malloc(size + frame_size - kPointerSize); |
754 } | 745 } |
755 | 746 |
756 void operator delete(void* pointer, uint32_t frame_size) { | 747 void operator delete(void* pointer, uint32_t frame_size) { |
757 free(pointer); | 748 free(pointer); |
758 } | 749 } |
759 | 750 |
760 void operator delete(void* description) { | 751 void operator delete(void* description) { |
761 free(description); | 752 free(description); |
762 } | 753 } |
763 | 754 |
764 uint32_t GetFrameSize() const { | 755 uint32_t GetFrameSize() const { |
765 DCHECK(static_cast<uint32_t>(frame_size_) == frame_size_); | 756 DCHECK(static_cast<uint32_t>(frame_size_) == frame_size_); |
766 return static_cast<uint32_t>(frame_size_); | 757 return static_cast<uint32_t>(frame_size_); |
767 } | 758 } |
768 | 759 |
769 JSFunction* GetFunction() const { return function_; } | |
770 | |
771 unsigned GetOffsetFromSlotIndex(int slot_index); | 760 unsigned GetOffsetFromSlotIndex(int slot_index); |
772 | 761 |
773 intptr_t GetFrameSlot(unsigned offset) { | 762 intptr_t GetFrameSlot(unsigned offset) { |
774 return *GetFrameSlotPointer(offset); | 763 return *GetFrameSlotPointer(offset); |
775 } | 764 } |
776 | 765 |
777 Address GetFramePointerAddress() { | 766 Address GetFramePointerAddress() { |
778 int fp_offset = GetFrameSize() - | 767 int fp_offset = GetFrameSize() - parameter_count() * kPointerSize - |
779 (ComputeParametersCount() + 1) * kPointerSize - | |
780 StandardFrameConstants::kCallerSPOffset; | 768 StandardFrameConstants::kCallerSPOffset; |
781 return reinterpret_cast<Address>(GetFrameSlotPointer(fp_offset)); | 769 return reinterpret_cast<Address>(GetFrameSlotPointer(fp_offset)); |
782 } | 770 } |
783 | 771 |
784 RegisterValues* GetRegisterValues() { return ®ister_values_; } | 772 RegisterValues* GetRegisterValues() { return ®ister_values_; } |
785 | 773 |
786 void SetFrameSlot(unsigned offset, intptr_t value) { | 774 void SetFrameSlot(unsigned offset, intptr_t value) { |
787 *GetFrameSlotPointer(offset) = value; | 775 *GetFrameSlotPointer(offset) = value; |
788 } | 776 } |
789 | 777 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 } | 815 } |
828 | 816 |
829 Smi* GetState() const { return state_; } | 817 Smi* GetState() const { return state_; } |
830 void SetState(Smi* state) { state_ = state; } | 818 void SetState(Smi* state) { state_ = state; } |
831 | 819 |
832 void SetContinuation(intptr_t pc) { continuation_ = pc; } | 820 void SetContinuation(intptr_t pc) { continuation_ = pc; } |
833 | 821 |
834 StackFrame::Type GetFrameType() const { return type_; } | 822 StackFrame::Type GetFrameType() const { return type_; } |
835 void SetFrameType(StackFrame::Type type) { type_ = type; } | 823 void SetFrameType(StackFrame::Type type) { type_ = type; } |
836 | 824 |
837 // Get the incoming arguments count. | 825 // Argument count, including receiver. |
838 int ComputeParametersCount(); | 826 int parameter_count() { return parameter_count_; } |
839 | |
840 // Get a parameter value for an unoptimized frame. | |
841 Object* GetParameter(int index); | |
842 | |
843 // Get the expression stack height for a unoptimized frame. | |
844 unsigned GetExpressionCount(); | |
845 | |
846 // Get the expression stack value for an unoptimized frame. | |
847 Object* GetExpression(int index); | |
848 | 827 |
849 static int registers_offset() { | 828 static int registers_offset() { |
850 return OFFSET_OF(FrameDescription, register_values_.registers_); | 829 return OFFSET_OF(FrameDescription, register_values_.registers_); |
851 } | 830 } |
852 | 831 |
853 static int double_registers_offset() { | 832 static int double_registers_offset() { |
854 return OFFSET_OF(FrameDescription, register_values_.double_registers_); | 833 return OFFSET_OF(FrameDescription, register_values_.double_registers_); |
855 } | 834 } |
856 | 835 |
857 static int frame_size_offset() { | 836 static int frame_size_offset() { |
(...skipping 12 matching lines...) Expand all Loading... |
870 return offsetof(FrameDescription, frame_content_); | 849 return offsetof(FrameDescription, frame_content_); |
871 } | 850 } |
872 | 851 |
873 private: | 852 private: |
874 static const uint32_t kZapUint32 = 0xbeeddead; | 853 static const uint32_t kZapUint32 = 0xbeeddead; |
875 | 854 |
876 // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to | 855 // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to |
877 // keep the variable-size array frame_content_ of type intptr_t at | 856 // keep the variable-size array frame_content_ of type intptr_t at |
878 // the end of the structure aligned. | 857 // the end of the structure aligned. |
879 uintptr_t frame_size_; // Number of bytes. | 858 uintptr_t frame_size_; // Number of bytes. |
880 JSFunction* function_; | 859 int parameter_count_; |
881 RegisterValues register_values_; | 860 RegisterValues register_values_; |
882 intptr_t top_; | 861 intptr_t top_; |
883 intptr_t pc_; | 862 intptr_t pc_; |
884 intptr_t fp_; | 863 intptr_t fp_; |
885 intptr_t context_; | 864 intptr_t context_; |
886 intptr_t constant_pool_; | 865 intptr_t constant_pool_; |
887 StackFrame::Type type_; | 866 StackFrame::Type type_; |
888 Smi* state_; | 867 Smi* state_; |
889 | 868 |
890 // Continuation is the PC where the execution continues after | 869 // Continuation is the PC where the execution continues after |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 | 1044 |
1066 | 1045 |
1067 // Class used to represent an unoptimized frame when the debugger | 1046 // Class used to represent an unoptimized frame when the debugger |
1068 // needs to inspect a frame that is part of an optimized frame. The | 1047 // needs to inspect a frame that is part of an optimized frame. The |
1069 // internally used FrameDescription objects are not GC safe so for use | 1048 // internally used FrameDescription objects are not GC safe so for use |
1070 // by the debugger frame information is copied to an object of this type. | 1049 // by the debugger frame information is copied to an object of this type. |
1071 // Represents parameters in unadapted form so their number might mismatch | 1050 // Represents parameters in unadapted form so their number might mismatch |
1072 // formal parameter count. | 1051 // formal parameter count. |
1073 class DeoptimizedFrameInfo : public Malloced { | 1052 class DeoptimizedFrameInfo : public Malloced { |
1074 public: | 1053 public: |
1075 DeoptimizedFrameInfo(Deoptimizer* deoptimizer, | 1054 DeoptimizedFrameInfo(TranslatedState* state, |
1076 int frame_index, | 1055 TranslatedState::iterator frame_it, Isolate* isolate); |
1077 bool has_arguments_adaptor, | 1056 |
1078 bool has_construct_stub); | |
1079 // Return the number of incoming arguments. | 1057 // Return the number of incoming arguments. |
1080 int parameters_count() { return static_cast<int>(parameters_.size()); } | 1058 int parameters_count() { return static_cast<int>(parameters_.size()); } |
1081 | 1059 |
1082 // Return the height of the expression stack. | 1060 // Return the height of the expression stack. |
1083 int expression_count() { return static_cast<int>(expression_stack_.size()); } | 1061 int expression_count() { return static_cast<int>(expression_stack_.size()); } |
1084 | 1062 |
1085 // Get the frame function. | 1063 // Get the frame function. |
1086 Handle<JSFunction> GetFunction() { return function_; } | 1064 Handle<JSFunction> GetFunction() { return function_; } |
1087 | 1065 |
1088 // Get the frame context. | 1066 // Get the frame context. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1130 std::vector<Handle<Object> > expression_stack_; | 1108 std::vector<Handle<Object> > expression_stack_; |
1131 int source_position_; | 1109 int source_position_; |
1132 | 1110 |
1133 friend class Deoptimizer; | 1111 friend class Deoptimizer; |
1134 }; | 1112 }; |
1135 | 1113 |
1136 } // namespace internal | 1114 } // namespace internal |
1137 } // namespace v8 | 1115 } // namespace v8 |
1138 | 1116 |
1139 #endif // V8_DEOPTIMIZER_H_ | 1117 #endif // V8_DEOPTIMIZER_H_ |
OLD | NEW |