frames.h revision 8b112d2025046f85ef7f6be087c6129c872ebad2
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 3144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "handles.h" 32b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#include "safepoint-table.h" 33b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef uint32_t RegList; 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Get the number of registers in a given register list. 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint NumRegs(RegList list); 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Return the code of the n-th saved register available to JavaScript. 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint JSCallerSavedCode(int n); 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Forward declarations. 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrameIterator; 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ThreadLocalTop; 4944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Isolate; 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass PcToCodeCache { 5280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 5380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen struct PcToCodeCacheEntry { 5480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Address pc; 5580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code* code; 56b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch SafepointEntry safepoint_entry; 5780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen }; 5880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit PcToCodeCache(Isolate* isolate) : isolate_(isolate) { 6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Flush(); 6180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 6280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 6344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* GcSafeFindCodeForPc(Address pc); 6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* GcSafeCastToCode(HeapObject* object, Address pc); 6580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 6644f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Flush() { 6780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen memset(&cache_[0], 0, sizeof(cache_)); 6880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 6980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 7044f0eee88ff00398ff7f715fab053374d808c90dSteve Block PcToCodeCacheEntry* GetCacheEntry(Address pc); 7180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 7280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block PcToCodeCacheEntry* cache(int index) { return &cache_[index]; } 7444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen static const int kPcToCodeCacheSize = 1024; 7844f0eee88ff00398ff7f715fab053374d808c90dSteve Block PcToCodeCacheEntry cache_[kPcToCodeCacheSize]; 7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block DISALLOW_COPY_AND_ASSIGN(PcToCodeCache); 8180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 8280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 8380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackHandler BASE_EMBEDDED { 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum State { 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ENTRY, 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TRY_CATCH, 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TRY_FINALLY 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the address of this stack handler. 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address address() const; 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the next stack handler in the chain. 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline StackHandler* next() const; 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tells whether the given address is inside this handler. 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool includes(Address address) const; 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 10280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen inline void Iterate(ObjectVisitor* v, Code* holder) const; 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Conversion support. 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline StackHandler* FromAddress(Address address); 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Testers 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_entry() { return state() == ENTRY; } 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_try_catch() { return state() == TRY_CATCH; } 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_try_finally() { return state() == TRY_FINALLY; } 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline State state() const; 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen inline Address* pc_address() const; 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler); 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define STACK_FRAME_TYPE_LIST(V) \ 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(ENTRY, EntryFrame) \ 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(ENTRY_CONSTRUCT, EntryConstructFrame) \ 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(EXIT, ExitFrame) \ 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(JAVA_SCRIPT, JavaScriptFrame) \ 127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch V(OPTIMIZED, OptimizedFrame) \ 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(INTERNAL, InternalFrame) \ 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(CONSTRUCT, ConstructFrame) \ 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame) 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Abstract base class for all stack frames. 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrame BASE_EMBEDDED { 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DECLARE_TYPE(type, ignore) type, 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum Type { 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NONE = 0, 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STACK_FRAME_TYPE_LIST(DECLARE_TYPE) 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NUMBER_OF_TYPES 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECLARE_TYPE 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Opaque data type for identifying stack frames. Used extensively 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // by the debugger. 146756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type 147756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // has correct value range (see Issue 830 for more details). 148756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick enum Id { 149756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ID_MIN_VALUE = kMinInt, 150756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ID_MAX_VALUE = kMaxInt, 151756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick NO_ID = 0 152756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick }; 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen struct State { 1550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen State() : sp(NULL), fp(NULL), pc_address(NULL) { } 1560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address sp; 1570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address fp; 1580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address* pc_address; 1590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen }; 1600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // Copy constructor; it breaks the connection to host iterator 1628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // (as an iterator usually lives on stack). 1636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block StackFrame(const StackFrame& original) { 1646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block this->state_ = original.state_; 1656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block this->iterator_ = NULL; 1668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch this->isolate_ = original.isolate_; 1676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Type testers. 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_entry() const { return type() == ENTRY; } 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; } 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_exit() const { return type() == EXIT; } 173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_optimized() const { return type() == OPTIMIZED; } 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; } 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_internal() const { return type() == INTERNAL; } 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_construct() const { return type() == CONSTRUCT; } 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual bool is_standard() const { return false; } 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_java_script() const { 180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Type type = this->type(); 181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return (type == JAVA_SCRIPT) || (type == OPTIMIZED); 182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address sp() const { return state_.sp; } 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp() const { return state_.fp; } 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address caller_sp() const { return GetCallerStackPointer(); } 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address pc() const { return *pc_address(); } 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_pc(Address pc) { *pc_address() = pc; } 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual void SetCallerFp(Address caller_fp) = 0; 1936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address* pc_address() const { return state_.pc_address; } 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the id of this stack frame. 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); } 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Checks if this frame includes any stack handlers. 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool HasHandler() const; 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the type of this frame. 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const = 0; 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the code associated with this frame. 206756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // This method could be called during marking phase of GC. 207756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const = 0; 208756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 209756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Get the code associated with this frame. 2108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Code* LookupCode() const { 2118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return GetContainingCode(isolate(), pc()); 21244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 21380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 21480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Get the code object that contains the given pc. 21544f0eee88ff00398ff7f715fab053374d808c90dSteve Block static inline Code* GetContainingCode(Isolate* isolate, Address pc); 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the code object containing the given pc and fill in the 218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // safepoint entry and the number of stack slots. The pc must be at 219b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // a safepoint. 2208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static Code* GetSafepointData(Isolate* isolate, 2218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Address pc, 222b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch SafepointEntry* safepoint_entry, 223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned* stack_slots); 224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 22580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void Iterate(ObjectVisitor* v) const = 0; 22680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder); 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum PrintMode { OVERVIEW, DETAILS }; 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print(StringStream* accumulator, 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const { } 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 2368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline explicit StackFrame(StackFrameIterator* iterator); 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual ~StackFrame() { } 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate() const { return isolate_; } 2408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the stack pointer for the calling frame. 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const = 0; 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void PrintIndex(StringStream* accumulator, 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index); 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the top handler from the current stack iterator. 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline StackHandler* top_handler() const; 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the stack frame type for the given state. 2538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static Type ComputeType(Isolate* isolate, State* state); 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const StackFrameIterator* iterator_; 2578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate_; 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block State state_; 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fill in the state of the calling frame. 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const = 0; 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the type and the state of the calling frame. 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type GetCallerState(State* state) const; 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static const intptr_t kIsolateTag = 1; 2678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackHandlerIterator; 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class SafeStackFrameIterator; 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 2736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void operator=(const StackFrame& original); 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Entry frames are used to enter JavaScript execution from C. 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EntryFrame: public StackFrame { 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return ENTRY; } 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 282756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static EntryFrame* cast(StackFrame* frame) { 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_entry()); 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<EntryFrame*>(frame); 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual void SetCallerFp(Address caller_fp); 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit EntryFrame(StackFrameIterator* iterator) : StackFrame(iterator) { } 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The caller stack pointer for entry frames is always zero. The 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // real information about the caller frame is available through the 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // link to the top exit frame. 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const { return 0; } 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const; 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type GetCallerState(State* state) const; 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EntryConstructFrame: public EntryFrame { 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return ENTRY_CONSTRUCT; } 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 313756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static EntryConstructFrame* cast(StackFrame* frame) { 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_entry_construct()); 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<EntryConstructFrame*>(frame); 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit EntryConstructFrame(StackFrameIterator* iterator) 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : EntryFrame(iterator) { } 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Exit frames are used to exit JavaScript execution and go to C. 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExitFrame: public StackFrame { 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return EXIT; } 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 334756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 336d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Object*& code_slot() const; 337d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual void SetCallerFp(Address caller_fp); 3426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExitFrame* cast(StackFrame* frame) { 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_exit()); 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<ExitFrame*>(frame); 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the state and type of an exit frame given a frame 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pointer. Used when constructing the first stack frame seen by an 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // iterator and the frames following entry frames. 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Type GetStateForFramePointer(Address fp, State* state); 3520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen static Address ComputeStackPointer(Address fp); 3530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen static void FillState(Address fp, Address sp, State* state); 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ExitFrame(StackFrameIterator* iterator) : StackFrame(iterator) { } 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const; 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StandardFrame: public StackFrame { 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Testers. 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual bool is_standard() const { return true; } 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* context() const; 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Access the expressions in the stack frame including locals. 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* GetExpression(int index) const; 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void SetExpression(int index, Object* value); 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int ComputeExpressionsCount() const; 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual void SetCallerFp(Address caller_fp); 3816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static StandardFrame* cast(StackFrame* frame) { 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_standard()); 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<StandardFrame*>(frame); 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit StandardFrame(StackFrameIterator* iterator) 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : StackFrame(iterator) { } 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const; 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address caller_fp() const; 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address caller_pc() const; 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computes the address of the PC field in the standard frame given 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // by the provided frame pointer. 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Address ComputePCAddress(Address fp); 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iterate over expression stack including stack handlers, locals, 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and parts of the fixed part including context and code fields. 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void IterateExpressions(ObjectVisitor* v) const; 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns the address of the n'th expression stack element. 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address GetExpressionAddress(int n) const; 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determines if the n'th expression stack element is in a stack 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler or not. Requires traversing all handlers in this frame. 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsExpressionInsideHandler(int n) const; 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determines if the standard frame for the given frame pointer is 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // an arguments adaptor frame. 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsArgumentsAdaptorFrame(Address fp); 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determines if the standard frame for the given frame pointer is a 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // construct frame. 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsConstructFrame(Address fp); 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrame; 42225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen friend class StackFrameIterator; 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass FrameSummary BASE_EMBEDDED { 427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FrameSummary(Object* receiver, 429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function, 430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Code* code, 431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int offset, 432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_constructor) 433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : receiver_(receiver), 434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function_(function), 435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code_(code), 436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch offset_(offset), 437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch is_constructor_(is_constructor) { } 438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Object> receiver() { return receiver_; } 439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<JSFunction> function() { return function_; } 440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code() { return code_; } 4418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Address pc() { return code_->address() + offset_; } 442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int offset() { return offset_; } 443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_constructor() { return is_constructor_; } 444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Print(); 446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Object> receiver_; 449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<JSFunction> function_; 450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code_; 451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int offset_; 452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_constructor_; 453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JavaScriptFrame: public StandardFrame { 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return JAVA_SCRIPT; } 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* function() const; 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* receiver() const; 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_receiver(Object* value); 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Access the parameters. 4668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline Address GetParameterSlot(int index) const; 4678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline Object* GetParameter(int index) const; 4688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline int ComputeParametersCount() const { 4698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return GetNumberOfIncomingArguments(); 4708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if this frame is a constructor frame invoked through 'new'. 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsConstructor() const; 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if this frame has "adapted" arguments in the sense that the 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // actual passed arguments are available in an arguments adaptor 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // frame below it on the stack. 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool has_adapted_arguments() const; 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print(StringStream* accumulator, 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const; 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determine the code for the frame. 489756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Return a list with JSFunctions of this frame. 492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void GetFunctions(List<JSFunction*>* functions); 493b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Build a list with summaries for this frame including all inlined frames. 495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Summarize(List<FrameSummary>* frames); 496b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static JavaScriptFrame* cast(StackFrame* frame) { 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_java_script()); 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<JavaScriptFrame*>(frame); 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit JavaScriptFrame(StackFrameIterator* iterator) 50480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : StandardFrame(iterator) { } 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch virtual int GetNumberOfIncomingArguments() const; 5098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 510b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Garbage collection support. Iterates over incoming arguments, 511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // receiver, and any callee-saved registers. 512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void IterateArguments(ObjectVisitor* v) const; 513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* function_slot_object() const; 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 5180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen friend class StackTracer; 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass OptimizedFrame : public JavaScriptFrame { 523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual Type type() const { return OPTIMIZED; } 525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // GC support. 527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Iterate(ObjectVisitor* v) const; 528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Return a list with JSFunctions of this frame. 530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The functions are ordered bottom-to-top (i.e. functions.last() 531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // is the top-most activation) 532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void GetFunctions(List<JSFunction*>* functions); 533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Summarize(List<FrameSummary>* frames); 535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizationInputData* GetDeoptimizationData(int* deopt_index); 537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected: 539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch explicit OptimizedFrame(StackFrameIterator* iterator) 540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : JavaScriptFrame(iterator) { } 541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class StackFrameIterator; 544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Arguments adaptor frames are automatically inserted below 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// JavaScript frames when the actual number of parameters does not 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// match the formal number of parameters. 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ArgumentsAdaptorFrame: public JavaScriptFrame { 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return ARGUMENTS_ADAPTOR; } 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determine the code for the frame. 555756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ArgumentsAdaptorFrame* cast(StackFrame* frame) { 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_arguments_adaptor()); 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<ArgumentsAdaptorFrame*>(frame); 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print(StringStream* accumulator, 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const; 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator) 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : JavaScriptFrame(iterator) { } 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch virtual int GetNumberOfIncomingArguments() const { 5718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Smi::cast(GetExpression(0))->value(); 5728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 5738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass InternalFrame: public StandardFrame { 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return INTERNAL; } 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determine the code for the frame. 589756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static InternalFrame* cast(StackFrame* frame) { 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_internal()); 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<InternalFrame*>(frame); 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit InternalFrame(StackFrameIterator* iterator) 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : StandardFrame(iterator) { } 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Construct frames are special trampoline frames introduced to handle 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function invocations through 'new'. 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ConstructFrame: public InternalFrame { 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return CONSTRUCT; } 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ConstructFrame* cast(StackFrame* frame) { 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_construct()); 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<ConstructFrame*>(frame); 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ConstructFrame(StackFrameIterator* iterator) 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : InternalFrame(iterator) { } 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrameIterator BASE_EMBEDDED { 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 6298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // An iterator that iterates over the current thread's stack, 6308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // and uses current isolate. 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator(); 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // An iterator that iterates over the isolate's current thread's stack, 6348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit StackFrameIterator(Isolate* isolate); 6358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // An iterator that iterates over a given thread's stack. 6378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StackFrameIterator(Isolate* isolate, ThreadLocalTop* t); 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // An iterator that can start from a given FP address. 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If use_top, then work as usual, if fp isn't NULL, use it, 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // otherwise, do nothing. 64244f0eee88ff00398ff7f715fab053374d808c90dSteve Block StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp); 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* frame() const { 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return frame_; 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate() const { return isolate_; } 6508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() const { return frame_ == NULL; } 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance() { (this->*advance_)(); } 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Go back to the first frame. 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reset(); 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 6588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate_; 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DECLARE_SINGLETON(ignore, type) type type##_; 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON) 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECLARE_SINGLETON 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* frame_; 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandler* handler_; 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadLocalTop* thread_; 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp_; 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address sp_; 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void (StackFrameIterator::*advance_)(); 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandler* handler() const { 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return handler_; 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the type-specific frame singleton in a given state. 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state); 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // A helper function, can return a NULL pointer. 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* SingletonFor(StackFrame::Type type); 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceWithHandler(); 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceWithoutHandler(); 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrame; 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class SafeStackFrameIterator; 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_COPY_AND_ASSIGN(StackFrameIterator); 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Iterator that supports iterating through all JavaScript frames. 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate<typename Iterator> 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JavaScriptFrameIteratorTemp BASE_EMBEDDED { 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrameIteratorTemp() { if (!done()) Advance(); } 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline explicit JavaScriptFrameIteratorTemp(Isolate* isolate); 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Skip frames until the frame with the given id is reached. 6978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit JavaScriptFrameIteratorTemp(StackFrame::Id id) { AdvanceToId(id); } 6988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 6998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline JavaScriptFrameIteratorTemp(Isolate* isolate, StackFrame::Id id); 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrameIteratorTemp(Address fp, Address sp, 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound) : 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block iterator_(fp, sp, low_bound, high_bound) { 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!done()) Advance(); 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 70744f0eee88ff00398ff7f715fab053374d808c90dSteve Block JavaScriptFrameIteratorTemp(Isolate* isolate, 70844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address fp, Address sp, 70944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address low_bound, Address high_bound) : 71044f0eee88ff00398ff7f715fab053374d808c90dSteve Block iterator_(isolate, fp, sp, low_bound, high_bound) { 71144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!done()) Advance(); 71244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 71344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline JavaScriptFrame* frame() const; 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() const { return iterator_.done(); } 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Advance to the frame holding the arguments for the current 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // frame. This only affects the current frame if it has adapted 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // arguments. 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceToArgumentsFrame(); 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Go back to the first frame. 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reset(); 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 7288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline void AdvanceToId(StackFrame::Id id); 7298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Iterator iterator_; 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator; 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NOTE: The stack trace frame iterator is an iterator that only 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// traverse proper JavaScript frames; that is JavaScript frames that 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// have proper JavaScript functions. This excludes the problematic 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// functions in runtime.js. 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackTraceFrameIterator: public JavaScriptFrameIterator { 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackTraceFrameIterator(); 7448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit StackTraceFrameIterator(Isolate* isolate); 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 7464515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 7474515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke private: 7484515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke bool IsValidFrame(); 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SafeStackFrameIterator BASE_EMBEDDED { 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 75444f0eee88ff00398ff7f715fab053374d808c90dSteve Block SafeStackFrameIterator(Isolate* isolate, 75544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address fp, Address sp, 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound); 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* frame() const { 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_working_iterator_); 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return iterator_.frame(); 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() const { return iteration_done_ ? true : iterator_.done(); } 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reset(); 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static bool is_active(Isolate* isolate); 76980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool IsWithinBounds( 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound, Address addr) { 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return low_bound <= addr && addr <= high_bound; 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 774d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 775d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke private: 7760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class StackAddressValidator { 7770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen public: 7780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen StackAddressValidator(Address low_bound, Address high_bound) 7790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen : low_bound_(low_bound), high_bound_(high_bound) { } 7800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool IsValid(Address addr) const { 7810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return IsWithinBounds(low_bound_, high_bound_, addr); 7820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 7830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen private: 7840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address low_bound_; 7850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address high_bound_; 7860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen }; 7870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 7880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class ExitFrameValidator { 7890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen public: 7900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen explicit ExitFrameValidator(const StackAddressValidator& validator) 7910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen : validator_(validator) { } 7920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ExitFrameValidator(Address low_bound, Address high_bound) 7930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen : validator_(low_bound, high_bound) { } 7940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool IsValidFP(Address fp); 7950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen private: 7960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen StackAddressValidator validator_; 7970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen }; 7980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsValidStackAddress(Address addr) const { 8000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return stack_validator_.IsValid(addr); 801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool CanIterateHandles(StackFrame* frame, StackHandler* handler); 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsValidFrame(StackFrame* frame) const; 804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsValidCaller(StackFrame* frame); 80544f0eee88ff00398ff7f715fab053374d808c90dSteve Block static bool IsValidTop(Isolate* isolate, 80644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address low_bound, Address high_bound); 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 80880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // This is a nasty hack to make sure the active count is incremented 80980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // before the constructor for the embedded iterator is invoked. This 81080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // is needed because the constructor will start looking at frames 81180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // right away and we need to make sure it doesn't start inspecting 81280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // heap objects. 81380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class ActiveCountMaintainer BASE_EMBEDDED { 81480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 8158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit ActiveCountMaintainer(Isolate* isolate); 8168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ~ActiveCountMaintainer(); 8178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch private: 8188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate_; 81980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen }; 82080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 82180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ActiveCountMaintainer maintainer_; 8220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen StackAddressValidator stack_validator_; 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const bool is_valid_top_; 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const bool is_valid_fp_; 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const bool is_working_iterator_; 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool iteration_done_; 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator iterator_; 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_LOGGING_AND_PROFILING 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator> 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SafeJavaScriptFrameIterator; 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SafeStackTraceFrameIterator: public SafeJavaScriptFrameIterator { 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 83844f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit SafeStackTraceFrameIterator(Isolate* isolate, 83944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address fp, Address sp, 840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound); 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrameLocator BASE_EMBEDDED { 847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find the nth JavaScript frame on the stack. The caller must 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // guarantee that such a frame exists. 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrame* FindJavaScriptFrame(int n); 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator iterator_; 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Reads all frames on the current stack and copies them into the current 8586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// zone memory. 8596ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockVector<StackFrame*> CreateStackMap(); 8606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_FRAMES_H_ 864