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