13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 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 523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass InnerPointerToCodeCache { 5380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch struct InnerPointerToCodeCacheEntry { 553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address inner_pointer; 5680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code* code; 57b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch SafepointEntry safepoint_entry; 5880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen }; 5980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit InnerPointerToCodeCache(Isolate* isolate) : isolate_(isolate) { 6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Flush(); 6280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 6380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* GcSafeFindCodeForInnerPointer(Address inner_pointer); 653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* GcSafeCastToCode(HeapObject* object, Address inner_pointer); 6680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Flush() { 6880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen memset(&cache_[0], 0, sizeof(cache_)); 6980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 7080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InnerPointerToCodeCacheEntry* GetCacheEntry(Address inner_pointer); 7280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 7380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InnerPointerToCodeCacheEntry* cache(int index) { return &cache_[index]; } 7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kInnerPointerToCodeCacheSize = 1024; 793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InnerPointerToCodeCacheEntry cache_[kInnerPointerToCodeCacheSize]; 8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DISALLOW_COPY_AND_ASSIGN(InnerPointerToCodeCache); 8280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 8380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 8480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackHandler BASE_EMBEDDED { 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch enum Kind { 883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JS_ENTRY, 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CATCH, 903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FINALLY, 913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LAST_KIND = FINALLY 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kKindWidth = 2; 953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(LAST_KIND < (1 << kKindWidth)); 963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kIndexWidth = 32 - kKindWidth; 973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class KindField: public BitField<StackHandler::Kind, 0, kKindWidth> {}; 983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class IndexField: public BitField<unsigned, kKindWidth, kIndexWidth> {}; 993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the address of this stack handler. 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address address() const; 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the next stack handler in the chain. 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline StackHandler* next() const; 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tells whether the given address is inside this handler. 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool includes(Address address) const; 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 11080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen inline void Iterate(ObjectVisitor* v, Code* holder) const; 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Conversion support. 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline StackHandler* FromAddress(Address address); 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Testers 1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline bool is_js_entry() const; 1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline bool is_catch() const; 1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline bool is_finally() const; 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Kind kind() const; 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch inline Object** context_address() const; 1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Object** code_address() const; 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler); 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define STACK_FRAME_TYPE_LIST(V) \ 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(ENTRY, EntryFrame) \ 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(ENTRY_CONSTRUCT, EntryConstructFrame) \ 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(EXIT, ExitFrame) \ 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(JAVA_SCRIPT, JavaScriptFrame) \ 136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch V(OPTIMIZED, OptimizedFrame) \ 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(INTERNAL, InternalFrame) \ 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(CONSTRUCT, ConstructFrame) \ 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame) 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Abstract base class for all stack frames. 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrame BASE_EMBEDDED { 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DECLARE_TYPE(type, ignore) type, 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum Type { 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NONE = 0, 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STACK_FRAME_TYPE_LIST(DECLARE_TYPE) 1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NUMBER_OF_TYPES, 1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Used by FrameScope to indicate that the stack frame is constructed 1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // manually and the FrameScope does not need to emit code. 1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MANUAL 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECLARE_TYPE 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Opaque data type for identifying stack frames. Used extensively 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // by the debugger. 158756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type 159756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // has correct value range (see Issue 830 for more details). 160756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick enum Id { 161756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ID_MIN_VALUE = kMinInt, 162756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ID_MAX_VALUE = kMaxInt, 163756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick NO_ID = 0 164756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick }; 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 166053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // Used to mark the outermost JS entry frame. 167053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block enum JsFrameMarker { 168053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block INNER_JSENTRY_FRAME = 0, 169053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block OUTERMOST_JSENTRY_FRAME = 1 170053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block }; 171053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block 1720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen struct State { 1730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen State() : sp(NULL), fp(NULL), pc_address(NULL) { } 1740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address sp; 1750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address fp; 1760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address* pc_address; 1770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen }; 1780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // Copy constructor; it breaks the connection to host iterator 1808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // (as an iterator usually lives on stack). 1816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block StackFrame(const StackFrame& original) { 1826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block this->state_ = original.state_; 1836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block this->iterator_ = NULL; 1848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch this->isolate_ = original.isolate_; 1856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Type testers. 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_entry() const { return type() == ENTRY; } 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; } 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_exit() const { return type() == EXIT; } 191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_optimized() const { return type() == OPTIMIZED; } 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; } 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_internal() const { return type() == INTERNAL; } 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_construct() const { return type() == CONSTRUCT; } 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual bool is_standard() const { return false; } 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_java_script() const { 198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Type type = this->type(); 199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return (type == JAVA_SCRIPT) || (type == OPTIMIZED); 200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address sp() const { return state_.sp; } 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp() const { return state_.fp; } 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address caller_sp() const { return GetCallerStackPointer(); } 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address pc() const { return *pc_address(); } 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_pc(Address pc) { *pc_address() = pc; } 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual void SetCallerFp(Address caller_fp) = 0; 2116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address* pc_address() const { return state_.pc_address; } 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the id of this stack frame. 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); } 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Checks if this frame includes any stack handlers. 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool HasHandler() const; 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the type of this frame. 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const = 0; 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the code associated with this frame. 224756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // This method could be called during marking phase of GC. 225756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const = 0; 226756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 227756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Get the code associated with this frame. 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Code* LookupCode() const; 22980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 23080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Get the code object that contains the given pc. 23144f0eee88ff00398ff7f715fab053374d808c90dSteve Block static inline Code* GetContainingCode(Isolate* isolate, Address pc); 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the code object containing the given pc and fill in the 234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // safepoint entry and the number of stack slots. The pc must be at 235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // a safepoint. 2368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static Code* GetSafepointData(Isolate* isolate, 2378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Address pc, 238b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch SafepointEntry* safepoint_entry, 239b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned* stack_slots); 240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 24180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void Iterate(ObjectVisitor* v) const = 0; 24280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder); 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Sets a callback function for return-address rewriting profilers 2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // to resolve the location of a return address to the location of the 2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // profiler's stashed return address. 2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void SetReturnAddressLocationResolver( 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReturnAddressLocationResolver resolver); 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum PrintMode { OVERVIEW, DETAILS }; 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print(StringStream* accumulator, 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const { } 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 2578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline explicit StackFrame(StackFrameIterator* iterator); 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual ~StackFrame() { } 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate() const { return isolate_; } 2618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the stack pointer for the calling frame. 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const = 0; 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void PrintIndex(StringStream* accumulator, 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index); 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the top handler from the current stack iterator. 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline StackHandler* top_handler() const; 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the stack frame type for the given state. 2748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static Type ComputeType(Isolate* isolate, State* state); 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const StackFrameIterator* iterator_; 2788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate_; 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block State state_; 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fill in the state of the calling frame. 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const = 0; 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the type and the state of the calling frame. 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type GetCallerState(State* state) const; 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static const intptr_t kIsolateTag = 1; 2888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackHandlerIterator; 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class SafeStackFrameIterator; 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 2946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void operator=(const StackFrame& original); 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Entry frames are used to enter JavaScript execution from C. 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EntryFrame: public StackFrame { 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return ENTRY; } 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 303756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static EntryFrame* cast(StackFrame* frame) { 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_entry()); 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<EntryFrame*>(frame); 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual void SetCallerFp(Address caller_fp); 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline explicit EntryFrame(StackFrameIterator* iterator); 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The caller stack pointer for entry frames is always zero. The 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // real information about the caller frame is available through the 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // link to the top exit frame. 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const { return 0; } 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const; 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type GetCallerState(State* state) const; 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EntryConstructFrame: public EntryFrame { 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return ENTRY_CONSTRUCT; } 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 334756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static EntryConstructFrame* cast(StackFrame* frame) { 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_entry_construct()); 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<EntryConstructFrame*>(frame); 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline explicit EntryConstructFrame(StackFrameIterator* iterator); 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Exit frames are used to exit JavaScript execution and go to C. 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExitFrame: public StackFrame { 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return EXIT; } 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 354756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 356d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Object*& code_slot() const; 357d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual void SetCallerFp(Address caller_fp); 3626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ExitFrame* cast(StackFrame* frame) { 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_exit()); 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<ExitFrame*>(frame); 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the state and type of an exit frame given a frame 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pointer. Used when constructing the first stack frame seen by an 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // iterator and the frames following entry frames. 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Type GetStateForFramePointer(Address fp, State* state); 3720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen static Address ComputeStackPointer(Address fp); 3730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen static void FillState(Address fp, Address sp, State* state); 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline explicit ExitFrame(StackFrameIterator* iterator); 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const; 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StandardFrame: public StackFrame { 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Testers. 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual bool is_standard() const { return true; } 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* context() const; 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Access the expressions in the stack frame including locals. 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* GetExpression(int index) const; 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void SetExpression(int index, Object* value); 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int ComputeExpressionsCount() const; 3993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static Object* GetExpression(Address fp, int index); 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual void SetCallerFp(Address caller_fp); 4026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static StandardFrame* cast(StackFrame* frame) { 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_standard()); 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<StandardFrame*>(frame); 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline explicit StandardFrame(StackFrameIterator* iterator); 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void ComputeCallerState(State* state) const; 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address caller_fp() const; 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address caller_pc() const; 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computes the address of the PC field in the standard frame given 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // by the provided frame pointer. 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Address ComputePCAddress(Address fp); 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iterate over expression stack including stack handlers, locals, 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and parts of the fixed part including context and code fields. 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void IterateExpressions(ObjectVisitor* v) const; 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns the address of the n'th expression stack element. 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address GetExpressionAddress(int n) const; 4273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static Address GetExpressionAddress(Address fp, int n); 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determines if the n'th expression stack element is in a stack 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler or not. Requires traversing all handlers in this frame. 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsExpressionInsideHandler(int n) const; 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determines if the standard frame for the given frame pointer is 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // an arguments adaptor frame. 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsArgumentsAdaptorFrame(Address fp); 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determines if the standard frame for the given frame pointer is a 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // construct frame. 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool IsConstructFrame(Address fp); 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrame; 44325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen friend class StackFrameIterator; 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass FrameSummary BASE_EMBEDDED { 448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FrameSummary(Object* receiver, 450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function, 451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Code* code, 452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int offset, 453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_constructor) 454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : receiver_(receiver), 455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function_(function), 456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code_(code), 457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch offset_(offset), 458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch is_constructor_(is_constructor) { } 459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Object> receiver() { return receiver_; } 460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<JSFunction> function() { return function_; } 461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code() { return code_; } 4628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Address pc() { return code_->address() + offset_; } 463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int offset() { return offset_; } 464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_constructor() { return is_constructor_; } 465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Print(); 467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Object> receiver_; 470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<JSFunction> function_; 471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code_; 472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int offset_; 473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool is_constructor_; 474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JavaScriptFrame: public StandardFrame { 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return JAVA_SCRIPT; } 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accessors. 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* function() const; 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* receiver() const; 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set_receiver(Object* value); 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Access the parameters. 4878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline Address GetParameterSlot(int index) const; 4888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline Object* GetParameter(int index) const; 4898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline int ComputeParametersCount() const { 4908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return GetNumberOfIncomingArguments(); 4918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if this frame is a constructor frame invoked through 'new'. 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsConstructor() const; 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if this frame has "adapted" arguments in the sense that the 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // actual passed arguments are available in an arguments adaptor 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // frame below it on the stack. 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool has_adapted_arguments() const; 5003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int GetArgumentsLength() const; 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print(StringStream* accumulator, 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const; 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determine the code for the frame. 511756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Returns the levels of inlining for this frame. 5143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual int GetInlineCount() { return 1; } 5153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Return a list with JSFunctions of this frame. 517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void GetFunctions(List<JSFunction*>* functions); 518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Build a list with summaries for this frame including all inlined frames. 520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Summarize(List<FrameSummary>* frames); 521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static JavaScriptFrame* cast(StackFrame* frame) { 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_java_script()); 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<JavaScriptFrame*>(frame); 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void PrintTop(FILE* file, bool print_args, bool print_line_number); 5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline explicit JavaScriptFrame(StackFrameIterator* iterator); 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch virtual int GetNumberOfIncomingArguments() const; 5358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Garbage collection support. Iterates over incoming arguments, 537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // receiver, and any callee-saved registers. 538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void IterateArguments(ObjectVisitor* v) const; 539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Object* function_slot_object() const; 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 5440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen friend class StackTracer; 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass OptimizedFrame : public JavaScriptFrame { 549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual Type type() const { return OPTIMIZED; } 551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // GC support. 553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Iterate(ObjectVisitor* v) const; 554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual int GetInlineCount(); 5563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Return a list with JSFunctions of this frame. 558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The functions are ordered bottom-to-top (i.e. functions.last() 559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // is the top-most activation) 560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void GetFunctions(List<JSFunction*>* functions); 561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Summarize(List<FrameSummary>* frames); 563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizationInputData* GetDeoptimizationData(int* deopt_index); 565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch protected: 5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline explicit OptimizedFrame(StackFrameIterator* iterator); 568b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch friend class StackFrameIterator; 571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Arguments adaptor frames are automatically inserted below 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// JavaScript frames when the actual number of parameters does not 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// match the formal number of parameters. 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ArgumentsAdaptorFrame: public JavaScriptFrame { 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return ARGUMENTS_ADAPTOR; } 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determine the code for the frame. 582756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ArgumentsAdaptorFrame* cast(StackFrame* frame) { 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_arguments_adaptor()); 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<ArgumentsAdaptorFrame*>(frame); 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Printing support. 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print(StringStream* accumulator, 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const; 593589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator); 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual int GetNumberOfIncomingArguments() const; 5988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass InternalFrame: public StandardFrame { 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return INTERNAL; } 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Iterate(ObjectVisitor* v) const; 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Determine the code for the frame. 614756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick virtual Code* unchecked_code() const; 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static InternalFrame* cast(StackFrame* frame) { 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_internal()); 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<InternalFrame*>(frame); 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline explicit InternalFrame(StackFrameIterator* iterator); 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Address GetCallerStackPointer() const; 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Construct frames are special trampoline frames introduced to handle 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function invocations through 'new'. 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ConstructFrame: public InternalFrame { 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Type type() const { return CONSTRUCT; } 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static ConstructFrame* cast(StackFrame* frame) { 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->is_construct()); 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<ConstructFrame*>(frame); 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline explicit ConstructFrame(StackFrameIterator* iterator); 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrameIterator; 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrameIterator BASE_EMBEDDED { 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 6528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // An iterator that iterates over the current thread's stack, 6538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // and uses current isolate. 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator(); 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // An iterator that iterates over the isolate's current thread's stack, 6578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit StackFrameIterator(Isolate* isolate); 6588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // An iterator that iterates over a given thread's stack. 6608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StackFrameIterator(Isolate* isolate, ThreadLocalTop* t); 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // An iterator that can start from a given FP address. 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If use_top, then work as usual, if fp isn't NULL, use it, 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // otherwise, do nothing. 66544f0eee88ff00398ff7f715fab053374d808c90dSteve Block StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp); 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* frame() const { 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return frame_; 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate() const { return isolate_; } 6738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() const { return frame_ == NULL; } 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance() { (this->*advance_)(); } 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Go back to the first frame. 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reset(); 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 6818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate_; 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DECLARE_SINGLETON(ignore, type) type type##_; 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON) 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DECLARE_SINGLETON 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* frame_; 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandler* handler_; 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadLocalTop* thread_; 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp_; 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address sp_; 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void (StackFrameIterator::*advance_)(); 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandler* handler() const { 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return handler_; 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the type-specific frame singleton in a given state. 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state); 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // A helper function, can return a NULL pointer. 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* SingletonFor(StackFrame::Type type); 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceWithHandler(); 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceWithoutHandler(); 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class StackFrame; 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class SafeStackFrameIterator; 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_COPY_AND_ASSIGN(StackFrameIterator); 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Iterator that supports iterating through all JavaScript frames. 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate<typename Iterator> 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JavaScriptFrameIteratorTemp BASE_EMBEDDED { 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrameIteratorTemp() { if (!done()) Advance(); } 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline explicit JavaScriptFrameIteratorTemp(Isolate* isolate); 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline JavaScriptFrameIteratorTemp(Isolate* isolate, ThreadLocalTop* top); 7203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Skip frames until the frame with the given id is reached. 7228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit JavaScriptFrameIteratorTemp(StackFrame::Id id) { AdvanceToId(id); } 7238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 7248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline JavaScriptFrameIteratorTemp(Isolate* isolate, StackFrame::Id id); 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JavaScriptFrameIteratorTemp(Address fp, 7273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address sp, 7283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address low_bound, 7293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address high_bound) : 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block iterator_(fp, sp, low_bound, high_bound) { 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!done()) Advance(); 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 73444f0eee88ff00398ff7f715fab053374d808c90dSteve Block JavaScriptFrameIteratorTemp(Isolate* isolate, 7353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address fp, 7363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address sp, 7373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address low_bound, 7383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address high_bound) : 73944f0eee88ff00398ff7f715fab053374d808c90dSteve Block iterator_(isolate, fp, sp, low_bound, high_bound) { 74044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!done()) Advance(); 74144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 74244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline JavaScriptFrame* frame() const; 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() const { return iterator_.done(); } 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Advance to the frame holding the arguments for the current 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // frame. This only affects the current frame if it has adapted 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // arguments. 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AdvanceToArgumentsFrame(); 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Go back to the first frame. 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reset(); 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 7578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline void AdvanceToId(StackFrame::Id id); 7588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Iterator iterator_; 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator; 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NOTE: The stack trace frame iterator is an iterator that only 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// traverse proper JavaScript frames; that is JavaScript frames that 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// have proper JavaScript functions. This excludes the problematic 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// functions in runtime.js. 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackTraceFrameIterator: public JavaScriptFrameIterator { 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackTraceFrameIterator(); 7738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit StackTraceFrameIterator(Isolate* isolate); 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 7754515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 7764515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke private: 7774515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke bool IsValidFrame(); 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SafeStackFrameIterator BASE_EMBEDDED { 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 78344f0eee88ff00398ff7f715fab053374d808c90dSteve Block SafeStackFrameIterator(Isolate* isolate, 78444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address fp, Address sp, 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound); 786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* frame() const { 788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_working_iterator_); 789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return iterator_.frame(); 790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() const { return iteration_done_ ? true : iterator_.done(); } 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Reset(); 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static bool is_active(Isolate* isolate); 79880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool IsWithinBounds( 800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound, Address addr) { 801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return low_bound <= addr && addr <= high_bound; 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 803d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 804d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke private: 8050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class StackAddressValidator { 8060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen public: 8070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen StackAddressValidator(Address low_bound, Address high_bound) 8080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen : low_bound_(low_bound), high_bound_(high_bound) { } 8090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool IsValid(Address addr) const { 8100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return IsWithinBounds(low_bound_, high_bound_, addr); 8110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 8120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen private: 8130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address low_bound_; 8140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address high_bound_; 8150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen }; 8160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class ExitFrameValidator { 8180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen public: 8190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen explicit ExitFrameValidator(const StackAddressValidator& validator) 8200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen : validator_(validator) { } 8210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ExitFrameValidator(Address low_bound, Address high_bound) 8220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen : validator_(low_bound, high_bound) { } 8230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool IsValidFP(Address fp); 8240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen private: 8250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen StackAddressValidator validator_; 8260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen }; 8270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsValidStackAddress(Address addr) const { 8290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return stack_validator_.IsValid(addr); 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool CanIterateHandles(StackFrame* frame, StackHandler* handler); 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsValidFrame(StackFrame* frame) const; 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsValidCaller(StackFrame* frame); 83444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static bool IsValidTop(Isolate* isolate, 83544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address low_bound, Address high_bound); 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 83780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // This is a nasty hack to make sure the active count is incremented 83880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // before the constructor for the embedded iterator is invoked. This 83980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // is needed because the constructor will start looking at frames 84080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // right away and we need to make sure it doesn't start inspecting 84180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // heap objects. 84280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class ActiveCountMaintainer BASE_EMBEDDED { 84380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 8448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit ActiveCountMaintainer(Isolate* isolate); 8458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ~ActiveCountMaintainer(); 8468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch private: 8478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate_; 84880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen }; 84980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 85080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ActiveCountMaintainer maintainer_; 8510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen StackAddressValidator stack_validator_; 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const bool is_valid_top_; 853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const bool is_valid_fp_; 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const bool is_working_iterator_; 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool iteration_done_; 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator iterator_; 857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator> 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SafeJavaScriptFrameIterator; 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SafeStackTraceFrameIterator: public SafeJavaScriptFrameIterator { 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 86644f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit SafeStackTraceFrameIterator(Isolate* isolate, 86744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address fp, Address sp, 868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low_bound, Address high_bound); 869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance(); 870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackFrameLocator BASE_EMBEDDED { 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find the nth JavaScript frame on the stack. The caller must 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // guarantee that such a frame exists. 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrame* FindJavaScriptFrame(int n); 878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrameIterator iterator_; 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Reads all frames on the current stack and copies them into the current 8856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// zone memory. 8866ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockVector<StackFrame*> CreateStackMap(); 8876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_FRAMES_H_ 891