13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/frames.h"
6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <memory>
8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <sstream>
9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/bits.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/deoptimizer.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/frames-inl.h"
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/full-codegen/full-codegen.h"
1462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/ic/ic-stats.h"
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/register-configuration.h"
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/safepoint-table.h"
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/string-stream.h"
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/vm-state-inl.h"
19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/wasm/wasm-module.h"
20c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/wasm/wasm-objects.h"
213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReturnAddressLocationResolver
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StackFrame::return_address_location_resolver_ = NULL;
273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Iterator that supports traversing the stack handlers of a
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// particular frame. Needs to know the top of the handler chain.
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackHandlerIterator BASE_EMBEDDED {
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StackHandlerIterator(const StackFrame* frame, StackHandler* handler)
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : limit_(frame->fp()), handler_(handler) {
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Make sure the handler has already been unwound to this frame.
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(frame->sp() <= handler->address());
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StackHandler* handler() const { return handler_; }
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool done() {
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return handler_ == NULL || handler_->address() > limit_;
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Advance() {
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!done());
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    handler_ = handler_->next();
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const Address limit_;
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StackHandler* handler_;
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -------------------------------------------------------------------------
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define INITIALIZE_SINGLETON(type, field) field##_(this),
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochStackFrameIteratorBase::StackFrameIteratorBase(Isolate* isolate,
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               bool can_access_heap_objects)
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : isolate_(isolate),
628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      frame_(NULL), handler_(NULL),
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      can_access_heap_objects_(can_access_heap_objects) {
658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef INITIALIZE_SINGLETON
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
688b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochStackFrameIterator::StackFrameIterator(Isolate* isolate)
69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    : StackFrameIterator(isolate, isolate->thread_local_top()) {}
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
718b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochStackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : StackFrameIteratorBase(isolate, true) {
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reset(t);
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid StackFrameIterator::Advance() {
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!done());
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute the state of the calling frame before restoring
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // callee-saved registers and unwinding handlers. This allows the
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // frame code that computes the caller state to access the top
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // handler and the value of any callee-saved register if needed.
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StackFrame::State state;
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StackFrame::Type type = frame_->GetCallerState(&state);
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Unwind handlers corresponding to the current frame.
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StackHandlerIterator it(frame_, handler_);
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (!it.done()) it.Advance();
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  handler_ = it.handler();
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Advance to the calling frame.
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  frame_ = SingletonFor(type, &state);
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // When we're done iterating over the stack frames, the handler
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // chain must have been completely unwound.
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!done() || handler_ == NULL);
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid StackFrameIterator::Reset(ThreadLocalTop* top) {
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StackFrame::State state;
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StackFrame::Type type = ExitFrame::GetStateForFramePointer(
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Isolate::c_entry_fp(top), &state);
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  handler_ = StackHandler::FromAddress(Isolate::handler(top));
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  frame_ = SingletonFor(type, &state);
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochStackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type,
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                             StackFrame::State* state) {
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StackFrame* result = SingletonFor(type);
111bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK((!result) == (type == StackFrame::NONE));
112bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (result) result->state_ = *state;
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochStackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type) {
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define FRAME_TYPE_CASE(type, field) \
119109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  case StackFrame::type:             \
120109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return &field##_;
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  switch (type) {
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case StackFrame::NONE: return NULL;
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    default: break;
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
127109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return NULL;
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef FRAME_TYPE_CASE
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -------------------------------------------------------------------------
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid JavaScriptFrameIterator::Advance() {
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  do {
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    iterator_.Advance();
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } while (!iterator_.done() && !iterator_.frame()->is_java_script());
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid JavaScriptFrameIterator::AdvanceToArgumentsFrame() {
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!frame()->has_adapted_arguments()) return;
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  iterator_.Advance();
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(iterator_.frame()->is_arguments_adaptor());
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -------------------------------------------------------------------------
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1508b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochStackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
151bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    : iterator_(isolate) {
152bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (!done() && !IsValidFrame(iterator_.frame())) Advance();
1538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
1548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochStackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate,
156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                 StackFrame::Id id)
157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    : StackTraceFrameIterator(isolate) {
158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  while (!done() && frame()->id() != id) Advance();
159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackTraceFrameIterator::Advance() {
162bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  do {
163bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    iterator_.Advance();
164bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } while (!done() && !IsValidFrame(iterator_.frame()));
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
167bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) const {
168bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (frame->is_java_script()) {
169bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    JavaScriptFrame* jsFrame = static_cast<JavaScriptFrame*>(frame);
170bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (!jsFrame->function()->IsJSFunction()) return false;
17162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return jsFrame->function()->shared()->IsSubjectToDebugging();
172bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
173bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // apart from javascript, only wasm is valid
174bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return frame->is_wasm();
1754515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke}
1764515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid StackTraceFrameIterator::AdvanceToArgumentsFrame() {
178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!is_javascript() || !javascript_frame()->has_adapted_arguments()) return;
179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  iterator_.Advance();
180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(iterator_.frame()->is_arguments_adaptor());
181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -------------------------------------------------------------------------
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
18562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace {
18662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
18762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool IsInterpreterFramePc(Isolate* isolate, Address pc) {
18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Code* interpreter_entry_trampoline =
18962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline);
19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Code* interpreter_bytecode_advance =
19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeAdvance);
19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Code* interpreter_bytecode_dispatch =
19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
19562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return (pc >= interpreter_entry_trampoline->instruction_start() &&
19662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          pc < interpreter_entry_trampoline->instruction_end()) ||
19762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch         (pc >= interpreter_bytecode_advance->instruction_start() &&
19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          pc < interpreter_bytecode_advance->instruction_end()) ||
19962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch         (pc >= interpreter_bytecode_dispatch->instruction_start() &&
20062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          pc < interpreter_bytecode_dispatch->instruction_end());
20162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
20262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
20362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochDISABLE_ASAN Address ReadMemoryAt(Address address) {
20462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return Memory::Address_at(address);
20562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
20662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
20762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}  // namespace
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSafeStackFrameIterator::SafeStackFrameIterator(
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Address fp, Address sp, Address js_entry_sp)
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : StackFrameIteratorBase(isolate, false),
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      low_bound_(sp),
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      high_bound_(js_entry_sp),
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      top_frame_type_(StackFrame::NONE),
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      external_callback_scope_(isolate->external_callback_scope()) {
2170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  StackFrame::State state;
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StackFrame::Type type;
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ThreadLocalTop* top = isolate->thread_local_top();
22062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool advance_frame = true;
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsValidTop(top)) {
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    top_frame_type_ = type;
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsValidStackAddress(fp)) {
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(fp != NULL);
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    state.fp = fp;
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    state.sp = sp;
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    state.pc_address = StackFrame::ResolveReturnAddressLocation(
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
23062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
23162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // If the top of stack is a return address to the interpreter trampoline,
23262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // then we are likely in a bytecode handler with elided frame. In that
23362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // case, set the PC properly and make sure we do not drop the frame.
23462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (IsValidStackAddress(sp)) {
23562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      MSAN_MEMORY_IS_INITIALIZED(sp, kPointerSize);
23662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Address tos = ReadMemoryAt(reinterpret_cast<Address>(sp));
23762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (IsInterpreterFramePc(isolate, tos)) {
23862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        state.pc_address = reinterpret_cast<Address*>(sp);
23962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        advance_frame = false;
24062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
24162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
24262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset,
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // we check only that kMarkerOffset is within the stack bounds and do
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // compile time check that kContextOffset slot is pushed on the stack before
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // kMarkerOffset.
2473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    STATIC_ASSERT(StandardFrameConstants::kFunctionOffset <
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  StandardFrameConstants::kContextOffset);
2493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Address frame_marker = fp + StandardFrameConstants::kFunctionOffset;
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (IsValidStackAddress(frame_marker)) {
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      type = StackFrame::ComputeType(this, &state);
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      top_frame_type_ = type;
25362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // We only keep the top frame if we believe it to be interpreted frame.
25462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (type != StackFrame::INTERPRETED) {
25562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        advance_frame = true;
25662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Mark the frame as JAVA_SCRIPT if we cannot determine its type.
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // The frame anyways will be skipped.
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      type = StackFrame::JAVA_SCRIPT;
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Top frame is incomplete so we cannot reliably determine its type.
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      top_frame_type_ = StackFrame::NONE;
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
2660d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  }
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  frame_ = SingletonFor(type, &state);
26862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (advance_frame && frame_) Advance();
2698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
2708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const {
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address c_entry_fp = Isolate::c_entry_fp(top);
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!IsValidExitFrame(c_entry_fp)) return false;
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // There should be at least one JS_ENTRY stack handler.
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address handler = Isolate::handler(top);
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (handler == NULL) return false;
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check that there are no js frames on top of the native frames.
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return c_entry_fp < handler;
2800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
2810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
2820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid SafeStackFrameIterator::AdvanceOneFrame() {
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!done());
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StackFrame* last_frame = frame_;
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Before advancing to the next stack frame, perform pointer validity tests.
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) {
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    frame_ = NULL;
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Advance to the previous frame.
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StackFrame::State state;
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StackFrame::Type type = frame_->GetCallerState(&state);
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  frame_ = SingletonFor(type, &state);
297bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (!frame_) return;
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check that we have actually moved to the previous frame in the stack.
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (frame_->sp() < last_sp || frame_->fp() < last_fp) {
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    frame_ = NULL;
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const {
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StackFrame::State state;
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (frame->is_entry() || frame->is_entry_construct()) {
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // See EntryFrame::GetCallerState. It computes the caller FP address
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // and calls ExitFrame::GetStateForFramePointer on it. We need to be
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // sure that caller FP address is valid.
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Address caller_fp = Memory::Address_at(
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        frame->fp() + EntryFrameConstants::kCallerFPOffset);
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!IsValidExitFrame(caller_fp)) return false;
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (frame->is_arguments_adaptor()) {
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // the number of arguments is stored on stack as Smi. We need to check
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // that it really an Smi.
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)->
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        GetExpression(0);
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!number_of_args->IsSmi()) {
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return false;
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  frame->ComputeCallerState(&state);
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) &&
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SingletonFor(frame->GetCallerState(&state)) != NULL;
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool SafeStackFrameIterator::IsValidExitFrame(Address fp) const {
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!IsValidStackAddress(fp)) return false;
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address sp = ExitFrame::ComputeStackPointer(fp);
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!IsValidStackAddress(sp)) return false;
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StackFrame::State state;
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExitFrame::FillState(fp, sp, &state);
342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  MSAN_MEMORY_IS_INITIALIZED(state.pc_address, sizeof(state.pc_address));
343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return *state.pc_address != nullptr;
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid SafeStackFrameIterator::Advance() {
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (true) {
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AdvanceOneFrame();
350109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (done()) break;
351109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    ExternalCallbackScope* last_callback_scope = NULL;
352109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    while (external_callback_scope_ != NULL &&
353109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           external_callback_scope_->scope_address() < frame_->fp()) {
354109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // As long as the setup of a frame is not atomic, we may happen to be
355109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // in an interval where an ExternalCallbackScope is already created,
356109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // but the frame is not yet entered. So we are actually observing
357109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // the previous frame.
358109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Skip all the ExternalCallbackScope's that are below the current fp.
359109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      last_callback_scope = external_callback_scope_;
360109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      external_callback_scope_ = external_callback_scope_->previous();
361109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
362109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (frame_->is_java_script()) break;
363f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (frame_->is_exit() || frame_->is_builtin_exit()) {
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Some of the EXIT frames may have ExternalCallbackScope allocated on
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // top of them. In that case the scope corresponds to the first EXIT
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // frame beneath it. There may be other EXIT frames on top of the
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // ExternalCallbackScope, just skip them as we cannot collect any useful
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // information about them.
369109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (last_callback_scope) {
370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame_->state_.pc_address =
371109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            last_callback_scope->callback_entrypoint_address();
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
373109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -------------------------------------------------------------------------
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3828b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochCode* StackFrame::GetSafepointData(Isolate* isolate,
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Address inner_pointer,
384b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                                   SafepointEntry* safepoint_entry,
385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                   unsigned* stack_slots) {
3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry =
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer);
388b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  if (!entry->safepoint_entry.is_valid()) {
3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer);
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(entry->safepoint_entry.is_valid());
391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(entry->safepoint_entry.Equals(
3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        entry->code->GetSafepointEntry(inner_pointer)));
394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Fill in the results and return the code.
397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Code* code = entry->code;
398b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  *safepoint_entry = entry->safepoint_entry;
399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  *stack_slots = code->stack_slots();
400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return code;
401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool GcSafeCodeContains(HeapObject* object, Address addr);
4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid StackFrame::IteratePc(ObjectVisitor* v, Address* pc_address,
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           Address* constant_pool_address, Code* holder) {
41180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Address pc = *pc_address;
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(GcSafeCodeContains(holder, pc));
41380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start());
41480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Object* code = holder;
41580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  v->VisitPointer(&code);
41680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  if (code != holder) {
41780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    holder = reinterpret_cast<Code*>(code);
41880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    pc = holder->instruction_start() + pc_offset;
41980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    *pc_address = pc;
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (FLAG_enable_embedded_constant_pool && constant_pool_address) {
421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *constant_pool_address = holder->constant_pool();
422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid StackFrame::SetReturnAddressLocationResolver(
4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ReturnAddressLocationResolver resolver) {
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(return_address_location_resolver_ == NULL);
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return_address_location_resolver_ = resolver;
4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochStackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         State* state) {
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(state->fp != NULL);
436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  MSAN_MEMORY_IS_INITIALIZED(
4383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      state->fp + CommonFrameConstants::kContextOrFrameTypeOffset,
4393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      kPointerSize);
44062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  intptr_t marker = Memory::intptr_at(
4413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      state->fp + CommonFrameConstants::kContextOrFrameTypeOffset);
442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!iterator->can_access_heap_objects_) {
443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // TODO(titzer): "can_access_heap_objects" is kind of bogus. It really
444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // means that we are being called from the profiler, which can interrupt
445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // the VM with a signal at any arbitrary instruction, with essentially
446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // anything on the stack. So basically none of these checks are 100%
447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // reliable.
448109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    MSAN_MEMORY_IS_INITIALIZED(
4493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        state->fp + StandardFrameConstants::kFunctionOffset, kPointerSize);
4503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Object* maybe_function =
4513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Memory::Object_at(state->fp + StandardFrameConstants::kFunctionOffset);
45262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!StackFrame::IsTypeMarker(marker)) {
4533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (maybe_function->IsSmi()) {
4543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return NONE;
455c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      } else if (IsInterpreterFramePc(iterator->isolate(),
456c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                      *(state->pc_address))) {
4573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return INTERPRETED;
4583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {
4593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return JAVA_SCRIPT;
4603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
4633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Look up the code object to figure out the type of the stack frame.
4643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Code* code_obj =
4653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        GetContainingCode(iterator->isolate(), *(state->pc_address));
4663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (code_obj != nullptr) {
4673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      switch (code_obj->kind()) {
4683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        case Code::BUILTIN:
46962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          if (StackFrame::IsTypeMarker(marker)) break;
47013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          if (code_obj->is_interpreter_trampoline_builtin()) {
47113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            return INTERPRETED;
47213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          }
47313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          if (code_obj->is_turbofanned()) {
47413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            // TODO(bmeurer): We treat frames for BUILTIN Code objects as
47513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            // OptimizedFrame for now (all the builtins with JavaScript
47613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            // linkage are actually generated with TurboFan currently, so
47713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            // this is sound).
47813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            return OPTIMIZED;
47913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          }
48013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          return BUILTIN;
4813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        case Code::FUNCTION:
4823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          return JAVA_SCRIPT;
4833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        case Code::OPTIMIZED_FUNCTION:
4843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          return OPTIMIZED;
4853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        case Code::WASM_FUNCTION:
48662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          return WASM_COMPILED;
4873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        case Code::WASM_TO_JS_FUNCTION:
4883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          return WASM_TO_JS;
4893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        case Code::JS_TO_WASM_FUNCTION:
4903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          return JS_TO_WASM;
49162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        case Code::WASM_INTERPRETER_ENTRY:
49262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          return WASM_INTERPRETER_ENTRY;
4933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        default:
4943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          // All other types should have an explicit marker
4953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          break;
4963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
4983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      return NONE;
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
50262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(StackFrame::IsTypeMarker(marker));
50362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StackFrame::Type candidate = StackFrame::MarkerToType(marker);
5043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  switch (candidate) {
5053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case ENTRY:
5063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case ENTRY_CONSTRUCT:
5073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case EXIT:
508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case BUILTIN_EXIT:
5093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case STUB:
5103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case STUB_FAILURE_TRAMPOLINE:
5113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case INTERNAL:
5123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case CONSTRUCT:
5133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case ARGUMENTS_ADAPTOR:
5143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case WASM_TO_JS:
51562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case WASM_COMPILED:
516bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return candidate;
517bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case JS_TO_WASM:
5183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case JAVA_SCRIPT:
5193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case OPTIMIZED:
5203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case INTERPRETED:
5213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    default:
5223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // Unoptimized and optimized JavaScript frames, including
5233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // interpreted frames, should never have a StackFrame::Type
5243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // marker. If we find one, we're likely being called from the
5253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // profiler in a bogus stack frame.
5263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      return NONE;
527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool StackFrame::can_access_heap_objects() const {
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return iterator_->can_access_heap_objects_;
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStackFrame::Type StackFrame::GetCallerState(State* state) const {
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ComputeCallerState(state);
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ComputeType(iterator_, state);
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress StackFrame::UnpaddedFP() const {
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return fp();
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
549756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickCode* EntryFrame::unchecked_code() const {
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return isolate()->heap()->js_entry_code();
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid EntryFrame::ComputeCallerState(State* state) const {
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  GetCallerState(state);
556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5596ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid EntryFrame::SetCallerFp(Address caller_fp) {
5606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const int offset = EntryFrameConstants::kCallerFPOffset;
5616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Memory::Address_at(this->fp() + offset) = caller_fp;
5626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
5636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStackFrame::Type EntryFrame::GetCallerState(State* state) const {
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const int offset = EntryFrameConstants::kCallerFPOffset;
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Address fp = Memory::Address_at(this->fp() + offset);
568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return ExitFrame::GetStateForFramePointer(fp, state);
569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
572756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickCode* EntryConstructFrame::unchecked_code() const {
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return isolate()->heap()->js_construct_entry_code();
574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
577d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockObject*& ExitFrame::code_slot() const {
578d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  const int offset = ExitFrameConstants::kCodeOffset;
579d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return Memory::Object_at(fp() + offset);
580d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
581d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
582756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickCode* ExitFrame::unchecked_code() const {
583756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return reinterpret_cast<Code*>(code_slot());
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ExitFrame::ComputeCallerState(State* state) const {
5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set up the caller state.
589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  state->sp = caller_sp();
590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);
5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  state->pc_address = ResolveReturnAddressLocation(
5923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
59362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  state->callee_pc_address = nullptr;
594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_enable_embedded_constant_pool) {
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    state->constant_pool_address = reinterpret_cast<Address*>(
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        fp() + ExitFrameConstants::kConstantPoolOffset);
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6016ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid ExitFrame::SetCallerFp(Address caller_fp) {
6026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp;
6036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
6046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
60680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid ExitFrame::Iterate(ObjectVisitor* v) const {
60780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // The arguments are traversed as part of the expression stack of
60880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // the calling frame.
609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
61080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  v->VisitPointer(&code_slot());
61180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
61280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
61380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress ExitFrame::GetCallerStackPointer() const {
6153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return fp() + ExitFrameConstants::kCallerSPOffset;
616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6190d5e116f6aee03185f237311a943491bb079a768Kristian MonsenStackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
6200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  if (fp == 0) return NONE;
6210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Address sp = ComputeStackPointer(fp);
6220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  FillState(fp, sp, state);
62362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_NOT_NULL(*state->pc_address);
624f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return ComputeFrameType(fp);
626f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
627f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
628f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochStackFrame::Type ExitFrame::ComputeFrameType(Address fp) {
629f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Distinguish between between regular and builtin exit frames.
630f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Default to EXIT in all hairy cases (e.g., when called from profiler).
631f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const int offset = ExitFrameConstants::kFrameTypeOffset;
632f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Object* marker = Memory::Object_at(fp + offset);
633f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
634f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!marker->IsSmi()) {
635f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return EXIT;
636f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
637f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
63862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  intptr_t marker_int = bit_cast<intptr_t>(marker);
63962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
64062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StackFrame::Type frame_type = static_cast<StackFrame::Type>(marker_int >> 1);
641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (frame_type == EXIT || frame_type == BUILTIN_EXIT) {
642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return frame_type;
643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
6450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  return EXIT;
6460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
6470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress ExitFrame::ComputeStackPointer(Address fp) {
64913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  MSAN_MEMORY_IS_INITIALIZED(fp + ExitFrameConstants::kSPOffset, kPointerSize);
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Memory::Address_at(fp + ExitFrameConstants::kSPOffset);
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6530d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid ExitFrame::FillState(Address fp, Address sp, State* state) {
6540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  state->sp = sp;
6550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  state->fp = fp;
6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  state->pc_address = ResolveReturnAddressLocation(
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize));
65862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  state->callee_pc_address = nullptr;
659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The constant pool recorded in the exit frame is not associated
660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // with the pc in this state (the return address into a C entry
661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // stub).  ComputeCallerState will retrieve the constant pool
662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // together with the associated caller pc.
66362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  state->constant_pool_address = nullptr;
6640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
6650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
666f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochJSFunction* BuiltinExitFrame::function() const {
667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return JSFunction::cast(target_slot_object());
668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochObject* BuiltinExitFrame::receiver() const { return receiver_slot_object(); }
671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool BuiltinExitFrame::IsConstructor() const {
673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return !new_target_slot_object()->IsUndefined(isolate());
674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochObject* BuiltinExitFrame::GetParameter(int i) const {
677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(i >= 0 && i < ComputeParametersCount());
678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int offset = BuiltinExitFrameConstants::kArgcOffset + (i + 1) * kPointerSize;
679f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return Memory::Object_at(fp() + offset);
680f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochint BuiltinExitFrame::ComputeParametersCount() const {
683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Object* argc_slot = argc_slot_object();
684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(argc_slot->IsSmi());
685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Argc also counts the receiver, target, new target, and argc itself as args,
686f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // therefore the real argument count is argc - 4.
687f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int argc = Smi::cast(argc_slot)->value() - 4;
688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(argc >= 0);
689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return argc;
690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid BuiltinExitFrame::Print(StringStream* accumulator, PrintMode mode,
693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                             int index) const {
694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DisallowHeapAllocation no_gc;
695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Object* receiver = this->receiver();
696f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  JSFunction* function = this->function();
697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
698f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  accumulator->PrintSecurityTokenIfChanged(function);
699f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  PrintIndex(accumulator, mode, index);
700f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  accumulator->Add("builtin exit frame: ");
701f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Code* code = NULL;
702f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (IsConstructor()) accumulator->Add("new ");
703f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  accumulator->PrintFunction(function, receiver, &code);
704f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
705f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  accumulator->Add("(this=%o", receiver);
706f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
707f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Print the parameters.
708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int parameters_count = ComputeParametersCount();
709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  for (int i = 0; i < parameters_count; i++) {
710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    accumulator->Add(",%o", GetParameter(i));
711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  accumulator->Add(")\n\n");
714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
715f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress StandardFrame::GetExpressionAddress(int n) const {
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const int offset = StandardFrameConstants::kExpressionsOffset;
718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return fp() + offset - n * kPointerSize;
719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
721109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochAddress InterpretedFrame::GetExpressionAddress(int n) const {
722109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const int offset = InterpreterFrameConstants::kExpressionsOffset;
723109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return fp() + offset - n * kPointerSize;
724f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch}
725f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochScript* StandardFrame::script() const {
727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // This should only be called on frames which override this method.
728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(false);
729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return nullptr;
730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochObject* StandardFrame::receiver() const {
733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return isolate()->heap()->undefined_value();
734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochObject* StandardFrame::context() const {
737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return isolate()->heap()->undefined_value();
738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
740c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochint StandardFrame::position() const {
741c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  AbstractCode* code = AbstractCode::cast(LookupCode());
742c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int code_offset = static_cast<int>(pc() - code->instruction_start());
743c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return code->SourcePosition(code_offset);
744c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
745c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint StandardFrame::ComputeExpressionsCount() const {
747109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Address base = GetExpressionAddress(0);
748109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Address limit = sp() - kPointerSize;
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(base >= limit);  // stack grows downwards
750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Include register-allocated locals in number of expressions.
751d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return static_cast<int>((base - limit) / kPointerSize);
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
754f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochObject* StandardFrame::GetParameter(int index) const {
755f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // StandardFrame does not define any parameters.
756f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  UNREACHABLE();
757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return nullptr;
758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
760f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochint StandardFrame::ComputeParametersCount() const { return 0; }
761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StandardFrame::ComputeCallerState(State* state) const {
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  state->sp = caller_sp();
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  state->fp = caller_fp();
7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  state->pc_address = ResolveReturnAddressLocation(
7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      reinterpret_cast<Address*>(ComputePCAddress(fp())));
76762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  state->callee_pc_address = pc_address();
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  state->constant_pool_address =
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp()));
770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7736ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid StandardFrame::SetCallerFp(Address caller_fp) {
7746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) =
7756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      caller_fp;
7766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
7776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
778f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool StandardFrame::IsConstructor() const { return false; }
7796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
78062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid StandardFrame::Summarize(List<FrameSummary>* functions,
78162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              FrameSummary::Mode mode) const {
78262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // This should only be called on frames which override this method.
78362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  UNREACHABLE();
78462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
78562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
787b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Make sure that we're not doing "safe" stack frame iteration. We cannot
788b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // possibly find pointers in optimized frames in that state.
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(can_access_heap_objects());
790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
791b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Compute the safepoint information.
792b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned stack_slots = 0;
793b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  SafepointEntry safepoint_entry;
794b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Code* code = StackFrame::GetSafepointData(
7958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      isolate(), pc(), &safepoint_entry, &stack_slots);
7963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  unsigned slot_space = stack_slots * kPointerSize;
797b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Determine the fixed header and spill slot area size.
7993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int frame_header_size = StandardFrameConstants::kFixedFrameSizeFromFp;
80062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  intptr_t marker =
80162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Memory::intptr_at(fp() + CommonFrameConstants::kContextOrFrameTypeOffset);
80262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (StackFrame::IsTypeMarker(marker)) {
80362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StackFrame::Type candidate = StackFrame::MarkerToType(marker);
8043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    switch (candidate) {
8053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case ENTRY:
8063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case ENTRY_CONSTRUCT:
8073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case EXIT:
808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case BUILTIN_EXIT:
8093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case STUB_FAILURE_TRAMPOLINE:
8103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case ARGUMENTS_ADAPTOR:
8113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case STUB:
8123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case INTERNAL:
8133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case CONSTRUCT:
8143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case JS_TO_WASM:
8153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case WASM_TO_JS:
81662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case WASM_COMPILED:
81762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case WASM_INTERPRETER_ENTRY:
8183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        frame_header_size = TypedFrameConstants::kFixedFrameSizeFromFp;
8193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        break;
8203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case JAVA_SCRIPT:
8213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case OPTIMIZED:
8223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case INTERPRETED:
82313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case BUILTIN:
8243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // These frame types have a context, but they are actually stored
8253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // in the place on the stack that one finds the frame type.
8263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        UNREACHABLE();
8273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        break;
8283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case NONE:
8293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case NUMBER_OF_TYPES:
8303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case MANUAL:
8313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        UNREACHABLE();
8323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        break;
8333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
8343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
8353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  slot_space -=
8363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      (frame_header_size + StandardFrameConstants::kFixedFrameSizeAboveFp);
8373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
8383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Object** frame_header_base = &Memory::Object_at(fp() - frame_header_size);
839bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Object** frame_header_limit =
840bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      &Memory::Object_at(fp() - StandardFrameConstants::kCPSlotSize);
841b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Object** parameters_base = &Memory::Object_at(sp());
8423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Object** parameters_limit = frame_header_base - slot_space / kPointerSize;
843b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
844b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // Visit the parameters that may be on top of the saved registers.
845b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  if (safepoint_entry.argument_count() > 0) {
846b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    v->VisitPointers(parameters_base,
847b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                     parameters_base + safepoint_entry.argument_count());
848b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    parameters_base += safepoint_entry.argument_count();
849b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
850b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
851b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // Skip saved double registers.
852b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  if (safepoint_entry.has_doubles()) {
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Number of doubles not known at snapshot time.
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!isolate()->serializer_enabled());
85513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    parameters_base += RegisterConfiguration::Crankshaft()
85613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                           ->num_allocatable_double_registers() *
85713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                       kDoubleSize / kPointerSize;
858b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  }
859b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Visit the registers that contain pointers if any.
861b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  if (safepoint_entry.HasRegisters()) {
862b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    for (int i = kNumSafepointRegisters - 1; i >=0; i--) {
863b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      if (safepoint_entry.HasRegisterAt(i)) {
864b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(i);
865b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        v->VisitPointer(parameters_base + reg_stack_index);
866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
867b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
868b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Skip the words containing the register values.
869b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    parameters_base += kNumSafepointRegisters;
870b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
871b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
872b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // We're done dealing with the register bits.
873b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  uint8_t* safepoint_bits = safepoint_entry.bits();
874b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  safepoint_bits += kNumSafepointRegisters >> kBitsPerByteLog2;
875b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
876b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Visit the rest of the parameters.
8773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (!is_js_to_wasm() && !is_wasm()) {
8783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Non-WASM frames have tagged values as parameters.
8793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    v->VisitPointers(parameters_base, parameters_limit);
8803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
881b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
882b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Visit pointer spill slots and locals.
883b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (unsigned index = 0; index < stack_slots; index++) {
884b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int byte_index = index >> kBitsPerByteLog2;
885b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int bit_index = index & (kBitsPerByte - 1);
886b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) {
887b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      v->VisitPointer(parameters_limit + index);
888b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
889b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
890b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit the return address in the callee and incoming arguments.
892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IteratePc(v, pc_address(), constant_pool_address(), code);
893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (!is_wasm() && !is_wasm_to_js()) {
8953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Visit the context in stub frame and JavaScript frame.
8963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Visit the function in JavaScript frame.
8973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    v->VisitPointers(frame_header_base, frame_header_limit);
8983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
900b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid StubFrame::Iterate(ObjectVisitor* v) const {
903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IterateCompiledFrame(v);
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCode* StubFrame::unchecked_code() const {
90862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return isolate()->FindCodeObject(pc());
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress StubFrame::GetCallerStackPointer() const {
9133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return fp() + ExitFrameConstants::kCallerSPOffset;
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint StubFrame::GetNumberOfIncomingArguments() const {
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return 0;
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid OptimizedFrame::Iterate(ObjectVisitor* v) const {
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IterateCompiledFrame(v);
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid JavaScriptFrame::SetParameterValue(int index, Object* value) const {
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Memory::Object_at(GetParameterSlot(index)) = value;
929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool JavaScriptFrame::IsConstructor() const {
933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Address fp = caller_fp();
934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (has_adapted_arguments()) {
935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Skip the arguments adaptor frame and look at the real caller.
936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset);
937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return IsConstructFrame(fp);
939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool JavaScriptFrame::HasInlinedFrames() const {
94362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  List<SharedFunctionInfo*> functions(1);
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GetFunctions(&functions);
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return functions.length() > 1;
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
9493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochint JavaScriptFrame::GetArgumentsLength() const {
9503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // If there is an arguments adaptor frame get the arguments length from it.
9513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (has_adapted_arguments()) {
952109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return ArgumentsAdaptorFrame::GetLength(caller_fp());
9533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else {
9543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return GetNumberOfIncomingArguments();
9553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
9563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
9573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
9583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
959756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickCode* JavaScriptFrame::unchecked_code() const {
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return function()->code();
961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochint JavaScriptFrame::GetNumberOfIncomingArguments() const {
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(can_access_heap_objects() &&
9668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch         isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
9678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return function()->shared()->internal_formal_parameter_count();
9698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
9708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
9718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
97280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenAddress JavaScriptFrame::GetCallerStackPointer() const {
9738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  return fp() + StandardFrameConstants::kCallerSPOffset;
97480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
97580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
97662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid JavaScriptFrame::GetFunctions(List<SharedFunctionInfo*>* functions) const {
97762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(functions->length() == 0);
97862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  functions->Add(function()->shared());
97962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
98080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
98162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid JavaScriptFrame::GetFunctions(
98262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    List<Handle<SharedFunctionInfo>>* functions) const {
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(functions->length() == 0);
98462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  List<SharedFunctionInfo*> raw_functions;
98562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GetFunctions(&raw_functions);
98662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  for (const auto& raw_function : raw_functions) {
98762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    functions->Add(Handle<SharedFunctionInfo>(raw_function));
98862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
989b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
990b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
991bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid JavaScriptFrame::Summarize(List<FrameSummary>* functions,
992bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                FrameSummary::Mode mode) const {
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(functions->length() == 0);
994109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Code* code = LookupCode();
995109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int offset = static_cast<int>(pc() - code->instruction_start());
996109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  AbstractCode* abstract_code = AbstractCode::cast(code);
99762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FrameSummary::JavaScriptFrameSummary summary(isolate(), receiver(),
99862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                               function(), abstract_code,
99962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                               offset, IsConstructor(), mode);
1000b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  functions->Add(summary);
1001b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1002b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1003bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochJSFunction* JavaScriptFrame::function() const {
1004bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return JSFunction::cast(function_slot_object());
1005bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1006bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1007bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochObject* JavaScriptFrame::receiver() const { return GetParameter(-1); }
1008bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1009f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochObject* JavaScriptFrame::context() const {
1010f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const int offset = StandardFrameConstants::kContextOffset;
1011f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Object* maybe_result = Memory::Object_at(fp() + offset);
1012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(!maybe_result->IsSmi());
1013f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return maybe_result;
1014f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1015f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
101662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochScript* JavaScriptFrame::script() const {
101762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return Script::cast(function()->shared()->script());
101862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
101962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint JavaScriptFrame::LookupExceptionHandlerInTable(
1021109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    int* stack_depth, HandlerTable::CatchPrediction* prediction) {
102262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_EQ(0, LookupCode()->handler_table()->length());
102362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(!LookupCode()->is_optimized_code());
102462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return -1;
1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1027c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function,
1028c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                             AbstractCode* code,
1029c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                             int code_offset, FILE* file,
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             bool print_line_number) {
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF(file, "%s", function->IsOptimized() ? "*" : "~");
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function->PrintName(file);
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF(file, "+%d", code_offset);
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (print_line_number) {
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SharedFunctionInfo* shared = function->shared();
1036c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    int source_pos = code->SourcePosition(code_offset);
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* maybe_script = shared->script();
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (maybe_script->IsScript()) {
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Script* script = Script::cast(maybe_script);
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int line = script->GetLineNumber(source_pos) + 1;
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Object* script_name_raw = script->name();
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (script_name_raw->IsString()) {
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        String* script_name = String::cast(script->name());
1044f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        std::unique_ptr<char[]> c_script_name =
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(file, " at %s:%d", c_script_name.get(), line);
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF(file, " at <unknown>:%d", line);
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrintF(file, " at <unknown>:<unknown>");
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file, bool print_args,
10573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               bool print_line_number) {
10583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // constructor calls
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JavaScriptFrameIterator it(isolate);
10613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (!it.done()) {
10623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (it.frame()->is_java_script()) {
10633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      JavaScriptFrame* frame = it.frame();
10643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (frame->IsConstructor()) PrintF(file, "new ");
1065c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      JSFunction* function = frame->function();
1066c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int code_offset = 0;
1067c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (frame->is_interpreted()) {
1068c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame);
1069c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        code_offset = iframe->GetBytecodeOffset();
1070c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      } else {
1071c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        Code* code = frame->unchecked_code();
1072c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        code_offset = static_cast<int>(frame->pc() - code->instruction_start());
1073c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
1074c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      PrintFunctionAndOffset(function, function->abstract_code(), code_offset,
1075c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                             file, print_line_number);
10763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (print_args) {
10773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // function arguments
10783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // (we are intentionally only printing the actually
10793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // supplied parameters, not all parameters required)
10803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        PrintF(file, "(this=");
10813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        frame->receiver()->ShortPrint(file);
10823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        const int length = frame->ComputeParametersCount();
10833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        for (int i = 0; i < length; i++) {
10843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          PrintF(file, ", ");
10853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          frame->GetParameter(i)->ShortPrint(file);
10863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
10873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        PrintF(file, ")");
10883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
10893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      break;
10903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
10913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    it.Advance();
10923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
10933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
10943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
109562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid JavaScriptFrame::CollectFunctionAndOffsetForICStats(JSFunction* function,
109662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                         AbstractCode* code,
109762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                         int code_offset) {
109862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  auto ic_stats = ICStats::instance();
109962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ICInfo& ic_info = ic_stats->Current();
110062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  SharedFunctionInfo* shared = function->shared();
110162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
110262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ic_info.function_name = ic_stats->GetOrCacheFunctionName(function);
110362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ic_info.script_offset = code_offset;
11043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
110562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int source_pos = code->SourcePosition(code_offset);
110662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Object* maybe_script = shared->script();
110762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (maybe_script->IsScript()) {
110862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Script* script = Script::cast(maybe_script);
110962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ic_info.line_num = script->GetLineNumber(source_pos) + 1;
111062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ic_info.script_name = ic_stats->GetOrCacheScriptName(script);
111162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
111262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
111362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
111462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid JavaScriptFrame::CollectTopFrameForICStats(Isolate* isolate) {
111562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // constructor calls
111662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DisallowHeapAllocation no_allocation;
111762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  JavaScriptFrameIterator it(isolate);
111862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ICInfo& ic_info = ICStats::instance()->Current();
111962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  while (!it.done()) {
112062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (it.frame()->is_java_script()) {
112162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      JavaScriptFrame* frame = it.frame();
112262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (frame->IsConstructor()) ic_info.is_constructor = true;
112362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      JSFunction* function = frame->function();
112462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      int code_offset = 0;
112562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (frame->is_interpreted()) {
112662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame);
112762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        code_offset = iframe->GetBytecodeOffset();
112862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else {
112962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Code* code = frame->unchecked_code();
113062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        code_offset = static_cast<int>(frame->pc() - code->instruction_start());
113162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
113262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      CollectFunctionAndOffsetForICStats(function, function->abstract_code(),
113362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         code_offset);
113462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return;
113562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
113662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    it.Advance();
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochObject* JavaScriptFrame::GetParameter(int index) const {
1141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return Memory::Object_at(GetParameterSlot(index));
1142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochint JavaScriptFrame::ComputeParametersCount() const {
1145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return GetNumberOfIncomingArguments();
1146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
11483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochnamespace {
11493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
11503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochbool CannotDeoptFromAsmCode(Code* code, JSFunction* function) {
115162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return code->is_turbofanned() && function->shared()->asm_function();
11523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
11533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
11543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}  // namespace
11553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
115662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFrameSummary::JavaScriptFrameSummary::JavaScriptFrameSummary(
115762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Isolate* isolate, Object* receiver, JSFunction* function,
115862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    AbstractCode* abstract_code, int code_offset, bool is_constructor,
115962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Mode mode)
116062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    : FrameSummaryBase(isolate, JAVA_SCRIPT),
116162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      receiver_(receiver, isolate),
116262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      function_(function, isolate),
116362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      abstract_code_(abstract_code, isolate),
1164109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      code_offset_(code_offset),
11653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      is_constructor_(is_constructor) {
11663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(abstract_code->IsBytecodeArray() ||
11673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch         Code::cast(abstract_code)->kind() != Code::OPTIMIZED_FUNCTION ||
1168bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         CannotDeoptFromAsmCode(Code::cast(abstract_code), function) ||
1169bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         mode == kApproximateSummary);
1170bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1171bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
117262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool FrameSummary::JavaScriptFrameSummary::is_subject_to_debugging() const {
117362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return function()->shared()->IsSubjectToDebugging();
117462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
117562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
117662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochint FrameSummary::JavaScriptFrameSummary::SourcePosition() const {
117762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return abstract_code()->SourcePosition(code_offset());
117862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
117962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
118062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochint FrameSummary::JavaScriptFrameSummary::SourceStatementPosition() const {
118162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return abstract_code()->SourceStatementPosition(code_offset());
118262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
118362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
118462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHandle<Object> FrameSummary::JavaScriptFrameSummary::script() const {
118562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return handle(function_->shared()->script(), isolate());
118662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
118762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
118862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHandle<String> FrameSummary::JavaScriptFrameSummary::FunctionName() const {
118962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return JSFunction::GetDebugName(function_);
119062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
119162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
119262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHandle<Context> FrameSummary::JavaScriptFrameSummary::native_context() const {
119362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return handle(function_->context()->native_context(), isolate());
119462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
119562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
119662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFrameSummary::WasmFrameSummary::WasmFrameSummary(
119762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Isolate* isolate, FrameSummary::Kind kind,
119862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Handle<WasmInstanceObject> instance, bool at_to_number_conversion)
119962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    : FrameSummaryBase(isolate, kind),
120062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      wasm_instance_(instance),
120162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      at_to_number_conversion_(at_to_number_conversion) {}
120262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
120362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHandle<Object> FrameSummary::WasmFrameSummary::receiver() const {
120462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return wasm_instance_->GetIsolate()->global_proxy();
120562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
120662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
120762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define WASM_SUMMARY_DISPATCH(type, name)                                      \
120862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  type FrameSummary::WasmFrameSummary::name() const {                          \
120962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(kind() == Kind::WASM_COMPILED || kind() == Kind::WASM_INTERPRETED); \
121062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return kind() == Kind::WASM_COMPILED                                       \
121162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch               ? static_cast<const WasmCompiledFrameSummary*>(this)->name()    \
121262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch               : static_cast<const WasmInterpretedFrameSummary*>(this)         \
121362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                     ->name();                                                 \
121462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
121562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
121662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochWASM_SUMMARY_DISPATCH(uint32_t, function_index)
121762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochWASM_SUMMARY_DISPATCH(int, byte_offset)
121862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
121962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef WASM_SUMMARY_DISPATCH
122062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
122162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochint FrameSummary::WasmFrameSummary::SourcePosition() const {
122262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int offset = byte_offset();
122362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<WasmCompiledModule> compiled_module(wasm_instance()->compiled_module(),
122462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                             isolate());
122562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (compiled_module->is_asm_js()) {
122662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    offset = WasmCompiledModule::GetAsmJsSourcePosition(
122762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        compiled_module, function_index(), offset, at_to_number_conversion());
122862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
122962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    offset += compiled_module->GetFunctionOffset(function_index());
123062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
123162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return offset;
123262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
123362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
123462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHandle<Script> FrameSummary::WasmFrameSummary::script() const {
123562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return handle(wasm_instance()->compiled_module()->script());
123662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
123762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
123862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHandle<String> FrameSummary::WasmFrameSummary::FunctionName() const {
123962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<WasmCompiledModule> compiled_module(
124062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      wasm_instance()->compiled_module());
124162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return WasmCompiledModule::GetFunctionName(compiled_module->GetIsolate(),
124262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                             compiled_module, function_index());
124362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
124462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
124562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHandle<Context> FrameSummary::WasmFrameSummary::native_context() const {
124662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return wasm_instance()->compiled_module()->native_context();
124762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
124862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
124962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFrameSummary::WasmCompiledFrameSummary::WasmCompiledFrameSummary(
125062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> code,
125162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int code_offset, bool at_to_number_conversion)
125262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    : WasmFrameSummary(isolate, WASM_COMPILED, instance,
125362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                       at_to_number_conversion),
125462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      code_(code),
125562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      code_offset_(code_offset) {}
125662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
125762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochuint32_t FrameSummary::WasmCompiledFrameSummary::function_index() const {
125862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FixedArray* deopt_data = code()->deoptimization_data();
125962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_EQ(2, deopt_data->length());
126062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(deopt_data->get(1)->IsSmi());
126162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int val = Smi::cast(deopt_data->get(1))->value();
126262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_LE(0, val);
126362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return static_cast<uint32_t>(val);
126462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
126562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
126662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochint FrameSummary::WasmCompiledFrameSummary::byte_offset() const {
126762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return AbstractCode::cast(*code())->SourcePosition(code_offset());
126862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
126962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
127062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFrameSummary::WasmInterpretedFrameSummary::WasmInterpretedFrameSummary(
127162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Isolate* isolate, Handle<WasmInstanceObject> instance,
127262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    uint32_t function_index, int byte_offset)
127362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    : WasmFrameSummary(isolate, WASM_INTERPRETED, instance, false),
127462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      function_index_(function_index),
127562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      byte_offset_(byte_offset) {}
127662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
127762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFrameSummary::~FrameSummary() {
127862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define FRAME_SUMMARY_DESTR(kind, type, field, desc) \
127962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  case kind:                                         \
128062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    field.~type();                                   \
128162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    break;
128262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  switch (base_.kind()) {
128362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_DESTR)
128462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    default:
128562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      UNREACHABLE();
128662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
128762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef FRAME_SUMMARY_DESTR
128862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
128962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
129062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFrameSummary FrameSummary::GetTop(const StandardFrame* frame) {
1291bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
1292bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  frame->Summarize(&frames);
129362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_LT(0, frames.length());
129462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return frames.last();
129562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
129662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
129762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFrameSummary FrameSummary::GetBottom(const StandardFrame* frame) {
129862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return Get(frame, 0);
129962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
130062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
130162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFrameSummary FrameSummary::GetSingle(const StandardFrame* frame) {
130262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  List<FrameSummary> frames(1);
130362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  frame->Summarize(&frames);
130462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_EQ(1, frames.length());
1305bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return frames.first();
13063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
130862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFrameSummary FrameSummary::Get(const StandardFrame* frame, int index) {
130962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_LE(0, index);
131062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
131162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  frame->Summarize(&frames);
131262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_GT(frames.length(), index);
131362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return frames[index];
131462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
131562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
131662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define FRAME_SUMMARY_DISPATCH(ret, name)        \
131762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ret FrameSummary::name() const {               \
131862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    switch (base_.kind()) {                      \
131962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case JAVA_SCRIPT:                          \
132062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        return java_script_summary_.name();      \
132162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case WASM_COMPILED:                        \
132262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        return wasm_compiled_summary_.name();    \
132362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case WASM_INTERPRETED:                     \
132462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        return wasm_interpreted_summary_.name(); \
132562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      default:                                   \
132662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        UNREACHABLE();                           \
132762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        return ret{};                            \
132862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }                                            \
1329109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
133062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
133162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFRAME_SUMMARY_DISPATCH(Handle<Object>, receiver)
133262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFRAME_SUMMARY_DISPATCH(int, code_offset)
133362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFRAME_SUMMARY_DISPATCH(bool, is_constructor)
133462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFRAME_SUMMARY_DISPATCH(bool, is_subject_to_debugging)
133562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFRAME_SUMMARY_DISPATCH(Handle<Object>, script)
133662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFRAME_SUMMARY_DISPATCH(int, SourcePosition)
133762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFRAME_SUMMARY_DISPATCH(int, SourceStatementPosition)
133862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFRAME_SUMMARY_DISPATCH(Handle<String>, FunctionName)
133962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochFRAME_SUMMARY_DISPATCH(Handle<Context>, native_context)
134062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
134162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef FRAME_SUMMARY_DISPATCH
1342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1343bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid OptimizedFrame::Summarize(List<FrameSummary>* frames,
1344bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                               FrameSummary::Mode mode) const {
1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(frames->length() == 0);
1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_optimized());
1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Delegate to JS frame in absence of turbofan deoptimization.
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(turbofan): Revisit once we support deoptimization across the board.
13503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Code* code = LookupCode();
13513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (code->kind() == Code::BUILTIN ||
13523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      CannotDeoptFromAsmCode(code, function())) {
1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return JavaScriptFrame::Summarize(frames);
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_gc;
13571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int deopt_index = Safepoint::kNoDeoptimizationIndex;
1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index);
1359bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (deopt_index == Safepoint::kNoDeoptimizationIndex) {
1360bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(data == nullptr);
1361bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (mode == FrameSummary::kApproximateSummary) {
1362bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return JavaScriptFrame::Summarize(frames, mode);
1363bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
1364bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    FATAL("Missing deoptimization information for OptimizedFrame::Summarize.");
1365bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedArray* const literal_array = data->LiteralArray();
1367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TranslationIterator it(data->TranslationByteArray(),
1369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         data->TranslationIndex(deopt_index)->value());
1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Translation::Opcode frame_opcode =
1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<Translation::Opcode>(it.Next());
1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(Translation::BEGIN, frame_opcode);
13733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  it.Next();  // Drop frame count.
13743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int jsframe_count = it.Next();
1375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // We create the summary in reverse order because the frames
1377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // in the deoptimization translation are ordered bottom-to-top.
13783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool is_constructor = IsConstructor();
1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (jsframe_count != 0) {
1380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    frame_opcode = static_cast<Translation::Opcode>(it.Next());
1381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (frame_opcode == Translation::JS_FRAME ||
1382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame_opcode == Translation::INTERPRETED_FRAME) {
1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      jsframe_count--;
13843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      BailoutId const bailout_id = BailoutId(it.Next());
1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SharedFunctionInfo* const shared_info =
1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SharedFunctionInfo::cast(literal_array->get(it.Next()));
1387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      it.Next();  // Skip height.
1388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The translation commands are ordered and the function is always
1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // at the first position, and the receiver is next.
1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Get the correct function in the optimized frame.
1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      JSFunction* function;
1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (opcode == Translation::LITERAL) {
1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        function = JSFunction::cast(literal_array->get(it.Next()));
1397f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch      } else {
1398109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        CHECK_EQ(opcode, Translation::STACK_SLOT);
1399109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        function = JSFunction::cast(StackSlotAt(it.Next()));
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_EQ(shared_info, function->shared());
1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // If we are at a call, the receiver is always in a stack slot.
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Otherwise we are not guaranteed to get the receiver value.
1405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      opcode = static_cast<Translation::Opcode>(it.Next());
1406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Get the correct receiver in the optimized frame.
1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Object* receiver;
1409257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (opcode == Translation::LITERAL) {
1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        receiver = literal_array->get(it.Next());
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (opcode == Translation::STACK_SLOT) {
1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        receiver = StackSlotAt(it.Next());
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // The receiver is not in a stack slot nor in a literal.  We give up.
1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        it.Skip(Translation::NumberOfOperandsFor(opcode));
1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // TODO(3029): Materializing a captured object (or duplicated
1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // object) is hard, we return undefined for now. This breaks the
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // produced stack trace, as constructor frames aren't marked as
1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // such anymore.
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        receiver = isolate()->heap()->undefined_value();
1421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
1422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1423109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      AbstractCode* abstract_code;
1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1425109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      unsigned code_offset;
1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (frame_opcode == Translation::JS_FRAME) {
1427109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        Code* code = shared_info->code();
1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DeoptimizationOutputData* const output_data =
1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            DeoptimizationOutputData::cast(code->deoptimization_data());
1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        unsigned const entry =
14313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            Deoptimizer::GetOutputInfo(output_data, bailout_id, shared_info);
1432109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        code_offset = FullCodeGenerator::PcField::decode(entry);
1433109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        abstract_code = AbstractCode::cast(code);
1434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_EQ(frame_opcode, Translation::INTERPRETED_FRAME);
1436c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        code_offset = bailout_id.ToInt();  // Points to current bytecode.
1437109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        abstract_code = AbstractCode::cast(shared_info->bytecode_array());
1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
143962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      FrameSummary::JavaScriptFrameSummary summary(isolate(), receiver,
144062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                   function, abstract_code,
144162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                   code_offset, is_constructor);
1442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      frames->Add(summary);
14433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      is_constructor = false;
1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (frame_opcode == Translation::CONSTRUCT_STUB_FRAME) {
14453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // The next encountered JS_FRAME will be marked as a constructor call.
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      it.Skip(Translation::NumberOfOperandsFor(frame_opcode));
1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!is_constructor);
14483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      is_constructor = true;
1449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    } else {
1450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Skip over operands to advance to the next opcode.
1451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      it.Skip(Translation::NumberOfOperandsFor(frame_opcode));
1452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
1453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!is_constructor);
1455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint OptimizedFrame::LookupExceptionHandlerInTable(
1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int* stack_slots, HandlerTable::CatchPrediction* prediction) {
1460f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // We cannot perform exception prediction on optimized code. Instead, we need
1461f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // to use FrameSummary to find the corresponding code offset in unoptimized
1462f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // code to perform prediction there.
1463f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK_NULL(prediction);
1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Code* code = LookupCode();
1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HandlerTable* table = HandlerTable::cast(code->handler_table());
1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pc_offset = static_cast<int>(pc() - code->entry());
1467109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (stack_slots) *stack_slots = code->stack_slots();
1468f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return table->LookupReturn(pc_offset);
1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizationInputData* OptimizedFrame::GetDeoptimizationData(
1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int* deopt_index) const {
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_optimized());
1475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSFunction* opt_function = function();
1477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Code* code = opt_function->code();
1478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // The code object may have been replaced by lazy deoptimization. Fall
1480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // back to a slow search in this case to find the original optimized
1481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // code object.
1482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (!code->contains(pc())) {
14833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    code = isolate()->inner_pointer_to_code_cache()->
14843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        GcSafeFindCodeForInnerPointer(pc());
1485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(code != NULL);
1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
1488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1489b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  SafepointEntry safepoint_entry = code->GetSafepointEntry(pc());
1490b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  *deopt_index = safepoint_entry.deoptimization_index();
1491bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (*deopt_index != Safepoint::kNoDeoptimizationIndex) {
1492bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return DeoptimizationInputData::cast(code->deoptimization_data());
1493bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1494bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return nullptr;
1495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1496b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1497c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochObject* OptimizedFrame::receiver() const {
1498c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Code* code = LookupCode();
1499c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (code->kind() == Code::BUILTIN) {
1500c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Address argc_ptr = fp() + OptimizedBuiltinFrameConstants::kArgCOffset;
1501c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    intptr_t argc = *reinterpret_cast<intptr_t*>(argc_ptr);
1502c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    intptr_t args_size =
1503c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        (StandardFrameConstants::kFixedSlotCountAboveFp + argc) * kPointerSize;
1504c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Address receiver_ptr = fp() + args_size;
1505c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return *reinterpret_cast<Object**>(receiver_ptr);
1506c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
1507c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return JavaScriptFrame::receiver();
1508c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
1509c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
1510b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
151162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid OptimizedFrame::GetFunctions(List<SharedFunctionInfo*>* functions) const {
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(functions->length() == 0);
1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_optimized());
1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Delegate to JS frame in absence of turbofan deoptimization.
1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(turbofan): Revisit once we support deoptimization across the board.
15173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Code* code = LookupCode();
15183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (code->kind() == Code::BUILTIN ||
15193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      CannotDeoptFromAsmCode(code, function())) {
1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return JavaScriptFrame::GetFunctions(functions);
1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_gc;
15241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int deopt_index = Safepoint::kNoDeoptimizationIndex;
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index);
1526bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK_NOT_NULL(data);
1527bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK_NE(Safepoint::kNoDeoptimizationIndex, deopt_index);
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedArray* const literal_array = data->LiteralArray();
1529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  TranslationIterator it(data->TranslationByteArray(),
1531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                         data->TranslationIndex(deopt_index)->value());
1532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(Translation::BEGIN, opcode);
1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  it.Next();  // Skip frame count.
15353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int jsframe_count = it.Next();
1536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // We insert the frames in reverse order because the frames
1538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // in the deoptimization translation are ordered bottom-to-top.
1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (jsframe_count != 0) {
1540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    opcode = static_cast<Translation::Opcode>(it.Next());
1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (opcode == Translation::JS_FRAME ||
1542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        opcode == Translation::INTERPRETED_FRAME) {
154362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      it.Next();  // Skip bailout id.
15443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      jsframe_count--;
1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
154662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // The second operand of the frame points to the function.
154762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Object* shared = literal_array->get(it.Next());
154862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      functions->Add(SharedFunctionInfo::cast(shared));
1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
155062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // Skip over remaining operands to advance to the next opcode.
155162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      it.Skip(Translation::NumberOfOperandsFor(opcode) - 2);
155262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    } else {
155362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // Skip over operands to advance to the next opcode.
155462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      it.Skip(Translation::NumberOfOperandsFor(opcode));
1555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
1556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint OptimizedFrame::StackSlotOffsetRelativeToFp(int slot_index) {
1561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return StandardFrameConstants::kCallerSPOffset -
1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         ((slot_index + 1) * kPointerSize);
1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochObject* OptimizedFrame::StackSlotAt(int index) const {
1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Memory::Object_at(fp() + StackSlotOffsetRelativeToFp(index));
1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1570c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochint InterpretedFrame::position() const {
1571c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  AbstractCode* code = AbstractCode::cast(GetBytecodeArray());
1572c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int code_offset = GetBytecodeOffset();
1573c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return code->SourcePosition(code_offset);
1574c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
1575c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochint InterpretedFrame::LookupExceptionHandlerInTable(
1577109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    int* context_register, HandlerTable::CatchPrediction* prediction) {
1578109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BytecodeArray* bytecode = function()->shared()->bytecode_array();
157962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  HandlerTable* table = HandlerTable::cast(bytecode->handler_table());
158062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return table->LookupRange(GetBytecodeOffset(), context_register, prediction);
1581109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1582109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1583109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochint InterpretedFrame::GetBytecodeOffset() const {
1584109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
1585109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK_EQ(
1586109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      InterpreterFrameConstants::kBytecodeOffsetFromFp,
1587109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1588109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int raw_offset = Smi::cast(GetExpression(index))->value();
1589109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
1590109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1591109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1592c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochint InterpretedFrame::GetBytecodeOffset(Address fp) {
1593c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const int offset = InterpreterFrameConstants::kExpressionsOffset;
1594c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
1595c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(
1596c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      InterpreterFrameConstants::kBytecodeOffsetFromFp,
1597c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1598c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Address expression_offset = fp + offset - index * kPointerSize;
1599c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int raw_offset = Smi::cast(Memory::Object_at(expression_offset))->value();
1600c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
1601c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
1602c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1603109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InterpretedFrame::PatchBytecodeOffset(int new_offset) {
1604109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
1605109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK_EQ(
1606109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      InterpreterFrameConstants::kBytecodeOffsetFromFp,
1607109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1608109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int raw_offset = new_offset + BytecodeArray::kHeaderSize - kHeapObjectTag;
1609109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  SetExpression(index, Smi::FromInt(raw_offset));
1610109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1611109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1612bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochBytecodeArray* InterpretedFrame::GetBytecodeArray() const {
1613109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
1614109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK_EQ(
1615109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      InterpreterFrameConstants::kBytecodeArrayFromFp,
1616109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1617bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return BytecodeArray::cast(GetExpression(index));
1618109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1619109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1620bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InterpretedFrame::PatchBytecodeArray(BytecodeArray* bytecode_array) {
1621109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
1622109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK_EQ(
1623109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      InterpreterFrameConstants::kBytecodeArrayFromFp,
1624109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1625109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  SetExpression(index, bytecode_array);
1626109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1627109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1628bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochObject* InterpretedFrame::ReadInterpreterRegister(int register_index) const {
1629109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
1630109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK_EQ(
1631bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      InterpreterFrameConstants::kRegisterFileFromFp,
1632109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1633109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return GetExpression(index + register_index);
1634109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1635109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1636bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InterpretedFrame::WriteInterpreterRegister(int register_index,
1637bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                                Object* value) {
1638bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
1639bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK_EQ(
1640bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      InterpreterFrameConstants::kRegisterFileFromFp,
1641bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1642bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return SetExpression(index + register_index, value);
1643bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1644bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1645bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InterpretedFrame::Summarize(List<FrameSummary>* functions,
1646bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 FrameSummary::Mode mode) const {
1647109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(functions->length() == 0);
1648109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  AbstractCode* abstract_code =
1649109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      AbstractCode::cast(function()->shared()->bytecode_array());
165062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FrameSummary::JavaScriptFrameSummary summary(
165162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      isolate(), receiver(), function(), abstract_code, GetBytecodeOffset(),
165262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      IsConstructor());
1653109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  functions->Add(summary);
1654109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
16563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const {
16573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Smi::cast(GetExpression(0))->value();
16583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
16593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1660109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochint ArgumentsAdaptorFrame::GetLength(Address fp) {
1661109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const int offset = ArgumentsAdaptorFrameConstants::kLengthOffset;
1662109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return Smi::cast(Memory::Object_at(fp + offset))->value();
166380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
166480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
1665756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickCode* ArgumentsAdaptorFrame::unchecked_code() const {
16668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  return isolate()->builtins()->builtin(
166744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Builtins::kArgumentsAdaptorTrampoline);
1668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
167013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochint BuiltinFrame::GetNumberOfIncomingArguments() const {
167113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return Smi::cast(GetExpression(0))->value();
167213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
167313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid BuiltinFrame::PrintFrameKind(StringStream* accumulator) const {
1675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  accumulator->Add("builtin frame: ");
1676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1678109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochAddress InternalFrame::GetCallerStackPointer() const {
1679109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Internal frames have no arguments. The stack pointer of the
1680109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // caller is at a fixed offset from the frame pointer.
1681109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return fp() + StandardFrameConstants::kCallerSPOffset;
1682109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1684756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickCode* InternalFrame::unchecked_code() const {
1685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const int offset = InternalFrameConstants::kCodeOffset;
1686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* code = Memory::Object_at(fp() + offset);
1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(code != NULL);
1688756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return reinterpret_cast<Code*>(code);
1689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackFrame::PrintIndex(StringStream* accumulator,
1693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            PrintMode mode,
1694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            int index) {
1695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index);
1696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
169862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid WasmCompiledFrame::Print(StringStream* accumulator, PrintMode mode,
169962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              int index) const {
170062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  PrintIndex(accumulator, mode, index);
170162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  accumulator->Add("WASM [");
170262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Script* script = this->script();
170362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  accumulator->PrintName(script->name());
170462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int pc = static_cast<int>(this->pc() - LookupCode()->instruction_start());
170562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Object* instance = this->wasm_instance();
170662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Vector<const uint8_t> raw_func_name =
170762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      WasmInstanceObject::cast(instance)->compiled_module()->GetRawFunctionName(
170862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          this->function_index());
170962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const int kMaxPrintedFunctionName = 64;
171062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  char func_name[kMaxPrintedFunctionName + 1];
171162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int func_name_len = std::min(kMaxPrintedFunctionName, raw_func_name.length());
171262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  memcpy(func_name, raw_func_name.start(), func_name_len);
171362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  func_name[func_name_len] = '\0';
171462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  accumulator->Add("], function #%u ('%s'), pc=%p, pos=%d\n",
171562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                   this->function_index(), func_name, pc, this->position());
171662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (mode != OVERVIEW) accumulator->Add("\n");
171762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
171862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
171962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochCode* WasmCompiledFrame::unchecked_code() const {
172062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return isolate()->FindCodeObject(pc());
172162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
172262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
172362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid WasmCompiledFrame::Iterate(ObjectVisitor* v) const {
172462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  IterateCompiledFrame(v);
17253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
17263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
172762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochAddress WasmCompiledFrame::GetCallerStackPointer() const {
172862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return fp() + ExitFrameConstants::kCallerSPOffset;
17293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
17303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
173162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochWasmInstanceObject* WasmCompiledFrame::wasm_instance() const {
173262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  WasmInstanceObject* obj = wasm::GetOwningWasmInstance(LookupCode());
173362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // This is a live stack frame; it must have a live instance.
173462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_NOT_NULL(obj);
173562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return obj;
173662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
17373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
173862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochuint32_t WasmCompiledFrame::function_index() const {
173962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return FrameSummary::GetSingle(this).AsWasmCompiled().function_index();
17403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
1741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
174262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochScript* WasmCompiledFrame::script() const {
174362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return wasm_instance()->compiled_module()->script();
1744bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1745bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
174662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochint WasmCompiledFrame::position() const {
174762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return FrameSummary::GetSingle(this).SourcePosition();
1748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1749f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
175062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid WasmCompiledFrame::Summarize(List<FrameSummary>* functions,
175162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  FrameSummary::Mode mode) const {
175262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_EQ(0, functions->length());
175362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<Code> code(LookupCode(), isolate());
175462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int offset = static_cast<int>(pc() - code->instruction_start());
175562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<WasmInstanceObject> instance(wasm_instance(), isolate());
175662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FrameSummary::WasmCompiledFrameSummary summary(
175762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      isolate(), instance, code, offset, at_to_number_conversion());
175862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  functions->Add(summary);
1759c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
1760c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
176162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool WasmCompiledFrame::at_to_number_conversion() const {
176262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Check whether our callee is a WASM_TO_JS frame, and this frame is at the
176362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // ToNumber conversion call.
176462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Address callee_pc = reinterpret_cast<Address>(this->callee_pc());
176562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Code* code = callee_pc ? isolate()->FindCodeObject(callee_pc) : nullptr;
176662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!code || code->kind() != Code::WASM_TO_JS_FUNCTION) return false;
176762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int offset = static_cast<int>(callee_pc - code->instruction_start());
176862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int pos = AbstractCode::cast(code)->SourcePosition(offset);
176962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(pos == 0 || pos == 1);
177062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // The imported call has position 0, ToNumber has position 1.
177162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return !!pos;
1772bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1773bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
177462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochint WasmCompiledFrame::LookupExceptionHandlerInTable(int* stack_slots) {
1775f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK_NOT_NULL(stack_slots);
1776f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Code* code = LookupCode();
1777f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  HandlerTable* table = HandlerTable::cast(code->handler_table());
1778f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pc_offset = static_cast<int>(pc() - code->entry());
1779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  *stack_slots = code->stack_slots();
1780f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return table->LookupReturn(pc_offset);
1781f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
1782f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
178362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid WasmInterpreterEntryFrame::Iterate(ObjectVisitor* v) const {
178462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  IterateCompiledFrame(v);
178562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
178662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
178762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid WasmInterpreterEntryFrame::Print(StringStream* accumulator, PrintMode mode,
178862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                      int index) const {
178962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  PrintIndex(accumulator, mode, index);
179062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  accumulator->Add("WASM INTERPRETER ENTRY [");
179162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Script* script = this->script();
179262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  accumulator->PrintName(script->name());
179362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  accumulator->Add("]");
179462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (mode != OVERVIEW) accumulator->Add("\n");
179562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
179662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
179762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid WasmInterpreterEntryFrame::Summarize(List<FrameSummary>* functions,
179862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                          FrameSummary::Mode mode) const {
179962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<WasmInstanceObject> instance(wasm_instance(), isolate());
180062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  std::vector<std::pair<uint32_t, int>> interpreted_stack =
180162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      instance->debug_info()->GetInterpretedStack(fp());
180262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
180362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  for (auto& e : interpreted_stack) {
180462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    FrameSummary::WasmInterpretedFrameSummary summary(isolate(), instance,
180562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                      e.first, e.second);
180662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    functions->Add(summary);
180762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
180862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
180962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
181062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochCode* WasmInterpreterEntryFrame::unchecked_code() const {
181162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return isolate()->FindCodeObject(pc());
181262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
181362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
181462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochWasmInstanceObject* WasmInterpreterEntryFrame::wasm_instance() const {
181562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  WasmInstanceObject* ret = wasm::GetOwningWasmInstance(LookupCode());
181662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // This is a live stack frame, there must be a live wasm instance available.
181762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_NOT_NULL(ret);
181862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return ret;
181962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
182062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
182162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochScript* WasmInterpreterEntryFrame::script() const {
182262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return wasm_instance()->compiled_module()->script();
182362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
182462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
182562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochint WasmInterpreterEntryFrame::position() const {
182662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return FrameSummary::GetBottom(this).AsWasmInterpreted().SourcePosition();
182762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
182862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
182962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochAddress WasmInterpreterEntryFrame::GetCallerStackPointer() const {
183062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return fp() + ExitFrameConstants::kCallerSPOffset;
183162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
183262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace {
1834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared,
1837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         Code* code) {
1838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_max_stack_trace_source_length != 0 && code != NULL) {
1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    std::ostringstream os;
1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << "--------- s o u r c e   c o d e ---------\n"
1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       << SourceCodeOf(shared, FLAG_max_stack_trace_source_length)
1842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       << "\n-----------------------------------------\n";
1843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    accumulator->Add(os.str().c_str());
1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace
1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid JavaScriptFrame::Print(StringStream* accumulator,
1852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            PrintMode mode,
1853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            int index) const {
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_gc;
1855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* receiver = this->receiver();
1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSFunction* function = this->function();
1857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  accumulator->PrintSecurityTokenIfChanged(function);
1859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndex(accumulator, mode, index);
1860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  PrintFrameKind(accumulator);
1861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code* code = NULL;
1862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IsConstructor()) accumulator->Add("new ");
1863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  accumulator->PrintFunction(function, receiver, &code);
18646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
18653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Get scope information for nicer output, if possible. If code is NULL, or
18663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // doesn't contain scope info, scope_info will return 0 for the number of
18673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // parameters, stack local variables, context local variables, stack slots,
18683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // or context slots.
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SharedFunctionInfo* shared = function->shared();
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ScopeInfo* scope_info = shared->scope_info();
1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* script_obj = shared->script();
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (script_obj->IsScript()) {
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Script* script = Script::cast(script_obj);
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    accumulator->Add(" [");
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    accumulator->PrintName(script->name());
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Address pc = this->pc();
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (code != NULL && code->kind() == Code::FUNCTION &&
1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        pc >= code->instruction_start() && pc < code->instruction_end()) {
1880109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      int offset = static_cast<int>(pc - code->instruction_start());
1881f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      int source_pos = AbstractCode::cast(code)->SourcePosition(offset);
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int line = script->GetLineNumber(source_pos) + 1;
1883bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      accumulator->Add(":%d] [pc=%p]", line, pc);
1884bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    } else if (is_interpreted()) {
1885bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      const InterpretedFrame* iframe =
1886bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          reinterpret_cast<const InterpretedFrame*>(this);
1887bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      BytecodeArray* bytecodes = iframe->GetBytecodeArray();
1888bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      int offset = iframe->GetBytecodeOffset();
1889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      int source_pos = AbstractCode::cast(bytecodes)->SourcePosition(offset);
1890bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      int line = script->GetLineNumber(source_pos) + 1;
1891bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      accumulator->Add(":%d] [bytecode=%p offset=%d]", line, bytecodes, offset);
1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int function_start_pos = shared->start_position();
1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int line = script->GetLineNumber(function_start_pos) + 1;
1895bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      accumulator->Add(":~%d] [pc=%p]", line, pc);
18966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
18976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
18986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  accumulator->Add("(this=%o", receiver);
1900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Print the parameters.
1902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int parameters_count = ComputeParametersCount();
1903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < parameters_count; i++) {
1904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add(",");
1905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If we have a name for the parameter we print it. Nameless
1906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // parameters are either because we have more actual parameters
1907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // than formal parameters or because we have no scope information.
19083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (i < scope_info->ParameterCount()) {
19093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      accumulator->PrintName(scope_info->ParameterName(i));
1910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      accumulator->Add("=");
1911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add("%o", GetParameter(i));
1913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  accumulator->Add(")");
1916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (mode == OVERVIEW) {
1917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add("\n");
1918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
1919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1920257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (is_optimized()) {
1921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    accumulator->Add(" {\n// optimized frame\n");
1922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintFunctionSource(accumulator, shared, code);
1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    accumulator->Add("}\n");
1924257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return;
1925257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  accumulator->Add(" {\n");
1927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute the number of locals and expression stack elements.
19293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int stack_locals_count = scope_info->StackLocalCount();
19303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int heap_locals_count = scope_info->ContextLocalCount();
1931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int expressions_count = ComputeExpressionsCount();
1932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Print stack-allocated local variables.
1934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (stack_locals_count > 0) {
1935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add("  // stack-allocated locals\n");
1936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < stack_locals_count; i++) {
1938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add("  var ");
19393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    accumulator->PrintName(scope_info->StackLocalName(i));
1940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add(" = ");
1941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (i < expressions_count) {
1942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      accumulator->Add("%o", GetExpression(i));
1943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
1944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      accumulator->Add("// no expression found - inconsistent frame?");
1945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add("\n");
1947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Try to get hold of the context of this frame.
1950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Context* context = NULL;
1951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (this->context() != NULL && this->context()->IsContext()) {
1952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    context = Context::cast(this->context());
1953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (context->IsWithContext()) {
1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    context = context->previous();
1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(context != NULL);
1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Print heap-allocated local variables.
19603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (heap_locals_count > 0) {
1961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add("  // heap-allocated locals\n");
1962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
19633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; i < heap_locals_count; i++) {
1964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add("  var ");
19653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    accumulator->PrintName(scope_info->ContextLocalName(i));
1966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add(" = ");
1967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (context != NULL) {
1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int index = Context::MIN_CONTEXT_SLOTS + i;
1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (index < context->length()) {
1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        accumulator->Add("%o", context->get(index));
1971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      } else {
1972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        accumulator->Add(
1973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block            "// warning: missing context slot - inconsistent frame?");
1974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
1976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      accumulator->Add("// warning: no context found - inconsistent frame?");
1977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add("\n");
1979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Print the expression stack.
1982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int expressions_start = stack_locals_count;
1983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (expressions_start < expressions_count) {
1984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add("  // expression stack (top to bottom)\n");
1985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = expressions_count - 1; i >= expressions_start; i--) {
1987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add("  [%02d] : %o\n", i, GetExpression(i));
1988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintFunctionSource(accumulator, shared, code);
1991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  accumulator->Add("}\n\n");
1993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ArgumentsAdaptorFrame::Print(StringStream* accumulator,
1997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  PrintMode mode,
1998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  int index) const {
1999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int actual = ComputeParametersCount();
2000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int expected = -1;
2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSFunction* function = this->function();
2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  expected = function->shared()->internal_formal_parameter_count();
2003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PrintIndex(accumulator, mode, index);
2005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  accumulator->Add("arguments adaptor frame: %d->%d", actual, expected);
2006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (mode == OVERVIEW) {
2007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add("\n");
2008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
2009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  accumulator->Add(" {\n");
2011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Print actual arguments.
2013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (actual > 0) accumulator->Add("  // actual arguments\n");
2014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < actual; i++) {
2015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add("  [%02d] : %o", i, GetParameter(i));
2016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (expected != -1 && i >= expected) {
2017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      accumulator->Add("  // not passed to callee");
2018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
2019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    accumulator->Add("\n");
2020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  accumulator->Add("}\n\n");
2023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid EntryFrame::Iterate(ObjectVisitor* v) const {
2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
2028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StandardFrame::IterateExpressions(ObjectVisitor* v) const {
2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int offset = StandardFrameConstants::kLastObjectOffset;
2033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object** base = &Memory::Object_at(sp());
2034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object** limit = &Memory::Object_at(fp() + offset) + 1;
2035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v->VisitPointers(base, limit);
2036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid JavaScriptFrame::Iterate(ObjectVisitor* v) const {
2040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IterateExpressions(v);
2041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
2042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid InternalFrame::Iterate(ObjectVisitor* v) const {
2045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Internal frames only have object pointers on the expression stack
2046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // as they never have any arguments.
2047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IterateExpressions(v);
2048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
2049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const {
2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** base = &Memory::Object_at(sp());
20543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Object** limit = &Memory::Object_at(
20553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      fp() + StubFailureTrampolineFrameConstants::kFixedHeaderBottomOffset);
2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->VisitPointers(base, limit);
20573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  base = &Memory::Object_at(fp() + StandardFrameConstants::kFunctionOffset);
2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int offset = StandardFrameConstants::kLastObjectOffset;
2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  limit = &Memory::Object_at(fp() + offset) + 1;
2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->VisitPointers(base, limit);
2061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress StubFailureTrampolineFrame::GetCallerStackPointer() const {
2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return fp() + StandardFrameConstants::kCallerSPOffset;
2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCode* StubFailureTrampolineFrame::unchecked_code() const {
2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* trampoline;
2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StubFailureTrampolineStub(isolate(), NOT_JS_FUNCTION_STUB_MODE).
2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      FindCodeInCache(&trampoline);
2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trampoline->contains(pc())) {
2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return trampoline;
2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StubFailureTrampolineStub(isolate(), JS_FUNCTION_STUB_MODE).
2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      FindCodeInCache(&trampoline);
2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (trampoline->contains(pc())) {
2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return trampoline;
2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -------------------------------------------------------------------------
2090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockJavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) {
2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(n >= 0);
2094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i <= n; i++) {
2095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    while (!iterator_.frame()->is_java_script()) iterator_.Advance();
2096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (i == n) return JavaScriptFrame::cast(iterator_.frame());
2097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    iterator_.Advance();
2098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
2100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
2101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -------------------------------------------------------------------------
2105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
21073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic Map* GcSafeMapOfCodeSpaceObject(HeapObject* object) {
21083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MapWord map_word = object->map_word();
21093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return map_word.IsForwardingAddress() ?
21103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      map_word.ToForwardingAddress()->map() : map_word.ToMap();
21113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
21123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
21133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
21143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic int GcSafeSizeOfCodeSpaceObject(HeapObject* object) {
21153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return object->SizeFromMap(GcSafeMapOfCodeSpaceObject(object));
21163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
21173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
21183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
21193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
21203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool GcSafeCodeContains(HeapObject* code, Address addr) {
21213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Map* map = GcSafeMapOfCodeSpaceObject(code);
2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(map == code->GetHeap()->code_map());
21233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Address start = code->address();
21243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Address end = code->address() + code->SizeFromMap(map);
21253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return start <= addr && addr < end;
21263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
21273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
21283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
21293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
21303ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochCode* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object,
21313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                Address inner_pointer) {
213280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Code* code = reinterpret_cast<Code*>(object);
2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(code != NULL && GcSafeCodeContains(code, inner_pointer));
213480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  return code;
213580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
213680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
213780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
21383ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochCode* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer(
21393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Address inner_pointer) {
214044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate_->heap();
2141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
21423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if the inner pointer points into a large object chunk.
21433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LargePage* large_page = heap->lo_space()->FindPage(inner_pointer);
21443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (large_page != NULL) {
21453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return GcSafeCastToCode(large_page->GetObject(), inner_pointer);
21463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
21473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2148109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!heap->code_space()->Contains(inner_pointer)) {
2149109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return nullptr;
2150109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2151109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
21523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Iterate through the page until we reach the end or find an object starting
21533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // after the inner pointer.
21543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Page* page = Page::FromAddress(inner_pointer);
21553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(page->owner(), heap->code_space());
2157bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  heap->mark_compact_collector()->sweeper().SweepOrWaitUntilSweepingCompleted(
2158bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      page);
2159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
21603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Address addr = page->skip_list()->StartFor(inner_pointer);
21613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
21623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Address top = heap->code_space()->top();
21633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Address limit = heap->code_space()->limit();
21643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
216580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  while (true) {
21663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (addr == top && addr != limit) {
21673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      addr = limit;
21683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      continue;
216980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    }
21703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
21713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    HeapObject* obj = HeapObject::FromAddress(addr);
21723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int obj_size = GcSafeSizeOfCodeSpaceObject(obj);
21733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Address next_addr = addr + obj_size;
21743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (next_addr > inner_pointer) return GcSafeCastToCode(obj, inner_pointer);
21753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    addr = next_addr;
217680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  }
217780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
217880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
2179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
21803ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochInnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
21813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
218244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate_->counters()->pc_to_code()->Increment();
2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(base::bits::IsPowerOfTwo32(kInnerPointerToCodeCacheSize));
2184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t hash = ComputeIntegerHash(ObjectAddressForHashing(inner_pointer),
2185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     v8::internal::kZeroHashSeed);
21863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
21873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  InnerPointerToCodeCacheEntry* entry = cache(index);
21883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (entry->inner_pointer == inner_pointer) {
218944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate_->counters()->pc_to_code_cached()->Increment();
2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(entry->code == GcSafeFindCodeForInnerPointer(inner_pointer));
219180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  } else {
219280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    // Because this code may be interrupted by a profiling signal that
21933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // also queries the cache, we cannot update inner_pointer before the code
21943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // has been set. Otherwise, we risk trying to use a cache entry before
219580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    // the code has been computed.
21963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    entry->code = GcSafeFindCodeForInnerPointer(inner_pointer);
2197b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    entry->safepoint_entry.Reset();
21983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    entry->inner_pointer = inner_pointer;
219980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  }
220080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  return entry;
220180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
220280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
220380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
220480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// -------------------------------------------------------------------------
220580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint NumRegs(RegList reglist) { return base::bits::CountPopulation(reglist); }
2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct JSCallerSavedCodeData {
221144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int reg_code[kNumJSCallerSaved];
221244f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
221344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochJSCallerSavedCodeData caller_saved_code_data;
2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid SetUpJSCallerSavedCodeData() {
2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int i = 0;
2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int r = 0; r < kNumRegs; r++)
2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if ((kJSCallerSaved & (1 << r)) != 0)
2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      caller_saved_code_data.reg_code[i++] = r;
2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(i == kNumJSCallerSaved);
2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
222444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
222544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
222644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint JSCallerSavedCode(int n) {
2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(0 <= n && n < kNumJSCallerSaved);
2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return caller_saved_code_data.reg_code[n];
2229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
22326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#define DEFINE_WRAPPER(type, field)                              \
22336ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass field##_Wrapper : public ZoneObject {                      \
22346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:  /* NOLINT */                                           \
22356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  field##_Wrapper(const field& original) : frame_(original) {    \
22366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }                                                              \
22376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  field frame_;                                                  \
22386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
22396ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockSTACK_FRAME_TYPE_LIST(DEFINE_WRAPPER)
22406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#undef DEFINE_WRAPPER
22416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic StackFrame* AllocateFrameCopy(StackFrame* frame, Zone* zone) {
22436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#define FRAME_TYPE_CASE(type, field) \
22446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  case StackFrame::type: { \
22456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    field##_Wrapper* wrapper = \
2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        new(zone) field##_Wrapper(*(reinterpret_cast<field*>(frame))); \
22476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return &wrapper->frame_; \
22486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
22496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
22506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  switch (frame->type()) {
22516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
22526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    default: UNREACHABLE();
22536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
22546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#undef FRAME_TYPE_CASE
22556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return NULL;
22566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
22576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone) {
2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<StackFrame*> list(10, zone);
2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    list.Add(frame, zone);
22646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
22656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return list.ToVector();
22666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
22676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
22686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
2270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
2271