frames.h revision 3fb3ca8c7ca439d408449a395897395c0faae8d1
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 31257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "allocation.h" 3244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "handles.h" 33b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#include "safepoint-table.h" 34b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef uint32_t RegList; 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Get the number of registers in a given register list. 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint NumRegs(RegList list); 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Return the code of the n-th saved register available to JavaScript. 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint JSCallerSavedCode(int n); 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Forward declarations. 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrameIterator; 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ThreadLocalTop; 5044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Isolate; 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass PcToCodeCache { 5380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 5480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen struct PcToCodeCacheEntry { 5580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Address pc; 5680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code* code; 57b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch SafepointEntry safepoint_entry; 5880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen }; 5980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit PcToCodeCache(Isolate* isolate) : isolate_(isolate) { 6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Flush(); 6280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 6380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* GcSafeFindCodeForPc(Address pc); 6544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* GcSafeCastToCode(HeapObject* object, Address pc); 6680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Flush() { 6880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen memset(&cache_[0], 0, sizeof(cache_)); 6980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 7080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 7144f0eee88ff00398ff7f715fab053374d808c90dSteve Block PcToCodeCacheEntry* GetCacheEntry(Address pc); 7280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 7380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 7444f0eee88ff00398ff7f715fab053374d808c90dSteve Block PcToCodeCacheEntry* cache(int index) { return &cache_[index]; } 7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen static const int kPcToCodeCacheSize = 1024; 7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block PcToCodeCacheEntry cache_[kPcToCodeCacheSize]; 8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 8144f0eee88ff00398ff7f715fab053374d808c90dSteve Block DISALLOW_COPY_AND_ASSIGN(PcToCodeCache); 8280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 8380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 8480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackHandler BASE_EMBEDDED { 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum State { 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ENTRY, 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TRY_CATCH, 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TRY_FINALLY 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the address of this stack handler. 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address address() const; 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the next stack handler in the chain. 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline StackHandler* next() const; 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tells whether the given address is inside this handler. 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool includes(Address address) const; 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 10380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen inline void Iterate(ObjectVisitor* v, Code* holder) const; 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Conversion support. 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline StackHandler* FromAddress(Address address); 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Testers 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_entry() { return state() == ENTRY; } 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_try_catch() { return state() == TRY_CATCH; } 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_try_finally() { return state() == TRY_FINALLY; } 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline State state() const; 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen inline Address* pc_address() const; 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler); 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define STACK_FRAME_TYPE_LIST(V) \ 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(ENTRY, EntryFrame) \ 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(ENTRY_CONSTRUCT, EntryConstructFrame) \ 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(EXIT, ExitFrame) \ 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(JAVA_SCRIPT, JavaScriptFrame) \ 128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch V(OPTIMIZED, OptimizedFrame) \ 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(INTERNAL, InternalFrame) \ 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(CONSTRUCT, ConstructFrame) \ 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame) 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Abstract base class for all stack frames. 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrame BASE_EMBEDDED { 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DECLARE_TYPE(type, ignore) type, 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum Type { 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NONE = 0, 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STACK_FRAME_TYPE_LIST(DECLARE_TYPE) 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NUMBER_OF_TYPES 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECLARE_TYPE 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Opaque data type for identifying stack frames. Used extensively 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // by the debugger. 147756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type 148756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // has correct value range (see Issue 830 for more details). 149756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick enum Id { 150756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ID_MIN_VALUE = kMinInt, 151756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ID_MAX_VALUE = kMaxInt, 152756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick NO_ID = 0 153756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick }; 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 155053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // Used to mark the outermost JS entry frame. 156053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block enum JsFrameMarker { 157053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block INNER_JSENTRY_FRAME = 0, 158053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block OUTERMOST_JSENTRY_FRAME = 1 159053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block }; 160053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block 1610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen struct State { 1620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen State() : sp(NULL), fp(NULL), pc_address(NULL) { } 1630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address sp; 1640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address fp; 1650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address* pc_address; 1660d5e116f6aee03185f237311a943491bb079a768Kristian Monsen }; 1670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // Copy constructor; it breaks the connection to host iterator 1698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // (as an iterator usually lives on stack). 1706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block StackFrame(const StackFrame& original) { 1716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block this->state_ = original.state_; 1726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block this->iterator_ = NULL; 1738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch this->isolate_ = original.isolate_; 1746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Type testers. 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_entry() const { return type() == ENTRY; } 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; } 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_exit() const { return type() == EXIT; } 180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_optimized() const { return type() == OPTIMIZED; } 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; } 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_internal() const { return type() == INTERNAL; } 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_construct() const { return type() == CONSTRUCT; } 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual bool is_standard() const { return false; } 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_java_script() const { 187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Type type = this->type(); 188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return (type == JAVA_SCRIPT) || (type == OPTIMIZED); 189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address sp() const { return state_.sp; } 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp() const { return state_.fp; } 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address caller_sp() const { return GetCallerStackPointer(); } 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address pc() const { return *pc_address(); } 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_pc(Address pc) { *pc_address() = pc; } 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual void SetCallerFp(Address caller_fp) = 0; 2006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address* pc_address() const { return state_.pc_address; } 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the id of this stack frame. 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); } 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Checks if this frame includes any stack handlers. 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool HasHandler() const; 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the type of this frame. 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const = 0; 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the code associated with this frame. 213756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // This method could be called during marking phase of GC. 214756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const = 0; 215756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 216756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Get the code associated with this frame. 2178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Code* LookupCode() const { 2188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return GetContainingCode(isolate(), pc()); 21944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 22080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 22180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Get the code object that contains the given pc. 22244f0eee88ff00398ff7f715fab053374d808c90dSteve Block static inline Code* GetContainingCode(Isolate* isolate, Address pc); 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the code object containing the given pc and fill in the 225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // safepoint entry and the number of stack slots. The pc must be at 226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // a safepoint. 2278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static Code* GetSafepointData(Isolate* isolate, 2288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Address pc, 229b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch SafepointEntry* safepoint_entry, 230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned* stack_slots); 231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 23280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void Iterate(ObjectVisitor* v) const = 0; 23380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder); 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum PrintMode { OVERVIEW, DETAILS }; 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print(StringStream* accumulator, 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const { } 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 2438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline explicit StackFrame(StackFrameIterator* iterator); 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual ~StackFrame() { } 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate() const { return isolate_; } 2478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the stack pointer for the calling frame. 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const = 0; 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void PrintIndex(StringStream* accumulator, 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index); 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the top handler from the current stack iterator. 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline StackHandler* top_handler() const; 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the stack frame type for the given state. 2608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static Type ComputeType(Isolate* isolate, State* state); 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const StackFrameIterator* iterator_; 2648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate_; 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block State state_; 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fill in the state of the calling frame. 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const = 0; 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the type and the state of the calling frame. 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type GetCallerState(State* state) const; 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static const intptr_t kIsolateTag = 1; 2748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackHandlerIterator; 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class SafeStackFrameIterator; 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 2806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void operator=(const StackFrame& original); 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Entry frames are used to enter JavaScript execution from C. 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EntryFrame: public StackFrame { 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return ENTRY; } 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 289756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static EntryFrame* cast(StackFrame* frame) { 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_entry()); 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<EntryFrame*>(frame); 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual void SetCallerFp(Address caller_fp); 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit EntryFrame(StackFrameIterator* iterator) : StackFrame(iterator) { } 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The caller stack pointer for entry frames is always zero. The 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // real information about the caller frame is available through the 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // link to the top exit frame. 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const { return 0; } 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const; 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type GetCallerState(State* state) const; 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EntryConstructFrame: public EntryFrame { 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return ENTRY_CONSTRUCT; } 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 320756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static EntryConstructFrame* cast(StackFrame* frame) { 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_entry_construct()); 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<EntryConstructFrame*>(frame); 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit EntryConstructFrame(StackFrameIterator* iterator) 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : EntryFrame(iterator) { } 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Exit frames are used to exit JavaScript execution and go to C. 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExitFrame: public StackFrame { 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return EXIT; } 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 341756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 343d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Object*& code_slot() const; 344d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual void SetCallerFp(Address caller_fp); 3496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExitFrame* cast(StackFrame* frame) { 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_exit()); 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<ExitFrame*>(frame); 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the state and type of an exit frame given a frame 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pointer. Used when constructing the first stack frame seen by an 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // iterator and the frames following entry frames. 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Type GetStateForFramePointer(Address fp, State* state); 3590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen static Address ComputeStackPointer(Address fp); 3600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen static void FillState(Address fp, Address sp, State* state); 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExitFrame(StackFrameIterator* iterator) : StackFrame(iterator) { } 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const; 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StandardFrame: public StackFrame { 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Testers. 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual bool is_standard() const { return true; } 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* context() const; 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Access the expressions in the stack frame including locals. 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* GetExpression(int index) const; 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void SetExpression(int index, Object* value); 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int ComputeExpressionsCount() const; 3863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static Object* GetExpression(Address fp, int index); 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual void SetCallerFp(Address caller_fp); 3896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static StandardFrame* cast(StackFrame* frame) { 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_standard()); 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<StandardFrame*>(frame); 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit StandardFrame(StackFrameIterator* iterator) 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : StackFrame(iterator) { } 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const; 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address caller_fp() const; 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address caller_pc() const; 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computes the address of the PC field in the standard frame given 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // by the provided frame pointer. 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Address ComputePCAddress(Address fp); 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iterate over expression stack including stack handlers, locals, 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and parts of the fixed part including context and code fields. 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void IterateExpressions(ObjectVisitor* v) const; 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns the address of the n'th expression stack element. 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address GetExpressionAddress(int n) const; 4153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static Address GetExpressionAddress(Address fp, int n); 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determines if the n'th expression stack element is in a stack 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler or not. Requires traversing all handlers in this frame. 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsExpressionInsideHandler(int n) const; 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determines if the standard frame for the given frame pointer is 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // an arguments adaptor frame. 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsArgumentsAdaptorFrame(Address fp); 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determines if the standard frame for the given frame pointer is a 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // construct frame. 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsConstructFrame(Address fp); 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrame; 43125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen friend class StackFrameIterator; 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass FrameSummary BASE_EMBEDDED { 436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FrameSummary(Object* receiver, 438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function, 439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Code* code, 440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int offset, 441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_constructor) 442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : receiver_(receiver), 443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function_(function), 444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code_(code), 445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch offset_(offset), 446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch is_constructor_(is_constructor) { } 447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Object> receiver() { return receiver_; } 448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<JSFunction> function() { return function_; } 449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code() { return code_; } 4508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Address pc() { return code_->address() + offset_; } 451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int offset() { return offset_; } 452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_constructor() { return is_constructor_; } 453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Print(); 455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Object> receiver_; 458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<JSFunction> function_; 459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code_; 460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int offset_; 461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_constructor_; 462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JavaScriptFrame: public StandardFrame { 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return JAVA_SCRIPT; } 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* function() const; 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* receiver() const; 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_receiver(Object* value); 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Access the parameters. 4758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline Address GetParameterSlot(int index) const; 4768b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline Object* GetParameter(int index) const; 4778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline int ComputeParametersCount() const { 4788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return GetNumberOfIncomingArguments(); 4798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if this frame is a constructor frame invoked through 'new'. 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsConstructor() const; 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if this frame has "adapted" arguments in the sense that the 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // actual passed arguments are available in an arguments adaptor 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // frame below it on the stack. 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool has_adapted_arguments() const; 4883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int GetArgumentsLength() const; 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print(StringStream* accumulator, 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const; 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determine the code for the frame. 499756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Returns the levels of inlining for this frame. 5023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual int GetInlineCount() { return 1; } 5033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Return a list with JSFunctions of this frame. 505b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void GetFunctions(List<JSFunction*>* functions); 506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Build a list with summaries for this frame including all inlined frames. 508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Summarize(List<FrameSummary>* frames); 509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static JavaScriptFrame* cast(StackFrame* frame) { 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_java_script()); 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<JavaScriptFrame*>(frame); 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit JavaScriptFrame(StackFrameIterator* iterator) 51780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : StandardFrame(iterator) { } 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch virtual int GetNumberOfIncomingArguments() const; 5228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Garbage collection support. Iterates over incoming arguments, 524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // receiver, and any callee-saved registers. 525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void IterateArguments(ObjectVisitor* v) const; 526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* function_slot_object() const; 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 5310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen friend class StackTracer; 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass OptimizedFrame : public JavaScriptFrame { 536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual Type type() const { return OPTIMIZED; } 538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // GC support. 540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Iterate(ObjectVisitor* v) const; 541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual int GetInlineCount(); 5433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Return a list with JSFunctions of this frame. 545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The functions are ordered bottom-to-top (i.e. functions.last() 546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // is the top-most activation) 547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void GetFunctions(List<JSFunction*>* functions); 548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Summarize(List<FrameSummary>* frames); 550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizationInputData* GetDeoptimizationData(int* deopt_index); 552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected: 554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch explicit OptimizedFrame(StackFrameIterator* iterator) 555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : JavaScriptFrame(iterator) { } 556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class StackFrameIterator; 559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Arguments adaptor frames are automatically inserted below 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// JavaScript frames when the actual number of parameters does not 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// match the formal number of parameters. 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ArgumentsAdaptorFrame: public JavaScriptFrame { 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return ARGUMENTS_ADAPTOR; } 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determine the code for the frame. 570756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ArgumentsAdaptorFrame* cast(StackFrame* frame) { 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_arguments_adaptor()); 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<ArgumentsAdaptorFrame*>(frame); 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print(StringStream* accumulator, 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const; 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator) 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : JavaScriptFrame(iterator) { } 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch virtual int GetNumberOfIncomingArguments() const { 5868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Smi::cast(GetExpression(0))->value(); 5878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 5888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass InternalFrame: public StandardFrame { 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return INTERNAL; } 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determine the code for the frame. 604756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static InternalFrame* cast(StackFrame* frame) { 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_internal()); 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<InternalFrame*>(frame); 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit InternalFrame(StackFrameIterator* iterator) 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : StandardFrame(iterator) { } 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Construct frames are special trampoline frames introduced to handle 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function invocations through 'new'. 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ConstructFrame: public InternalFrame { 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return CONSTRUCT; } 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ConstructFrame* cast(StackFrame* frame) { 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_construct()); 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<ConstructFrame*>(frame); 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ConstructFrame(StackFrameIterator* iterator) 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : InternalFrame(iterator) { } 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrameIterator BASE_EMBEDDED { 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 6448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // An iterator that iterates over the current thread's stack, 6458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // and uses current isolate. 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator(); 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // An iterator that iterates over the isolate's current thread's stack, 6498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit StackFrameIterator(Isolate* isolate); 6508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // An iterator that iterates over a given thread's stack. 6528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StackFrameIterator(Isolate* isolate, ThreadLocalTop* t); 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // An iterator that can start from a given FP address. 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If use_top, then work as usual, if fp isn't NULL, use it, 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // otherwise, do nothing. 65744f0eee88ff00398ff7f715fab053374d808c90dSteve Block StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp); 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* frame() const { 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return frame_; 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate() const { return isolate_; } 6658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() const { return frame_ == NULL; } 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance() { (this->*advance_)(); } 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Go back to the first frame. 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reset(); 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 6738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate_; 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DECLARE_SINGLETON(ignore, type) type type##_; 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON) 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECLARE_SINGLETON 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* frame_; 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandler* handler_; 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadLocalTop* thread_; 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp_; 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address sp_; 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void (StackFrameIterator::*advance_)(); 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandler* handler() const { 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return handler_; 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the type-specific frame singleton in a given state. 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state); 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // A helper function, can return a NULL pointer. 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* SingletonFor(StackFrame::Type type); 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceWithHandler(); 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceWithoutHandler(); 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrame; 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class SafeStackFrameIterator; 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_COPY_AND_ASSIGN(StackFrameIterator); 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Iterator that supports iterating through all JavaScript frames. 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate<typename Iterator> 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JavaScriptFrameIteratorTemp BASE_EMBEDDED { 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrameIteratorTemp() { if (!done()) Advance(); } 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline explicit JavaScriptFrameIteratorTemp(Isolate* isolate); 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Skip frames until the frame with the given id is reached. 7128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit JavaScriptFrameIteratorTemp(StackFrame::Id id) { AdvanceToId(id); } 7138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 7148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline JavaScriptFrameIteratorTemp(Isolate* isolate, StackFrame::Id id); 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrameIteratorTemp(Address fp, Address sp, 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound) : 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block iterator_(fp, sp, low_bound, high_bound) { 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!done()) Advance(); 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 72244f0eee88ff00398ff7f715fab053374d808c90dSteve Block JavaScriptFrameIteratorTemp(Isolate* isolate, 72344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address fp, Address sp, 72444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address low_bound, Address high_bound) : 72544f0eee88ff00398ff7f715fab053374d808c90dSteve Block iterator_(isolate, fp, sp, low_bound, high_bound) { 72644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!done()) Advance(); 72744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 72844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline JavaScriptFrame* frame() const; 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() const { return iterator_.done(); } 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Advance to the frame holding the arguments for the current 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // frame. This only affects the current frame if it has adapted 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // arguments. 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceToArgumentsFrame(); 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Go back to the first frame. 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reset(); 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 7438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline void AdvanceToId(StackFrame::Id id); 7448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Iterator iterator_; 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator; 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NOTE: The stack trace frame iterator is an iterator that only 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// traverse proper JavaScript frames; that is JavaScript frames that 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// have proper JavaScript functions. This excludes the problematic 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// functions in runtime.js. 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackTraceFrameIterator: public JavaScriptFrameIterator { 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackTraceFrameIterator(); 7598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit StackTraceFrameIterator(Isolate* isolate); 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 7614515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 7624515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke private: 7634515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke bool IsValidFrame(); 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SafeStackFrameIterator BASE_EMBEDDED { 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 76944f0eee88ff00398ff7f715fab053374d808c90dSteve Block SafeStackFrameIterator(Isolate* isolate, 77044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address fp, Address sp, 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound); 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* frame() const { 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_working_iterator_); 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return iterator_.frame(); 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() const { return iteration_done_ ? true : iterator_.done(); } 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reset(); 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static bool is_active(Isolate* isolate); 78480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool IsWithinBounds( 786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound, Address addr) { 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return low_bound <= addr && addr <= high_bound; 788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 789d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 790d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke private: 7910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class StackAddressValidator { 7920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen public: 7930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen StackAddressValidator(Address low_bound, Address high_bound) 7940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen : low_bound_(low_bound), high_bound_(high_bound) { } 7950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool IsValid(Address addr) const { 7960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return IsWithinBounds(low_bound_, high_bound_, addr); 7970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 7980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen private: 7990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address low_bound_; 8000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address high_bound_; 8010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen }; 8020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class ExitFrameValidator { 8040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen public: 8050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen explicit ExitFrameValidator(const StackAddressValidator& validator) 8060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen : validator_(validator) { } 8070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ExitFrameValidator(Address low_bound, Address high_bound) 8080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen : validator_(low_bound, high_bound) { } 8090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool IsValidFP(Address fp); 8100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen private: 8110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen StackAddressValidator validator_; 8120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen }; 8130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsValidStackAddress(Address addr) const { 8150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return stack_validator_.IsValid(addr); 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool CanIterateHandles(StackFrame* frame, StackHandler* handler); 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsValidFrame(StackFrame* frame) const; 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsValidCaller(StackFrame* frame); 82044f0eee88ff00398ff7f715fab053374d808c90dSteve Block static bool IsValidTop(Isolate* isolate, 82144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address low_bound, Address high_bound); 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // This is a nasty hack to make sure the active count is incremented 82480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // before the constructor for the embedded iterator is invoked. This 82580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // is needed because the constructor will start looking at frames 82680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // right away and we need to make sure it doesn't start inspecting 82780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // heap objects. 82880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class ActiveCountMaintainer BASE_EMBEDDED { 82980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 8308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit ActiveCountMaintainer(Isolate* isolate); 8318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ~ActiveCountMaintainer(); 8328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch private: 8338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate_; 83480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen }; 83580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 83680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ActiveCountMaintainer maintainer_; 8370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen StackAddressValidator stack_validator_; 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const bool is_valid_top_; 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const bool is_valid_fp_; 840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const bool is_working_iterator_; 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool iteration_done_; 842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator iterator_; 843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator> 847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SafeJavaScriptFrameIterator; 848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SafeStackTraceFrameIterator: public SafeJavaScriptFrameIterator { 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 85244f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit SafeStackTraceFrameIterator(Isolate* isolate, 85344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address fp, Address sp, 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound); 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrameLocator BASE_EMBEDDED { 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find the nth JavaScript frame on the stack. The caller must 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // guarantee that such a frame exists. 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrame* FindJavaScriptFrame(int n); 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator iterator_; 867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Reads all frames on the current stack and copies them into the current 8716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// zone memory. 8726ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockVector<StackFrame*> CreateStackMap(); 8736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_FRAMES_H_ 877