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