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