| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifndef V8_FRAMES_H_ | 28 #ifndef V8_FRAMES_H_ |
| 29 #define V8_FRAMES_H_ | 29 #define V8_FRAMES_H_ |
| 30 | 30 |
| 31 #include "handles.h" |
| 31 #include "safepoint-table.h" | 32 #include "safepoint-table.h" |
| 32 | 33 |
| 33 namespace v8 { | 34 namespace v8 { |
| 34 namespace internal { | 35 namespace internal { |
| 35 | 36 |
| 36 typedef uint32_t RegList; | 37 typedef uint32_t RegList; |
| 37 | 38 |
| 38 // Get the number of registers in a given register list. | 39 // Get the number of registers in a given register list. |
| 39 int NumRegs(RegList list); | 40 int NumRegs(RegList list); |
| 40 | 41 |
| 41 // Return the code of the n-th saved register available to JavaScript. | 42 // Return the code of the n-th saved register available to JavaScript. |
| 42 int JSCallerSavedCode(int n); | 43 int JSCallerSavedCode(int n); |
| 43 | 44 |
| 44 | 45 |
| 45 // Forward declarations. | 46 // Forward declarations. |
| 46 class StackFrameIterator; | 47 class StackFrameIterator; |
| 47 class Top; | |
| 48 class ThreadLocalTop; | 48 class ThreadLocalTop; |
| 49 class Isolate; |
| 49 | 50 |
| 50 | 51 class PcToCodeCache { |
| 51 class PcToCodeCache : AllStatic { | |
| 52 public: | 52 public: |
| 53 struct PcToCodeCacheEntry { | 53 struct PcToCodeCacheEntry { |
| 54 Address pc; | 54 Address pc; |
| 55 Code* code; | 55 Code* code; |
| 56 SafepointEntry safepoint_entry; | 56 SafepointEntry safepoint_entry; |
| 57 }; | 57 }; |
| 58 | 58 |
| 59 static PcToCodeCacheEntry* cache(int index) { | 59 explicit PcToCodeCache(Isolate* isolate) : isolate_(isolate) { |
| 60 return &cache_[index]; | 60 Flush(); |
| 61 } | 61 } |
| 62 | 62 |
| 63 static Code* GcSafeFindCodeForPc(Address pc); | 63 Code* GcSafeFindCodeForPc(Address pc); |
| 64 static Code* GcSafeCastToCode(HeapObject* object, Address pc); | 64 Code* GcSafeCastToCode(HeapObject* object, Address pc); |
| 65 | 65 |
| 66 static void FlushPcToCodeCache() { | 66 void Flush() { |
| 67 memset(&cache_[0], 0, sizeof(cache_)); | 67 memset(&cache_[0], 0, sizeof(cache_)); |
| 68 } | 68 } |
| 69 | 69 |
| 70 static PcToCodeCacheEntry* GetCacheEntry(Address pc); | 70 PcToCodeCacheEntry* GetCacheEntry(Address pc); |
| 71 | 71 |
| 72 private: | 72 private: |
| 73 PcToCodeCacheEntry* cache(int index) { return &cache_[index]; } |
| 74 |
| 75 Isolate* isolate_; |
| 76 |
| 73 static const int kPcToCodeCacheSize = 1024; | 77 static const int kPcToCodeCacheSize = 1024; |
| 74 static PcToCodeCacheEntry cache_[kPcToCodeCacheSize]; | 78 PcToCodeCacheEntry cache_[kPcToCodeCacheSize]; |
| 79 |
| 80 DISALLOW_COPY_AND_ASSIGN(PcToCodeCache); |
| 75 }; | 81 }; |
| 76 | 82 |
| 77 | 83 |
| 78 class StackHandler BASE_EMBEDDED { | 84 class StackHandler BASE_EMBEDDED { |
| 79 public: | 85 public: |
| 80 enum State { | 86 enum State { |
| 81 ENTRY, | 87 ENTRY, |
| 82 TRY_CATCH, | 88 TRY_CATCH, |
| 83 TRY_FINALLY | 89 TRY_FINALLY |
| 84 }; | 90 }; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 bool HasHandler() const; | 198 bool HasHandler() const; |
| 193 | 199 |
| 194 // Get the type of this frame. | 200 // Get the type of this frame. |
| 195 virtual Type type() const = 0; | 201 virtual Type type() const = 0; |
| 196 | 202 |
| 197 // Get the code associated with this frame. | 203 // Get the code associated with this frame. |
| 198 // This method could be called during marking phase of GC. | 204 // This method could be called during marking phase of GC. |
| 199 virtual Code* unchecked_code() const = 0; | 205 virtual Code* unchecked_code() const = 0; |
| 200 | 206 |
| 201 // Get the code associated with this frame. | 207 // Get the code associated with this frame. |
| 202 Code* code() const { return GetContainingCode(pc()); } | 208 Code* LookupCode(Isolate* isolate) const { |
| 209 return GetContainingCode(isolate, pc()); |
| 210 } |
| 203 | 211 |
| 204 // Get the code object that contains the given pc. | 212 // Get the code object that contains the given pc. |
| 205 static Code* GetContainingCode(Address pc) { | 213 static inline Code* GetContainingCode(Isolate* isolate, Address pc); |
| 206 return PcToCodeCache::GetCacheEntry(pc)->code; | |
| 207 } | |
| 208 | 214 |
| 209 // Get the code object containing the given pc and fill in the | 215 // Get the code object containing the given pc and fill in the |
| 210 // safepoint entry and the number of stack slots. The pc must be at | 216 // safepoint entry and the number of stack slots. The pc must be at |
| 211 // a safepoint. | 217 // a safepoint. |
| 212 static Code* GetSafepointData(Address pc, | 218 static Code* GetSafepointData(Address pc, |
| 213 SafepointEntry* safepoint_entry, | 219 SafepointEntry* safepoint_entry, |
| 214 unsigned* stack_slots); | 220 unsigned* stack_slots); |
| 215 | 221 |
| 216 virtual void Iterate(ObjectVisitor* v) const = 0; | 222 virtual void Iterate(ObjectVisitor* v) const = 0; |
| 217 static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder); | 223 static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder); |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 public: | 611 public: |
| 606 // An iterator that iterates over the current thread's stack. | 612 // An iterator that iterates over the current thread's stack. |
| 607 StackFrameIterator(); | 613 StackFrameIterator(); |
| 608 | 614 |
| 609 // An iterator that iterates over a given thread's stack. | 615 // An iterator that iterates over a given thread's stack. |
| 610 explicit StackFrameIterator(ThreadLocalTop* thread); | 616 explicit StackFrameIterator(ThreadLocalTop* thread); |
| 611 | 617 |
| 612 // An iterator that can start from a given FP address. | 618 // An iterator that can start from a given FP address. |
| 613 // If use_top, then work as usual, if fp isn't NULL, use it, | 619 // If use_top, then work as usual, if fp isn't NULL, use it, |
| 614 // otherwise, do nothing. | 620 // otherwise, do nothing. |
| 615 StackFrameIterator(bool use_top, Address fp, Address sp); | 621 StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp); |
| 616 | 622 |
| 617 StackFrame* frame() const { | 623 StackFrame* frame() const { |
| 618 ASSERT(!done()); | 624 ASSERT(!done()); |
| 619 return frame_; | 625 return frame_; |
| 620 } | 626 } |
| 621 | 627 |
| 622 bool done() const { return frame_ == NULL; } | 628 bool done() const { return frame_ == NULL; } |
| 623 void Advance() { (this->*advance_)(); } | 629 void Advance() { (this->*advance_)(); } |
| 624 | 630 |
| 625 // Go back to the first frame. | 631 // Go back to the first frame. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 | 674 |
| 669 // Skip frames until the frame with the given id is reached. | 675 // Skip frames until the frame with the given id is reached. |
| 670 explicit JavaScriptFrameIteratorTemp(StackFrame::Id id); | 676 explicit JavaScriptFrameIteratorTemp(StackFrame::Id id); |
| 671 | 677 |
| 672 JavaScriptFrameIteratorTemp(Address fp, Address sp, | 678 JavaScriptFrameIteratorTemp(Address fp, Address sp, |
| 673 Address low_bound, Address high_bound) : | 679 Address low_bound, Address high_bound) : |
| 674 iterator_(fp, sp, low_bound, high_bound) { | 680 iterator_(fp, sp, low_bound, high_bound) { |
| 675 if (!done()) Advance(); | 681 if (!done()) Advance(); |
| 676 } | 682 } |
| 677 | 683 |
| 684 JavaScriptFrameIteratorTemp(Isolate* isolate, |
| 685 Address fp, Address sp, |
| 686 Address low_bound, Address high_bound) : |
| 687 iterator_(isolate, fp, sp, low_bound, high_bound) { |
| 688 if (!done()) Advance(); |
| 689 } |
| 690 |
| 678 inline JavaScriptFrame* frame() const; | 691 inline JavaScriptFrame* frame() const; |
| 679 | 692 |
| 680 bool done() const { return iterator_.done(); } | 693 bool done() const { return iterator_.done(); } |
| 681 void Advance(); | 694 void Advance(); |
| 682 | 695 |
| 683 // Advance to the frame holding the arguments for the current | 696 // Advance to the frame holding the arguments for the current |
| 684 // frame. This only affects the current frame if it has adapted | 697 // frame. This only affects the current frame if it has adapted |
| 685 // arguments. | 698 // arguments. |
| 686 void AdvanceToArgumentsFrame(); | 699 void AdvanceToArgumentsFrame(); |
| 687 | 700 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 705 StackTraceFrameIterator(); | 718 StackTraceFrameIterator(); |
| 706 void Advance(); | 719 void Advance(); |
| 707 | 720 |
| 708 private: | 721 private: |
| 709 bool IsValidFrame(); | 722 bool IsValidFrame(); |
| 710 }; | 723 }; |
| 711 | 724 |
| 712 | 725 |
| 713 class SafeStackFrameIterator BASE_EMBEDDED { | 726 class SafeStackFrameIterator BASE_EMBEDDED { |
| 714 public: | 727 public: |
| 715 SafeStackFrameIterator(Address fp, Address sp, | 728 SafeStackFrameIterator(Isolate* isolate, |
| 729 Address fp, Address sp, |
| 716 Address low_bound, Address high_bound); | 730 Address low_bound, Address high_bound); |
| 717 | 731 |
| 718 StackFrame* frame() const { | 732 StackFrame* frame() const { |
| 719 ASSERT(is_working_iterator_); | 733 ASSERT(is_working_iterator_); |
| 720 return iterator_.frame(); | 734 return iterator_.frame(); |
| 721 } | 735 } |
| 722 | 736 |
| 723 bool done() const { return iteration_done_ ? true : iterator_.done(); } | 737 bool done() const { return iteration_done_ ? true : iterator_.done(); } |
| 724 | 738 |
| 725 void Advance(); | 739 void Advance(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 755 private: | 769 private: |
| 756 StackAddressValidator validator_; | 770 StackAddressValidator validator_; |
| 757 }; | 771 }; |
| 758 | 772 |
| 759 bool IsValidStackAddress(Address addr) const { | 773 bool IsValidStackAddress(Address addr) const { |
| 760 return stack_validator_.IsValid(addr); | 774 return stack_validator_.IsValid(addr); |
| 761 } | 775 } |
| 762 bool CanIterateHandles(StackFrame* frame, StackHandler* handler); | 776 bool CanIterateHandles(StackFrame* frame, StackHandler* handler); |
| 763 bool IsValidFrame(StackFrame* frame) const; | 777 bool IsValidFrame(StackFrame* frame) const; |
| 764 bool IsValidCaller(StackFrame* frame); | 778 bool IsValidCaller(StackFrame* frame); |
| 765 static bool IsValidTop(Address low_bound, Address high_bound); | 779 static bool IsValidTop(Isolate* isolate, |
| 780 Address low_bound, Address high_bound); |
| 766 | 781 |
| 767 // This is a nasty hack to make sure the active count is incremented | 782 // This is a nasty hack to make sure the active count is incremented |
| 768 // before the constructor for the embedded iterator is invoked. This | 783 // before the constructor for the embedded iterator is invoked. This |
| 769 // is needed because the constructor will start looking at frames | 784 // is needed because the constructor will start looking at frames |
| 770 // right away and we need to make sure it doesn't start inspecting | 785 // right away and we need to make sure it doesn't start inspecting |
| 771 // heap objects. | 786 // heap objects. |
| 772 class ActiveCountMaintainer BASE_EMBEDDED { | 787 class ActiveCountMaintainer BASE_EMBEDDED { |
| 773 public: | 788 public: |
| 774 ActiveCountMaintainer() { active_count_++; } | 789 ActiveCountMaintainer() { active_count_++; } |
| 775 ~ActiveCountMaintainer() { active_count_--; } | 790 ~ActiveCountMaintainer() { active_count_--; } |
| 776 }; | 791 }; |
| 777 | 792 |
| 778 ActiveCountMaintainer maintainer_; | 793 ActiveCountMaintainer maintainer_; |
| 794 // TODO(isolates): this is dangerous. |
| 779 static int active_count_; | 795 static int active_count_; |
| 780 StackAddressValidator stack_validator_; | 796 StackAddressValidator stack_validator_; |
| 781 const bool is_valid_top_; | 797 const bool is_valid_top_; |
| 782 const bool is_valid_fp_; | 798 const bool is_valid_fp_; |
| 783 const bool is_working_iterator_; | 799 const bool is_working_iterator_; |
| 784 bool iteration_done_; | 800 bool iteration_done_; |
| 785 StackFrameIterator iterator_; | 801 StackFrameIterator iterator_; |
| 786 }; | 802 }; |
| 787 | 803 |
| 788 | 804 |
| 789 #ifdef ENABLE_LOGGING_AND_PROFILING | 805 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 790 typedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator> | 806 typedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator> |
| 791 SafeJavaScriptFrameIterator; | 807 SafeJavaScriptFrameIterator; |
| 792 | 808 |
| 793 | 809 |
| 794 class SafeStackTraceFrameIterator: public SafeJavaScriptFrameIterator { | 810 class SafeStackTraceFrameIterator: public SafeJavaScriptFrameIterator { |
| 795 public: | 811 public: |
| 796 explicit SafeStackTraceFrameIterator(Address fp, Address sp, | 812 explicit SafeStackTraceFrameIterator(Isolate* isolate, |
| 813 Address fp, Address sp, |
| 797 Address low_bound, Address high_bound); | 814 Address low_bound, Address high_bound); |
| 798 void Advance(); | 815 void Advance(); |
| 799 }; | 816 }; |
| 800 #endif | 817 #endif |
| 801 | 818 |
| 802 | 819 |
| 803 class StackFrameLocator BASE_EMBEDDED { | 820 class StackFrameLocator BASE_EMBEDDED { |
| 804 public: | 821 public: |
| 805 // Find the nth JavaScript frame on the stack. The caller must | 822 // Find the nth JavaScript frame on the stack. The caller must |
| 806 // guarantee that such a frame exists. | 823 // guarantee that such a frame exists. |
| 807 JavaScriptFrame* FindJavaScriptFrame(int n); | 824 JavaScriptFrame* FindJavaScriptFrame(int n); |
| 808 | 825 |
| 809 private: | 826 private: |
| 810 StackFrameIterator iterator_; | 827 StackFrameIterator iterator_; |
| 811 }; | 828 }; |
| 812 | 829 |
| 813 | 830 |
| 814 // Reads all frames on the current stack and copies them into the current | 831 // Reads all frames on the current stack and copies them into the current |
| 815 // zone memory. | 832 // zone memory. |
| 816 Vector<StackFrame*> CreateStackMap(); | 833 Vector<StackFrame*> CreateStackMap(); |
| 817 | 834 |
| 818 } } // namespace v8::internal | 835 } } // namespace v8::internal |
| 819 | 836 |
| 820 #endif // V8_FRAMES_H_ | 837 #endif // V8_FRAMES_H_ |
| OLD | NEW |