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 |