LCOV - code coverage report
Current view: top level - src - frames.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 717 928 77.3 %
Date: 2019-01-20 Functions: 137 191 71.7 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/frames.h"
       6             : 
       7             : #include <memory>
       8             : #include <sstream>
       9             : 
      10             : #include "src/base/bits.h"
      11             : #include "src/deoptimizer.h"
      12             : #include "src/frames-inl.h"
      13             : #include "src/ic/ic-stats.h"
      14             : #include "src/macro-assembler.h"
      15             : #include "src/objects/code.h"
      16             : #include "src/objects/slots.h"
      17             : #include "src/objects/smi.h"
      18             : #include "src/register-configuration.h"
      19             : #include "src/safepoint-table.h"
      20             : #include "src/snapshot/snapshot.h"
      21             : #include "src/string-stream.h"
      22             : #include "src/visitors.h"
      23             : #include "src/vm-state-inl.h"
      24             : #include "src/wasm/wasm-code-manager.h"
      25             : #include "src/wasm/wasm-engine.h"
      26             : #include "src/wasm/wasm-objects-inl.h"
      27             : #include "src/zone/zone-containers.h"
      28             : 
      29             : namespace v8 {
      30             : namespace internal {
      31             : 
      32             : ReturnAddressLocationResolver StackFrame::return_address_location_resolver_ =
      33             :     nullptr;
      34             : 
      35             : // Iterator that supports traversing the stack handlers of a
      36             : // particular frame. Needs to know the top of the handler chain.
      37             : class StackHandlerIterator {
      38             :  public:
      39    50588760 :   StackHandlerIterator(const StackFrame* frame, StackHandler* handler)
      40             :       : limit_(frame->fp()), handler_(handler) {
      41             :     // Make sure the handler has already been unwound to this frame.
      42             :     DCHECK(frame->sp() <= handler->address());
      43             :   }
      44             : 
      45             :   StackHandler* handler() const { return handler_; }
      46             : 
      47   103105155 :   bool done() { return handler_ == nullptr || handler_->address() > limit_; }
      48             :   void Advance() {
      49             :     DCHECK(!done());
      50             :     handler_ = handler_->next();
      51             :   }
      52             : 
      53             :  private:
      54             :   const Address limit_;
      55             :   StackHandler* handler_;
      56             : };
      57             : 
      58             : 
      59             : // -------------------------------------------------------------------------
      60             : 
      61             : 
      62             : #define INITIALIZE_SINGLETON(type, field) field##_(this),
      63     8515823 : StackFrameIteratorBase::StackFrameIteratorBase(Isolate* isolate,
      64             :                                                bool can_access_heap_objects)
      65             :     : isolate_(isolate),
      66             :       STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) frame_(nullptr),
      67             :       handler_(nullptr),
      68    17031646 :       can_access_heap_objects_(can_access_heap_objects) {}
      69             : #undef INITIALIZE_SINGLETON
      70             : 
      71     7916940 : StackFrameIterator::StackFrameIterator(Isolate* isolate)
      72    15833896 :     : StackFrameIterator(isolate, isolate->thread_local_top()) {}
      73             : 
      74      573573 : StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
      75     8490513 :     : StackFrameIteratorBase(isolate, true) {
      76     8490530 :   Reset(t);
      77      573573 : }
      78             : 
      79    50588718 : void StackFrameIterator::Advance() {
      80             :   DCHECK(!done());
      81             :   // Compute the state of the calling frame before restoring
      82             :   // callee-saved registers and unwinding handlers. This allows the
      83             :   // frame code that computes the caller state to access the top
      84             :   // handler and the value of any callee-saved register if needed.
      85    50588718 :   StackFrame::State state;
      86    50588718 :   StackFrame::Type type = frame_->GetCallerState(&state);
      87             : 
      88             :   // Unwind handlers corresponding to the current frame.
      89    50588760 :   StackHandlerIterator it(frame_, handler_);
      90    52256287 :   while (!it.done()) it.Advance();
      91    50588760 :   handler_ = it.handler();
      92             : 
      93             :   // Advance to the calling frame.
      94    50588760 :   frame_ = SingletonFor(type, &state);
      95             : 
      96             :   // When we're done iterating over the stack frames, the handler
      97             :   // chain must have been completely unwound.
      98             :   DCHECK(!done() || handler_ == nullptr);
      99    50588761 : }
     100             : 
     101             : 
     102    25471597 : void StackFrameIterator::Reset(ThreadLocalTop* top) {
     103     8490527 :   StackFrame::State state;
     104             :   StackFrame::Type type = ExitFrame::GetStateForFramePointer(
     105     8490527 :       Isolate::c_entry_fp(top), &state);
     106     8490543 :   handler_ = StackHandler::FromAddress(Isolate::handler(top));
     107     8490543 :   frame_ = SingletonFor(type, &state);
     108     8490548 : }
     109             : 
     110             : 
     111    59204774 : StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type,
     112             :                                              StackFrame::State* state) {
     113    59204774 :   StackFrame* result = SingletonFor(type);
     114             :   DCHECK((!result) == (type == StackFrame::NONE));
     115    59204762 :   if (result) result->state_ = *state;
     116    59204762 :   return result;
     117             : }
     118             : 
     119             : 
     120    59304975 : StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type) {
     121             : #define FRAME_TYPE_CASE(type, field) \
     122             :   case StackFrame::type:             \
     123             :     return &field##_;
     124             : 
     125    59304975 :   switch (type) {
     126             :     case StackFrame::NONE:
     127             :       return nullptr;
     128     1827761 :       STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
     129             :     default: break;
     130             :   }
     131             :   return nullptr;
     132             : 
     133             : #undef FRAME_TYPE_CASE
     134             : }
     135             : 
     136             : // -------------------------------------------------------------------------
     137             : 
     138     1425022 : void JavaScriptFrameIterator::Advance() {
     139     2926443 :   do {
     140     2926443 :     iterator_.Advance();
     141     2926443 :   } while (!iterator_.done() && !iterator_.frame()->is_java_script());
     142     1425022 : }
     143             : 
     144             : // -------------------------------------------------------------------------
     145             : 
     146     2047151 : StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
     147     2047151 :     : iterator_(isolate) {
     148     2047151 :   if (!done() && !IsValidFrame(iterator_.frame())) Advance();
     149     2047151 : }
     150             : 
     151      185316 : StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate,
     152             :                                                  StackFrame::Id id)
     153      185316 :     : StackTraceFrameIterator(isolate) {
     154     2577396 :   while (!done() && frame()->id() != id) Advance();
     155      185316 : }
     156             : 
     157     3920744 : void StackTraceFrameIterator::Advance() {
     158     7151154 :   do {
     159     7151154 :     iterator_.Advance();
     160     7151154 :   } while (!done() && !IsValidFrame(iterator_.frame()));
     161     3920744 : }
     162             : 
     163     8978104 : bool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) const {
     164     8978104 :   if (frame->is_java_script()) {
     165             :     JavaScriptFrame* jsFrame = static_cast<JavaScriptFrame*>(frame);
     166     8088812 :     if (!jsFrame->function()->IsJSFunction()) return false;
     167     4044406 :     return jsFrame->function()->shared()->IsSubjectToDebugging();
     168             :   }
     169             :   // apart from javascript, only wasm is valid
     170     4933698 :   return frame->is_wasm();
     171             : }
     172             : 
     173             : // -------------------------------------------------------------------------
     174             : 
     175             : namespace {
     176             : 
     177      107163 : bool IsInterpreterFramePc(Isolate* isolate, Address pc,
     178             :                           StackFrame::State* state) {
     179             :   Code interpreter_entry_trampoline =
     180      107163 :       isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline);
     181             :   Code interpreter_bytecode_advance =
     182      107163 :       isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeAdvance);
     183             :   Code interpreter_bytecode_dispatch =
     184      107163 :       isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
     185             : 
     186      240758 :   if (interpreter_entry_trampoline->contains(pc) ||
     187      133595 :       interpreter_bytecode_advance->contains(pc) ||
     188       26432 :       interpreter_bytecode_dispatch->contains(pc)) {
     189             :     return true;
     190       26432 :   } else if (FLAG_interpreted_frames_native_stack) {
     191             :     intptr_t marker = Memory<intptr_t>(
     192           0 :         state->fp + CommonFrameConstants::kContextOrFrameTypeOffset);
     193             :     MSAN_MEMORY_IS_INITIALIZED(
     194             :         state->fp + StandardFrameConstants::kFunctionOffset,
     195             :         kSystemPointerSize);
     196             :     Object maybe_function = Object(
     197           0 :         Memory<Address>(state->fp + StandardFrameConstants::kFunctionOffset));
     198             :     // There's no need to run a full ContainsSlow if we know the frame can't be
     199             :     // an InterpretedFrame,  so we do these fast checks first
     200           0 :     if (StackFrame::IsTypeMarker(marker) || maybe_function->IsSmi()) {
     201             :       return false;
     202           0 :     } else if (!isolate->heap()->code_space()->ContainsSlow(pc)) {
     203             :       return false;
     204             :     }
     205             :     interpreter_entry_trampoline =
     206           0 :         isolate->heap()->GcSafeFindCodeForInnerPointer(pc);
     207             :     return interpreter_entry_trampoline->is_interpreter_trampoline_builtin();
     208             :   } else {
     209             :     return false;
     210             :   }
     211             : }
     212             : 
     213             : DISABLE_ASAN Address ReadMemoryAt(Address address) {
     214       12283 :   return Memory<Address>(address);
     215             : }
     216             : 
     217             : }  // namespace
     218             : 
     219       25308 : SafeStackFrameIterator::SafeStackFrameIterator(
     220       25308 :     Isolate* isolate,
     221       36849 :     Address fp, Address sp, Address js_entry_sp)
     222             :     : StackFrameIteratorBase(isolate, false),
     223             :       low_bound_(sp),
     224             :       high_bound_(js_entry_sp),
     225             :       top_frame_type_(StackFrame::NONE),
     226       50616 :       external_callback_scope_(isolate->external_callback_scope()) {
     227       25308 :   StackFrame::State state;
     228             :   StackFrame::Type type;
     229       38331 :   ThreadLocalTop* top = isolate->thread_local_top();
     230             :   bool advance_frame = true;
     231             : 
     232       25308 :   Address fast_c_fp = isolate->isolate_data()->fast_c_call_caller_fp();
     233             :   // 'Fast C calls' are a special type of C call where we call directly from JS
     234             :   // to C without an exit frame inbetween. The CEntryStub is responsible for
     235             :   // setting Isolate::c_entry_fp, meaning that it won't be set for fast C calls.
     236             :   // To keep the stack iterable, we store the FP and PC of the caller of the
     237             :   // fast C call on the isolate. This is guaranteed to be the topmost JS frame,
     238             :   // because fast C calls cannot call back into JS. We start iterating the stack
     239             :   // from this topmost JS frame.
     240       25308 :   if (fast_c_fp) {
     241             :     DCHECK_NE(kNullAddress, isolate->isolate_data()->fast_c_call_caller_pc());
     242             :     type = StackFrame::Type::OPTIMIZED;
     243           2 :     top_frame_type_ = type;
     244           2 :     state.fp = fast_c_fp;
     245           2 :     state.sp = sp;
     246           2 :     state.pc_address = isolate->isolate_data()->fast_c_call_caller_pc_address();
     247             :     advance_frame = false;
     248       25306 :   } else if (IsValidTop(top)) {
     249       13023 :     type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
     250       13023 :     top_frame_type_ = type;
     251       12283 :   } else if (IsValidStackAddress(fp)) {
     252             :     DCHECK_NE(fp, kNullAddress);
     253       12283 :     state.fp = fp;
     254       12283 :     state.sp = sp;
     255             :     state.pc_address = StackFrame::ResolveReturnAddressLocation(
     256       24566 :         reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
     257             : 
     258             :     // If the top of stack is a return address to the interpreter trampoline,
     259             :     // then we are likely in a bytecode handler with elided frame. In that
     260             :     // case, set the PC properly and make sure we do not drop the frame.
     261       12283 :     if (IsValidStackAddress(sp)) {
     262             :       MSAN_MEMORY_IS_INITIALIZED(sp, kSystemPointerSize);
     263             :       Address tos = ReadMemoryAt(sp);
     264       12283 :       if (IsInterpreterFramePc(isolate, tos, &state)) {
     265        7545 :         state.pc_address = reinterpret_cast<Address*>(sp);
     266             :         advance_frame = false;
     267             :       }
     268             :     }
     269             : 
     270             :     // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset,
     271             :     // we check only that kMarkerOffset is within the stack bounds and do
     272             :     // compile time check that kContextOffset slot is pushed on the stack before
     273             :     // kMarkerOffset.
     274             :     STATIC_ASSERT(StandardFrameConstants::kFunctionOffset <
     275             :                   StandardFrameConstants::kContextOffset);
     276       12283 :     Address frame_marker = fp + StandardFrameConstants::kFunctionOffset;
     277       12283 :     if (IsValidStackAddress(frame_marker)) {
     278       12168 :       type = StackFrame::ComputeType(this, &state);
     279       12168 :       top_frame_type_ = type;
     280             :       // We only keep the top frame if we believe it to be interpreted frame.
     281       12168 :       if (type != StackFrame::INTERPRETED) {
     282             :         advance_frame = true;
     283             :       }
     284             :     } else {
     285             :       // Mark the frame as OPTIMIZED if we cannot determine its type.
     286             :       // We chose OPTIMIZED rather than INTERPRETED because it's closer to
     287             :       // the original value of StackFrame::JAVA_SCRIPT here, in that JAVA_SCRIPT
     288             :       // referred to full-codegen frames (now removed from the tree), and
     289             :       // OPTIMIZED refers to turbofan frames, both of which are generated
     290             :       // code. INTERPRETED frames refer to bytecode.
     291             :       // The frame anyways will be skipped.
     292             :       type = StackFrame::OPTIMIZED;
     293             :       // Top frame is incomplete so we cannot reliably determine its type.
     294         115 :       top_frame_type_ = StackFrame::NONE;
     295             :     }
     296             :   } else {
     297           0 :     return;
     298             :   }
     299       25308 :   frame_ = SingletonFor(type, &state);
     300       25308 :   if (advance_frame && frame_) Advance();
     301             : }
     302             : 
     303             : 
     304       38329 : bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const {
     305             :   Address c_entry_fp = Isolate::c_entry_fp(top);
     306       25306 :   if (!IsValidExitFrame(c_entry_fp)) return false;
     307             :   // There should be at least one JS_ENTRY stack handler.
     308             :   Address handler = Isolate::handler(top);
     309       13023 :   if (handler == kNullAddress) return false;
     310             :   // Check that there are no js frames on top of the native frames.
     311       13023 :   return c_entry_fp < handler;
     312             : }
     313             : 
     314             : 
     315      125511 : void SafeStackFrameIterator::AdvanceOneFrame() {
     316             :   DCHECK(!done());
     317      125511 :   StackFrame* last_frame = frame_;
     318             :   Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
     319             :   // Before advancing to the next stack frame, perform pointer validity tests.
     320      125511 :   if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) {
     321       25303 :     frame_ = nullptr;
     322       50606 :     return;
     323             :   }
     324             : 
     325             :   // Advance to the previous frame.
     326      100208 :   StackFrame::State state;
     327      300624 :   StackFrame::Type type = frame_->GetCallerState(&state);
     328      100208 :   frame_ = SingletonFor(type, &state);
     329      100208 :   if (!frame_) return;
     330             : 
     331             :   // Check that we have actually moved to the previous frame in the stack.
     332      200416 :   if (frame_->sp() <= last_sp || frame_->fp() <= last_fp) {
     333           0 :     frame_ = nullptr;
     334             :   }
     335             : }
     336             : 
     337             : 
     338      125511 : bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const {
     339      251022 :   return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
     340             : }
     341             : 
     342             : 
     343      251127 : bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
     344      125511 :   StackFrame::State state;
     345      225614 :   if (frame->is_entry() || frame->is_construct_entry()) {
     346             :     // See EntryFrame::GetCallerState. It computes the caller FP address
     347             :     // and calls ExitFrame::GetStateForFramePointer on it. We need to be
     348             :     // sure that caller FP address is valid.
     349             :     Address caller_fp =
     350       50816 :         Memory<Address>(frame->fp() + EntryFrameConstants::kCallerFPOffset);
     351       25408 :     if (!IsValidExitFrame(caller_fp)) return false;
     352      100103 :   } else if (frame->is_arguments_adaptor()) {
     353             :     // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that
     354             :     // the number of arguments is stored on stack as Smi. We need to check
     355             :     // that it really an Smi.
     356             :     Object number_of_args =
     357           0 :         reinterpret_cast<ArgumentsAdaptorFrame*>(frame)->GetExpression(0);
     358           0 :     if (!number_of_args->IsSmi()) {
     359           0 :       return false;
     360             :     }
     361             :   }
     362      100208 :   frame->ComputeCallerState(&state);
     363      400832 :   return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) &&
     364      200416 :          SingletonFor(frame->GetCallerState(&state)) != nullptr;
     365             : }
     366             : 
     367             : 
     368       50714 : bool SafeStackFrameIterator::IsValidExitFrame(Address fp) const {
     369       50714 :   if (!IsValidStackAddress(fp)) return false;
     370             :   Address sp = ExitFrame::ComputeStackPointer(fp);
     371       13128 :   if (!IsValidStackAddress(sp)) return false;
     372             :   StackFrame::State state;
     373             :   ExitFrame::FillState(fp, sp, &state);
     374             :   MSAN_MEMORY_IS_INITIALIZED(state.pc_address, sizeof(state.pc_address));
     375       13128 :   return *state.pc_address != kNullAddress;
     376             : }
     377             : 
     378             : 
     379       69010 : void SafeStackFrameIterator::Advance() {
     380             :   while (true) {
     381      125511 :     AdvanceOneFrame();
     382      125511 :     if (done()) break;
     383             :     ExternalCallbackScope* last_callback_scope = nullptr;
     384      125966 :     while (external_callback_scope_ != nullptr &&
     385       13066 :            external_callback_scope_->scope_address() < frame_->fp()) {
     386             :       // As long as the setup of a frame is not atomic, we may happen to be
     387             :       // in an interval where an ExternalCallbackScope is already created,
     388             :       // but the frame is not yet entered. So we are actually observing
     389             :       // the previous frame.
     390             :       // Skip all the ExternalCallbackScope's that are below the current fp.
     391             :       last_callback_scope = external_callback_scope_;
     392       12692 :       external_callback_scope_ = external_callback_scope_->previous();
     393             :     }
     394      156814 :     if (frame_->is_java_script() || frame_->is_wasm()) break;
     395      169713 :     if (frame_->is_exit() || frame_->is_builtin_exit()) {
     396             :       // Some of the EXIT frames may have ExternalCallbackScope allocated on
     397             :       // top of them. In that case the scope corresponds to the first EXIT
     398             :       // frame beneath it. There may be other EXIT frames on top of the
     399             :       // ExternalCallbackScope, just skip them as we cannot collect any useful
     400             :       // information about them.
     401         105 :       if (last_callback_scope) {
     402             :         frame_->state_.pc_address =
     403         210 :             last_callback_scope->callback_entrypoint_address();
     404             :       }
     405             :       break;
     406             :     }
     407             :   }
     408       69010 : }
     409             : 
     410             : 
     411             : // -------------------------------------------------------------------------
     412             : 
     413             : namespace {
     414    56550988 : Code GetContainingCode(Isolate* isolate, Address pc) {
     415    56550988 :   return isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code;
     416             : }
     417             : }  // namespace
     418             : 
     419    21727930 : Code StackFrame::LookupCode() const {
     420             :   Code result = GetContainingCode(isolate(), pc());
     421             :   DCHECK_GE(pc(), result->InstructionStart());
     422             :   DCHECK_LT(pc(), result->InstructionEnd());
     423    10863965 :   return result;
     424             : }
     425             : 
     426     4574795 : void StackFrame::IteratePc(RootVisitor* v, Address* pc_address,
     427             :                            Address* constant_pool_address, Code holder) {
     428     4574795 :   Address pc = *pc_address;
     429             :   DCHECK(holder->GetHeap()->GcSafeCodeContains(holder, pc));
     430     4574795 :   unsigned pc_offset = static_cast<unsigned>(pc - holder->InstructionStart());
     431     4574795 :   Object code = holder;
     432     9149590 :   v->VisitRootPointer(Root::kTop, nullptr, FullObjectSlot(&code));
     433     9149119 :   if (code == holder) return;
     434         475 :   holder = Code::unchecked_cast(code);
     435         475 :   pc = holder->InstructionStart() + pc_offset;
     436         475 :   *pc_address = pc;
     437             :   if (FLAG_enable_embedded_constant_pool && constant_pool_address) {
     438             :     *constant_pool_address = holder->constant_pool();
     439             :   }
     440             : }
     441             : 
     442             : 
     443           0 : void StackFrame::SetReturnAddressLocationResolver(
     444             :     ReturnAddressLocationResolver resolver) {
     445             :   DCHECK_NULL(return_address_location_resolver_);
     446           0 :   return_address_location_resolver_ = resolver;
     447           0 : }
     448             : 
     449   143836577 : StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
     450             :                                          State* state) {
     451             :   DCHECK_NE(state->fp, kNullAddress);
     452             : 
     453             :   MSAN_MEMORY_IS_INITIALIZED(
     454             :       state->fp + CommonFrameConstants::kContextOrFrameTypeOffset,
     455             :       kSystemPointerSize);
     456             :   intptr_t marker = Memory<intptr_t>(
     457    98267048 :       state->fp + CommonFrameConstants::kContextOrFrameTypeOffset);
     458    49133524 :   if (!iterator->can_access_heap_objects_) {
     459             :     // TODO(titzer): "can_access_heap_objects" is kind of bogus. It really
     460             :     // means that we are being called from the profiler, which can interrupt
     461             :     // the VM with a signal at any arbitrary instruction, with essentially
     462             :     // anything on the stack. So basically none of these checks are 100%
     463             :     // reliable.
     464             :     MSAN_MEMORY_IS_INITIALIZED(
     465             :         state->fp + StandardFrameConstants::kFunctionOffset,
     466             :         kSystemPointerSize);
     467             :     Object maybe_function = Object(
     468      424748 :         Memory<Address>(state->fp + StandardFrameConstants::kFunctionOffset));
     469      212374 :     if (!StackFrame::IsTypeMarker(marker)) {
     470       94880 :       if (maybe_function->IsSmi()) {
     471       94880 :         return NATIVE;
     472       94880 :       } else if (IsInterpreterFramePc(iterator->isolate(), *(state->pc_address),
     473       94880 :                                       state)) {
     474             :         return INTERPRETED;
     475             :       } else {
     476       21694 :         return OPTIMIZED;
     477             :       }
     478             :     }
     479             :   } else {
     480    48921150 :     Address pc = *(state->pc_address);
     481             :     // If the {pc} does not point into WebAssembly code we can rely on the
     482             :     // returned {wasm_code} to be null and fall back to {GetContainingCode}.
     483     3234235 :     wasm::WasmCode* wasm_code =
     484    48921150 :         iterator->isolate()->wasm_engine()->code_manager()->LookupCode(pc);
     485    48921258 :     if (wasm_code != nullptr) {
     486     3234235 :       switch (wasm_code->kind()) {
     487             :         case wasm::WasmCode::kFunction:
     488             :           return WASM_COMPILED;
     489             :         case wasm::WasmCode::kWasmToJsWrapper:
     490        8837 :           return WASM_TO_JS;
     491             :         case wasm::WasmCode::kLazyStub:
     492           0 :           return WASM_COMPILE_LAZY;
     493             :         case wasm::WasmCode::kRuntimeStub:
     494          74 :           return STUB;
     495             :         case wasm::WasmCode::kInterpreterEntry:
     496       44790 :           return WASM_INTERPRETER_ENTRY;
     497             :         default:
     498           0 :           UNREACHABLE();
     499             :       }
     500             :     } else {
     501             :       // Look up the code object to figure out the type of the stack frame.
     502             :       Code code_obj = GetContainingCode(iterator->isolate(), pc);
     503    45687000 :       if (!code_obj.is_null()) {
     504    45687000 :         switch (code_obj->kind()) {
     505             :           case Code::BUILTIN:
     506    34644830 :             if (StackFrame::IsTypeMarker(marker)) break;
     507    26957771 :             if (code_obj->is_interpreter_trampoline_builtin()) {
     508             :               return INTERPRETED;
     509             :             }
     510     1474994 :             if (code_obj->is_turbofanned()) {
     511             :               // TODO(bmeurer): We treat frames for BUILTIN Code objects as
     512             :               // OptimizedFrame for now (all the builtins with JavaScript
     513             :               // linkage are actually generated with TurboFan currently, so
     514             :               // this is sound).
     515             :               return OPTIMIZED;
     516             :             }
     517           0 :             return BUILTIN;
     518             :           case Code::OPTIMIZED_FUNCTION:
     519             :             return OPTIMIZED;
     520             :           case Code::WASM_FUNCTION:
     521           0 :             return WASM_COMPILED;
     522             :           case Code::WASM_TO_JS_FUNCTION:
     523           0 :             return WASM_TO_JS;
     524             :           case Code::JS_TO_WASM_FUNCTION:
     525      349064 :             return JS_TO_WASM;
     526             :           case Code::WASM_INTERPRETER_ENTRY:
     527           0 :             return WASM_INTERPRETER_ENTRY;
     528             :           case Code::C_WASM_ENTRY:
     529        1499 :             return C_WASM_ENTRY;
     530             :           default:
     531             :             // All other types should have an explicit marker
     532             :             break;
     533             :         }
     534             :       } else {
     535             :         return NATIVE;
     536             :       }
     537             :     }
     538             :   }
     539             :   DCHECK(StackFrame::IsTypeMarker(marker));
     540             :   StackFrame::Type candidate = StackFrame::MarkerToType(marker);
     541    12753018 :   switch (candidate) {
     542             :     case ENTRY:
     543             :     case CONSTRUCT_ENTRY:
     544             :     case EXIT:
     545             :     case BUILTIN_CONTINUATION:
     546             :     case JAVA_SCRIPT_BUILTIN_CONTINUATION:
     547             :     case JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH:
     548             :     case BUILTIN_EXIT:
     549             :     case STUB:
     550             :     case INTERNAL:
     551             :     case CONSTRUCT:
     552             :     case ARGUMENTS_ADAPTOR:
     553             :     case WASM_TO_JS:
     554             :     case WASM_COMPILED:
     555             :       return candidate;
     556             :     case JS_TO_WASM:
     557             :     case OPTIMIZED:
     558             :     case INTERPRETED:
     559             :     default:
     560             :       // Unoptimized and optimized JavaScript frames, including
     561             :       // interpreted frames, should never have a StackFrame::Type
     562             :       // marker. If we find one, we're likely being called from the
     563             :       // profiler in a bogus stack frame.
     564             :       return NATIVE;
     565             :   }
     566             : }
     567             : 
     568             : 
     569             : #ifdef DEBUG
     570             : bool StackFrame::can_access_heap_objects() const {
     571             :   return iterator_->can_access_heap_objects_;
     572             : }
     573             : #endif
     574             : 
     575             : 
     576    49121376 : StackFrame::Type StackFrame::GetCallerState(State* state) const {
     577    49121376 :   ComputeCallerState(state);
     578    49121378 :   return ComputeType(iterator_, state);
     579             : }
     580             : 
     581             : 
     582           0 : Address StackFrame::UnpaddedFP() const {
     583           0 :   return fp();
     584             : }
     585             : 
     586           0 : Code NativeFrame::unchecked_code() const { return Code(); }
     587             : 
     588           0 : void NativeFrame::ComputeCallerState(State* state) const {
     589           0 :   state->sp = caller_sp();
     590           0 :   state->fp = Memory<Address>(fp() + CommonFrameConstants::kCallerFPOffset);
     591             :   state->pc_address = ResolveReturnAddressLocation(
     592           0 :       reinterpret_cast<Address*>(fp() + CommonFrameConstants::kCallerPCOffset));
     593           0 :   state->callee_pc_address = nullptr;
     594           0 :   state->constant_pool_address = nullptr;
     595           0 : }
     596             : 
     597           0 : Code EntryFrame::unchecked_code() const {
     598           0 :   return isolate()->heap()->builtin(Builtins::kJSEntry);
     599             : }
     600             : 
     601             : 
     602         105 : void EntryFrame::ComputeCallerState(State* state) const {
     603         105 :   GetCallerState(state);
     604         105 : }
     605             : 
     606             : 
     607     1667842 : StackFrame::Type EntryFrame::GetCallerState(State* state) const {
     608             :   const int offset = EntryFrameConstants::kCallerFPOffset;
     609     3335684 :   Address fp = Memory<Address>(this->fp() + offset);
     610     1667842 :   return ExitFrame::GetStateForFramePointer(fp, state);
     611             : }
     612             : 
     613           0 : Code ConstructEntryFrame::unchecked_code() const {
     614           0 :   return isolate()->heap()->builtin(Builtins::kJSConstructEntry);
     615             : }
     616             : 
     617           0 : Address& ExitFrame::code_slot() const {
     618             :   const int offset = ExitFrameConstants::kCodeOffset;
     619      173599 :   return Memory<Address>(fp() + offset);
     620             : }
     621             : 
     622           0 : Code ExitFrame::unchecked_code() const {
     623           0 :   return Code::unchecked_cast(Object(code_slot()));
     624             : }
     625             : 
     626     8143295 : void ExitFrame::ComputeCallerState(State* state) const {
     627             :   // Set up the caller state.
     628    24429925 :   state->sp = caller_sp();
     629     8143315 :   state->fp = Memory<Address>(fp() + ExitFrameConstants::kCallerFPOffset);
     630             :   state->pc_address = ResolveReturnAddressLocation(
     631    16286630 :       reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
     632     8143315 :   state->callee_pc_address = nullptr;
     633             :   if (FLAG_enable_embedded_constant_pool) {
     634             :     state->constant_pool_address = reinterpret_cast<Address*>(
     635             :         fp() + ExitFrameConstants::kConstantPoolOffset);
     636             :   }
     637     8143315 : }
     638             : 
     639             : 
     640      173599 : void ExitFrame::Iterate(RootVisitor* v) const {
     641             :   // The arguments are traversed as part of the expression stack of
     642             :   // the calling frame.
     643      173599 :   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
     644      347198 :   v->VisitRootPointer(Root::kTop, nullptr, FullObjectSlot(&code_slot()));
     645      173599 : }
     646             : 
     647             : 
     648     8144278 : Address ExitFrame::GetCallerStackPointer() const {
     649     8144278 :   return fp() + ExitFrameConstants::kCallerSPOffset;
     650             : }
     651             : 
     652             : 
     653    10171387 : StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
     654    10171387 :   if (fp == 0) return NONE;
     655             :   Address sp = ComputeStackPointer(fp);
     656             :   FillState(fp, sp, state);
     657             :   DCHECK_NE(*state->pc_address, kNullAddress);
     658             : 
     659     8117345 :   return ComputeFrameType(fp);
     660             : }
     661             : 
     662     8117344 : StackFrame::Type ExitFrame::ComputeFrameType(Address fp) {
     663             :   // Distinguish between between regular and builtin exit frames.
     664             :   // Default to EXIT in all hairy cases (e.g., when called from profiler).
     665             :   const int offset = ExitFrameConstants::kFrameTypeOffset;
     666    16234688 :   Object marker(Memory<Address>(fp + offset));
     667             : 
     668     8117346 :   if (!marker->IsSmi()) {
     669             :     return EXIT;
     670             :   }
     671             : 
     672             :   intptr_t marker_int = bit_cast<intptr_t>(marker);
     673             : 
     674     8117348 :   StackFrame::Type frame_type = static_cast<StackFrame::Type>(marker_int >> 1);
     675     8117348 :   if (frame_type == EXIT || frame_type == BUILTIN_EXIT) {
     676     8117350 :     return frame_type;
     677             :   }
     678             : 
     679             :   return EXIT;
     680             : }
     681             : 
     682           0 : Address ExitFrame::ComputeStackPointer(Address fp) {
     683             :   MSAN_MEMORY_IS_INITIALIZED(fp + ExitFrameConstants::kSPOffset,
     684             :                              kSystemPointerSize);
     685    16260946 :   return Memory<Address>(fp + ExitFrameConstants::kSPOffset);
     686             : }
     687             : 
     688           0 : void ExitFrame::FillState(Address fp, Address sp, State* state) {
     689     8117345 :   state->sp = sp;
     690     8117345 :   state->fp = fp;
     691             :   state->pc_address = ResolveReturnAddressLocation(
     692    16247818 :       reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize));
     693     8117345 :   state->callee_pc_address = nullptr;
     694             :   // The constant pool recorded in the exit frame is not associated
     695             :   // with the pc in this state (the return address into a C entry
     696             :   // stub).  ComputeCallerState will retrieve the constant pool
     697             :   // together with the associated caller pc.
     698     8117345 :   state->constant_pool_address = nullptr;
     699           0 : }
     700             : 
     701       66782 : JSFunction BuiltinExitFrame::function() const {
     702       66782 :   return JSFunction::cast(target_slot_object());
     703             : }
     704             : 
     705       36491 : Object BuiltinExitFrame::receiver() const { return receiver_slot_object(); }
     706             : 
     707       36491 : bool BuiltinExitFrame::IsConstructor() const {
     708      109473 :   return !new_target_slot_object()->IsUndefined(isolate());
     709             : }
     710             : 
     711           0 : Object BuiltinExitFrame::GetParameter(int i) const {
     712             :   DCHECK(i >= 0 && i < ComputeParametersCount());
     713             :   int offset =
     714           9 :       BuiltinExitFrameConstants::kFirstArgumentOffset + i * kSystemPointerSize;
     715          18 :   return Object(Memory<Address>(fp() + offset));
     716             : }
     717             : 
     718           0 : int BuiltinExitFrame::ComputeParametersCount() const {
     719           9 :   Object argc_slot = argc_slot_object();
     720             :   DCHECK(argc_slot->IsSmi());
     721             :   // Argc also counts the receiver, target, new target, and argc itself as args,
     722             :   // therefore the real argument count is argc - 4.
     723           9 :   int argc = Smi::ToInt(argc_slot) - 4;
     724             :   DCHECK_GE(argc, 0);
     725           0 :   return argc;
     726             : }
     727             : 
     728             : namespace {
     729             : void PrintIndex(StringStream* accumulator, StackFrame::PrintMode mode,
     730             :                 int index) {
     731         250 :   accumulator->Add((mode == StackFrame::OVERVIEW) ? "%5d: " : "[%d]: ", index);
     732             : }
     733             : 
     734         124 : const char* StringForStackFrameType(StackFrame::Type type) {
     735         124 :   switch (type) {
     736             : #define CASE(value, name) \
     737             :   case StackFrame::value: \
     738             :     return #name;
     739           0 :     STACK_FRAME_TYPE_LIST(CASE)
     740             : #undef CASE
     741             :     default:
     742           0 :       UNREACHABLE();
     743             :   }
     744             : }
     745             : }  // namespace
     746             : 
     747         124 : void StackFrame::Print(StringStream* accumulator, PrintMode mode,
     748             :                        int index) const {
     749             :   DisallowHeapAllocation no_gc;
     750             :   PrintIndex(accumulator, mode, index);
     751         124 :   accumulator->Add(StringForStackFrameType(type()));
     752         124 :   accumulator->Add(" [pc: %p]\n", reinterpret_cast<void*>(pc()));
     753         124 : }
     754             : 
     755           9 : void BuiltinExitFrame::Print(StringStream* accumulator, PrintMode mode,
     756             :                              int index) const {
     757             :   DisallowHeapAllocation no_gc;
     758           9 :   Object receiver = this->receiver();
     759           9 :   JSFunction function = this->function();
     760             : 
     761           9 :   accumulator->PrintSecurityTokenIfChanged(function);
     762             :   PrintIndex(accumulator, mode, index);
     763           9 :   accumulator->Add("builtin exit frame: ");
     764           9 :   Code code;
     765           9 :   if (IsConstructor()) accumulator->Add("new ");
     766           9 :   accumulator->PrintFunction(function, receiver, &code);
     767             : 
     768           9 :   accumulator->Add("(this=%o", receiver);
     769             : 
     770             :   // Print the parameters.
     771             :   int parameters_count = ComputeParametersCount();
     772          18 :   for (int i = 0; i < parameters_count; i++) {
     773           9 :     accumulator->Add(",%o", GetParameter(i));
     774             :   }
     775             : 
     776           9 :   accumulator->Add(")\n\n");
     777           9 : }
     778             : 
     779     1585089 : Address StandardFrame::GetExpressionAddress(int n) const {
     780             :   const int offset = StandardFrameConstants::kExpressionsOffset;
     781     1585089 :   return fp() + offset - n * kSystemPointerSize;
     782             : }
     783             : 
     784    55178693 : Address InterpretedFrame::GetExpressionAddress(int n) const {
     785             :   const int offset = InterpreterFrameConstants::kExpressionsOffset;
     786    55178693 :   return fp() + offset - n * kSystemPointerSize;
     787             : }
     788             : 
     789           0 : Script StandardFrame::script() const {
     790             :   // This should only be called on frames which override this method.
     791           0 :   UNREACHABLE();
     792             :   return Script();
     793             : }
     794             : 
     795           0 : Object StandardFrame::receiver() const {
     796           0 :   return ReadOnlyRoots(isolate()).undefined_value();
     797             : }
     798             : 
     799         212 : Object StandardFrame::context() const {
     800         424 :   return ReadOnlyRoots(isolate()).undefined_value();
     801             : }
     802             : 
     803         706 : int StandardFrame::position() const {
     804        1412 :   AbstractCode code = AbstractCode::cast(LookupCode());
     805         706 :   int code_offset = static_cast<int>(pc() - code->InstructionStart());
     806         706 :   return code->SourcePosition(code_offset);
     807             : }
     808             : 
     809           0 : int StandardFrame::ComputeExpressionsCount() const {
     810          24 :   Address base = GetExpressionAddress(0);
     811          24 :   Address limit = sp() - kSystemPointerSize;
     812             :   DCHECK(base >= limit);  // stack grows downwards
     813             :   // Include register-allocated locals in number of expressions.
     814          24 :   return static_cast<int>((base - limit) / kSystemPointerSize);
     815             : }
     816             : 
     817           0 : Object StandardFrame::GetParameter(int index) const {
     818             :   // StandardFrame does not define any parameters.
     819           0 :   UNREACHABLE();
     820             : }
     821             : 
     822           0 : int StandardFrame::ComputeParametersCount() const { return 0; }
     823             : 
     824    41078195 : void StandardFrame::ComputeCallerState(State* state) const {
     825   205390975 :   state->sp = caller_sp();
     826    41078195 :   state->fp = caller_fp();
     827             :   state->pc_address = ResolveReturnAddressLocation(
     828    82156390 :       reinterpret_cast<Address*>(ComputePCAddress(fp())));
     829    41078195 :   state->callee_pc_address = pc_address();
     830             :   state->constant_pool_address =
     831    41078195 :       reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp()));
     832    41078195 : }
     833             : 
     834             : 
     835           0 : bool StandardFrame::IsConstructor() const { return false; }
     836             : 
     837           0 : void StandardFrame::Summarize(std::vector<FrameSummary>* functions) const {
     838             :   // This should only be called on frames which override this method.
     839           0 :   UNREACHABLE();
     840             : }
     841             : 
     842     1061973 : void StandardFrame::IterateCompiledFrame(RootVisitor* v) const {
     843             :   // Make sure that we're not doing "safe" stack frame iteration. We cannot
     844             :   // possibly find pointers in optimized frames in that state.
     845             :   DCHECK(can_access_heap_objects());
     846             : 
     847             :   // Find the code and compute the safepoint information.
     848     5284567 :   Address inner_pointer = pc();
     849       25298 :   const wasm::WasmCode* wasm_code =
     850     1061973 :       isolate()->wasm_engine()->code_manager()->LookupCode(inner_pointer);
     851             :   SafepointEntry safepoint_entry;
     852             :   uint32_t stack_slots;
     853             :   Code code;
     854             :   bool has_tagged_params = false;
     855     1061973 :   if (wasm_code != nullptr) {
     856             :     SafepointTable table(wasm_code->instruction_start(),
     857             :                          wasm_code->safepoint_table_offset(),
     858       12649 :                          wasm_code->stack_slots());
     859       12649 :     safepoint_entry = table.FindEntry(inner_pointer);
     860             :     stack_slots = wasm_code->stack_slots();
     861       12649 :     has_tagged_params = wasm_code->kind() != wasm::WasmCode::kFunction;
     862             :   } else {
     863             :     InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry =
     864     1049324 :         isolate()->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer);
     865     1049324 :     if (!entry->safepoint_entry.is_valid()) {
     866      113710 :       entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer);
     867             :       DCHECK(entry->safepoint_entry.is_valid());
     868             :     } else {
     869             :       DCHECK(entry->safepoint_entry.Equals(
     870             :           entry->code->GetSafepointEntry(inner_pointer)));
     871             :     }
     872             : 
     873     1049324 :     code = entry->code;
     874     1049324 :     safepoint_entry = entry->safepoint_entry;
     875             :     stack_slots = code->stack_slots();
     876             :     has_tagged_params = code->has_tagged_params();
     877             :   }
     878     1061973 :   uint32_t slot_space = stack_slots * kSystemPointerSize;
     879             : 
     880             :   // Determine the fixed header and spill slot area size.
     881             :   int frame_header_size = StandardFrameConstants::kFixedFrameSizeFromFp;
     882             :   intptr_t marker =
     883     2123946 :       Memory<intptr_t>(fp() + CommonFrameConstants::kContextOrFrameTypeOffset);
     884     1061973 :   if (StackFrame::IsTypeMarker(marker)) {
     885             :     StackFrame::Type candidate = StackFrame::MarkerToType(marker);
     886      177073 :     switch (candidate) {
     887             :       case ENTRY:
     888             :       case CONSTRUCT_ENTRY:
     889             :       case EXIT:
     890             :       case BUILTIN_CONTINUATION:
     891             :       case JAVA_SCRIPT_BUILTIN_CONTINUATION:
     892             :       case JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH:
     893             :       case BUILTIN_EXIT:
     894             :       case ARGUMENTS_ADAPTOR:
     895             :       case STUB:
     896             :       case INTERNAL:
     897             :       case CONSTRUCT:
     898             :       case JS_TO_WASM:
     899             :       case C_WASM_ENTRY:
     900             :         frame_header_size = TypedFrameConstants::kFixedFrameSizeFromFp;
     901      164468 :         break;
     902             :       case WASM_TO_JS:
     903             :       case WASM_COMPILED:
     904             :       case WASM_INTERPRETER_ENTRY:
     905             :       case WASM_COMPILE_LAZY:
     906             :         frame_header_size = WasmCompiledFrameConstants::kFixedFrameSizeFromFp;
     907             :         break;
     908             :       case OPTIMIZED:
     909             :       case INTERPRETED:
     910             :       case BUILTIN:
     911             :         // These frame types have a context, but they are actually stored
     912             :         // in the place on the stack that one finds the frame type.
     913           0 :         UNREACHABLE();
     914             :         break;
     915             :       case NATIVE:
     916             :       case NONE:
     917             :       case NUMBER_OF_TYPES:
     918             :       case MANUAL:
     919           0 :         UNREACHABLE();
     920             :         break;
     921             :     }
     922             :   }
     923             :   slot_space -=
     924     1061973 :       (frame_header_size + StandardFrameConstants::kFixedFrameSizeAboveFp);
     925             : 
     926     1061973 :   FullObjectSlot frame_header_base(&Memory<Address>(fp() - frame_header_size));
     927             :   FullObjectSlot frame_header_limit(
     928             :       &Memory<Address>(fp() - StandardFrameConstants::kCPSlotSize));
     929             :   FullObjectSlot parameters_base(&Memory<Address>(sp()));
     930     1061973 :   FullObjectSlot parameters_limit(frame_header_base.address() - slot_space);
     931             : 
     932             :   // Visit the parameters that may be on top of the saved registers.
     933     2123946 :   if (safepoint_entry.has_argument_count()) {
     934             :     int argument_count = safepoint_entry.argument_count();
     935             :     v->VisitRootPointers(Root::kTop, nullptr, parameters_base,
     936           0 :                          parameters_base + argument_count);
     937             :     parameters_base += argument_count;
     938             :   }
     939             : 
     940             :   // Skip saved double registers.
     941     2123946 :   if (safepoint_entry.has_doubles()) {
     942             :     // Number of doubles not known at snapshot time.
     943             :     DCHECK(!isolate()->serializer_enabled());
     944           0 :     parameters_base +=
     945             :         RegisterConfiguration::Default()->num_allocatable_double_registers() *
     946             :         kDoubleSize / kSystemPointerSize;
     947             :   }
     948             : 
     949             :   // Visit the registers that contain pointers if any.
     950     1061973 :   if (safepoint_entry.HasRegisters()) {
     951           0 :     for (int i = kNumSafepointRegisters - 1; i >=0; i--) {
     952           0 :       if (safepoint_entry.HasRegisterAt(i)) {
     953             :         int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(i);
     954             :         v->VisitRootPointer(Root::kTop, nullptr,
     955           0 :                             parameters_base + reg_stack_index);
     956             :       }
     957             :     }
     958             :     // Skip the words containing the register values.
     959             :     parameters_base += kNumSafepointRegisters;
     960             :   }
     961             : 
     962             :   // We're done dealing with the register bits.
     963     1061973 :   uint8_t* safepoint_bits = safepoint_entry.bits();
     964     1061973 :   safepoint_bits += kNumSafepointRegisters >> kBitsPerByteLog2;
     965             : 
     966             :   // Visit the rest of the parameters if they are tagged.
     967     1061973 :   if (has_tagged_params) {
     968             :     v->VisitRootPointers(Root::kTop, nullptr, parameters_base,
     969     1049102 :                          parameters_limit);
     970             :   }
     971             : 
     972             :   // Visit pointer spill slots and locals.
     973     7387737 :   for (unsigned index = 0; index < stack_slots; index++) {
     974     7387737 :     int byte_index = index >> kBitsPerByteLog2;
     975     7387737 :     int bit_index = index & (kBitsPerByte - 1);
     976     7387737 :     if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) {
     977     2713062 :       v->VisitRootPointer(Root::kTop, nullptr, parameters_limit + index);
     978             :     }
     979             :   }
     980             : 
     981             :   // For the off-heap code cases, we can skip this.
     982     1061973 :   if (!code.is_null()) {
     983             :     // Visit the return address in the callee and incoming arguments.
     984     1049324 :     IteratePc(v, pc_address(), constant_pool_address(), code);
     985             :   }
     986             : 
     987             :   // If this frame has JavaScript ABI, visit the context (in stub and JS
     988             :   // frames) and the function (in JS frames). If it has WebAssembly ABI, visit
     989             :   // the instance object.
     990             :   v->VisitRootPointers(Root::kTop, nullptr, frame_header_base,
     991     1061973 :                        frame_header_limit);
     992     1061973 : }
     993             : 
     994      177014 : void StubFrame::Iterate(RootVisitor* v) const { IterateCompiledFrame(v); }
     995             : 
     996           0 : Code StubFrame::unchecked_code() const {
     997           0 :   return isolate()->FindCodeObject(pc());
     998             : }
     999             : 
    1000             : 
    1001     6526593 : Address StubFrame::GetCallerStackPointer() const {
    1002     6526593 :   return fp() + ExitFrameConstants::kCallerSPOffset;
    1003             : }
    1004             : 
    1005             : 
    1006           0 : int StubFrame::GetNumberOfIncomingArguments() const {
    1007           0 :   return 0;
    1008             : }
    1009             : 
    1010       45604 : int StubFrame::LookupExceptionHandlerInTable(int* stack_slots) {
    1011       45604 :   Code code = LookupCode();
    1012             :   DCHECK(code->is_turbofanned());
    1013             :   DCHECK_EQ(code->kind(), Code::BUILTIN);
    1014       45604 :   HandlerTable table(code);
    1015       45604 :   int pc_offset = static_cast<int>(pc() - code->InstructionStart());
    1016       45604 :   *stack_slots = code->stack_slots();
    1017       45604 :   return table.LookupReturn(pc_offset);
    1018             : }
    1019             : 
    1020      878483 : void OptimizedFrame::Iterate(RootVisitor* v) const { IterateCompiledFrame(v); }
    1021             : 
    1022        2138 : void JavaScriptFrame::SetParameterValue(int index, Object value) const {
    1023        4276 :   Memory<Address>(GetParameterSlot(index)) = value->ptr();
    1024        2138 : }
    1025             : 
    1026     7302553 : bool JavaScriptFrame::IsConstructor() const {
    1027             :   Address fp = caller_fp();
    1028     7302553 :   if (has_adapted_arguments()) {
    1029             :     // Skip the arguments adaptor frame and look at the real caller.
    1030      724008 :     fp = Memory<Address>(fp + StandardFrameConstants::kCallerFPOffset);
    1031             :   }
    1032     7302553 :   return IsConstructFrame(fp);
    1033             : }
    1034             : 
    1035             : 
    1036           0 : bool JavaScriptFrame::HasInlinedFrames() const {
    1037             :   std::vector<SharedFunctionInfo> functions;
    1038           0 :   GetFunctions(&functions);
    1039           0 :   return functions.size() > 1;
    1040             : }
    1041             : 
    1042           0 : Code JavaScriptFrame::unchecked_code() const { return function()->code(); }
    1043             : 
    1044     5990362 : int JavaScriptFrame::GetNumberOfIncomingArguments() const {
    1045             :   DCHECK(can_access_heap_objects() &&
    1046             :          isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
    1047    11980724 :   return function()->shared()->internal_formal_parameter_count();
    1048             : }
    1049             : 
    1050       26076 : int OptimizedFrame::GetNumberOfIncomingArguments() const {
    1051       26266 :   Code code = LookupCode();
    1052       26076 :   if (code->kind() == Code::BUILTIN) {
    1053             :     return static_cast<int>(
    1054         380 :         Memory<intptr_t>(fp() + OptimizedBuiltinFrameConstants::kArgCOffset));
    1055             :   } else {
    1056       25886 :     return JavaScriptFrame::GetNumberOfIncomingArguments();
    1057             :   }
    1058             : }
    1059             : 
    1060    38485140 : Address JavaScriptFrame::GetCallerStackPointer() const {
    1061    38485140 :   return fp() + StandardFrameConstants::kCallerSPOffset;
    1062             : }
    1063             : 
    1064      101684 : void JavaScriptFrame::GetFunctions(
    1065             :     std::vector<SharedFunctionInfo>* functions) const {
    1066             :   DCHECK(functions->empty());
    1067      203368 :   functions->push_back(function()->shared());
    1068      101684 : }
    1069             : 
    1070      104844 : void JavaScriptFrame::GetFunctions(
    1071             :     std::vector<Handle<SharedFunctionInfo>>* functions) const {
    1072             :   DCHECK(functions->empty());
    1073             :   std::vector<SharedFunctionInfo> raw_functions;
    1074      104844 :   GetFunctions(&raw_functions);
    1075      314546 :   for (const auto& raw_function : raw_functions) {
    1076             :     functions->push_back(
    1077      209716 :         Handle<SharedFunctionInfo>(raw_function, function()->GetIsolate()));
    1078             :   }
    1079      104844 : }
    1080             : 
    1081      209110 : void JavaScriptFrame::Summarize(std::vector<FrameSummary>* functions) const {
    1082             :   DCHECK(functions->empty());
    1083      418220 :   Code code = LookupCode();
    1084      209110 :   int offset = static_cast<int>(pc() - code->InstructionStart());
    1085      209110 :   AbstractCode abstract_code = AbstractCode::cast(code);
    1086      209110 :   FrameSummary::JavaScriptFrameSummary summary(isolate(), receiver(),
    1087      209110 :                                                function(), abstract_code,
    1088      836440 :                                                offset, IsConstructor());
    1089      209110 :   functions->push_back(summary);
    1090      209110 : }
    1091             : 
    1092    27604918 : JSFunction JavaScriptFrame::function() const {
    1093    27604920 :   return JSFunction::cast(function_slot_object());
    1094             : }
    1095             : 
    1096      122104 : Object JavaScriptFrame::unchecked_function() const {
    1097             :   // During deoptimization of an optimized function, we may have yet to
    1098             :   // materialize some closures on the stack. The arguments marker object
    1099             :   // marks this case.
    1100             :   DCHECK(function_slot_object()->IsJSFunction() ||
    1101             :          ReadOnlyRoots(isolate()).arguments_marker() == function_slot_object());
    1102      122104 :   return function_slot_object();
    1103             : }
    1104             : 
    1105     5792133 : Object JavaScriptFrame::receiver() const { return GetParameter(-1); }
    1106             : 
    1107      582850 : Object JavaScriptFrame::context() const {
    1108             :   const int offset = StandardFrameConstants::kContextOffset;
    1109     1165700 :   Object maybe_result(Memory<Address>(fp() + offset));
    1110             :   DCHECK(!maybe_result->IsSmi());
    1111      582850 :   return maybe_result;
    1112             : }
    1113             : 
    1114           0 : Script JavaScriptFrame::script() const {
    1115           0 :   return Script::cast(function()->shared()->script());
    1116             : }
    1117             : 
    1118           0 : int JavaScriptFrame::LookupExceptionHandlerInTable(
    1119             :     int* stack_depth, HandlerTable::CatchPrediction* prediction) {
    1120             :   DCHECK_EQ(0, LookupCode()->handler_table_offset());
    1121             :   DCHECK(!LookupCode()->is_optimized_code());
    1122           0 :   return -1;
    1123             : }
    1124             : 
    1125           0 : void JavaScriptFrame::PrintFunctionAndOffset(JSFunction function,
    1126             :                                              AbstractCode code, int code_offset,
    1127             :                                              FILE* file,
    1128             :                                              bool print_line_number) {
    1129           0 :   PrintF(file, "%s", function->IsOptimized() ? "*" : "~");
    1130           0 :   function->PrintName(file);
    1131           0 :   PrintF(file, "+%d", code_offset);
    1132           0 :   if (print_line_number) {
    1133           0 :     SharedFunctionInfo shared = function->shared();
    1134           0 :     int source_pos = code->SourcePosition(code_offset);
    1135           0 :     Object maybe_script = shared->script();
    1136           0 :     if (maybe_script->IsScript()) {
    1137           0 :       Script script = Script::cast(maybe_script);
    1138           0 :       int line = script->GetLineNumber(source_pos) + 1;
    1139           0 :       Object script_name_raw = script->name();
    1140           0 :       if (script_name_raw->IsString()) {
    1141           0 :         String script_name = String::cast(script->name());
    1142             :         std::unique_ptr<char[]> c_script_name =
    1143           0 :             script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
    1144           0 :         PrintF(file, " at %s:%d", c_script_name.get(), line);
    1145             :       } else {
    1146           0 :         PrintF(file, " at <unknown>:%d", line);
    1147             :       }
    1148             :     } else {
    1149           0 :       PrintF(file, " at <unknown>:<unknown>");
    1150             :     }
    1151             :   }
    1152           0 : }
    1153             : 
    1154           0 : void JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file, bool print_args,
    1155             :                                bool print_line_number) {
    1156             :   // constructor calls
    1157             :   DisallowHeapAllocation no_allocation;
    1158           0 :   JavaScriptFrameIterator it(isolate);
    1159           0 :   while (!it.done()) {
    1160           0 :     if (it.frame()->is_java_script()) {
    1161             :       JavaScriptFrame* frame = it.frame();
    1162           0 :       if (frame->IsConstructor()) PrintF(file, "new ");
    1163           0 :       JSFunction function = frame->function();
    1164             :       int code_offset = 0;
    1165           0 :       if (frame->is_interpreted()) {
    1166             :         InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame);
    1167           0 :         code_offset = iframe->GetBytecodeOffset();
    1168             :       } else {
    1169           0 :         Code code = frame->unchecked_code();
    1170           0 :         code_offset = static_cast<int>(frame->pc() - code->InstructionStart());
    1171             :       }
    1172             :       PrintFunctionAndOffset(function, function->abstract_code(), code_offset,
    1173           0 :                              file, print_line_number);
    1174           0 :       if (print_args) {
    1175             :         // function arguments
    1176             :         // (we are intentionally only printing the actually
    1177             :         // supplied parameters, not all parameters required)
    1178           0 :         PrintF(file, "(this=");
    1179           0 :         frame->receiver()->ShortPrint(file);
    1180           0 :         const int length = frame->ComputeParametersCount();
    1181           0 :         for (int i = 0; i < length; i++) {
    1182           0 :           PrintF(file, ", ");
    1183           0 :           frame->GetParameter(i)->ShortPrint(file);
    1184             :         }
    1185           0 :         PrintF(file, ")");
    1186             :       }
    1187             :       break;
    1188             :     }
    1189           0 :     it.Advance();
    1190             :   }
    1191           0 : }
    1192             : 
    1193           0 : void JavaScriptFrame::CollectFunctionAndOffsetForICStats(JSFunction function,
    1194             :                                                          AbstractCode code,
    1195             :                                                          int code_offset) {
    1196             :   auto ic_stats = ICStats::instance();
    1197             :   ICInfo& ic_info = ic_stats->Current();
    1198           0 :   SharedFunctionInfo shared = function->shared();
    1199             : 
    1200           0 :   ic_info.function_name = ic_stats->GetOrCacheFunctionName(function);
    1201           0 :   ic_info.script_offset = code_offset;
    1202             : 
    1203           0 :   int source_pos = code->SourcePosition(code_offset);
    1204           0 :   Object maybe_script = shared->script();
    1205           0 :   if (maybe_script->IsScript()) {
    1206           0 :     Script script = Script::cast(maybe_script);
    1207           0 :     ic_info.line_num = script->GetLineNumber(source_pos) + 1;
    1208           0 :     ic_info.script_name = ic_stats->GetOrCacheScriptName(script);
    1209             :   }
    1210           0 : }
    1211             : 
    1212           0 : void JavaScriptFrame::CollectTopFrameForICStats(Isolate* isolate) {
    1213             :   // constructor calls
    1214             :   DisallowHeapAllocation no_allocation;
    1215           0 :   JavaScriptFrameIterator it(isolate);
    1216             :   ICInfo& ic_info = ICStats::instance()->Current();
    1217           0 :   while (!it.done()) {
    1218           0 :     if (it.frame()->is_java_script()) {
    1219             :       JavaScriptFrame* frame = it.frame();
    1220           0 :       if (frame->IsConstructor()) ic_info.is_constructor = true;
    1221           0 :       JSFunction function = frame->function();
    1222             :       int code_offset = 0;
    1223           0 :       if (frame->is_interpreted()) {
    1224             :         InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame);
    1225           0 :         code_offset = iframe->GetBytecodeOffset();
    1226             :       } else {
    1227           0 :         Code code = frame->unchecked_code();
    1228           0 :         code_offset = static_cast<int>(frame->pc() - code->InstructionStart());
    1229             :       }
    1230             :       CollectFunctionAndOffsetForICStats(function, function->abstract_code(),
    1231           0 :                                          code_offset);
    1232           0 :       return;
    1233             :     }
    1234           0 :     it.Advance();
    1235             :   }
    1236             : }
    1237             : 
    1238     7511960 : Object JavaScriptFrame::GetParameter(int index) const {
    1239    15023920 :   return Object(Memory<Address>(GetParameterSlot(index)));
    1240             : }
    1241             : 
    1242     7575641 : int JavaScriptFrame::ComputeParametersCount() const {
    1243     7575641 :   return GetNumberOfIncomingArguments();
    1244             : }
    1245             : 
    1246          46 : int JavaScriptBuiltinContinuationFrame::ComputeParametersCount() const {
    1247             :   // Assert that the first allocatable register is also the argument count
    1248             :   // register.
    1249             :   DCHECK_EQ(RegisterConfiguration::Default()->GetAllocatableGeneralCode(0),
    1250             :             kJavaScriptCallArgCountRegister.code());
    1251             :   Object argc_object(
    1252          92 :       Memory<Address>(fp() + BuiltinContinuationFrameConstants::kArgCOffset));
    1253          46 :   return Smi::ToInt(argc_object);
    1254             : }
    1255             : 
    1256           8 : intptr_t JavaScriptBuiltinContinuationFrame::GetSPToFPDelta() const {
    1257             :   Address height_slot =
    1258           8 :       fp() + BuiltinContinuationFrameConstants::kFrameSPtoFPDeltaAtDeoptimize;
    1259          16 :   intptr_t height = Smi::ToInt(Smi(Memory<Address>(height_slot)));
    1260           8 :   return height;
    1261             : }
    1262             : 
    1263         246 : Object JavaScriptBuiltinContinuationFrame::context() const {
    1264             :   return Object(Memory<Address>(
    1265         492 :       fp() + BuiltinContinuationFrameConstants::kBuiltinContextOffset));
    1266             : }
    1267             : 
    1268           8 : void JavaScriptBuiltinContinuationWithCatchFrame::SetException(
    1269             :     Object exception) {
    1270             :   Address exception_argument_slot =
    1271          16 :       fp() + JavaScriptFrameConstants::kLastParameterOffset +
    1272           8 :       kSystemPointerSize;  // Skip over return value slot.
    1273             : 
    1274             :   // Only allow setting exception if previous value was the hole.
    1275          24 :   CHECK_EQ(ReadOnlyRoots(isolate()).the_hole_value(),
    1276             :            Object(Memory<Address>(exception_argument_slot)));
    1277           8 :   Memory<Address>(exception_argument_slot) = exception->ptr();
    1278           8 : }
    1279             : 
    1280     7550946 : FrameSummary::JavaScriptFrameSummary::JavaScriptFrameSummary(
    1281             :     Isolate* isolate, Object receiver, JSFunction function,
    1282             :     AbstractCode abstract_code, int code_offset, bool is_constructor)
    1283             :     : FrameSummaryBase(isolate, FrameSummary::JAVA_SCRIPT),
    1284             :       receiver_(receiver, isolate),
    1285             :       function_(function, isolate),
    1286             :       abstract_code_(abstract_code, isolate),
    1287             :       code_offset_(code_offset),
    1288     7550946 :       is_constructor_(is_constructor) {
    1289             :   DCHECK(abstract_code->IsBytecodeArray() ||
    1290             :          Code::cast(abstract_code)->kind() != Code::OPTIMIZED_FUNCTION);
    1291     7550946 : }
    1292             : 
    1293      314424 : bool FrameSummary::JavaScriptFrameSummary::is_subject_to_debugging() const {
    1294      314424 :   return function()->shared()->IsSubjectToDebugging();
    1295             : }
    1296             : 
    1297     1092402 : int FrameSummary::JavaScriptFrameSummary::SourcePosition() const {
    1298     1092402 :   return abstract_code()->SourcePosition(code_offset());
    1299             : }
    1300             : 
    1301       46395 : int FrameSummary::JavaScriptFrameSummary::SourceStatementPosition() const {
    1302       46395 :   return abstract_code()->SourceStatementPosition(code_offset());
    1303             : }
    1304             : 
    1305     1447515 : Handle<Object> FrameSummary::JavaScriptFrameSummary::script() const {
    1306     4342545 :   return handle(function_->shared()->script(), isolate());
    1307             : }
    1308             : 
    1309       10534 : Handle<String> FrameSummary::JavaScriptFrameSummary::FunctionName() const {
    1310      270684 :   return JSFunction::GetDebugName(function_);
    1311             : }
    1312             : 
    1313         847 : Handle<Context> FrameSummary::JavaScriptFrameSummary::native_context() const {
    1314        2541 :   return handle(function_->context()->native_context(), isolate());
    1315             : }
    1316             : 
    1317           0 : FrameSummary::WasmFrameSummary::WasmFrameSummary(
    1318             :     Isolate* isolate, FrameSummary::Kind kind,
    1319             :     Handle<WasmInstanceObject> instance, bool at_to_number_conversion)
    1320             :     : FrameSummaryBase(isolate, kind),
    1321             :       wasm_instance_(instance),
    1322      344237 :       at_to_number_conversion_(at_to_number_conversion) {}
    1323             : 
    1324        1036 : Handle<Object> FrameSummary::WasmFrameSummary::receiver() const {
    1325        1036 :   return wasm_instance_->GetIsolate()->global_proxy();
    1326             : }
    1327             : 
    1328             : #define WASM_SUMMARY_DISPATCH(type, name)                                      \
    1329             :   type FrameSummary::WasmFrameSummary::name() const {                          \
    1330             :     DCHECK(kind() == Kind::WASM_COMPILED || kind() == Kind::WASM_INTERPRETED); \
    1331             :     return kind() == Kind::WASM_COMPILED                                       \
    1332             :                ? static_cast<const WasmCompiledFrameSummary*>(this)->name()    \
    1333             :                : static_cast<const WasmInterpretedFrameSummary*>(this)         \
    1334             :                      ->name();                                                 \
    1335             :   }
    1336             : 
    1337      175902 : WASM_SUMMARY_DISPATCH(uint32_t, function_index)
    1338      172931 : WASM_SUMMARY_DISPATCH(int, byte_offset)
    1339             : 
    1340             : #undef WASM_SUMMARY_DISPATCH
    1341             : 
    1342      341686 : int FrameSummary::WasmFrameSummary::SourcePosition() const {
    1343             :   Handle<WasmModuleObject> module_object(wasm_instance()->module_object(),
    1344      512529 :                                          isolate());
    1345             :   return WasmModuleObject::GetSourcePosition(module_object, function_index(),
    1346             :                                              byte_offset(),
    1347      512529 :                                              at_to_number_conversion());
    1348             : }
    1349             : 
    1350      171320 : Handle<Script> FrameSummary::WasmFrameSummary::script() const {
    1351      342640 :   return handle(wasm_instance()->module_object()->script(),
    1352      513960 :                 wasm_instance()->GetIsolate());
    1353             : }
    1354             : 
    1355        1036 : Handle<String> FrameSummary::WasmFrameSummary::FunctionName() const {
    1356             :   Handle<WasmModuleObject> module_object(wasm_instance()->module_object(),
    1357        4144 :                                          isolate());
    1358             :   return WasmModuleObject::GetFunctionName(isolate(), module_object,
    1359        1036 :                                            function_index());
    1360             : }
    1361             : 
    1362         165 : Handle<Context> FrameSummary::WasmFrameSummary::native_context() const {
    1363         495 :   return handle(wasm_instance()->native_context(), isolate());
    1364             : }
    1365             : 
    1366           0 : FrameSummary::WasmCompiledFrameSummary::WasmCompiledFrameSummary(
    1367             :     Isolate* isolate, Handle<WasmInstanceObject> instance, wasm::WasmCode* code,
    1368             :     int code_offset, bool at_to_number_conversion)
    1369             :     : WasmFrameSummary(isolate, WASM_COMPILED, instance,
    1370             :                        at_to_number_conversion),
    1371             :       code_(code),
    1372           0 :       code_offset_(code_offset) {}
    1373             : 
    1374      344296 : uint32_t FrameSummary::WasmCompiledFrameSummary::function_index() const {
    1375      344296 :   return code()->index();
    1376             : }
    1377             : 
    1378      171787 : int FrameSummary::WasmCompiledFrameSummary::GetWasmSourcePosition(
    1379             :     const wasm::WasmCode* code, int offset) {
    1380             :   int position = 0;
    1381             :   // Subtract one because the current PC is one instruction after the call site.
    1382             :   offset--;
    1383      572071 :   for (SourcePositionTableIterator iterator(code->source_positions());
    1384      400284 :        !iterator.done() && iterator.code_offset() <= offset;
    1385      228497 :        iterator.Advance()) {
    1386      228497 :     position = iterator.source_position().ScriptOffset();
    1387             :   }
    1388      171787 :   return position;
    1389             : }
    1390             : 
    1391      169925 : int FrameSummary::WasmCompiledFrameSummary::byte_offset() const {
    1392      169925 :   return GetWasmSourcePosition(code_, code_offset());
    1393             : }
    1394             : 
    1395           0 : FrameSummary::WasmInterpretedFrameSummary::WasmInterpretedFrameSummary(
    1396             :     Isolate* isolate, Handle<WasmInstanceObject> instance,
    1397             :     uint32_t function_index, int byte_offset)
    1398             :     : WasmFrameSummary(isolate, WASM_INTERPRETED, instance, false),
    1399             :       function_index_(function_index),
    1400           0 :       byte_offset_(byte_offset) {}
    1401             : 
    1402    20244168 : FrameSummary::~FrameSummary() {
    1403             : #define FRAME_SUMMARY_DESTR(kind, type, field, desc) \
    1404             :   case kind:                                         \
    1405             :     field.~type();                                   \
    1406             :     break;
    1407    20244168 :   switch (base_.kind()) {
    1408             :     FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_DESTR)
    1409             :     default:
    1410           0 :       UNREACHABLE();
    1411             :   }
    1412             : #undef FRAME_SUMMARY_DESTR
    1413    20244168 : }
    1414             : 
    1415      914332 : FrameSummary FrameSummary::GetTop(const StandardFrame* frame) {
    1416             :   std::vector<FrameSummary> frames;
    1417      914332 :   frame->Summarize(&frames);
    1418             :   DCHECK_LT(0, frames.size());
    1419      914332 :   return frames.back();
    1420             : }
    1421             : 
    1422           0 : FrameSummary FrameSummary::GetBottom(const StandardFrame* frame) {
    1423           0 :   return Get(frame, 0);
    1424             : }
    1425             : 
    1426         234 : FrameSummary FrameSummary::GetSingle(const StandardFrame* frame) {
    1427             :   std::vector<FrameSummary> frames;
    1428         234 :   frame->Summarize(&frames);
    1429             :   DCHECK_EQ(1, frames.size());
    1430         234 :   return frames.front();
    1431             : }
    1432             : 
    1433      510495 : FrameSummary FrameSummary::Get(const StandardFrame* frame, int index) {
    1434             :   DCHECK_LE(0, index);
    1435             :   std::vector<FrameSummary> frames;
    1436      510495 :   frame->Summarize(&frames);
    1437             :   DCHECK_GT(frames.size(), index);
    1438     1020990 :   return frames[index];
    1439             : }
    1440             : 
    1441             : #define FRAME_SUMMARY_DISPATCH(ret, name)        \
    1442             :   ret FrameSummary::name() const {               \
    1443             :     switch (base_.kind()) {                      \
    1444             :       case JAVA_SCRIPT:                          \
    1445             :         return java_script_summary_.name();      \
    1446             :       case WASM_COMPILED:                        \
    1447             :         return wasm_compiled_summary_.name();    \
    1448             :       case WASM_INTERPRETED:                     \
    1449             :         return wasm_interpreted_summary_.name(); \
    1450             :       default:                                   \
    1451             :         UNREACHABLE();                           \
    1452             :         return ret{};                            \
    1453             :     }                                            \
    1454             :   }
    1455             : 
    1456      261186 : FRAME_SUMMARY_DISPATCH(Handle<Object>, receiver)
    1457      357778 : FRAME_SUMMARY_DISPATCH(int, code_offset)
    1458      261186 : FRAME_SUMMARY_DISPATCH(bool, is_constructor)
    1459      316045 : FRAME_SUMMARY_DISPATCH(bool, is_subject_to_debugging)
    1460     1607716 : FRAME_SUMMARY_DISPATCH(Handle<Object>, script)
    1461     1252711 : FRAME_SUMMARY_DISPATCH(int, SourcePosition)
    1462       46395 : FRAME_SUMMARY_DISPATCH(int, SourceStatementPosition)
    1463      261292 : FRAME_SUMMARY_DISPATCH(Handle<String>, FunctionName)
    1464        1012 : FRAME_SUMMARY_DISPATCH(Handle<Context>, native_context)
    1465             : 
    1466             : #undef FRAME_SUMMARY_DISPATCH
    1467             : 
    1468     1510420 : void OptimizedFrame::Summarize(std::vector<FrameSummary>* frames) const {
    1469             :   DCHECK(frames->empty());
    1470             :   DCHECK(is_optimized());
    1471             : 
    1472             :   // Delegate to JS frame in absence of turbofan deoptimization.
    1473             :   // TODO(turbofan): Revisit once we support deoptimization across the board.
    1474     5912875 :   Code code = LookupCode();
    1475     1510420 :   if (code->kind() == Code::BUILTIN) {
    1476     1719484 :     return JavaScriptFrame::Summarize(frames);
    1477             :   }
    1478             : 
    1479     1301356 :   int deopt_index = Safepoint::kNoDeoptimizationIndex;
    1480     1301356 :   DeoptimizationData const data = GetDeoptimizationData(&deopt_index);
    1481     1301356 :   if (deopt_index == Safepoint::kNoDeoptimizationIndex) {
    1482           0 :     CHECK(data.is_null());
    1483           0 :     FATAL("Missing deoptimization information for OptimizedFrame::Summarize.");
    1484             :   }
    1485             : 
    1486             :   // Prepare iteration over translation. Note that the below iteration might
    1487             :   // materialize objects without storing them back to the Isolate, this will
    1488             :   // lead to objects being re-materialized again for each summary.
    1489     1301356 :   TranslatedState translated(this);
    1490     1301356 :   translated.Prepare(fp());
    1491             : 
    1492             :   // We create the summary in reverse order because the frames
    1493             :   // in the deoptimization translation are ordered bottom-to-top.
    1494     1301356 :   bool is_constructor = IsConstructor();
    1495     4330155 :   for (auto it = translated.begin(); it != translated.end(); it++) {
    1496     3633992 :     if (it->kind() == TranslatedFrame::kInterpretedFunction ||
    1497     1905124 :         it->kind() == TranslatedFrame::kJavaScriptBuiltinContinuation ||
    1498             :         it->kind() ==
    1499             :             TranslatedFrame::kJavaScriptBuiltinContinuationWithCatch) {
    1500             :       Handle<SharedFunctionInfo> shared_info = it->shared_info();
    1501             : 
    1502             :       // The translation commands are ordered and the function is always
    1503             :       // at the first position, and the receiver is next.
    1504             :       TranslatedFrame::iterator translated_values = it->begin();
    1505             : 
    1506             :       // Get or materialize the correct function in the optimized frame.
    1507             :       Handle<JSFunction> function =
    1508     1549812 :           Handle<JSFunction>::cast(translated_values->GetValue());
    1509     1549812 :       translated_values++;
    1510             : 
    1511             :       // Get or materialize the correct receiver in the optimized frame.
    1512     1549812 :       Handle<Object> receiver = translated_values->GetValue();
    1513     1549812 :       translated_values++;
    1514             : 
    1515             :       // Determine the underlying code object and the position within it from
    1516             :       // the translation corresponding to the frame type in question.
    1517             :       Handle<AbstractCode> abstract_code;
    1518             :       unsigned code_offset;
    1519     1549812 :       if (it->kind() == TranslatedFrame::kJavaScriptBuiltinContinuation ||
    1520             :           it->kind() ==
    1521             :               TranslatedFrame::kJavaScriptBuiltinContinuationWithCatch) {
    1522             :         code_offset = 0;
    1523             :         abstract_code =
    1524             :             handle(AbstractCode::cast(isolate()->builtins()->builtin(
    1525        2950 :                        Builtins::GetBuiltinFromBailoutId(it->node_id()))),
    1526        2950 :                    isolate());
    1527             :       } else {
    1528             :         DCHECK_EQ(it->kind(), TranslatedFrame::kInterpretedFunction);
    1529     1548337 :         code_offset = it->node_id().ToInt();  // Points to current bytecode.
    1530     3096674 :         abstract_code = handle(shared_info->abstract_code(), isolate());
    1531             :       }
    1532             : 
    1533             :       // Append full summary of the encountered JS frame.
    1534             :       FrameSummary::JavaScriptFrameSummary summary(isolate(), *receiver,
    1535             :                                                    *function, *abstract_code,
    1536     3099624 :                                                    code_offset, is_constructor);
    1537     1549812 :       frames->push_back(summary);
    1538             :       is_constructor = false;
    1539      177631 :     } else if (it->kind() == TranslatedFrame::kConstructStub) {
    1540             :       // The next encountered JS frame will be marked as a constructor call.
    1541             :       DCHECK(!is_constructor);
    1542             :       is_constructor = true;
    1543             :     }
    1544             :   }
    1545             : }
    1546             : 
    1547             : 
    1548     3441022 : int OptimizedFrame::LookupExceptionHandlerInTable(
    1549             :     int* stack_slots, HandlerTable::CatchPrediction* prediction) {
    1550             :   // We cannot perform exception prediction on optimized code. Instead, we need
    1551             :   // to use FrameSummary to find the corresponding code offset in unoptimized
    1552             :   // code to perform prediction there.
    1553             :   DCHECK_NULL(prediction);
    1554     3441022 :   Code code = LookupCode();
    1555     3441022 :   HandlerTable table(code);
    1556     3441022 :   int pc_offset = static_cast<int>(pc() - code->InstructionStart());
    1557     6834785 :   if (stack_slots) *stack_slots = code->stack_slots();
    1558             : 
    1559             :   // When the return pc has been replaced by a trampoline there won't be
    1560             :   // a handler for this trampoline. Thus we need to use the return pc that
    1561             :   // _used to be_ on the stack to get the right ExceptionHandler.
    1562     6230961 :   if (code->kind() == Code::OPTIMIZED_FUNCTION &&
    1563     2789939 :       code->marked_for_deoptimization()) {
    1564        5449 :     SafepointTable safepoints(code);
    1565        5449 :     pc_offset = safepoints.find_return_pc(pc_offset);
    1566             :   }
    1567     3441022 :   return table.LookupReturn(pc_offset);
    1568             : }
    1569             : 
    1570     2639637 : DeoptimizationData OptimizedFrame::GetDeoptimizationData(
    1571             :     int* deopt_index) const {
    1572             :   DCHECK(is_optimized());
    1573             : 
    1574     2639637 :   JSFunction opt_function = function();
    1575     2639637 :   Code code = opt_function->code();
    1576             : 
    1577             :   // The code object may have been replaced by lazy deoptimization. Fall
    1578             :   // back to a slow search in this case to find the original optimized
    1579             :   // code object.
    1580     2809124 :   if (!code->contains(pc())) {
    1581      169487 :     code = isolate()->heap()->GcSafeFindCodeForInnerPointer(pc());
    1582             :   }
    1583             :   DCHECK(!code.is_null());
    1584             :   DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
    1585             : 
    1586     2639637 :   SafepointEntry safepoint_entry = code->GetSafepointEntry(pc());
    1587     2639637 :   if (safepoint_entry.has_deoptimization_index()) {
    1588     2639637 :     *deopt_index = safepoint_entry.deoptimization_index();
    1589     5279274 :     return DeoptimizationData::cast(code->deoptimization_data());
    1590             :   }
    1591           0 :   *deopt_index = Safepoint::kNoDeoptimizationIndex;
    1592           0 :   return DeoptimizationData();
    1593             : }
    1594             : 
    1595      209156 : Object OptimizedFrame::receiver() const {
    1596      418305 :   Code code = LookupCode();
    1597      209156 :   if (code->kind() == Code::BUILTIN) {
    1598      209149 :     Address argc_ptr = fp() + OptimizedBuiltinFrameConstants::kArgCOffset;
    1599      209149 :     intptr_t argc = *reinterpret_cast<intptr_t*>(argc_ptr);
    1600             :     intptr_t args_size =
    1601      209149 :         (StandardFrameConstants::kFixedSlotCountAboveFp + argc) *
    1602      209149 :         kSystemPointerSize;
    1603      209149 :     Address receiver_ptr = fp() + args_size;
    1604             :     return *FullObjectSlot(receiver_ptr);
    1605             :   } else {
    1606           7 :     return JavaScriptFrame::receiver();
    1607             :   }
    1608             : }
    1609             : 
    1610       23831 : void OptimizedFrame::GetFunctions(
    1611             :     std::vector<SharedFunctionInfo>* functions) const {
    1612             :   DCHECK(functions->empty());
    1613             :   DCHECK(is_optimized());
    1614             : 
    1615             :   // Delegate to JS frame in absence of turbofan deoptimization.
    1616             :   // TODO(turbofan): Revisit once we support deoptimization across the board.
    1617       23831 :   Code code = LookupCode();
    1618       23831 :   if (code->kind() == Code::BUILTIN) {
    1619       38218 :     return JavaScriptFrame::GetFunctions(functions);
    1620             :   }
    1621             : 
    1622             :   DisallowHeapAllocation no_gc;
    1623        9444 :   int deopt_index = Safepoint::kNoDeoptimizationIndex;
    1624        9444 :   DeoptimizationData const data = GetDeoptimizationData(&deopt_index);
    1625             :   DCHECK(!data.is_null());
    1626             :   DCHECK_NE(Safepoint::kNoDeoptimizationIndex, deopt_index);
    1627        9444 :   FixedArray const literal_array = data->LiteralArray();
    1628             : 
    1629             :   TranslationIterator it(data->TranslationByteArray(),
    1630       18888 :                          data->TranslationIndex(deopt_index)->value());
    1631        9444 :   Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
    1632             :   DCHECK_EQ(Translation::BEGIN, opcode);
    1633        9444 :   it.Next();  // Skip frame count.
    1634        9444 :   int jsframe_count = it.Next();
    1635        9444 :   it.Next();  // Skip update feedback count.
    1636             : 
    1637             :   // We insert the frames in reverse order because the frames
    1638             :   // in the deoptimization translation are ordered bottom-to-top.
    1639       28689 :   while (jsframe_count != 0) {
    1640        9801 :     opcode = static_cast<Translation::Opcode>(it.Next());
    1641       19602 :     if (opcode == Translation::INTERPRETED_FRAME ||
    1642       10102 :         opcode == Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME ||
    1643             :         opcode ==
    1644             :             Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME) {
    1645        9500 :       it.Next();  // Skip bailout id.
    1646        9500 :       jsframe_count--;
    1647             : 
    1648             :       // The second operand of the frame points to the function.
    1649        9500 :       Object shared = literal_array->get(it.Next());
    1650       19000 :       functions->push_back(SharedFunctionInfo::cast(shared));
    1651             : 
    1652             :       // Skip over remaining operands to advance to the next opcode.
    1653        9500 :       it.Skip(Translation::NumberOfOperandsFor(opcode) - 2);
    1654             :     } else {
    1655             :       // Skip over operands to advance to the next opcode.
    1656         301 :       it.Skip(Translation::NumberOfOperandsFor(opcode));
    1657             :     }
    1658             :   }
    1659             : }
    1660             : 
    1661     8730459 : int OptimizedFrame::StackSlotOffsetRelativeToFp(int slot_index) {
    1662     8730459 :   return StandardFrameConstants::kCallerSPOffset -
    1663     8730459 :          ((slot_index + 1) * kSystemPointerSize);
    1664             : }
    1665             : 
    1666           0 : Object OptimizedFrame::StackSlotAt(int index) const {
    1667           0 :   return Object(Memory<Address>(fp() + StackSlotOffsetRelativeToFp(index)));
    1668             : }
    1669             : 
    1670        3041 : int InterpretedFrame::position() const {
    1671        6082 :   AbstractCode code = AbstractCode::cast(GetBytecodeArray());
    1672        3041 :   int code_offset = GetBytecodeOffset();
    1673        3041 :   return code->SourcePosition(code_offset);
    1674             : }
    1675             : 
    1676    12676728 : int InterpretedFrame::LookupExceptionHandlerInTable(
    1677             :     int* context_register, HandlerTable::CatchPrediction* prediction) {
    1678    12676728 :   HandlerTable table(GetBytecodeArray());
    1679    12676728 :   return table.LookupRange(GetBytecodeOffset(), context_register, prediction);
    1680             : }
    1681             : 
    1682    18556140 : int InterpretedFrame::GetBytecodeOffset() const {
    1683             :   const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
    1684             :   DCHECK_EQ(InterpreterFrameConstants::kBytecodeOffsetFromFp,
    1685             :             InterpreterFrameConstants::kExpressionsOffset -
    1686             :                 index * kSystemPointerSize);
    1687    37112280 :   int raw_offset = Smi::ToInt(GetExpression(index));
    1688    18556140 :   return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
    1689             : }
    1690             : 
    1691           0 : int InterpretedFrame::GetBytecodeOffset(Address fp) {
    1692             :   const int offset = InterpreterFrameConstants::kExpressionsOffset;
    1693             :   const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
    1694             :   DCHECK_EQ(InterpreterFrameConstants::kBytecodeOffsetFromFp,
    1695             :             InterpreterFrameConstants::kExpressionsOffset -
    1696             :                 index * kSystemPointerSize);
    1697           0 :   Address expression_offset = fp + offset - index * kSystemPointerSize;
    1698           0 :   int raw_offset = Smi::ToInt(Object(Memory<Address>(expression_offset)));
    1699           0 :   return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
    1700             : }
    1701             : 
    1702      809964 : void InterpretedFrame::PatchBytecodeOffset(int new_offset) {
    1703             :   const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
    1704             :   DCHECK_EQ(InterpreterFrameConstants::kBytecodeOffsetFromFp,
    1705             :             InterpreterFrameConstants::kExpressionsOffset -
    1706             :                 index * kSystemPointerSize);
    1707      809964 :   int raw_offset = new_offset + BytecodeArray::kHeaderSize - kHeapObjectTag;
    1708      809964 :   SetExpression(index, Smi::FromInt(raw_offset));
    1709      809964 : }
    1710             : 
    1711    30959222 : BytecodeArray InterpretedFrame::GetBytecodeArray() const {
    1712             :   const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
    1713             :   DCHECK_EQ(InterpreterFrameConstants::kBytecodeArrayFromFp,
    1714             :             InterpreterFrameConstants::kExpressionsOffset -
    1715             :                 index * kSystemPointerSize);
    1716    61918444 :   return BytecodeArray::cast(GetExpression(index));
    1717             : }
    1718             : 
    1719        8875 : void InterpretedFrame::PatchBytecodeArray(BytecodeArray bytecode_array) {
    1720             :   const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
    1721             :   DCHECK_EQ(InterpreterFrameConstants::kBytecodeArrayFromFp,
    1722             :             InterpreterFrameConstants::kExpressionsOffset -
    1723             :                 index * kSystemPointerSize);
    1724        8875 :   SetExpression(index, bytecode_array);
    1725        8875 : }
    1726             : 
    1727      812573 : Object InterpretedFrame::ReadInterpreterRegister(int register_index) const {
    1728             :   const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
    1729             :   DCHECK_EQ(InterpreterFrameConstants::kRegisterFileFromFp,
    1730             :             InterpreterFrameConstants::kExpressionsOffset -
    1731             :                 index * kSystemPointerSize);
    1732     1625146 :   return GetExpression(index + register_index);
    1733             : }
    1734             : 
    1735           0 : void InterpretedFrame::WriteInterpreterRegister(int register_index,
    1736             :                                                 Object value) {
    1737             :   const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
    1738             :   DCHECK_EQ(InterpreterFrameConstants::kRegisterFileFromFp,
    1739             :             InterpreterFrameConstants::kExpressionsOffset -
    1740             :                 index * kSystemPointerSize);
    1741           0 :   return SetExpression(index + register_index, value);
    1742             : }
    1743             : 
    1744     5792024 : void InterpretedFrame::Summarize(std::vector<FrameSummary>* functions) const {
    1745             :   DCHECK(functions->empty());
    1746    11584048 :   AbstractCode abstract_code = AbstractCode::cast(GetBytecodeArray());
    1747             :   FrameSummary::JavaScriptFrameSummary summary(
    1748    11584048 :       isolate(), receiver(), function(), abstract_code, GetBytecodeOffset(),
    1749    17376072 :       IsConstructor());
    1750     5792024 :   functions->push_back(summary);
    1751     5792024 : }
    1752             : 
    1753     1585089 : int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const {
    1754     3170178 :   return Smi::ToInt(GetExpression(0));
    1755             : }
    1756             : 
    1757           0 : Code ArgumentsAdaptorFrame::unchecked_code() const {
    1758             :   return isolate()->builtins()->builtin(
    1759           0 :       Builtins::kArgumentsAdaptorTrampoline);
    1760             : }
    1761             : 
    1762           0 : int BuiltinFrame::GetNumberOfIncomingArguments() const {
    1763           0 :   return Smi::ToInt(GetExpression(0));
    1764             : }
    1765             : 
    1766           0 : void BuiltinFrame::PrintFrameKind(StringStream* accumulator) const {
    1767           0 :   accumulator->Add("builtin frame: ");
    1768           0 : }
    1769             : 
    1770     2549118 : Address InternalFrame::GetCallerStackPointer() const {
    1771             :   // Internal frames have no arguments. The stack pointer of the
    1772             :   // caller is at a fixed offset from the frame pointer.
    1773     2549118 :   return fp() + StandardFrameConstants::kCallerSPOffset;
    1774             : }
    1775             : 
    1776           0 : Code InternalFrame::unchecked_code() const { UNREACHABLE(); }
    1777             : 
    1778          18 : void WasmCompiledFrame::Print(StringStream* accumulator, PrintMode mode,
    1779             :                               int index) const {
    1780             :   PrintIndex(accumulator, mode, index);
    1781          18 :   accumulator->Add("WASM [");
    1782          18 :   accumulator->PrintName(script()->name());
    1783             :   Address instruction_start = isolate()
    1784             :                                   ->wasm_engine()
    1785             :                                   ->code_manager()
    1786             :                                   ->LookupCode(pc())
    1787          36 :                                   ->instruction_start();
    1788             :   Vector<const uint8_t> raw_func_name =
    1789          36 :       module_object()->GetRawFunctionName(function_index());
    1790          18 :   const int kMaxPrintedFunctionName = 64;
    1791             :   char func_name[kMaxPrintedFunctionName + 1];
    1792          54 :   int func_name_len = std::min(kMaxPrintedFunctionName, raw_func_name.length());
    1793          18 :   memcpy(func_name, raw_func_name.start(), func_name_len);
    1794          18 :   func_name[func_name_len] = '\0';
    1795          18 :   int pos = position();
    1796          36 :   const wasm::WasmModule* module = wasm_instance()->module_object()->module();
    1797          18 :   int func_index = function_index();
    1798          36 :   int func_code_offset = module->functions[func_index].code.offset();
    1799             :   accumulator->Add("], function #%u ('%s'), pc=%p (+0x%x), pos=%d (+%d)\n",
    1800             :                    func_index, func_name, reinterpret_cast<void*>(pc()),
    1801             :                    static_cast<int>(pc() - instruction_start), pos,
    1802          36 :                    pos - func_code_offset);
    1803          18 :   if (mode != OVERVIEW) accumulator->Add("\n");
    1804          18 : }
    1805             : 
    1806           0 : Code WasmCompiledFrame::unchecked_code() const {
    1807           0 :   return isolate()->FindCodeObject(pc());
    1808             : }
    1809             : 
    1810        6454 : void WasmCompiledFrame::Iterate(RootVisitor* v) const {
    1811        6454 :   IterateCompiledFrame(v);
    1812        6454 : }
    1813             : 
    1814     3005954 : Address WasmCompiledFrame::GetCallerStackPointer() const {
    1815     3005954 :   return fp() + ExitFrameConstants::kCallerSPOffset;
    1816             : }
    1817             : 
    1818          90 : wasm::WasmCode* WasmCompiledFrame::wasm_code() const {
    1819      688654 :   return isolate()->wasm_engine()->code_manager()->LookupCode(pc());
    1820             : }
    1821             : 
    1822      348576 : WasmInstanceObject WasmCompiledFrame::wasm_instance() const {
    1823             :   const int offset = WasmCompiledFrameConstants::kWasmInstanceOffset;
    1824      697152 :   Object instance(Memory<Address>(fp() + offset));
    1825      348576 :   return WasmInstanceObject::cast(instance);
    1826             : }
    1827             : 
    1828           0 : WasmModuleObject WasmCompiledFrame::module_object() const {
    1829          36 :   return wasm_instance()->module_object();
    1830             : }
    1831             : 
    1832         126 : uint32_t WasmCompiledFrame::function_index() const {
    1833         252 :   return FrameSummary::GetSingle(this).AsWasmCompiled().function_index();
    1834             : }
    1835             : 
    1836          36 : Script WasmCompiledFrame::script() const { return module_object()->script(); }
    1837             : 
    1838         108 : int WasmCompiledFrame::position() const {
    1839         108 :   return FrameSummary::GetSingle(this).SourcePosition();
    1840             : }
    1841             : 
    1842      344237 : void WasmCompiledFrame::Summarize(std::vector<FrameSummary>* functions) const {
    1843             :   DCHECK(functions->empty());
    1844             :   wasm::WasmCode* code = wasm_code();
    1845     1032711 :   int offset = static_cast<int>(pc() - code->instruction_start());
    1846      344237 :   Handle<WasmInstanceObject> instance(wasm_instance(), isolate());
    1847             :   FrameSummary::WasmCompiledFrameSummary summary(
    1848      344237 :       isolate(), instance, code, offset, at_to_number_conversion());
    1849      344237 :   functions->push_back(summary);
    1850      344237 : }
    1851             : 
    1852      344237 : bool WasmCompiledFrame::at_to_number_conversion() const {
    1853             :   // Check whether our callee is a WASM_TO_JS frame, and this frame is at the
    1854             :   // ToNumber conversion call.
    1855        5063 :   wasm::WasmCode* code =
    1856      349877 :       callee_pc() != kNullAddress
    1857        5063 :           ? isolate()->wasm_engine()->code_manager()->LookupCode(callee_pc())
    1858      349300 :           : nullptr;
    1859      349300 :   if (!code || code->kind() != wasm::WasmCode::kWasmToJsWrapper) return false;
    1860        1154 :   int offset = static_cast<int>(callee_pc() - code->instruction_start());
    1861             :   int pos = FrameSummary::WasmCompiledFrameSummary::GetWasmSourcePosition(
    1862         577 :       code, offset);
    1863             :   DCHECK(pos == 0 || pos == 1);
    1864             :   // The imported call has position 0, ToNumber has position 1.
    1865         577 :   return !!pos;
    1866             : }
    1867             : 
    1868     2825564 : int WasmCompiledFrame::LookupExceptionHandlerInTable(int* stack_slots) {
    1869             :   DCHECK_NOT_NULL(stack_slots);
    1870     5652712 :   wasm::WasmCode* code =
    1871     5651128 :       isolate()->wasm_engine()->code_manager()->LookupCode(pc());
    1872     5651128 :   if (!code->IsAnonymous() && code->handler_table_offset() > 0) {
    1873         792 :     HandlerTable table(code->instruction_start(), code->handler_table_offset());
    1874        1584 :     int pc_offset = static_cast<int>(pc() - code->instruction_start());
    1875         792 :     *stack_slots = static_cast<int>(code->stack_slots());
    1876         792 :     return table.LookupReturn(pc_offset);
    1877             :   }
    1878             :   return -1;
    1879             : }
    1880             : 
    1881          22 : void WasmInterpreterEntryFrame::Iterate(RootVisitor* v) const {
    1882          22 :   IterateCompiledFrame(v);
    1883          22 : }
    1884             : 
    1885           0 : void WasmInterpreterEntryFrame::Print(StringStream* accumulator, PrintMode mode,
    1886             :                                       int index) const {
    1887             :   PrintIndex(accumulator, mode, index);
    1888           0 :   accumulator->Add("WASM INTERPRETER ENTRY [");
    1889           0 :   Script script = this->script();
    1890           0 :   accumulator->PrintName(script->name());
    1891           0 :   accumulator->Add("]");
    1892           0 :   if (mode != OVERVIEW) accumulator->Add("\n");
    1893           0 : }
    1894             : 
    1895        3872 : void WasmInterpreterEntryFrame::Summarize(
    1896             :     std::vector<FrameSummary>* functions) const {
    1897      768638 :   Handle<WasmInstanceObject> instance(wasm_instance(), isolate());
    1898             :   std::vector<std::pair<uint32_t, int>> interpreted_stack =
    1899        3872 :       instance->debug_info()->GetInterpretedStack(fp());
    1900             : 
    1901      768638 :   for (auto& e : interpreted_stack) {
    1902             :     FrameSummary::WasmInterpretedFrameSummary summary(isolate(), instance,
    1903      760894 :                                                       e.first, e.second);
    1904      760894 :     functions->push_back(summary);
    1905             :   }
    1906        3872 : }
    1907             : 
    1908           0 : Code WasmInterpreterEntryFrame::unchecked_code() const { UNREACHABLE(); }
    1909             : 
    1910       48167 : WasmInstanceObject WasmInterpreterEntryFrame::wasm_instance() const {
    1911             :   const int offset = WasmCompiledFrameConstants::kWasmInstanceOffset;
    1912       96334 :   Object instance(Memory<Address>(fp() + offset));
    1913       48167 :   return WasmInstanceObject::cast(instance);
    1914             : }
    1915             : 
    1916        3777 : WasmDebugInfo WasmInterpreterEntryFrame::debug_info() const {
    1917        3777 :   return wasm_instance()->debug_info();
    1918             : }
    1919             : 
    1920           0 : WasmModuleObject WasmInterpreterEntryFrame::module_object() const {
    1921           0 :   return wasm_instance()->module_object();
    1922             : }
    1923             : 
    1924           0 : Script WasmInterpreterEntryFrame::script() const {
    1925           0 :   return module_object()->script();
    1926             : }
    1927             : 
    1928           0 : int WasmInterpreterEntryFrame::position() const {
    1929           0 :   return FrameSummary::GetBottom(this).AsWasmInterpreted().SourcePosition();
    1930             : }
    1931             : 
    1932         575 : Object WasmInterpreterEntryFrame::context() const {
    1933         575 :   return wasm_instance()->native_context();
    1934             : }
    1935             : 
    1936        5234 : Address WasmInterpreterEntryFrame::GetCallerStackPointer() const {
    1937        5234 :   return fp() + ExitFrameConstants::kCallerSPOffset;
    1938             : }
    1939             : 
    1940           0 : Code WasmCompileLazyFrame::unchecked_code() const { return Code(); }
    1941             : 
    1942           0 : WasmInstanceObject WasmCompileLazyFrame::wasm_instance() const {
    1943           0 :   return WasmInstanceObject::cast(*wasm_instance_slot());
    1944             : }
    1945             : 
    1946           0 : FullObjectSlot WasmCompileLazyFrame::wasm_instance_slot() const {
    1947             :   const int offset = WasmCompileLazyFrameConstants::kWasmInstanceOffset;
    1948           0 :   return FullObjectSlot(&Memory<Address>(fp() + offset));
    1949             : }
    1950             : 
    1951           0 : void WasmCompileLazyFrame::Iterate(RootVisitor* v) const {
    1952             :   const int header_size = WasmCompileLazyFrameConstants::kFixedFrameSizeFromFp;
    1953           0 :   FullObjectSlot base(&Memory<Address>(sp()));
    1954           0 :   FullObjectSlot limit(&Memory<Address>(fp() - header_size));
    1955           0 :   v->VisitRootPointers(Root::kTop, nullptr, base, limit);
    1956           0 :   v->VisitRootPointer(Root::kTop, nullptr, wasm_instance_slot());
    1957           0 : }
    1958             : 
    1959           0 : Address WasmCompileLazyFrame::GetCallerStackPointer() const {
    1960           0 :   return fp() + WasmCompileLazyFrameConstants::kCallerSPOffset;
    1961             : }
    1962             : 
    1963             : namespace {
    1964             : 
    1965          27 : void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo shared,
    1966             :                          Code code) {
    1967          54 :   if (FLAG_max_stack_trace_source_length != 0 && !code.is_null()) {
    1968          27 :     std::ostringstream os;
    1969          27 :     os << "--------- s o u r c e   c o d e ---------\n"
    1970          81 :        << SourceCodeOf(shared, FLAG_max_stack_trace_source_length)
    1971          27 :        << "\n-----------------------------------------\n";
    1972          54 :     accumulator->Add(os.str().c_str());
    1973             :   }
    1974          27 : }
    1975             : 
    1976             : }  // namespace
    1977             : 
    1978             : 
    1979          63 : void JavaScriptFrame::Print(StringStream* accumulator,
    1980             :                             PrintMode mode,
    1981             :                             int index) const {
    1982             :   DisallowHeapAllocation no_gc;
    1983          63 :   Object receiver = this->receiver();
    1984          63 :   JSFunction function = this->function();
    1985             : 
    1986          63 :   accumulator->PrintSecurityTokenIfChanged(function);
    1987             :   PrintIndex(accumulator, mode, index);
    1988          63 :   PrintFrameKind(accumulator);
    1989          63 :   Code code;
    1990          63 :   if (IsConstructor()) accumulator->Add("new ");
    1991          63 :   accumulator->PrintFunction(function, receiver, &code);
    1992          63 :   accumulator->Add(" [%p]", function);
    1993             : 
    1994             :   // Get scope information for nicer output, if possible. If code is nullptr, or
    1995             :   // doesn't contain scope info, scope_info will return 0 for the number of
    1996             :   // parameters, stack local variables, context local variables, stack slots,
    1997             :   // or context slots.
    1998          63 :   SharedFunctionInfo shared = function->shared();
    1999          63 :   ScopeInfo scope_info = shared->scope_info();
    2000          63 :   Object script_obj = shared->script();
    2001          63 :   if (script_obj->IsScript()) {
    2002          63 :     Script script = Script::cast(script_obj);
    2003          63 :     accumulator->Add(" [");
    2004          63 :     accumulator->PrintName(script->name());
    2005             : 
    2006         126 :     if (is_interpreted()) {
    2007             :       const InterpretedFrame* iframe =
    2008             :           reinterpret_cast<const InterpretedFrame*>(this);
    2009          56 :       BytecodeArray bytecodes = iframe->GetBytecodeArray();
    2010          56 :       int offset = iframe->GetBytecodeOffset();
    2011          56 :       int source_pos = AbstractCode::cast(bytecodes)->SourcePosition(offset);
    2012          56 :       int line = script->GetLineNumber(source_pos) + 1;
    2013             :       accumulator->Add(":%d] [bytecode=%p offset=%d]", line,
    2014          56 :                        reinterpret_cast<void*>(bytecodes.ptr()), offset);
    2015             :     } else {
    2016           7 :       int function_start_pos = shared->StartPosition();
    2017           7 :       int line = script->GetLineNumber(function_start_pos) + 1;
    2018           7 :       accumulator->Add(":~%d] [pc=%p]", line, reinterpret_cast<void*>(pc()));
    2019             :     }
    2020             :   }
    2021             : 
    2022          63 :   accumulator->Add("(this=%o", receiver);
    2023             : 
    2024             :   // Print the parameters.
    2025          63 :   int parameters_count = ComputeParametersCount();
    2026          63 :   for (int i = 0; i < parameters_count; i++) {
    2027           0 :     accumulator->Add(",");
    2028           0 :     accumulator->Add("%o", GetParameter(i));
    2029             :   }
    2030             : 
    2031          63 :   accumulator->Add(")");
    2032          63 :   if (mode == OVERVIEW) {
    2033          36 :     accumulator->Add("\n");
    2034          36 :     return;
    2035             :   }
    2036          54 :   if (is_optimized()) {
    2037           3 :     accumulator->Add(" {\n// optimized frame\n");
    2038           3 :     PrintFunctionSource(accumulator, shared, code);
    2039           3 :     accumulator->Add("}\n");
    2040           3 :     return;
    2041             :   }
    2042          24 :   accumulator->Add(" {\n");
    2043             : 
    2044             :   // Compute the number of locals and expression stack elements.
    2045          24 :   int heap_locals_count = scope_info->ContextLocalCount();
    2046          24 :   int expressions_count = ComputeExpressionsCount();
    2047             : 
    2048             :   // Try to get hold of the context of this frame.
    2049          24 :   Context context;
    2050          48 :   if (this->context()->IsContext()) {
    2051          48 :     context = Context::cast(this->context());
    2052          48 :     while (context->IsWithContext()) {
    2053           0 :       context = context->previous();
    2054             :       DCHECK(!context.is_null());
    2055             :     }
    2056             :   }
    2057             : 
    2058             :   // Print heap-allocated local variables.
    2059          24 :   if (heap_locals_count > 0) {
    2060           0 :     accumulator->Add("  // heap-allocated locals\n");
    2061             :   }
    2062           0 :   for (int i = 0; i < heap_locals_count; i++) {
    2063           0 :     accumulator->Add("  var ");
    2064           0 :     accumulator->PrintName(scope_info->ContextLocalName(i));
    2065           0 :     accumulator->Add(" = ");
    2066           0 :     if (!context.is_null()) {
    2067           0 :       int index = Context::MIN_CONTEXT_SLOTS + i;
    2068           0 :       if (index < context->length()) {
    2069           0 :         accumulator->Add("%o", context->get(index));
    2070             :       } else {
    2071             :         accumulator->Add(
    2072           0 :             "// warning: missing context slot - inconsistent frame?");
    2073             :       }
    2074             :     } else {
    2075           0 :       accumulator->Add("// warning: no context found - inconsistent frame?");
    2076             :     }
    2077           0 :     accumulator->Add("\n");
    2078             :   }
    2079             : 
    2080             :   // Print the expression stack.
    2081          24 :   if (0 < expressions_count) {
    2082          16 :     accumulator->Add("  // expression stack (top to bottom)\n");
    2083             :   }
    2084         160 :   for (int i = expressions_count - 1; i >= 0; i--) {
    2085         136 :     accumulator->Add("  [%02d] : %o\n", i, GetExpression(i));
    2086             :   }
    2087             : 
    2088          24 :   PrintFunctionSource(accumulator, shared, code);
    2089             : 
    2090          24 :   accumulator->Add("}\n\n");
    2091             : }
    2092             : 
    2093             : 
    2094          36 : void ArgumentsAdaptorFrame::Print(StringStream* accumulator,
    2095             :                                   PrintMode mode,
    2096             :                                   int index) const {
    2097          36 :   int actual = ComputeParametersCount();
    2098             :   int expected = -1;
    2099          36 :   JSFunction function = this->function();
    2100          72 :   expected = function->shared()->internal_formal_parameter_count();
    2101             : 
    2102             :   PrintIndex(accumulator, mode, index);
    2103          36 :   accumulator->Add("arguments adaptor frame: %d->%d", actual, expected);
    2104          36 :   if (mode == OVERVIEW) {
    2105          18 :     accumulator->Add("\n");
    2106          54 :     return;
    2107             :   }
    2108          18 :   accumulator->Add(" {\n");
    2109             : 
    2110             :   // Print actual arguments.
    2111          18 :   if (actual > 0) accumulator->Add("  // actual arguments\n");
    2112          18 :   for (int i = 0; i < actual; i++) {
    2113          18 :     accumulator->Add("  [%02d] : %o", i, GetParameter(i));
    2114          18 :     if (expected != -1 && i >= expected) {
    2115          18 :       accumulator->Add("  // not passed to callee");
    2116             :     }
    2117          18 :     accumulator->Add("\n");
    2118             :   }
    2119             : 
    2120          18 :   accumulator->Add("}\n\n");
    2121             : }
    2122             : 
    2123      173599 : void EntryFrame::Iterate(RootVisitor* v) const {
    2124      173599 :   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
    2125      173599 : }
    2126             : 
    2127     3178275 : void StandardFrame::IterateExpressions(RootVisitor* v) const {
    2128             :   const int offset = StandardFrameConstants::kLastObjectOffset;
    2129     6356550 :   FullObjectSlot base(&Memory<Address>(sp()));
    2130     6356550 :   FullObjectSlot limit(&Memory<Address>(fp() + offset) + 1);
    2131     3178275 :   v->VisitRootPointers(Root::kTop, nullptr, base, limit);
    2132     3178275 : }
    2133             : 
    2134     2960535 : void JavaScriptFrame::Iterate(RootVisitor* v) const {
    2135     2960535 :   IterateExpressions(v);
    2136     2960535 :   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
    2137     2960535 : }
    2138             : 
    2139      217740 : void InternalFrame::Iterate(RootVisitor* v) const {
    2140      217740 :   Code code = LookupCode();
    2141      217740 :   IteratePc(v, pc_address(), constant_pool_address(), code);
    2142             :   // Internal frames typically do not receive any arguments, hence their stack
    2143             :   // only contains tagged pointers.
    2144             :   // We are misusing the has_tagged_params flag here to tell us whether
    2145             :   // the full stack frame contains only tagged pointers or only raw values.
    2146             :   // This is used for the WasmCompileLazy builtin, where we actually pass
    2147             :   // untagged arguments and also store untagged values on the stack.
    2148      217740 :   if (code->has_tagged_params()) IterateExpressions(v);
    2149      217740 : }
    2150             : 
    2151             : // -------------------------------------------------------------------------
    2152             : 
    2153             : namespace {
    2154             : 
    2155    57600313 : uint32_t PcAddressForHashing(Isolate* isolate, Address address) {
    2156    57600313 :   if (InstructionStream::PcIsOffHeap(isolate, address)) {
    2157             :     // Ensure that we get predictable hashes for addresses in embedded code.
    2158    91876034 :     return EmbeddedData::FromBlob(isolate).AddressForHashing(address);
    2159             :   }
    2160    11662287 :   return ObjectAddressForHashing(address);
    2161             : }
    2162             : 
    2163             : }  // namespace
    2164             : 
    2165             : InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
    2166    57600313 :     InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
    2167   115200626 :   isolate_->counters()->pc_to_code()->Increment();
    2168             :   DCHECK(base::bits::IsPowerOfTwo(kInnerPointerToCodeCacheSize));
    2169             :   uint32_t hash =
    2170    57600311 :       ComputeUnseededHash(PcAddressForHashing(isolate_, inner_pointer));
    2171    57600297 :   uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
    2172    57600297 :   InnerPointerToCodeCacheEntry* entry = cache(index);
    2173    57600297 :   if (entry->inner_pointer == inner_pointer) {
    2174   113017708 :     isolate_->counters()->pc_to_code_cached()->Increment();
    2175             :     DCHECK(entry->code ==
    2176             :            isolate_->heap()->GcSafeFindCodeForInnerPointer(inner_pointer));
    2177             :   } else {
    2178             :     // Because this code may be interrupted by a profiling signal that
    2179             :     // also queries the cache, we cannot update inner_pointer before the code
    2180             :     // has been set. Otherwise, we risk trying to use a cache entry before
    2181             :     // the code has been computed.
    2182             :     entry->code =
    2183     1091443 :         isolate_->heap()->GcSafeFindCodeForInnerPointer(inner_pointer);
    2184             :     entry->safepoint_entry.Reset();
    2185     1091438 :     entry->inner_pointer = inner_pointer;
    2186             :   }
    2187    57600294 :   return entry;
    2188             : }
    2189             : }  // namespace internal
    2190      183867 : }  // namespace v8

Generated by: LCOV version 1.10