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