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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 NO_ID = 0 | 151 NO_ID = 0 |
152 }; | 152 }; |
153 | 153 |
154 struct State { | 154 struct State { |
155 State() : sp(NULL), fp(NULL), pc_address(NULL) { } | 155 State() : sp(NULL), fp(NULL), pc_address(NULL) { } |
156 Address sp; | 156 Address sp; |
157 Address fp; | 157 Address fp; |
158 Address* pc_address; | 158 Address* pc_address; |
159 }; | 159 }; |
160 | 160 |
161 // Copy constructor; it breaks the connection to host iterator. | 161 // Copy constructor; it breaks the connection to host iterator |
| 162 // (as an iterator usually lives on stack). But as we need |
| 163 // a pointer to isolate, we store it in place of the iterator ptr, |
| 164 // and tag accordingly. |
162 StackFrame(const StackFrame& original) { | 165 StackFrame(const StackFrame& original) { |
163 this->state_ = original.state_; | 166 this->state_ = original.state_; |
164 this->iterator_ = NULL; | 167 this->tagged_isolate_ptr_ = |
| 168 reinterpret_cast<intptr_t>(original.isolate()) | kIsolateTag; |
165 } | 169 } |
166 | 170 |
167 // Type testers. | 171 // Type testers. |
168 bool is_entry() const { return type() == ENTRY; } | 172 bool is_entry() const { return type() == ENTRY; } |
169 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; } | 173 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; } |
170 bool is_exit() const { return type() == EXIT; } | 174 bool is_exit() const { return type() == EXIT; } |
171 bool is_optimized() const { return type() == OPTIMIZED; } | 175 bool is_optimized() const { return type() == OPTIMIZED; } |
172 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; } | 176 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; } |
173 bool is_internal() const { return type() == INTERNAL; } | 177 bool is_internal() const { return type() == INTERNAL; } |
174 bool is_construct() const { return type() == CONSTRUCT; } | 178 bool is_construct() const { return type() == CONSTRUCT; } |
(...skipping 23 matching lines...) Expand all Loading... |
198 bool HasHandler() const; | 202 bool HasHandler() const; |
199 | 203 |
200 // Get the type of this frame. | 204 // Get the type of this frame. |
201 virtual Type type() const = 0; | 205 virtual Type type() const = 0; |
202 | 206 |
203 // Get the code associated with this frame. | 207 // Get the code associated with this frame. |
204 // This method could be called during marking phase of GC. | 208 // This method could be called during marking phase of GC. |
205 virtual Code* unchecked_code() const = 0; | 209 virtual Code* unchecked_code() const = 0; |
206 | 210 |
207 // Get the code associated with this frame. | 211 // Get the code associated with this frame. |
208 Code* LookupCode(Isolate* isolate) const { | 212 Code* LookupCode() const { |
209 return GetContainingCode(isolate, pc()); | 213 return GetContainingCode(isolate(), pc()); |
210 } | 214 } |
211 | 215 |
212 // Get the code object that contains the given pc. | 216 // Get the code object that contains the given pc. |
213 static inline Code* GetContainingCode(Isolate* isolate, Address pc); | 217 static inline Code* GetContainingCode(Isolate* isolate, Address pc); |
214 | 218 |
215 // Get the code object containing the given pc and fill in the | 219 // Get the code object containing the given pc and fill in the |
216 // safepoint entry and the number of stack slots. The pc must be at | 220 // safepoint entry and the number of stack slots. The pc must be at |
217 // a safepoint. | 221 // a safepoint. |
218 static Code* GetSafepointData(Address pc, | 222 static Code* GetSafepointData(Isolate* isolate, |
| 223 Address pc, |
219 SafepointEntry* safepoint_entry, | 224 SafepointEntry* safepoint_entry, |
220 unsigned* stack_slots); | 225 unsigned* stack_slots); |
221 | 226 |
222 virtual void Iterate(ObjectVisitor* v) const = 0; | 227 virtual void Iterate(ObjectVisitor* v) const = 0; |
223 static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder); | 228 static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder); |
224 | 229 |
225 | 230 |
226 // Printing support. | 231 // Printing support. |
227 enum PrintMode { OVERVIEW, DETAILS }; | 232 enum PrintMode { OVERVIEW, DETAILS }; |
228 virtual void Print(StringStream* accumulator, | 233 virtual void Print(StringStream* accumulator, |
229 PrintMode mode, | 234 PrintMode mode, |
230 int index) const { } | 235 int index) const { } |
231 | 236 |
232 protected: | 237 protected: |
233 explicit StackFrame(StackFrameIterator* iterator) : iterator_(iterator) { } | 238 explicit StackFrame(StackFrameIterator* iterator) : iterator_(iterator) { } |
234 virtual ~StackFrame() { } | 239 virtual ~StackFrame() { } |
235 | 240 |
| 241 inline Isolate* isolate() const; |
| 242 |
236 // Compute the stack pointer for the calling frame. | 243 // Compute the stack pointer for the calling frame. |
237 virtual Address GetCallerStackPointer() const = 0; | 244 virtual Address GetCallerStackPointer() const = 0; |
238 | 245 |
239 // Printing support. | 246 // Printing support. |
240 static void PrintIndex(StringStream* accumulator, | 247 static void PrintIndex(StringStream* accumulator, |
241 PrintMode mode, | 248 PrintMode mode, |
242 int index); | 249 int index); |
243 | 250 |
244 // Get the top handler from the current stack iterator. | 251 // Get the top handler from the current stack iterator. |
245 inline StackHandler* top_handler() const; | 252 inline StackHandler* top_handler() const; |
246 | 253 |
247 // Compute the stack frame type for the given state. | 254 // Compute the stack frame type for the given state. |
248 static Type ComputeType(State* state); | 255 static Type ComputeType(Isolate* isolate, State* state); |
249 | 256 |
250 private: | 257 private: |
251 const StackFrameIterator* iterator_; | 258 union { |
| 259 const StackFrameIterator* iterator_; |
| 260 intptr_t tagged_isolate_ptr_; |
| 261 }; |
252 State state_; | 262 State state_; |
253 | 263 |
254 // Fill in the state of the calling frame. | 264 // Fill in the state of the calling frame. |
255 virtual void ComputeCallerState(State* state) const = 0; | 265 virtual void ComputeCallerState(State* state) const = 0; |
256 | 266 |
257 // Get the type and the state of the calling frame. | 267 // Get the type and the state of the calling frame. |
258 virtual Type GetCallerState(State* state) const; | 268 virtual Type GetCallerState(State* state) const; |
259 | 269 |
| 270 static const intptr_t kIsolateTag = 1; |
| 271 |
260 friend class StackFrameIterator; | 272 friend class StackFrameIterator; |
261 friend class StackHandlerIterator; | 273 friend class StackHandlerIterator; |
262 friend class SafeStackFrameIterator; | 274 friend class SafeStackFrameIterator; |
263 | 275 |
264 private: | 276 private: |
265 void operator=(const StackFrame& original); | 277 void operator=(const StackFrame& original); |
266 }; | 278 }; |
267 | 279 |
268 | 280 |
269 // Entry frames are used to enter JavaScript execution from C. | 281 // Entry frames are used to enter JavaScript execution from C. |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 explicit ConstructFrame(StackFrameIterator* iterator) | 614 explicit ConstructFrame(StackFrameIterator* iterator) |
603 : InternalFrame(iterator) { } | 615 : InternalFrame(iterator) { } |
604 | 616 |
605 private: | 617 private: |
606 friend class StackFrameIterator; | 618 friend class StackFrameIterator; |
607 }; | 619 }; |
608 | 620 |
609 | 621 |
610 class StackFrameIterator BASE_EMBEDDED { | 622 class StackFrameIterator BASE_EMBEDDED { |
611 public: | 623 public: |
612 // An iterator that iterates over the current thread's stack. | 624 // An iterator that iterates over the current thread's stack, |
| 625 // and uses current isolate. |
613 StackFrameIterator(); | 626 StackFrameIterator(); |
614 | 627 |
| 628 // An iterator that iterates over the isolate's current thread's stack, |
| 629 explicit StackFrameIterator(Isolate* isolate); |
| 630 |
615 // An iterator that iterates over a given thread's stack. | 631 // An iterator that iterates over a given thread's stack. |
616 explicit StackFrameIterator(ThreadLocalTop* thread); | 632 StackFrameIterator(Isolate* isolate, ThreadLocalTop* t); |
617 | 633 |
618 // An iterator that can start from a given FP address. | 634 // An iterator that can start from a given FP address. |
619 // If use_top, then work as usual, if fp isn't NULL, use it, | 635 // If use_top, then work as usual, if fp isn't NULL, use it, |
620 // otherwise, do nothing. | 636 // otherwise, do nothing. |
621 StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp); | 637 StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp); |
622 | 638 |
623 StackFrame* frame() const { | 639 StackFrame* frame() const { |
624 ASSERT(!done()); | 640 ASSERT(!done()); |
625 return frame_; | 641 return frame_; |
626 } | 642 } |
627 | 643 |
| 644 Isolate* isolate() const { return isolate_; } |
| 645 |
628 bool done() const { return frame_ == NULL; } | 646 bool done() const { return frame_ == NULL; } |
629 void Advance() { (this->*advance_)(); } | 647 void Advance() { (this->*advance_)(); } |
630 | 648 |
631 // Go back to the first frame. | 649 // Go back to the first frame. |
632 void Reset(); | 650 void Reset(); |
633 | 651 |
634 private: | 652 private: |
635 #define DECLARE_SINGLETON(ignore, type) type type##_; | 653 #define DECLARE_SINGLETON(ignore, type) type type##_; |
636 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON) | 654 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON) |
637 #undef DECLARE_SINGLETON | 655 #undef DECLARE_SINGLETON |
638 StackFrame* frame_; | 656 StackFrame* frame_; |
639 StackHandler* handler_; | 657 StackHandler* handler_; |
| 658 Isolate* isolate_; |
640 ThreadLocalTop* thread_; | 659 ThreadLocalTop* thread_; |
641 Address fp_; | 660 Address fp_; |
642 Address sp_; | 661 Address sp_; |
643 void (StackFrameIterator::*advance_)(); | 662 void (StackFrameIterator::*advance_)(); |
644 | 663 |
645 StackHandler* handler() const { | 664 StackHandler* handler() const { |
646 ASSERT(!done()); | 665 ASSERT(!done()); |
647 return handler_; | 666 return handler_; |
648 } | 667 } |
649 | 668 |
(...skipping 10 matching lines...) Expand all Loading... |
660 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator); | 679 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator); |
661 }; | 680 }; |
662 | 681 |
663 | 682 |
664 // Iterator that supports iterating through all JavaScript frames. | 683 // Iterator that supports iterating through all JavaScript frames. |
665 template<typename Iterator> | 684 template<typename Iterator> |
666 class JavaScriptFrameIteratorTemp BASE_EMBEDDED { | 685 class JavaScriptFrameIteratorTemp BASE_EMBEDDED { |
667 public: | 686 public: |
668 JavaScriptFrameIteratorTemp() { if (!done()) Advance(); } | 687 JavaScriptFrameIteratorTemp() { if (!done()) Advance(); } |
669 | 688 |
670 explicit JavaScriptFrameIteratorTemp(ThreadLocalTop* thread) : | 689 inline explicit JavaScriptFrameIteratorTemp(Isolate* isolate); |
671 iterator_(thread) { | |
672 if (!done()) Advance(); | |
673 } | |
674 | 690 |
675 // Skip frames until the frame with the given id is reached. | 691 // Skip frames until the frame with the given id is reached. |
676 explicit JavaScriptFrameIteratorTemp(StackFrame::Id id); | 692 explicit JavaScriptFrameIteratorTemp(StackFrame::Id id) { AdvanceToId(id); } |
| 693 |
| 694 inline JavaScriptFrameIteratorTemp(Isolate* isolate, StackFrame::Id id); |
677 | 695 |
678 JavaScriptFrameIteratorTemp(Address fp, Address sp, | 696 JavaScriptFrameIteratorTemp(Address fp, Address sp, |
679 Address low_bound, Address high_bound) : | 697 Address low_bound, Address high_bound) : |
680 iterator_(fp, sp, low_bound, high_bound) { | 698 iterator_(fp, sp, low_bound, high_bound) { |
681 if (!done()) Advance(); | 699 if (!done()) Advance(); |
682 } | 700 } |
683 | 701 |
684 JavaScriptFrameIteratorTemp(Isolate* isolate, | 702 JavaScriptFrameIteratorTemp(Isolate* isolate, |
685 Address fp, Address sp, | 703 Address fp, Address sp, |
686 Address low_bound, Address high_bound) : | 704 Address low_bound, Address high_bound) : |
687 iterator_(isolate, fp, sp, low_bound, high_bound) { | 705 iterator_(isolate, fp, sp, low_bound, high_bound) { |
688 if (!done()) Advance(); | 706 if (!done()) Advance(); |
689 } | 707 } |
690 | 708 |
691 inline JavaScriptFrame* frame() const; | 709 inline JavaScriptFrame* frame() const; |
692 | 710 |
693 bool done() const { return iterator_.done(); } | 711 bool done() const { return iterator_.done(); } |
694 void Advance(); | 712 void Advance(); |
695 | 713 |
696 // Advance to the frame holding the arguments for the current | 714 // Advance to the frame holding the arguments for the current |
697 // frame. This only affects the current frame if it has adapted | 715 // frame. This only affects the current frame if it has adapted |
698 // arguments. | 716 // arguments. |
699 void AdvanceToArgumentsFrame(); | 717 void AdvanceToArgumentsFrame(); |
700 | 718 |
701 // Go back to the first frame. | 719 // Go back to the first frame. |
702 void Reset(); | 720 void Reset(); |
703 | 721 |
704 private: | 722 private: |
| 723 inline void AdvanceToId(StackFrame::Id id); |
| 724 |
705 Iterator iterator_; | 725 Iterator iterator_; |
706 }; | 726 }; |
707 | 727 |
708 | 728 |
709 typedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator; | 729 typedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator; |
710 | 730 |
711 | 731 |
712 // NOTE: The stack trace frame iterator is an iterator that only | 732 // NOTE: The stack trace frame iterator is an iterator that only |
713 // traverse proper JavaScript frames; that is JavaScript frames that | 733 // traverse proper JavaScript frames; that is JavaScript frames that |
714 // have proper JavaScript functions. This excludes the problematic | 734 // have proper JavaScript functions. This excludes the problematic |
715 // functions in runtime.js. | 735 // functions in runtime.js. |
716 class StackTraceFrameIterator: public JavaScriptFrameIterator { | 736 class StackTraceFrameIterator: public JavaScriptFrameIterator { |
717 public: | 737 public: |
718 StackTraceFrameIterator(); | 738 StackTraceFrameIterator(); |
| 739 explicit StackTraceFrameIterator(Isolate* isolate); |
719 void Advance(); | 740 void Advance(); |
720 | 741 |
721 private: | 742 private: |
722 bool IsValidFrame(); | 743 bool IsValidFrame(); |
723 }; | 744 }; |
724 | 745 |
725 | 746 |
726 class SafeStackFrameIterator BASE_EMBEDDED { | 747 class SafeStackFrameIterator BASE_EMBEDDED { |
727 public: | 748 public: |
728 SafeStackFrameIterator(Isolate* isolate, | 749 SafeStackFrameIterator(Isolate* isolate, |
729 Address fp, Address sp, | 750 Address fp, Address sp, |
730 Address low_bound, Address high_bound); | 751 Address low_bound, Address high_bound); |
731 | 752 |
732 StackFrame* frame() const { | 753 StackFrame* frame() const { |
733 ASSERT(is_working_iterator_); | 754 ASSERT(is_working_iterator_); |
734 return iterator_.frame(); | 755 return iterator_.frame(); |
735 } | 756 } |
736 | 757 |
737 bool done() const { return iteration_done_ ? true : iterator_.done(); } | 758 bool done() const { return iteration_done_ ? true : iterator_.done(); } |
738 | 759 |
739 void Advance(); | 760 void Advance(); |
740 void Reset(); | 761 void Reset(); |
741 | 762 |
742 static bool is_active() { return active_count_ > 0; } | 763 static bool is_active(Isolate* isolate); |
743 | 764 |
744 static bool IsWithinBounds( | 765 static bool IsWithinBounds( |
745 Address low_bound, Address high_bound, Address addr) { | 766 Address low_bound, Address high_bound, Address addr) { |
746 return low_bound <= addr && addr <= high_bound; | 767 return low_bound <= addr && addr <= high_bound; |
747 } | 768 } |
748 | 769 |
749 private: | 770 private: |
750 class StackAddressValidator { | 771 class StackAddressValidator { |
751 public: | 772 public: |
752 StackAddressValidator(Address low_bound, Address high_bound) | 773 StackAddressValidator(Address low_bound, Address high_bound) |
(...skipping 26 matching lines...) Expand all Loading... |
779 static bool IsValidTop(Isolate* isolate, | 800 static bool IsValidTop(Isolate* isolate, |
780 Address low_bound, Address high_bound); | 801 Address low_bound, Address high_bound); |
781 | 802 |
782 // This is a nasty hack to make sure the active count is incremented | 803 // This is a nasty hack to make sure the active count is incremented |
783 // before the constructor for the embedded iterator is invoked. This | 804 // before the constructor for the embedded iterator is invoked. This |
784 // is needed because the constructor will start looking at frames | 805 // is needed because the constructor will start looking at frames |
785 // right away and we need to make sure it doesn't start inspecting | 806 // right away and we need to make sure it doesn't start inspecting |
786 // heap objects. | 807 // heap objects. |
787 class ActiveCountMaintainer BASE_EMBEDDED { | 808 class ActiveCountMaintainer BASE_EMBEDDED { |
788 public: | 809 public: |
789 ActiveCountMaintainer() { active_count_++; } | 810 explicit ActiveCountMaintainer(Isolate* isolate); |
790 ~ActiveCountMaintainer() { active_count_--; } | 811 ~ActiveCountMaintainer(); |
| 812 private: |
| 813 Isolate* isolate_; |
791 }; | 814 }; |
792 | 815 |
793 ActiveCountMaintainer maintainer_; | 816 ActiveCountMaintainer maintainer_; |
794 // TODO(isolates): this is dangerous. | |
795 static int active_count_; | |
796 StackAddressValidator stack_validator_; | 817 StackAddressValidator stack_validator_; |
797 const bool is_valid_top_; | 818 const bool is_valid_top_; |
798 const bool is_valid_fp_; | 819 const bool is_valid_fp_; |
799 const bool is_working_iterator_; | 820 const bool is_working_iterator_; |
800 bool iteration_done_; | 821 bool iteration_done_; |
801 StackFrameIterator iterator_; | 822 StackFrameIterator iterator_; |
802 }; | 823 }; |
803 | 824 |
804 | 825 |
805 #ifdef ENABLE_LOGGING_AND_PROFILING | 826 #ifdef ENABLE_LOGGING_AND_PROFILING |
(...skipping 22 matching lines...) Expand all Loading... |
828 }; | 849 }; |
829 | 850 |
830 | 851 |
831 // Reads all frames on the current stack and copies them into the current | 852 // Reads all frames on the current stack and copies them into the current |
832 // zone memory. | 853 // zone memory. |
833 Vector<StackFrame*> CreateStackMap(); | 854 Vector<StackFrame*> CreateStackMap(); |
834 | 855 |
835 } } // namespace v8::internal | 856 } } // namespace v8::internal |
836 | 857 |
837 #endif // V8_FRAMES_H_ | 858 #endif // V8_FRAMES_H_ |
OLD | NEW |