| 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 |