📄 frames.h.svn-base
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met://// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following// disclaimer in the documentation and/or other materials provided// with the distribution.// * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived// from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#ifndef V8_FRAMES_H_#define V8_FRAMES_H_namespace v8 { namespace internal {typedef uint32_t RegList;// Get the number of registers in a given register list.int NumRegs(RegList list);// Return the code of the n-th saved register available to JavaScript.int JSCallerSavedCode(int n);// Forward declarations.class StackFrameIterator;class Top;class ThreadLocalTop;class StackHandler BASE_EMBEDDED { public: enum State { ENTRY, TRY_CATCH, TRY_FINALLY }; // Get the address of this stack handler. inline Address address() const; // Get the next stack handler in the chain. inline StackHandler* next() const; // Tells whether the given address is inside this handler. inline bool includes(Address address) const; // Garbage collection support. inline void Iterate(ObjectVisitor* v) const; // Conversion support. static inline StackHandler* FromAddress(Address address); // Testers bool is_entry() { return state() == ENTRY; } bool is_try_catch() { return state() == TRY_CATCH; } bool is_try_finally() { return state() == TRY_FINALLY; } // Garbage collection support. void Cook(Code* code); void Uncook(Code* code); // TODO(1233780): Get rid of the code slot in stack handlers. static const int kCodeNotPresent = 0; private: // Accessors. inline State state() const; inline Address pc() const; inline void set_pc(Address value); DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);};#define STACK_FRAME_TYPE_LIST(V) \ V(ENTRY, EntryFrame) \ V(ENTRY_CONSTRUCT, EntryConstructFrame) \ V(EXIT, ExitFrame) \ V(EXIT_DEBUG, ExitDebugFrame) \ V(JAVA_SCRIPT, JavaScriptFrame) \ V(INTERNAL, InternalFrame) \ V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)// Abstract base class for all stack frames.class StackFrame BASE_EMBEDDED { public:#define DECLARE_TYPE(type, ignore) type, enum Type { NONE = 0, STACK_FRAME_TYPE_LIST(DECLARE_TYPE) NUMBER_OF_TYPES };#undef DECLARE_TYPE // Opaque data type for identifying stack frames. Used extensively // by the debugger. enum Id { NO_ID = 0 }; // Type testers. bool is_entry() const { return type() == ENTRY; } bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; } bool is_exit() const { return type() == EXIT; } bool is_exit_debug() const { return type() == EXIT_DEBUG; } bool is_java_script() const { return type() == JAVA_SCRIPT; } bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; } bool is_internal() const { return type() == INTERNAL; } virtual bool is_standard() const { return false; } // Accessors. Address sp() const { return state_.sp; } Address fp() const { return state_.fp; } Address pp() const { return GetCallerStackPointer(); } Address pc() const { return *pc_address(); } void set_pc(Address pc) { *pc_address() = pc; } Address* pc_address() const { return state_.pc_address; } // Get the id of this stack frame. Id id() const { return static_cast<Id>(OffsetFrom(pp())); } // Checks if this frame includes any stack handlers. bool HasHandler() const; // Get the type of this frame. virtual Type type() const = 0; // Get the code associated with this frame. virtual Code* FindCode() const = 0; // Garbage collection support. static void CookFramesForThread(ThreadLocalTop* thread); static void UncookFramesForThread(ThreadLocalTop* thread); virtual void Iterate(ObjectVisitor* v) const { } // Printing support. enum PrintMode { OVERVIEW, DETAILS }; virtual void Print(StringStream* accumulator, PrintMode mode, int index) const { } protected: struct State { Address sp; Address fp; Address* pc_address; }; explicit StackFrame(StackFrameIterator* iterator) : iterator_(iterator) { } virtual ~StackFrame() { } // Compute the stack pointer for the calling frame. virtual Address GetCallerStackPointer() const = 0; // Printing support. static void PrintIndex(StringStream* accumulator, PrintMode mode, int index); // Get the top handler from the current stack iterator. inline StackHandler* top_handler() const; // Compute the stack frame type for the given state. static Type ComputeType(State* state); private: const StackFrameIterator* iterator_; State state_; // Get the type and the state of the calling frame. virtual Type GetCallerState(State* state) const = 0; // Cooking/uncooking support. void Cook(); void Uncook(); friend class StackFrameIterator; friend class StackHandlerIterator; DISALLOW_IMPLICIT_CONSTRUCTORS(StackFrame);};// Entry frames are used to enter JavaScript execution from C.class EntryFrame: public StackFrame { public: virtual Type type() const { return ENTRY; } virtual Code* FindCode() const; // Garbage collection support. virtual void Iterate(ObjectVisitor* v) const; static EntryFrame* cast(StackFrame* frame) { ASSERT(frame->is_entry()); return static_cast<EntryFrame*>(frame); } protected: explicit EntryFrame(StackFrameIterator* iterator) : StackFrame(iterator) { } // The caller stack pointer for entry frames is always zero. The // real information about the caller frame is available through the // link to the top exit frame. virtual Address GetCallerStackPointer() const { return 0; } private: virtual Type GetCallerState(State* state) const; friend class StackFrameIterator;};class EntryConstructFrame: public EntryFrame { public: virtual Type type() const { return ENTRY_CONSTRUCT; } virtual Code* FindCode() const; static EntryConstructFrame* cast(StackFrame* frame) { ASSERT(frame->is_entry_construct()); return static_cast<EntryConstructFrame*>(frame); } protected: explicit EntryConstructFrame(StackFrameIterator* iterator) : EntryFrame(iterator) { } private: friend class StackFrameIterator;};// Exit frames are used to exit JavaScript execution and go to C.class ExitFrame: public StackFrame { public: virtual Type type() const { return EXIT; } virtual Code* FindCode() const; // Garbage colletion support. virtual void Iterate(ObjectVisitor* v) const; static ExitFrame* cast(StackFrame* frame) { ASSERT(frame->is_exit()); return static_cast<ExitFrame*>(frame); } // Compute the state and type of an exit frame given a frame // pointer. Used when constructing the first stack frame seen by an // iterator and the frames following entry frames. static Type GetStateForFramePointer(Address fp, State* state); protected: explicit ExitFrame(StackFrameIterator* iterator) : StackFrame(iterator) { } virtual Address GetCallerStackPointer() const; private: virtual Type GetCallerState(State* state) const; friend class StackFrameIterator;};class ExitDebugFrame: public ExitFrame {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -