frames.h revision a7e24c173cf37484693b9abb38e494fa7bd7baeb
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_FRAMES_H_ 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_FRAMES_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef uint32_t RegList; 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Get the number of registers in a given register list. 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint NumRegs(RegList list); 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Return the code of the n-th saved register available to JavaScript. 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint JSCallerSavedCode(int n); 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Forward declarations. 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrameIterator; 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Top; 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ThreadLocalTop; 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackHandler BASE_EMBEDDED { 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum State { 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ENTRY, 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TRY_CATCH, 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TRY_FINALLY 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the address of this stack handler. 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address address() const; 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the next stack handler in the chain. 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline StackHandler* next() const; 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tells whether the given address is inside this handler. 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool includes(Address address) const; 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void Iterate(ObjectVisitor* v) const; 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Conversion support. 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline StackHandler* FromAddress(Address address); 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Testers 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_entry() { return state() == ENTRY; } 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_try_catch() { return state() == TRY_CATCH; } 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_try_finally() { return state() == TRY_FINALLY; } 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Cook(Code* code); 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Uncook(Code* code); 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline State state() const; 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address pc() const; 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_pc(Address value); 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler); 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define STACK_FRAME_TYPE_LIST(V) \ 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(ENTRY, EntryFrame) \ 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(ENTRY_CONSTRUCT, EntryConstructFrame) \ 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(EXIT, ExitFrame) \ 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(EXIT_DEBUG, ExitDebugFrame) \ 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(JAVA_SCRIPT, JavaScriptFrame) \ 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(INTERNAL, InternalFrame) \ 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(CONSTRUCT, ConstructFrame) \ 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame) 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Abstract base class for all stack frames. 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrame BASE_EMBEDDED { 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DECLARE_TYPE(type, ignore) type, 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum Type { 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NONE = 0, 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STACK_FRAME_TYPE_LIST(DECLARE_TYPE) 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NUMBER_OF_TYPES 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECLARE_TYPE 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Opaque data type for identifying stack frames. Used extensively 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // by the debugger. 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum Id { NO_ID = 0 }; 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Type testers. 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_entry() const { return type() == ENTRY; } 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; } 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_exit() const { return type() == EXIT; } 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_exit_debug() const { return type() == EXIT_DEBUG; } 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_java_script() const { return type() == JAVA_SCRIPT; } 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; } 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_internal() const { return type() == INTERNAL; } 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_construct() const { return type() == CONSTRUCT; } 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual bool is_standard() const { return false; } 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address sp() const { return state_.sp; } 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp() const { return state_.fp; } 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address caller_sp() const { return GetCallerStackPointer(); } 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address pc() const { return *pc_address(); } 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_pc(Address pc) { *pc_address() = pc; } 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address* pc_address() const { return state_.pc_address; } 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the id of this stack frame. 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); } 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Checks if this frame includes any stack handlers. 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool HasHandler() const; 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the type of this frame. 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const = 0; 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the code associated with this frame. 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Code* code() const = 0; 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void CookFramesForThread(ThreadLocalTop* thread); 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void UncookFramesForThread(ThreadLocalTop* thread); 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const { } 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum PrintMode { OVERVIEW, DETAILS }; 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print(StringStream* accumulator, 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const { } 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block struct State { 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address sp; 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp; 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address* pc_address; 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit StackFrame(StackFrameIterator* iterator) : iterator_(iterator) { } 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual ~StackFrame() { } 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the stack pointer for the calling frame. 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const = 0; 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void PrintIndex(StringStream* accumulator, 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index); 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the top handler from the current stack iterator. 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline StackHandler* top_handler() const; 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the stack frame type for the given state. 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Type ComputeType(State* state); 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const StackFrameIterator* iterator_; 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block State state_; 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fill in the state of the calling frame. 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const = 0; 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the type and the state of the calling frame. 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type GetCallerState(State* state) const; 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Cooking/uncooking support. 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Cook(); 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Uncook(); 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackHandlerIterator; 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class SafeStackFrameIterator; 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(StackFrame); 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Entry frames are used to enter JavaScript execution from C. 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EntryFrame: public StackFrame { 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return ENTRY; } 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Code* code() const; 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static EntryFrame* cast(StackFrame* frame) { 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_entry()); 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<EntryFrame*>(frame); 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit EntryFrame(StackFrameIterator* iterator) : StackFrame(iterator) { } 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The caller stack pointer for entry frames is always zero. The 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // real information about the caller frame is available through the 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // link to the top exit frame. 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const { return 0; } 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const; 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type GetCallerState(State* state) const; 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EntryConstructFrame: public EntryFrame { 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return ENTRY_CONSTRUCT; } 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Code* code() const; 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static EntryConstructFrame* cast(StackFrame* frame) { 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_entry_construct()); 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<EntryConstructFrame*>(frame); 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit EntryConstructFrame(StackFrameIterator* iterator) 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : EntryFrame(iterator) { } 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Exit frames are used to exit JavaScript execution and go to C. 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExitFrame: public StackFrame { 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return EXIT; } 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Code* code() const; 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExitFrame* cast(StackFrame* frame) { 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_exit()); 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<ExitFrame*>(frame); 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the state and type of an exit frame given a frame 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pointer. Used when constructing the first stack frame seen by an 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // iterator and the frames following entry frames. 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Type GetStateForFramePointer(Address fp, State* state); 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExitFrame(StackFrameIterator* iterator) : StackFrame(iterator) { } 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const; 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExitDebugFrame: public ExitFrame { 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return EXIT_DEBUG; } 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Code* code() const; 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExitDebugFrame* cast(StackFrame* frame) { 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_exit_debug()); 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<ExitDebugFrame*>(frame); 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExitDebugFrame(StackFrameIterator* iterator) 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : ExitFrame(iterator) { } 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StandardFrame: public StackFrame { 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Testers. 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual bool is_standard() const { return true; } 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* context() const; 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Access the expressions in the stack frame including locals. 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* GetExpression(int index) const; 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void SetExpression(int index, Object* value); 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int ComputeExpressionsCount() const; 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static StandardFrame* cast(StackFrame* frame) { 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_standard()); 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<StandardFrame*>(frame); 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit StandardFrame(StackFrameIterator* iterator) 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : StackFrame(iterator) { } 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const; 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address caller_fp() const; 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address caller_pc() const; 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computes the address of the PC field in the standard frame given 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // by the provided frame pointer. 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Address ComputePCAddress(Address fp); 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iterate over expression stack including stack handlers, locals, 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and parts of the fixed part including context and code fields. 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void IterateExpressions(ObjectVisitor* v) const; 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns the address of the n'th expression stack element. 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address GetExpressionAddress(int n) const; 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determines if the n'th expression stack element is in a stack 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler or not. Requires traversing all handlers in this frame. 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsExpressionInsideHandler(int n) const; 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determines if the standard frame for the given frame pointer is 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // an arguments adaptor frame. 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsArgumentsAdaptorFrame(Address fp); 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determines if the standard frame for the given frame pointer is a 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // construct frame. 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsConstructFrame(Address fp); 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrame; 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JavaScriptFrame: public StandardFrame { 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return JAVA_SCRIPT; } 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* function() const; 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* receiver() const; 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_receiver(Object* value); 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Access the parameters. 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* GetParameter(int index) const; 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int ComputeParametersCount() const; 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Temporary way of getting access to the number of parameters 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // passed on the stack by the caller. Once argument adaptor frames 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // has been introduced on ARM, this number will always match the 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // computed parameters count. 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int GetProvidedParametersCount() const; 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if this frame is a constructor frame invoked through 'new'. 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsConstructor() const; 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if this frame has "adapted" arguments in the sense that the 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // actual passed arguments are available in an arguments adaptor 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // frame below it on the stack. 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool has_adapted_arguments() const; 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print(StringStream* accumulator, 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const; 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determine the code for the frame. 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Code* code() const; 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static JavaScriptFrame* cast(StackFrame* frame) { 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_java_script()); 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<JavaScriptFrame*>(frame); 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit JavaScriptFrame(StackFrameIterator* iterator) 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : StandardFrame(iterator), disable_heap_access_(false) { } 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When this mode is enabled it is not allowed to access heap objects. 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This is a special mode used when gathering stack samples in profiler. 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // A shortcoming is that caller's SP value will be calculated incorrectly 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // (see GetCallerStackPointer implementation), but it is not used for stack 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // sampling. 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void DisableHeapAccess() { disable_heap_access_ = true; } 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool disable_heap_access_; 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* function_slot_object() const; 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Arguments adaptor frames are automatically inserted below 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// JavaScript frames when the actual number of parameters does not 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// match the formal number of parameters. 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ArgumentsAdaptorFrame: public JavaScriptFrame { 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return ARGUMENTS_ADAPTOR; } 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determine the code for the frame. 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Code* code() const; 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ArgumentsAdaptorFrame* cast(StackFrame* frame) { 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_arguments_adaptor()); 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<ArgumentsAdaptorFrame*>(frame); 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print(StringStream* accumulator, 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const; 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator) 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : JavaScriptFrame(iterator) { } 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass InternalFrame: public StandardFrame { 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return INTERNAL; } 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determine the code for the frame. 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Code* code() const; 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static InternalFrame* cast(StackFrame* frame) { 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_internal()); 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<InternalFrame*>(frame); 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit InternalFrame(StackFrameIterator* iterator) 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : StandardFrame(iterator) { } 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Construct frames are special trampoline frames introduced to handle 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function invocations through 'new'. 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ConstructFrame: public InternalFrame { 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return CONSTRUCT; } 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ConstructFrame* cast(StackFrame* frame) { 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_construct()); 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<ConstructFrame*>(frame); 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ConstructFrame(StackFrameIterator* iterator) 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : InternalFrame(iterator) { } 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrameIterator BASE_EMBEDDED { 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // An iterator that iterates over the current thread's stack. 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator(); 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // An iterator that iterates over a given thread's stack. 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit StackFrameIterator(ThreadLocalTop* thread); 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // An iterator that can start from a given FP address. 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If use_top, then work as usual, if fp isn't NULL, use it, 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // otherwise, do nothing. 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator(bool use_top, Address fp, Address sp); 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* frame() const { 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return frame_; 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() const { return frame_ == NULL; } 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance() { (this->*advance_)(); } 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Go back to the first frame. 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reset(); 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DECLARE_SINGLETON(ignore, type) type type##_; 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON) 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECLARE_SINGLETON 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* frame_; 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandler* handler_; 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadLocalTop* thread_; 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp_; 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address sp_; 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void (StackFrameIterator::*advance_)(); 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandler* handler() const { 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return handler_; 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the type-specific frame singleton in a given state. 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state); 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // A helper function, can return a NULL pointer. 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* SingletonFor(StackFrame::Type type); 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceWithHandler(); 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceWithoutHandler(); 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrame; 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class SafeStackFrameIterator; 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_COPY_AND_ASSIGN(StackFrameIterator); 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Iterator that supports iterating through all JavaScript frames. 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate<typename Iterator> 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JavaScriptFrameIteratorTemp BASE_EMBEDDED { 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrameIteratorTemp() { if (!done()) Advance(); } 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit JavaScriptFrameIteratorTemp(ThreadLocalTop* thread) : 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block iterator_(thread) { 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!done()) Advance(); 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Skip frames until the frame with the given id is reached. 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit JavaScriptFrameIteratorTemp(StackFrame::Id id); 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrameIteratorTemp(Address fp, Address sp, 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound) : 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block iterator_(fp, sp, low_bound, high_bound) { 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!done()) Advance(); 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline JavaScriptFrame* frame() const; 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() const { return iterator_.done(); } 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Advance to the frame holding the arguments for the current 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // frame. This only affects the current frame if it has adapted 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // arguments. 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceToArgumentsFrame(); 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Go back to the first frame. 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reset(); 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Iterator iterator_; 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator; 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NOTE: The stack trace frame iterator is an iterator that only 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// traverse proper JavaScript frames; that is JavaScript frames that 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// have proper JavaScript functions. This excludes the problematic 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// functions in runtime.js. 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackTraceFrameIterator: public JavaScriptFrameIterator { 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackTraceFrameIterator(); 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SafeStackFrameIterator BASE_EMBEDDED { 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SafeStackFrameIterator(Address fp, Address sp, 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound); 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* frame() const { 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_working_iterator_); 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return iterator_.frame(); 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() const { return iteration_done_ ? true : iterator_.done(); } 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reset(); 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool IsWithinBounds( 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound, Address addr) { 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return low_bound <= addr && addr <= high_bound; 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsValidStackAddress(Address addr) const { 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return IsWithinBounds(low_bound_, high_bound_, addr); 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool CanIterateHandles(StackFrame* frame, StackHandler* handler); 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsValidFrame(StackFrame* frame) const; 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsValidCaller(StackFrame* frame); 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound_; 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address high_bound_; 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const bool is_valid_top_; 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const bool is_valid_fp_; 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const bool is_working_iterator_; 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool iteration_done_; 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator iterator_; 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator> 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SafeJavaScriptFrameIterator; 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SafeStackTraceFrameIterator: public SafeJavaScriptFrameIterator { 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit SafeStackTraceFrameIterator(Address fp, Address sp, 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound); 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrameLocator BASE_EMBEDDED { 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find the nth JavaScript frame on the stack. The caller must 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // guarantee that such a frame exists. 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrame* FindJavaScriptFrame(int n); 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator iterator_; 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_FRAMES_H_ 679