LCOV - code coverage report
Current view: top level - src - frames.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 580 836 69.4 %
Date: 2017-10-20 Functions: 119 178 66.9 %

          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/register-configuration.h"
      15             : #include "src/safepoint-table.h"
      16             : #include "src/string-stream.h"
      17             : #include "src/visitors.h"
      18             : #include "src/vm-state-inl.h"
      19             : #include "src/wasm/wasm-objects-inl.h"
      20             : 
      21             : namespace v8 {
      22             : namespace internal {
      23             : 
      24             : ReturnAddressLocationResolver StackFrame::return_address_location_resolver_ =
      25             :     nullptr;
      26             : 
      27             : // Iterator that supports traversing the stack handlers of a
      28             : // particular frame. Needs to know the top of the handler chain.
      29             : class StackHandlerIterator BASE_EMBEDDED {
      30             :  public:
      31    52900959 :   StackHandlerIterator(const StackFrame* frame, StackHandler* handler)
      32             :       : limit_(frame->fp()), handler_(handler) {
      33             :     // Make sure the handler has already been unwound to this frame.
      34             :     DCHECK(frame->sp() <= handler->address());
      35             :   }
      36             : 
      37             :   StackHandler* handler() const { return handler_; }
      38             : 
      39    54288701 :   bool done() { return handler_ == nullptr || handler_->address() > limit_; }
      40             :   void Advance() {
      41             :     DCHECK(!done());
      42             :     handler_ = handler_->next();
      43             :   }
      44             : 
      45             :  private:
      46             :   const Address limit_;
      47             :   StackHandler* handler_;
      48             : };
      49             : 
      50             : 
      51             : // -------------------------------------------------------------------------
      52             : 
      53             : 
      54             : #define INITIALIZE_SINGLETON(type, field) field##_(this),
      55    10905745 : StackFrameIteratorBase::StackFrameIteratorBase(Isolate* isolate,
      56             :                                                bool can_access_heap_objects)
      57             :     : isolate_(isolate),
      58             :       STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) frame_(nullptr),
      59             :       handler_(nullptr),
      60    21811490 :       can_access_heap_objects_(can_access_heap_objects) {}
      61             : #undef INITIALIZE_SINGLETON
      62             : 
      63    10367203 : StackFrameIterator::StackFrameIterator(Isolate* isolate)
      64    20734406 :     : StackFrameIterator(isolate, isolate->thread_local_top()) {}
      65             : 
      66      507709 : StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
      67    10874912 :     : StackFrameIteratorBase(isolate, true) {
      68    10874911 :   Reset(t);
      69      507709 : }
      70             : 
      71    52900952 : void StackFrameIterator::Advance() {
      72             :   DCHECK(!done());
      73             :   // Compute the state of the calling frame before restoring
      74             :   // callee-saved registers and unwinding handlers. This allows the
      75             :   // frame code that computes the caller state to access the top
      76             :   // handler and the value of any callee-saved register if needed.
      77    52900952 :   StackFrame::State state;
      78    52900952 :   StackFrame::Type type = frame_->GetCallerState(&state);
      79             : 
      80             :   // Unwind handlers corresponding to the current frame.
      81    52900959 :   StackHandlerIterator it(frame_, handler_);
      82    54288701 :   while (!it.done()) it.Advance();
      83    52900959 :   handler_ = it.handler();
      84             : 
      85             :   // Advance to the calling frame.
      86    52900959 :   frame_ = SingletonFor(type, &state);
      87             : 
      88             :   // When we're done iterating over the stack frames, the handler
      89             :   // chain must have been completely unwound.
      90             :   DCHECK(!done() || handler_ == nullptr);
      91    52900958 : }
      92             : 
      93             : 
      94    32624736 : void StackFrameIterator::Reset(ThreadLocalTop* top) {
      95    10874912 :   StackFrame::State state;
      96             :   StackFrame::Type type = ExitFrame::GetStateForFramePointer(
      97    10874912 :       Isolate::c_entry_fp(top), &state);
      98    10874912 :   handler_ = StackHandler::FromAddress(Isolate::handler(top));
      99    10874912 :   frame_ = SingletonFor(type, &state);
     100    10874912 : }
     101             : 
     102             : 
     103    63931278 : StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type,
     104             :                                              StackFrame::State* state) {
     105    63931278 :   StackFrame* result = SingletonFor(type);
     106             :   DCHECK((!result) == (type == StackFrame::NONE));
     107    63931273 :   if (result) result->state_ = *state;
     108    63931273 :   return result;
     109             : }
     110             : 
     111             : 
     112    64056841 : StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type) {
     113             : #define FRAME_TYPE_CASE(type, field) \
     114             :   case StackFrame::type:             \
     115             :     return &field##_;
     116             : 
     117    64056841 :   switch (type) {
     118             :     case StackFrame::NONE:
     119             :       return nullptr;
     120     1508987 :       STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
     121             :     default: break;
     122             :   }
     123             :   return nullptr;
     124             : 
     125             : #undef FRAME_TYPE_CASE
     126             : }
     127             : 
     128             : // -------------------------------------------------------------------------
     129             : 
     130     1351765 : void JavaScriptFrameIterator::Advance() {
     131     2212657 :   do {
     132     2212657 :     iterator_.Advance();
     133     2212657 :   } while (!iterator_.done() && !iterator_.frame()->is_java_script());
     134     1351765 : }
     135             : 
     136             : // -------------------------------------------------------------------------
     137             : 
     138     1767337 : StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
     139     1767337 :     : iterator_(isolate) {
     140     1767337 :   if (!done() && !IsValidFrame(iterator_.frame())) Advance();
     141     1767337 : }
     142             : 
     143      158339 : StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate,
     144             :                                                  StackFrame::Id id)
     145      158339 :     : StackTraceFrameIterator(isolate) {
     146     1561697 :   while (!done() && frame()->id() != id) Advance();
     147      158339 : }
     148             : 
     149     3062865 : void StackTraceFrameIterator::Advance() {
     150     6092418 :   do {
     151     6092418 :     iterator_.Advance();
     152     6092418 :   } while (!done() && !IsValidFrame(iterator_.frame()));
     153     3062865 : }
     154             : 
     155     7620675 : bool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) const {
     156     7620675 :   if (frame->is_java_script()) {
     157             :     JavaScriptFrame* jsFrame = static_cast<JavaScriptFrame*>(frame);
     158     6449812 :     if (!jsFrame->function()->IsJSFunction()) return false;
     159     6449812 :     return jsFrame->function()->shared()->IsSubjectToDebugging();
     160             :   }
     161             :   // apart from javascript, only wasm is valid
     162     4395769 :   return frame->is_wasm();
     163             : }
     164             : 
     165             : // -------------------------------------------------------------------------
     166             : 
     167             : namespace {
     168             : 
     169      127412 : bool IsInterpreterFramePc(Isolate* isolate, Address pc) {
     170             :   Code* interpreter_entry_trampoline =
     171             :       isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline);
     172             :   Code* interpreter_bytecode_advance =
     173             :       isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeAdvance);
     174             :   Code* interpreter_bytecode_dispatch =
     175             :       isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
     176             : 
     177      252149 :   return (pc >= interpreter_entry_trampoline->instruction_start() &&
     178       12347 :           pc < interpreter_entry_trampoline->instruction_end()) ||
     179       22019 :          (pc >= interpreter_bytecode_advance->instruction_start() &&
     180      139759 :           pc < interpreter_bytecode_advance->instruction_end()) ||
     181       22019 :          (pc >= interpreter_bytecode_dispatch->instruction_start() &&
     182      127412 :           pc < interpreter_bytecode_dispatch->instruction_end());
     183             : }
     184             : 
     185             : DISABLE_ASAN Address ReadMemoryAt(Address address) {
     186       12523 :   return Memory::Address_at(address);
     187             : }
     188             : 
     189             : }  // namespace
     190             : 
     191       30835 : SafeStackFrameIterator::SafeStackFrameIterator(
     192       30835 :     Isolate* isolate,
     193       26017 :     Address fp, Address sp, Address js_entry_sp)
     194             :     : StackFrameIteratorBase(isolate, false),
     195             :       low_bound_(sp),
     196             :       high_bound_(js_entry_sp),
     197             :       top_frame_type_(StackFrame::NONE),
     198       61670 :       external_callback_scope_(isolate->external_callback_scope()) {
     199       30835 :   StackFrame::State state;
     200             :   StackFrame::Type type;
     201       48176 :   ThreadLocalTop* top = isolate->thread_local_top();
     202             :   bool advance_frame = true;
     203       30835 :   if (IsValidTop(top)) {
     204       17341 :     type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
     205       17341 :     top_frame_type_ = type;
     206       13494 :   } else if (IsValidStackAddress(fp)) {
     207             :     DCHECK_NOT_NULL(fp);
     208       12523 :     state.fp = fp;
     209       12523 :     state.sp = sp;
     210             :     state.pc_address = StackFrame::ResolveReturnAddressLocation(
     211       25046 :         reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
     212             : 
     213             :     // If the top of stack is a return address to the interpreter trampoline,
     214             :     // then we are likely in a bytecode handler with elided frame. In that
     215             :     // case, set the PC properly and make sure we do not drop the frame.
     216       12523 :     if (IsValidStackAddress(sp)) {
     217             :       MSAN_MEMORY_IS_INITIALIZED(sp, kPointerSize);
     218             :       Address tos = ReadMemoryAt(reinterpret_cast<Address>(sp));
     219       12523 :       if (IsInterpreterFramePc(isolate, tos)) {
     220        7327 :         state.pc_address = reinterpret_cast<Address*>(sp);
     221             :         advance_frame = false;
     222             :       }
     223             :     }
     224             : 
     225             :     // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset,
     226             :     // we check only that kMarkerOffset is within the stack bounds and do
     227             :     // compile time check that kContextOffset slot is pushed on the stack before
     228             :     // kMarkerOffset.
     229             :     STATIC_ASSERT(StandardFrameConstants::kFunctionOffset <
     230             :                   StandardFrameConstants::kContextOffset);
     231       12523 :     Address frame_marker = fp + StandardFrameConstants::kFunctionOffset;
     232       12523 :     if (IsValidStackAddress(frame_marker)) {
     233       12266 :       type = StackFrame::ComputeType(this, &state);
     234       12266 :       top_frame_type_ = type;
     235             :       // We only keep the top frame if we believe it to be interpreted frame.
     236       12266 :       if (type != StackFrame::INTERPRETED) {
     237             :         advance_frame = true;
     238             :       }
     239             :     } else {
     240             :       // Mark the frame as OPTIMIZED if we cannot determine its type.
     241             :       // We chose OPTIMIZED rather than INTERPRETED because it's closer to
     242             :       // the original value of StackFrame::JAVA_SCRIPT here, in that JAVA_SCRIPT
     243             :       // referred to full-codegen frames (now removed from the tree), and
     244             :       // OPTIMIZED refers to turbofan frames, both of which are generated
     245             :       // code. INTERPRETED frames refer to bytecode.
     246             :       // The frame anyways will be skipped.
     247             :       type = StackFrame::OPTIMIZED;
     248             :       // Top frame is incomplete so we cannot reliably determine its type.
     249         257 :       top_frame_type_ = StackFrame::NONE;
     250             :     }
     251             :   } else {
     252         971 :     return;
     253             :   }
     254       29864 :   frame_ = SingletonFor(type, &state);
     255       29864 :   if (advance_frame && frame_) Advance();
     256             : }
     257             : 
     258             : 
     259       48176 : bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const {
     260             :   Address c_entry_fp = Isolate::c_entry_fp(top);
     261       30835 :   if (!IsValidExitFrame(c_entry_fp)) return false;
     262             :   // There should be at least one JS_ENTRY stack handler.
     263             :   Address handler = Isolate::handler(top);
     264       17341 :   if (handler == nullptr) return false;
     265             :   // Check that there are no js frames on top of the native frames.
     266       17341 :   return c_entry_fp < handler;
     267             : }
     268             : 
     269             : 
     270      155423 : void SafeStackFrameIterator::AdvanceOneFrame() {
     271             :   DCHECK(!done());
     272      155423 :   StackFrame* last_frame = frame_;
     273             :   Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
     274             :   // Before advancing to the next stack frame, perform pointer validity tests.
     275      155423 :   if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) {
     276       29858 :     frame_ = nullptr;
     277       59716 :     return;
     278             :   }
     279             : 
     280             :   // Advance to the previous frame.
     281      125565 :   StackFrame::State state;
     282      376695 :   StackFrame::Type type = frame_->GetCallerState(&state);
     283      125565 :   frame_ = SingletonFor(type, &state);
     284      125565 :   if (!frame_) return;
     285             : 
     286             :   // Check that we have actually moved to the previous frame in the stack.
     287      251130 :   if (frame_->sp() < last_sp || frame_->fp() < last_fp) {
     288           0 :     frame_ = nullptr;
     289             :   }
     290             : }
     291             : 
     292             : 
     293      155423 : bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const {
     294      310846 :   return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
     295             : }
     296             : 
     297             : 
     298      310912 : bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
     299      155423 :   StackFrame::State state;
     300      280922 :   if (frame->is_entry() || frame->is_construct_entry()) {
     301             :     // See EntryFrame::GetCallerState. It computes the caller FP address
     302             :     // and calls ExitFrame::GetStateForFramePointer on it. We need to be
     303             :     // sure that caller FP address is valid.
     304             :     Address caller_fp = Memory::Address_at(
     305       29924 :         frame->fp() + EntryFrameConstants::kCallerFPOffset);
     306       29924 :     if (!IsValidExitFrame(caller_fp)) return false;
     307      125499 :   } else if (frame->is_arguments_adaptor()) {
     308             :     // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that
     309             :     // the number of arguments is stored on stack as Smi. We need to check
     310             :     // that it really an Smi.
     311             :     Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)->
     312          16 :         GetExpression(0);
     313          16 :     if (!number_of_args->IsSmi()) {
     314             :       return false;
     315             :     }
     316             :   }
     317      125565 :   frame->ComputeCallerState(&state);
     318      502260 :   return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) &&
     319      251130 :          SingletonFor(frame->GetCallerState(&state)) != nullptr;
     320             : }
     321             : 
     322             : 
     323       60759 : bool SafeStackFrameIterator::IsValidExitFrame(Address fp) const {
     324       60759 :   if (!IsValidStackAddress(fp)) return false;
     325             :   Address sp = ExitFrame::ComputeStackPointer(fp);
     326       17416 :   if (!IsValidStackAddress(sp)) return false;
     327             :   StackFrame::State state;
     328             :   ExitFrame::FillState(fp, sp, &state);
     329             :   MSAN_MEMORY_IS_INITIALIZED(state.pc_address, sizeof(state.pc_address));
     330       17407 :   return *state.pc_address != nullptr;
     331             : }
     332             : 
     333             : 
     334       83642 : void SafeStackFrameIterator::Advance() {
     335             :   while (true) {
     336      155423 :     AdvanceOneFrame();
     337      155423 :     if (done()) break;
     338             :     ExternalCallbackScope* last_callback_scope = nullptr;
     339      159781 :     while (external_callback_scope_ != nullptr &&
     340       17230 :            external_callback_scope_->scope_address() < frame_->fp()) {
     341             :       // As long as the setup of a frame is not atomic, we may happen to be
     342             :       // in an interval where an ExternalCallbackScope is already created,
     343             :       // but the frame is not yet entered. So we are actually observing
     344             :       // the previous frame.
     345             :       // Skip all the ExternalCallbackScope's that are below the current fp.
     346             :       last_callback_scope = external_callback_scope_;
     347       16986 :       external_callback_scope_ = external_callback_scope_->previous();
     348             :     }
     349      125565 :     if (frame_->is_java_script()) break;
     350      215475 :     if (frame_->is_exit() || frame_->is_builtin_exit()) {
     351             :       // Some of the EXIT frames may have ExternalCallbackScope allocated on
     352             :       // top of them. In that case the scope corresponds to the first EXIT
     353             :       // frame beneath it. There may be other EXIT frames on top of the
     354             :       // ExternalCallbackScope, just skip them as we cannot collect any useful
     355             :       // information about them.
     356          66 :       if (last_callback_scope) {
     357             :         frame_->state_.pc_address =
     358         132 :             last_callback_scope->callback_entrypoint_address();
     359             :       }
     360             :       break;
     361             :     }
     362             :   }
     363       83642 : }
     364             : 
     365             : 
     366             : // -------------------------------------------------------------------------
     367             : 
     368             : namespace {
     369    63282657 : Code* GetContainingCode(Isolate* isolate, Address pc) {
     370    63282657 :   return isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code;
     371             : }
     372             : }  // namespace
     373             : 
     374    16455506 : Code* StackFrame::LookupCode() const {
     375             :   Code* result = GetContainingCode(isolate(), pc());
     376             :   DCHECK_GE(pc(), result->instruction_start());
     377             :   DCHECK_LT(pc(), result->instruction_end());
     378     4769472 :   return result;
     379             : }
     380             : 
     381             : #ifdef DEBUG
     382             : static bool GcSafeCodeContains(HeapObject* object, Address addr);
     383             : #endif
     384             : 
     385           0 : void StackFrame::IteratePc(RootVisitor* v, Address* pc_address,
     386             :                            Address* constant_pool_address, Code* holder) {
     387     2863636 :   Address pc = *pc_address;
     388             :   DCHECK(GcSafeCodeContains(holder, pc));
     389     2863636 :   unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start());
     390     2863636 :   Object* code = holder;
     391     2863636 :   v->VisitRootPointer(Root::kTop, &code);
     392     5727272 :   if (code == holder) return;
     393             :   holder = reinterpret_cast<Code*>(code);
     394           0 :   pc = holder->instruction_start() + pc_offset;
     395           0 :   *pc_address = pc;
     396             :   if (FLAG_enable_embedded_constant_pool && constant_pool_address) {
     397             :     *constant_pool_address = holder->constant_pool();
     398             :   }
     399             : }
     400             : 
     401             : 
     402           0 : void StackFrame::SetReturnAddressLocationResolver(
     403             :     ReturnAddressLocationResolver resolver) {
     404             :   DCHECK_NULL(return_address_location_resolver_);
     405           0 :   return_address_location_resolver_ = resolver;
     406           0 : }
     407             : 
     408   103404591 : StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
     409             :                                          State* state) {
     410             :   DCHECK_NOT_NULL(state->fp);
     411             : 
     412             :   MSAN_MEMORY_IS_INITIALIZED(
     413             :       state->fp + CommonFrameConstants::kContextOrFrameTypeOffset,
     414             :       kPointerSize);
     415             :   intptr_t marker = Memory::intptr_at(
     416    51776483 :       state->fp + CommonFrameConstants::kContextOrFrameTypeOffset);
     417    51776483 :   if (!iterator->can_access_heap_objects_) {
     418             :     // TODO(titzer): "can_access_heap_objects" is kind of bogus. It really
     419             :     // means that we are being called from the profiler, which can interrupt
     420             :     // the VM with a signal at any arbitrary instruction, with essentially
     421             :     // anything on the stack. So basically none of these checks are 100%
     422             :     // reliable.
     423             :     MSAN_MEMORY_IS_INITIALIZED(
     424             :         state->fp + StandardFrameConstants::kFunctionOffset, kPointerSize);
     425             :     Object* maybe_function =
     426      263264 :         Memory::Object_at(state->fp + StandardFrameConstants::kFunctionOffset);
     427      263264 :     if (!StackFrame::IsTypeMarker(marker)) {
     428      114889 :       if (maybe_function->IsSmi()) {
     429             :         return NONE;
     430      114889 :       } else if (IsInterpreterFramePc(iterator->isolate(),
     431      114889 :                                       *(state->pc_address))) {
     432             :         return INTERPRETED;
     433             :       } else {
     434        7149 :         return OPTIMIZED;
     435             :       }
     436             :     }
     437             :   } else {
     438             :     // Look up the code object to figure out the type of the stack frame.
     439             :     Code* code_obj =
     440    51513219 :         GetContainingCode(iterator->isolate(), *(state->pc_address));
     441    51513220 :     if (code_obj != nullptr) {
     442    51513220 :       switch (code_obj->kind()) {
     443             :         case Code::BUILTIN:
     444    33483069 :           if (StackFrame::IsTypeMarker(marker)) break;
     445    29076636 :           if (code_obj->is_interpreter_trampoline_builtin()) {
     446             :             return INTERPRETED;
     447             :           }
     448      621931 :           if (code_obj->is_turbofanned()) {
     449             :             // TODO(bmeurer): We treat frames for BUILTIN Code objects as
     450             :             // OptimizedFrame for now (all the builtins with JavaScript
     451             :             // linkage are actually generated with TurboFan currently, so
     452             :             // this is sound).
     453             :             return OPTIMIZED;
     454             :           }
     455          28 :           return BUILTIN;
     456             :         case Code::OPTIMIZED_FUNCTION:
     457             :           return OPTIMIZED;
     458             :         case Code::WASM_FUNCTION:
     459     2900909 :           return WASM_COMPILED;
     460             :         case Code::WASM_TO_JS_FUNCTION:
     461        7303 :           return WASM_TO_JS;
     462             :         case Code::JS_TO_WASM_FUNCTION:
     463       94745 :           return JS_TO_WASM;
     464             :         case Code::WASM_INTERPRETER_ENTRY:
     465       49145 :           return WASM_INTERPRETER_ENTRY;
     466             :         case Code::C_WASM_ENTRY:
     467          80 :           return C_WASM_ENTRY;
     468             :         default:
     469             :           // All other types should have an explicit marker
     470             :           break;
     471             :       }
     472             :     } else {
     473             :       return NONE;
     474             :     }
     475             :   }
     476             : 
     477             :   DCHECK(StackFrame::IsTypeMarker(marker));
     478             :   StackFrame::Type candidate = StackFrame::MarkerToType(marker);
     479    13726535 :   switch (candidate) {
     480             :     case ENTRY:
     481             :     case CONSTRUCT_ENTRY:
     482             :     case EXIT:
     483             :     case BUILTIN_CONTINUATION:
     484             :     case JAVA_SCRIPT_BUILTIN_CONTINUATION:
     485             :     case BUILTIN_EXIT:
     486             :     case STUB:
     487             :     case INTERNAL:
     488             :     case CONSTRUCT:
     489             :     case ARGUMENTS_ADAPTOR:
     490             :     case WASM_TO_JS:
     491             :     case WASM_COMPILED:
     492             :       return candidate;
     493             :     case JS_TO_WASM:
     494             :     case OPTIMIZED:
     495             :     case INTERPRETED:
     496             :     default:
     497             :       // Unoptimized and optimized JavaScript frames, including
     498             :       // interpreted frames, should never have a StackFrame::Type
     499             :       // marker. If we find one, we're likely being called from the
     500             :       // profiler in a bogus stack frame.
     501             :       return NONE;
     502             :   }
     503             : }
     504             : 
     505             : 
     506             : #ifdef DEBUG
     507             : bool StackFrame::can_access_heap_objects() const {
     508             :   return iterator_->can_access_heap_objects_;
     509             : }
     510             : #endif
     511             : 
     512             : 
     513    51764217 : StackFrame::Type StackFrame::GetCallerState(State* state) const {
     514    51764217 :   ComputeCallerState(state);
     515    51764214 :   return ComputeType(iterator_, state);
     516             : }
     517             : 
     518             : 
     519           0 : Address StackFrame::UnpaddedFP() const {
     520           0 :   return fp();
     521             : }
     522             : 
     523             : 
     524           0 : Code* EntryFrame::unchecked_code() const {
     525           0 :   return isolate()->heap()->js_entry_code();
     526             : }
     527             : 
     528             : 
     529          66 : void EntryFrame::ComputeCallerState(State* state) const {
     530          66 :   GetCallerState(state);
     531          66 : }
     532             : 
     533             : 
     534     1387940 : StackFrame::Type EntryFrame::GetCallerState(State* state) const {
     535             :   const int offset = EntryFrameConstants::kCallerFPOffset;
     536     1387940 :   Address fp = Memory::Address_at(this->fp() + offset);
     537     1387940 :   return ExitFrame::GetStateForFramePointer(fp, state);
     538             : }
     539             : 
     540           0 : Code* ConstructEntryFrame::unchecked_code() const {
     541           0 :   return isolate()->heap()->js_construct_entry_code();
     542             : }
     543             : 
     544             : 
     545           0 : Object*& ExitFrame::code_slot() const {
     546             :   const int offset = ExitFrameConstants::kCodeOffset;
     547      119488 :   return Memory::Object_at(fp() + offset);
     548             : }
     549             : 
     550           0 : Code* ExitFrame::unchecked_code() const {
     551           0 :   return reinterpret_cast<Code*>(code_slot());
     552             : }
     553             : 
     554             : 
     555    10701167 : void ExitFrame::ComputeCallerState(State* state) const {
     556             :   // Set up the caller state.
     557    32103497 :   state->sp = caller_sp();
     558    10701165 :   state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);
     559             :   state->pc_address = ResolveReturnAddressLocation(
     560    21402330 :       reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
     561    10701165 :   state->callee_pc_address = nullptr;
     562             :   if (FLAG_enable_embedded_constant_pool) {
     563             :     state->constant_pool_address = reinterpret_cast<Address*>(
     564             :         fp() + ExitFrameConstants::kConstantPoolOffset);
     565             :   }
     566    10701165 : }
     567             : 
     568             : 
     569      119488 : void ExitFrame::Iterate(RootVisitor* v) const {
     570             :   // The arguments are traversed as part of the expression stack of
     571             :   // the calling frame.
     572      119488 :   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
     573      238976 :   v->VisitRootPointer(Root::kTop, &code_slot());
     574      119488 : }
     575             : 
     576             : 
     577    10702242 : Address ExitFrame::GetCallerStackPointer() const {
     578    10702242 :   return fp() + ExitFrameConstants::kCallerSPOffset;
     579             : }
     580             : 
     581             : 
     582    12280192 : StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
     583    12280192 :   if (fp == 0) return NONE;
     584             :   Address sp = ComputeStackPointer(fp);
     585             :   FillState(fp, sp, state);
     586             :   DCHECK_NOT_NULL(*state->pc_address);
     587             : 
     588    10666571 :   return ComputeFrameType(fp);
     589             : }
     590             : 
     591           0 : StackFrame::Type ExitFrame::ComputeFrameType(Address fp) {
     592             :   // Distinguish between between regular and builtin exit frames.
     593             :   // Default to EXIT in all hairy cases (e.g., when called from profiler).
     594             :   const int offset = ExitFrameConstants::kFrameTypeOffset;
     595    10666571 :   Object* marker = Memory::Object_at(fp + offset);
     596             : 
     597    10666571 :   if (!marker->IsSmi()) {
     598             :     return EXIT;
     599             :   }
     600             : 
     601             :   intptr_t marker_int = bit_cast<intptr_t>(marker);
     602             : 
     603    10666571 :   StackFrame::Type frame_type = static_cast<StackFrame::Type>(marker_int >> 1);
     604    10666571 :   if (frame_type == EXIT || frame_type == BUILTIN_EXIT) {
     605           0 :     return frame_type;
     606             :   }
     607             : 
     608             :   return EXIT;
     609             : }
     610             : 
     611           0 : Address ExitFrame::ComputeStackPointer(Address fp) {
     612             :   MSAN_MEMORY_IS_INITIALIZED(fp + ExitFrameConstants::kSPOffset, kPointerSize);
     613    10683987 :   return Memory::Address_at(fp + ExitFrameConstants::kSPOffset);
     614             : }
     615             : 
     616           0 : void ExitFrame::FillState(Address fp, Address sp, State* state) {
     617    10666571 :   state->sp = sp;
     618    10666571 :   state->fp = fp;
     619             :   state->pc_address = ResolveReturnAddressLocation(
     620    21350549 :       reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize));
     621    10666571 :   state->callee_pc_address = nullptr;
     622             :   // The constant pool recorded in the exit frame is not associated
     623             :   // with the pc in this state (the return address into a C entry
     624             :   // stub).  ComputeCallerState will retrieve the constant pool
     625             :   // together with the associated caller pc.
     626    10666571 :   state->constant_pool_address = nullptr;
     627           0 : }
     628             : 
     629       68416 : JSFunction* BuiltinExitFrame::function() const {
     630       68416 :   return JSFunction::cast(target_slot_object());
     631             : }
     632             : 
     633       74870 : Object* BuiltinExitFrame::receiver() const { return receiver_slot_object(); }
     634             : 
     635       37445 : bool BuiltinExitFrame::IsConstructor() const {
     636       74890 :   return !new_target_slot_object()->IsUndefined(isolate());
     637             : }
     638             : 
     639           0 : Object* BuiltinExitFrame::GetParameter(int i) const {
     640             :   DCHECK(i >= 0 && i < ComputeParametersCount());
     641             :   int offset =
     642          10 :       BuiltinExitFrameConstants::kFirstArgumentOffset + i * kPointerSize;
     643          10 :   return Memory::Object_at(fp() + offset);
     644             : }
     645             : 
     646           0 : int BuiltinExitFrame::ComputeParametersCount() const {
     647             :   Object* argc_slot = argc_slot_object();
     648             :   DCHECK(argc_slot->IsSmi());
     649             :   // Argc also counts the receiver, target, new target, and argc itself as args,
     650             :   // therefore the real argument count is argc - 4.
     651          10 :   int argc = Smi::ToInt(argc_slot) - 4;
     652             :   DCHECK_GE(argc, 0);
     653           0 :   return argc;
     654             : }
     655             : 
     656             : namespace {
     657             : void PrintIndex(StringStream* accumulator, StackFrame::PrintMode mode,
     658             :                 int index) {
     659          20 :   accumulator->Add((mode == StackFrame::OVERVIEW) ? "%5d: " : "[%d]: ", index);
     660             : }
     661             : }  // namespace
     662             : 
     663          10 : void BuiltinExitFrame::Print(StringStream* accumulator, PrintMode mode,
     664             :                              int index) const {
     665             :   DisallowHeapAllocation no_gc;
     666             :   Object* receiver = this->receiver();
     667             :   JSFunction* function = this->function();
     668             : 
     669          10 :   accumulator->PrintSecurityTokenIfChanged(function);
     670             :   PrintIndex(accumulator, mode, index);
     671          10 :   accumulator->Add("builtin exit frame: ");
     672          10 :   Code* code = nullptr;
     673          10 :   if (IsConstructor()) accumulator->Add("new ");
     674          10 :   accumulator->PrintFunction(function, receiver, &code);
     675             : 
     676          10 :   accumulator->Add("(this=%o", receiver);
     677             : 
     678             :   // Print the parameters.
     679             :   int parameters_count = ComputeParametersCount();
     680          20 :   for (int i = 0; i < parameters_count; i++) {
     681          10 :     accumulator->Add(",%o", GetParameter(i));
     682             :   }
     683             : 
     684          10 :   accumulator->Add(")\n\n");
     685          10 : }
     686             : 
     687     1782647 : Address StandardFrame::GetExpressionAddress(int n) const {
     688             :   const int offset = StandardFrameConstants::kExpressionsOffset;
     689     1782647 :   return fp() + offset - n * kPointerSize;
     690             : }
     691             : 
     692    39310785 : Address InterpretedFrame::GetExpressionAddress(int n) const {
     693             :   const int offset = InterpreterFrameConstants::kExpressionsOffset;
     694    39310785 :   return fp() + offset - n * kPointerSize;
     695             : }
     696             : 
     697           0 : Script* StandardFrame::script() const {
     698             :   // This should only be called on frames which override this method.
     699             :   DCHECK(false);
     700           0 :   return nullptr;
     701             : }
     702             : 
     703           0 : Object* StandardFrame::receiver() const {
     704           0 :   return isolate()->heap()->undefined_value();
     705             : }
     706             : 
     707         222 : Object* StandardFrame::context() const {
     708         222 :   return isolate()->heap()->undefined_value();
     709             : }
     710             : 
     711           0 : int StandardFrame::position() const {
     712             :   AbstractCode* code = AbstractCode::cast(LookupCode());
     713           0 :   int code_offset = static_cast<int>(pc() - code->instruction_start());
     714           0 :   return code->SourcePosition(code_offset);
     715             : }
     716             : 
     717           0 : int StandardFrame::ComputeExpressionsCount() const {
     718           0 :   Address base = GetExpressionAddress(0);
     719           0 :   Address limit = sp() - kPointerSize;
     720             :   DCHECK(base >= limit);  // stack grows downwards
     721             :   // Include register-allocated locals in number of expressions.
     722           0 :   return static_cast<int>((base - limit) / kPointerSize);
     723             : }
     724             : 
     725           0 : Object* StandardFrame::GetParameter(int index) const {
     726             :   // StandardFrame does not define any parameters.
     727           0 :   UNREACHABLE();
     728             : }
     729             : 
     730           0 : int StandardFrame::ComputeParametersCount() const { return 0; }
     731             : 
     732    41188557 : void StandardFrame::ComputeCallerState(State* state) const {
     733   205942785 :   state->sp = caller_sp();
     734    41188557 :   state->fp = caller_fp();
     735             :   state->pc_address = ResolveReturnAddressLocation(
     736    82377114 :       reinterpret_cast<Address*>(ComputePCAddress(fp())));
     737    41188557 :   state->callee_pc_address = pc_address();
     738             :   state->constant_pool_address =
     739    41188557 :       reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp()));
     740    41188557 : }
     741             : 
     742             : 
     743           0 : bool StandardFrame::IsConstructor() const { return false; }
     744             : 
     745           0 : void StandardFrame::Summarize(std::vector<FrameSummary>* functions) const {
     746             :   // This should only be called on frames which override this method.
     747           0 :   UNREACHABLE();
     748             : }
     749             : 
     750      604927 : void StandardFrame::IterateCompiledFrame(RootVisitor* v) const {
     751             :   // Make sure that we're not doing "safe" stack frame iteration. We cannot
     752             :   // possibly find pointers in optimized frames in that state.
     753             :   DCHECK(can_access_heap_objects());
     754             : 
     755             :   // Find the code and compute the safepoint information.
     756     2419708 :   Address inner_pointer = pc();
     757             :   InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry =
     758      604927 :       isolate()->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer);
     759      604927 :   if (!entry->safepoint_entry.is_valid()) {
     760       42420 :     entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer);
     761             :     DCHECK(entry->safepoint_entry.is_valid());
     762             :   } else {
     763             :     DCHECK(entry->safepoint_entry.Equals(
     764             :         entry->code->GetSafepointEntry(inner_pointer)));
     765             :   }
     766             : 
     767      604927 :   Code* code = entry->code;
     768      604927 :   SafepointEntry safepoint_entry = entry->safepoint_entry;
     769             :   unsigned stack_slots = code->stack_slots();
     770      604927 :   unsigned slot_space = stack_slots * kPointerSize;
     771             : 
     772             :   // Determine the fixed header and spill slot area size.
     773             :   int frame_header_size = StandardFrameConstants::kFixedFrameSizeFromFp;
     774             :   intptr_t marker =
     775      604927 :       Memory::intptr_at(fp() + CommonFrameConstants::kContextOrFrameTypeOffset);
     776      604927 :   if (StackFrame::IsTypeMarker(marker)) {
     777             :     StackFrame::Type candidate = StackFrame::MarkerToType(marker);
     778       79124 :     switch (candidate) {
     779             :       case ENTRY:
     780             :       case CONSTRUCT_ENTRY:
     781             :       case EXIT:
     782             :       case BUILTIN_CONTINUATION:
     783             :       case JAVA_SCRIPT_BUILTIN_CONTINUATION:
     784             :       case BUILTIN_EXIT:
     785             :       case ARGUMENTS_ADAPTOR:
     786             :       case STUB:
     787             :       case INTERNAL:
     788             :       case CONSTRUCT:
     789             :       case JS_TO_WASM:
     790             :       case WASM_TO_JS:
     791             :       case WASM_COMPILED:
     792             :       case WASM_INTERPRETER_ENTRY:
     793             :       case C_WASM_ENTRY:
     794             :         frame_header_size = TypedFrameConstants::kFixedFrameSizeFromFp;
     795       79124 :         break;
     796             :       case OPTIMIZED:
     797             :       case INTERPRETED:
     798             :       case BUILTIN:
     799             :         // These frame types have a context, but they are actually stored
     800             :         // in the place on the stack that one finds the frame type.
     801           0 :         UNREACHABLE();
     802             :         break;
     803             :       case NONE:
     804             :       case NUMBER_OF_TYPES:
     805             :       case MANUAL:
     806           0 :         UNREACHABLE();
     807             :         break;
     808             :     }
     809             :   }
     810             :   slot_space -=
     811      604927 :       (frame_header_size + StandardFrameConstants::kFixedFrameSizeAboveFp);
     812             : 
     813      604927 :   Object** frame_header_base = &Memory::Object_at(fp() - frame_header_size);
     814             :   Object** frame_header_limit =
     815             :       &Memory::Object_at(fp() - StandardFrameConstants::kCPSlotSize);
     816             :   Object** parameters_base = &Memory::Object_at(sp());
     817      604927 :   Object** parameters_limit = frame_header_base - slot_space / kPointerSize;
     818             : 
     819             :   // Visit the parameters that may be on top of the saved registers.
     820     1209854 :   if (safepoint_entry.argument_count() > 0) {
     821             :     v->VisitRootPointers(Root::kTop, parameters_base,
     822           0 :                          parameters_base + safepoint_entry.argument_count());
     823           0 :     parameters_base += safepoint_entry.argument_count();
     824             :   }
     825             : 
     826             :   // Skip saved double registers.
     827     1209854 :   if (safepoint_entry.has_doubles()) {
     828             :     // Number of doubles not known at snapshot time.
     829             :     DCHECK(!isolate()->serializer_enabled());
     830           0 :     parameters_base +=
     831             :         RegisterConfiguration::Default()->num_allocatable_double_registers() *
     832           0 :         kDoubleSize / kPointerSize;
     833             :   }
     834             : 
     835             :   // Visit the registers that contain pointers if any.
     836      604927 :   if (safepoint_entry.HasRegisters()) {
     837           0 :     for (int i = kNumSafepointRegisters - 1; i >=0; i--) {
     838           0 :       if (safepoint_entry.HasRegisterAt(i)) {
     839             :         int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(i);
     840           0 :         v->VisitRootPointer(Root::kTop, parameters_base + reg_stack_index);
     841             :       }
     842             :     }
     843             :     // Skip the words containing the register values.
     844           0 :     parameters_base += kNumSafepointRegisters;
     845             :   }
     846             : 
     847             :   // We're done dealing with the register bits.
     848      604927 :   uint8_t* safepoint_bits = safepoint_entry.bits();
     849      604927 :   safepoint_bits += kNumSafepointRegisters >> kBitsPerByteLog2;
     850             : 
     851             :   // Visit the rest of the parameters if they are tagged.
     852      604927 :   if (code->has_tagged_params()) {
     853      592087 :     v->VisitRootPointers(Root::kTop, parameters_base, parameters_limit);
     854             :   }
     855             : 
     856             :   // Visit pointer spill slots and locals.
     857     3641487 :   for (unsigned index = 0; index < stack_slots; index++) {
     858     3641487 :     int byte_index = index >> kBitsPerByteLog2;
     859     3641487 :     int bit_index = index & (kBitsPerByte - 1);
     860     3641487 :     if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) {
     861      295484 :       v->VisitRootPointer(Root::kTop, parameters_limit + index);
     862             :     }
     863             :   }
     864             : 
     865             :   // Visit the return address in the callee and incoming arguments.
     866             :   IteratePc(v, pc_address(), constant_pool_address(), code);
     867             : 
     868     1808324 :   if (!is_wasm() && !is_wasm_to_js()) {
     869             :     // If this frame has JavaScript ABI, visit the context (in stub and JS
     870             :     // frames) and the function (in JS frames).
     871      592192 :     v->VisitRootPointers(Root::kTop, frame_header_base, frame_header_limit);
     872             :   }
     873      604927 : }
     874             : 
     875       79053 : void StubFrame::Iterate(RootVisitor* v) const { IterateCompiledFrame(v); }
     876             : 
     877           0 : Code* StubFrame::unchecked_code() const {
     878           0 :   return isolate()->FindCodeObject(pc());
     879             : }
     880             : 
     881             : 
     882     8105952 : Address StubFrame::GetCallerStackPointer() const {
     883     8105952 :   return fp() + ExitFrameConstants::kCallerSPOffset;
     884             : }
     885             : 
     886             : 
     887           0 : int StubFrame::GetNumberOfIncomingArguments() const {
     888           0 :   return 0;
     889             : }
     890             : 
     891          55 : int StubFrame::LookupExceptionHandlerInTable(int* stack_slots) {
     892             :   Code* code = LookupCode();
     893             :   DCHECK(code->is_turbofanned());
     894             :   DCHECK_EQ(code->kind(), Code::BUILTIN);
     895             :   HandlerTable* table = HandlerTable::cast(code->handler_table());
     896          55 :   int pc_offset = static_cast<int>(pc() - code->entry());
     897          55 :   *stack_slots = code->stack_slots();
     898          55 :   return table->LookupReturn(pc_offset);
     899             : }
     900             : 
     901      519417 : void OptimizedFrame::Iterate(RootVisitor* v) const { IterateCompiledFrame(v); }
     902             : 
     903        2076 : void JavaScriptFrame::SetParameterValue(int index, Object* value) const {
     904        2076 :   Memory::Object_at(GetParameterSlot(index)) = value;
     905        2076 : }
     906             : 
     907             : 
     908     6830996 : bool JavaScriptFrame::IsConstructor() const {
     909             :   Address fp = caller_fp();
     910     6830996 :   if (has_adapted_arguments()) {
     911             :     // Skip the arguments adaptor frame and look at the real caller.
     912      701951 :     fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset);
     913             :   }
     914     6830996 :   return IsConstructFrame(fp);
     915             : }
     916             : 
     917             : 
     918           0 : bool JavaScriptFrame::HasInlinedFrames() const {
     919             :   std::vector<SharedFunctionInfo*> functions;
     920           0 :   GetFunctions(&functions);
     921           0 :   return functions.size() > 1;
     922             : }
     923             : 
     924             : 
     925           8 : int JavaScriptFrame::GetArgumentsLength() const {
     926             :   // If there is an arguments adaptor frame get the arguments length from it.
     927           8 :   if (has_adapted_arguments()) {
     928           8 :     return ArgumentsAdaptorFrame::GetLength(caller_fp());
     929             :   } else {
     930           0 :     return GetNumberOfIncomingArguments();
     931             :   }
     932             : }
     933             : 
     934             : 
     935           0 : Code* JavaScriptFrame::unchecked_code() const {
     936           0 :   return function()->code();
     937             : }
     938             : 
     939             : 
     940     5756171 : int JavaScriptFrame::GetNumberOfIncomingArguments() const {
     941             :   DCHECK(can_access_heap_objects() &&
     942             :          isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
     943             : 
     944    11512342 :   return function()->shared()->internal_formal_parameter_count();
     945             : }
     946             : 
     947             : 
     948    36774878 : Address JavaScriptFrame::GetCallerStackPointer() const {
     949    36774878 :   return fp() + StandardFrameConstants::kCallerSPOffset;
     950             : }
     951             : 
     952       46849 : void JavaScriptFrame::GetFunctions(
     953             :     std::vector<SharedFunctionInfo*>* functions) const {
     954             :   DCHECK(functions->empty());
     955      140547 :   functions->push_back(function()->shared());
     956       46849 : }
     957             : 
     958       52361 : void JavaScriptFrame::GetFunctions(
     959             :     std::vector<Handle<SharedFunctionInfo>>* functions) const {
     960             :   DCHECK(functions->empty());
     961             :   std::vector<SharedFunctionInfo*> raw_functions;
     962       52361 :   GetFunctions(&raw_functions);
     963      157097 :   for (const auto& raw_function : raw_functions) {
     964      104750 :     functions->push_back(Handle<SharedFunctionInfo>(raw_function));
     965             :   }
     966       52361 : }
     967             : 
     968      149736 : void JavaScriptFrame::Summarize(std::vector<FrameSummary>* functions) const {
     969             :   DCHECK(functions->empty());
     970      149736 :   Code* code = LookupCode();
     971      149736 :   int offset = static_cast<int>(pc() - code->instruction_start());
     972             :   AbstractCode* abstract_code = AbstractCode::cast(code);
     973      149736 :   FrameSummary::JavaScriptFrameSummary summary(isolate(), receiver(),
     974      149736 :                                                function(), abstract_code,
     975      598944 :                                                offset, IsConstructor());
     976      149736 :   functions->push_back(summary);
     977      149736 : }
     978             : 
     979    49115320 : JSFunction* JavaScriptFrame::function() const {
     980    49115320 :   return JSFunction::cast(function_slot_object());
     981             : }
     982             : 
     983     5507063 : Object* JavaScriptFrame::receiver() const { return GetParameter(-1); }
     984             : 
     985      605476 : Object* JavaScriptFrame::context() const {
     986             :   const int offset = StandardFrameConstants::kContextOffset;
     987      605476 :   Object* maybe_result = Memory::Object_at(fp() + offset);
     988             :   DCHECK(!maybe_result->IsSmi());
     989      605476 :   return maybe_result;
     990             : }
     991             : 
     992           0 : Script* JavaScriptFrame::script() const {
     993           0 :   return Script::cast(function()->shared()->script());
     994             : }
     995             : 
     996           0 : int JavaScriptFrame::LookupExceptionHandlerInTable(
     997             :     int* stack_depth, HandlerTable::CatchPrediction* prediction) {
     998             :   DCHECK_EQ(0, LookupCode()->handler_table()->length());
     999             :   DCHECK(!LookupCode()->is_optimized_code());
    1000           0 :   return -1;
    1001             : }
    1002             : 
    1003           0 : void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function,
    1004             :                                              AbstractCode* code,
    1005             :                                              int code_offset, FILE* file,
    1006             :                                              bool print_line_number) {
    1007           0 :   PrintF(file, "%s", function->IsOptimized() ? "*" : "~");
    1008           0 :   function->PrintName(file);
    1009           0 :   PrintF(file, "+%d", code_offset);
    1010           0 :   if (print_line_number) {
    1011             :     SharedFunctionInfo* shared = function->shared();
    1012           0 :     int source_pos = code->SourcePosition(code_offset);
    1013             :     Object* maybe_script = shared->script();
    1014           0 :     if (maybe_script->IsScript()) {
    1015             :       Script* script = Script::cast(maybe_script);
    1016           0 :       int line = script->GetLineNumber(source_pos) + 1;
    1017             :       Object* script_name_raw = script->name();
    1018           0 :       if (script_name_raw->IsString()) {
    1019             :         String* script_name = String::cast(script->name());
    1020             :         std::unique_ptr<char[]> c_script_name =
    1021           0 :             script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
    1022           0 :         PrintF(file, " at %s:%d", c_script_name.get(), line);
    1023             :       } else {
    1024           0 :         PrintF(file, " at <unknown>:%d", line);
    1025             :       }
    1026             :     } else {
    1027           0 :       PrintF(file, " at <unknown>:<unknown>");
    1028             :     }
    1029             :   }
    1030           0 : }
    1031             : 
    1032           0 : void JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file, bool print_args,
    1033             :                                bool print_line_number) {
    1034             :   // constructor calls
    1035             :   DisallowHeapAllocation no_allocation;
    1036           0 :   JavaScriptFrameIterator it(isolate);
    1037           0 :   while (!it.done()) {
    1038           0 :     if (it.frame()->is_java_script()) {
    1039             :       JavaScriptFrame* frame = it.frame();
    1040           0 :       if (frame->IsConstructor()) PrintF(file, "new ");
    1041           0 :       JSFunction* function = frame->function();
    1042             :       int code_offset = 0;
    1043           0 :       if (frame->is_interpreted()) {
    1044             :         InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame);
    1045             :         code_offset = iframe->GetBytecodeOffset();
    1046             :       } else {
    1047           0 :         Code* code = frame->unchecked_code();
    1048           0 :         code_offset = static_cast<int>(frame->pc() - code->instruction_start());
    1049             :       }
    1050             :       PrintFunctionAndOffset(function, function->abstract_code(), code_offset,
    1051           0 :                              file, print_line_number);
    1052           0 :       if (print_args) {
    1053             :         // function arguments
    1054             :         // (we are intentionally only printing the actually
    1055             :         // supplied parameters, not all parameters required)
    1056           0 :         PrintF(file, "(this=");
    1057           0 :         frame->receiver()->ShortPrint(file);
    1058           0 :         const int length = frame->ComputeParametersCount();
    1059           0 :         for (int i = 0; i < length; i++) {
    1060           0 :           PrintF(file, ", ");
    1061           0 :           frame->GetParameter(i)->ShortPrint(file);
    1062             :         }
    1063           0 :         PrintF(file, ")");
    1064             :       }
    1065             :       break;
    1066             :     }
    1067           0 :     it.Advance();
    1068             :   }
    1069           0 : }
    1070             : 
    1071           0 : void JavaScriptFrame::CollectFunctionAndOffsetForICStats(JSFunction* function,
    1072             :                                                          AbstractCode* code,
    1073             :                                                          int code_offset) {
    1074             :   auto ic_stats = ICStats::instance();
    1075             :   ICInfo& ic_info = ic_stats->Current();
    1076             :   SharedFunctionInfo* shared = function->shared();
    1077             : 
    1078           0 :   ic_info.function_name = ic_stats->GetOrCacheFunctionName(function);
    1079           0 :   ic_info.script_offset = code_offset;
    1080             : 
    1081           0 :   int source_pos = code->SourcePosition(code_offset);
    1082             :   Object* maybe_script = shared->script();
    1083           0 :   if (maybe_script->IsScript()) {
    1084             :     Script* script = Script::cast(maybe_script);
    1085           0 :     ic_info.line_num = script->GetLineNumber(source_pos) + 1;
    1086           0 :     ic_info.script_name = ic_stats->GetOrCacheScriptName(script);
    1087             :   }
    1088           0 : }
    1089             : 
    1090           0 : void JavaScriptFrame::CollectTopFrameForICStats(Isolate* isolate) {
    1091             :   // constructor calls
    1092             :   DisallowHeapAllocation no_allocation;
    1093           0 :   JavaScriptFrameIterator it(isolate);
    1094             :   ICInfo& ic_info = ICStats::instance()->Current();
    1095           0 :   while (!it.done()) {
    1096           0 :     if (it.frame()->is_java_script()) {
    1097             :       JavaScriptFrame* frame = it.frame();
    1098           0 :       if (frame->IsConstructor()) ic_info.is_constructor = true;
    1099           0 :       JSFunction* function = frame->function();
    1100             :       int code_offset = 0;
    1101           0 :       if (frame->is_interpreted()) {
    1102             :         InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame);
    1103             :         code_offset = iframe->GetBytecodeOffset();
    1104             :       } else {
    1105           0 :         Code* code = frame->unchecked_code();
    1106           0 :         code_offset = static_cast<int>(frame->pc() - code->instruction_start());
    1107             :       }
    1108             :       CollectFunctionAndOffsetForICStats(function, function->abstract_code(),
    1109           0 :                                          code_offset);
    1110           0 :       return;
    1111             :     }
    1112           0 :     it.Advance();
    1113             :   }
    1114             : }
    1115             : 
    1116     7433984 : Object* JavaScriptFrame::GetParameter(int index) const {
    1117     7433984 :   return Memory::Object_at(GetParameterSlot(index));
    1118             : }
    1119             : 
    1120     7538802 : int JavaScriptFrame::ComputeParametersCount() const {
    1121     7538802 :   return GetNumberOfIncomingArguments();
    1122             : }
    1123             : 
    1124          15 : int JavaScriptBuiltinContinuationFrame::ComputeParametersCount() const {
    1125             :   // Assert that the first allocatable register is also the argument count
    1126             :   // register.
    1127             :   DCHECK_EQ(RegisterConfiguration::Default()->GetAllocatableGeneralCode(0),
    1128             :             kJavaScriptCallArgCountRegister.code());
    1129             :   Object* argc_object =
    1130          15 :       Memory::Object_at(fp() + BuiltinContinuationFrameConstants::kArgCOffset);
    1131          15 :   return Smi::ToInt(argc_object);
    1132             : }
    1133             : 
    1134             : namespace {
    1135             : 
    1136     1204924 : bool IsNonDeoptimizingAsmCode(Code* code, JSFunction* function) {
    1137     2409848 :   return code->is_turbofanned() && !function->shared()->HasBytecodeArray();
    1138             : }
    1139             : 
    1140             : }  // namespace
    1141             : 
    1142     7031282 : FrameSummary::JavaScriptFrameSummary::JavaScriptFrameSummary(
    1143             :     Isolate* isolate, Object* receiver, JSFunction* function,
    1144             :     AbstractCode* abstract_code, int code_offset, bool is_constructor)
    1145             :     : FrameSummaryBase(isolate, FrameSummary::JAVA_SCRIPT),
    1146             :       receiver_(receiver, isolate),
    1147             :       function_(function, isolate),
    1148             :       abstract_code_(abstract_code, isolate),
    1149             :       code_offset_(code_offset),
    1150     7031282 :       is_constructor_(is_constructor) {
    1151             :   DCHECK(abstract_code->IsBytecodeArray() ||
    1152             :          Code::cast(abstract_code)->kind() != Code::OPTIMIZED_FUNCTION ||
    1153             :          IsNonDeoptimizingAsmCode(Code::cast(abstract_code), function));
    1154     7031282 : }
    1155             : 
    1156           0 : bool FrameSummary::JavaScriptFrameSummary::is_subject_to_debugging() const {
    1157      255044 :   return function()->shared()->IsSubjectToDebugging();
    1158             : }
    1159             : 
    1160     1027970 : int FrameSummary::JavaScriptFrameSummary::SourcePosition() const {
    1161     1027970 :   return abstract_code()->SourcePosition(code_offset());
    1162             : }
    1163             : 
    1164       42041 : int FrameSummary::JavaScriptFrameSummary::SourceStatementPosition() const {
    1165       42041 :   return abstract_code()->SourceStatementPosition(code_offset());
    1166             : }
    1167             : 
    1168     1027970 : Handle<Object> FrameSummary::JavaScriptFrameSummary::script() const {
    1169     2055940 :   return handle(function_->shared()->script(), isolate());
    1170             : }
    1171             : 
    1172       70175 : Handle<String> FrameSummary::JavaScriptFrameSummary::FunctionName() const {
    1173      263823 :   return JSFunction::GetDebugName(function_);
    1174             : }
    1175             : 
    1176       10741 : Handle<Context> FrameSummary::JavaScriptFrameSummary::native_context() const {
    1177       21482 :   return handle(function_->context()->native_context(), isolate());
    1178             : }
    1179             : 
    1180           0 : FrameSummary::WasmFrameSummary::WasmFrameSummary(
    1181             :     Isolate* isolate, FrameSummary::Kind kind,
    1182             :     Handle<WasmInstanceObject> instance, bool at_to_number_conversion)
    1183             :     : FrameSummaryBase(isolate, kind),
    1184             :       wasm_instance_(instance),
    1185       83404 :       at_to_number_conversion_(at_to_number_conversion) {}
    1186             : 
    1187         396 : Handle<Object> FrameSummary::WasmFrameSummary::receiver() const {
    1188         396 :   return wasm_instance_->GetIsolate()->global_proxy();
    1189             : }
    1190             : 
    1191             : #define WASM_SUMMARY_DISPATCH(type, name)                                      \
    1192             :   type FrameSummary::WasmFrameSummary::name() const {                          \
    1193             :     DCHECK(kind() == Kind::WASM_COMPILED || kind() == Kind::WASM_INTERPRETED); \
    1194             :     return kind() == Kind::WASM_COMPILED                                       \
    1195             :                ? static_cast<const WasmCompiledFrameSummary*>(this)->name()    \
    1196             :                : static_cast<const WasmInterpretedFrameSummary*>(this)         \
    1197             :                      ->name();                                                 \
    1198             :   }
    1199             : 
    1200       41384 : WASM_SUMMARY_DISPATCH(uint32_t, function_index)
    1201       41889 : WASM_SUMMARY_DISPATCH(int, byte_offset)
    1202             : 
    1203             : #undef WASM_SUMMARY_DISPATCH
    1204             : 
    1205       80540 : int FrameSummary::WasmFrameSummary::SourcePosition() const {
    1206             :   Handle<WasmCompiledModule> compiled_module(wasm_instance()->compiled_module(),
    1207       40270 :                                              isolate());
    1208             :   return WasmCompiledModule::GetSourcePosition(compiled_module,
    1209       40270 :                                                function_index(), byte_offset(),
    1210      120810 :                                                at_to_number_conversion());
    1211             : }
    1212             : 
    1213       40575 : Handle<Script> FrameSummary::WasmFrameSummary::script() const {
    1214       40575 :   return handle(wasm_instance()->compiled_module()->script());
    1215             : }
    1216             : 
    1217         396 : Handle<String> FrameSummary::WasmFrameSummary::FunctionName() const {
    1218             :   Handle<WasmCompiledModule> compiled_module(
    1219             :       wasm_instance()->compiled_module());
    1220             :   return WasmCompiledModule::GetFunctionName(compiled_module->GetIsolate(),
    1221         396 :                                              compiled_module, function_index());
    1222             : }
    1223             : 
    1224           0 : Handle<Context> FrameSummary::WasmFrameSummary::native_context() const {
    1225          84 :   return wasm_instance()->compiled_module()->native_context();
    1226             : }
    1227             : 
    1228           0 : FrameSummary::WasmCompiledFrameSummary::WasmCompiledFrameSummary(
    1229             :     Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> code,
    1230             :     int code_offset, bool at_to_number_conversion)
    1231             :     : WasmFrameSummary(isolate, WASM_COMPILED, instance,
    1232             :                        at_to_number_conversion),
    1233             :       code_(code),
    1234           0 :       code_offset_(code_offset) {}
    1235             : 
    1236       83377 : uint32_t FrameSummary::WasmCompiledFrameSummary::function_index() const {
    1237             :   FixedArray* deopt_data = code()->deoptimization_data();
    1238             :   DCHECK_EQ(2, deopt_data->length());
    1239             :   DCHECK(deopt_data->get(1)->IsSmi());
    1240             :   int val = Smi::ToInt(deopt_data->get(1));
    1241             :   DCHECK_LE(0, val);
    1242       83377 :   return static_cast<uint32_t>(val);
    1243             : }
    1244             : 
    1245       39369 : int FrameSummary::WasmCompiledFrameSummary::byte_offset() const {
    1246       39369 :   return AbstractCode::cast(*code())->SourcePosition(code_offset());
    1247             : }
    1248             : 
    1249           0 : FrameSummary::WasmInterpretedFrameSummary::WasmInterpretedFrameSummary(
    1250             :     Isolate* isolate, Handle<WasmInstanceObject> instance,
    1251             :     uint32_t function_index, int byte_offset)
    1252             :     : WasmFrameSummary(isolate, WASM_INTERPRETED, instance, false),
    1253             :       function_index_(function_index),
    1254           0 :       byte_offset_(byte_offset) {}
    1255             : 
    1256    19950342 : FrameSummary::~FrameSummary() {
    1257             : #define FRAME_SUMMARY_DESTR(kind, type, field, desc) \
    1258             :   case kind:                                         \
    1259             :     field.~type();                                   \
    1260             :     break;
    1261    19950342 :   switch (base_.kind()) {
    1262             :     FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_DESTR)
    1263             :     default:
    1264           0 :       UNREACHABLE();
    1265             :   }
    1266             : #undef FRAME_SUMMARY_DESTR
    1267    19950342 : }
    1268             : 
    1269      758129 : FrameSummary FrameSummary::GetTop(const StandardFrame* frame) {
    1270             :   std::vector<FrameSummary> frames;
    1271      758129 :   frames.reserve(FLAG_max_inlining_levels + 1);
    1272      758129 :   frame->Summarize(&frames);
    1273             :   DCHECK_LT(0, frames.size());
    1274      758129 :   return frames.back();
    1275             : }
    1276             : 
    1277           0 : FrameSummary FrameSummary::GetBottom(const StandardFrame* frame) {
    1278           0 :   return Get(frame, 0);
    1279             : }
    1280             : 
    1281         108 : FrameSummary FrameSummary::GetSingle(const StandardFrame* frame) {
    1282             :   std::vector<FrameSummary> frames;
    1283         108 :   frame->Summarize(&frames);
    1284             :   DCHECK_EQ(1, frames.size());
    1285         108 :   return frames.front();
    1286             : }
    1287             : 
    1288      337834 : FrameSummary FrameSummary::Get(const StandardFrame* frame, int index) {
    1289             :   DCHECK_LE(0, index);
    1290             :   std::vector<FrameSummary> frames;
    1291      337834 :   frames.reserve(FLAG_max_inlining_levels + 1);
    1292      337834 :   frame->Summarize(&frames);
    1293             :   DCHECK_GT(frames.size(), index);
    1294      675668 :   return frames[index];
    1295             : }
    1296             : 
    1297             : #define FRAME_SUMMARY_DISPATCH(ret, name)        \
    1298             :   ret FrameSummary::name() const {               \
    1299             :     switch (base_.kind()) {                      \
    1300             :       case JAVA_SCRIPT:                          \
    1301             :         return java_script_summary_.name();      \
    1302             :       case WASM_COMPILED:                        \
    1303             :         return wasm_compiled_summary_.name();    \
    1304             :       case WASM_INTERPRETED:                     \
    1305             :         return wasm_interpreted_summary_.name(); \
    1306             :       default:                                   \
    1307             :         UNREACHABLE();                           \
    1308             :         return ret{};                            \
    1309             :     }                                            \
    1310             :   }
    1311             : 
    1312      194044 : FRAME_SUMMARY_DISPATCH(Handle<Object>, receiver)
    1313      374037 : FRAME_SUMMARY_DISPATCH(int, code_offset)
    1314      194044 : FRAME_SUMMARY_DISPATCH(bool, is_constructor)
    1315      255799 : FRAME_SUMMARY_DISPATCH(bool, is_subject_to_debugging)
    1316     1058216 : FRAME_SUMMARY_DISPATCH(Handle<Object>, script)
    1317     1097555 : FRAME_SUMMARY_DISPATCH(int, SourcePosition)
    1318       42041 : FRAME_SUMMARY_DISPATCH(int, SourceStatementPosition)
    1319      194155 : FRAME_SUMMARY_DISPATCH(Handle<String>, FunctionName)
    1320       10825 : FRAME_SUMMARY_DISPATCH(Handle<Context>, native_context)
    1321             : 
    1322             : #undef FRAME_SUMMARY_DISPATCH
    1323             : 
    1324     1342962 : void OptimizedFrame::Summarize(std::vector<FrameSummary>* frames) const {
    1325             :   DCHECK(frames->empty());
    1326             :   DCHECK(is_optimized());
    1327             : 
    1328             :   // Delegate to JS frame in absence of turbofan deoptimization.
    1329             :   // TODO(turbofan): Revisit once we support deoptimization across the board.
    1330     3981069 :   Code* code = LookupCode();
    1331     2536203 :   if (code->kind() == Code::BUILTIN ||
    1332     1193241 :       IsNonDeoptimizingAsmCode(code, function())) {
    1333     1492683 :     return JavaScriptFrame::Summarize(frames);
    1334             :   }
    1335             : 
    1336     1193241 :   int deopt_index = Safepoint::kNoDeoptimizationIndex;
    1337     1193241 :   DeoptimizationData* const data = GetDeoptimizationData(&deopt_index);
    1338     1193241 :   if (deopt_index == Safepoint::kNoDeoptimizationIndex) {
    1339           0 :     CHECK_NULL(data);
    1340           0 :     FATAL("Missing deoptimization information for OptimizedFrame::Summarize.");
    1341             :   }
    1342             : 
    1343             :   // Prepare iteration over translation. Note that the below iteration might
    1344             :   // materialize objects without storing them back to the Isolate, this will
    1345             :   // lead to objects being re-materialized again for each summary.
    1346     1193241 :   TranslatedState translated(this);
    1347     1193241 :   translated.Prepare(fp());
    1348             : 
    1349             :   // We create the summary in reverse order because the frames
    1350             :   // in the deoptimization translation are ordered bottom-to-top.
    1351     1193241 :   bool is_constructor = IsConstructor();
    1352     3924144 :   for (auto it = translated.begin(); it != translated.end(); it++) {
    1353     1537662 :     if (it->kind() == TranslatedFrame::kInterpretedFunction ||
    1354             :         it->kind() == TranslatedFrame::kJavaScriptBuiltinContinuation) {
    1355             :       Handle<SharedFunctionInfo> shared_info = it->shared_info();
    1356             : 
    1357             :       // The translation commands are ordered and the function is always
    1358             :       // at the first position, and the receiver is next.
    1359             :       TranslatedFrame::iterator translated_values = it->begin();
    1360             : 
    1361             :       // Get or materialize the correct function in the optimized frame.
    1362             :       Handle<JSFunction> function =
    1363     1393537 :           Handle<JSFunction>::cast(translated_values->GetValue());
    1364             :       translated_values++;
    1365             : 
    1366             :       // Get or materialize the correct receiver in the optimized frame.
    1367     1393537 :       Handle<Object> receiver = translated_values->GetValue();
    1368             :       translated_values++;
    1369             : 
    1370             :       // Determine the underlying code object and the position within it from
    1371             :       // the translation corresponding to the frame type in question.
    1372             :       Handle<AbstractCode> abstract_code;
    1373             :       unsigned code_offset;
    1374     1393537 :       if (it->kind() == TranslatedFrame::kJavaScriptBuiltinContinuation) {
    1375             :         code_offset = 0;
    1376             :         abstract_code =
    1377             :             handle(AbstractCode::cast(isolate()->builtins()->builtin(
    1378         754 :                        Builtins::GetBuiltinFromBailoutId(it->node_id()))),
    1379             :                    isolate());
    1380             :       } else {
    1381             :         DCHECK_EQ(it->kind(), TranslatedFrame::kInterpretedFunction);
    1382     1392783 :         code_offset = it->node_id().ToInt();  // Points to current bytecode.
    1383             :         abstract_code = handle(shared_info->abstract_code(), isolate());
    1384             :       }
    1385             : 
    1386             :       // Append full summary of the encountered JS frame.
    1387             :       FrameSummary::JavaScriptFrameSummary summary(isolate(), *receiver,
    1388             :                                                    *function, *abstract_code,
    1389     2787074 :                                                    code_offset, is_constructor);
    1390     1393537 :       frames->push_back(summary);
    1391             :       is_constructor = false;
    1392      144125 :     } else if (it->kind() == TranslatedFrame::kConstructStub) {
    1393             :       // The next encountered JS frame will be marked as a constructor call.
    1394             :       DCHECK(!is_constructor);
    1395             :       is_constructor = true;
    1396             :     }
    1397             :   }
    1398             : }
    1399             : 
    1400             : 
    1401     2905719 : int OptimizedFrame::LookupExceptionHandlerInTable(
    1402             :     int* stack_slots, HandlerTable::CatchPrediction* prediction) {
    1403             :   // We cannot perform exception prediction on optimized code. Instead, we need
    1404             :   // to use FrameSummary to find the corresponding code offset in unoptimized
    1405             :   // code to perform prediction there.
    1406             :   DCHECK_NULL(prediction);
    1407             :   Code* code = LookupCode();
    1408             :   HandlerTable* table = HandlerTable::cast(code->handler_table());
    1409     2905719 :   int pc_offset = static_cast<int>(pc() - code->entry());
    1410     5756727 :   if (stack_slots) *stack_slots = code->stack_slots();
    1411             : 
    1412             :   // When the return pc has been replaced by a trampoline there won't be
    1413             :   // a handler for this trampoline. Thus we need to use the return pc that
    1414             :   // _used to be_ on the stack to get the right ExceptionHandler.
    1415     5609910 :   if (code->kind() == Code::OPTIMIZED_FUNCTION &&
    1416             :       code->marked_for_deoptimization()) {
    1417        3144 :     SafepointTable safepoints(code);
    1418        3144 :     pc_offset = safepoints.find_return_pc(pc_offset);
    1419             :   }
    1420     2905719 :   return table->LookupReturn(pc_offset);
    1421             : }
    1422             : 
    1423     2435573 : DeoptimizationData* OptimizedFrame::GetDeoptimizationData(
    1424             :     int* deopt_index) const {
    1425             :   DCHECK(is_optimized());
    1426             : 
    1427     2435573 :   JSFunction* opt_function = function();
    1428             :   Code* code = opt_function->code();
    1429             : 
    1430             :   // The code object may have been replaced by lazy deoptimization. Fall
    1431             :   // back to a slow search in this case to find the original optimized
    1432             :   // code object.
    1433     2641816 :   if (!code->contains(pc())) {
    1434             :     code = isolate()->inner_pointer_to_code_cache()->
    1435      206243 :         GcSafeFindCodeForInnerPointer(pc());
    1436             :   }
    1437             :   DCHECK_NOT_NULL(code);
    1438             :   DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
    1439             : 
    1440     2435573 :   SafepointEntry safepoint_entry = code->GetSafepointEntry(pc());
    1441     4871146 :   *deopt_index = safepoint_entry.deoptimization_index();
    1442     2435573 :   if (*deopt_index != Safepoint::kNoDeoptimizationIndex) {
    1443     2435573 :     return DeoptimizationData::cast(code->deoptimization_data());
    1444             :   }
    1445             :   return nullptr;
    1446             : }
    1447             : 
    1448      157307 : Object* OptimizedFrame::receiver() const {
    1449      149721 :   Code* code = LookupCode();
    1450      157307 :   if (code->kind() == Code::BUILTIN) {
    1451             :     Address argc_ptr = fp() + OptimizedBuiltinFrameConstants::kArgCOffset;
    1452      149721 :     intptr_t argc = *reinterpret_cast<intptr_t*>(argc_ptr);
    1453             :     intptr_t args_size =
    1454      149721 :         (StandardFrameConstants::kFixedSlotCountAboveFp + argc) * kPointerSize;
    1455      149721 :     Address receiver_ptr = fp() + args_size;
    1456      149721 :     return *reinterpret_cast<Object**>(receiver_ptr);
    1457             :   } else {
    1458       15172 :     return JavaScriptFrame::receiver();
    1459             :   }
    1460             : }
    1461             : 
    1462       13723 : void OptimizedFrame::GetFunctions(
    1463             :     std::vector<SharedFunctionInfo*>* functions) const {
    1464             :   DCHECK(functions->empty());
    1465             :   DCHECK(is_optimized());
    1466             : 
    1467             :   // Delegate to JS frame in absence of turbofan deoptimization.
    1468             :   // TODO(turbofan): Revisit once we support deoptimization across the board.
    1469             :   Code* code = LookupCode();
    1470       25406 :   if (code->kind() == Code::BUILTIN ||
    1471       11683 :       IsNonDeoptimizingAsmCode(code, function())) {
    1472       15763 :     return JavaScriptFrame::GetFunctions(functions);
    1473             :   }
    1474             : 
    1475             :   DisallowHeapAllocation no_gc;
    1476       11683 :   int deopt_index = Safepoint::kNoDeoptimizationIndex;
    1477       11683 :   DeoptimizationData* const data = GetDeoptimizationData(&deopt_index);
    1478             :   DCHECK_NOT_NULL(data);
    1479             :   DCHECK_NE(Safepoint::kNoDeoptimizationIndex, deopt_index);
    1480             :   FixedArray* const literal_array = data->LiteralArray();
    1481             : 
    1482             :   TranslationIterator it(data->TranslationByteArray(),
    1483       23366 :                          data->TranslationIndex(deopt_index)->value());
    1484       11683 :   Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
    1485             :   DCHECK_EQ(Translation::BEGIN, opcode);
    1486       11683 :   it.Next();  // Skip frame count.
    1487       11683 :   int jsframe_count = it.Next();
    1488             : 
    1489             :   // We insert the frames in reverse order because the frames
    1490             :   // in the deoptimization translation are ordered bottom-to-top.
    1491       35406 :   while (jsframe_count != 0) {
    1492       12040 :     opcode = static_cast<Translation::Opcode>(it.Next());
    1493       24080 :     if (opcode == Translation::INTERPRETED_FRAME ||
    1494       12040 :         opcode == Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME) {
    1495       11739 :       it.Next();  // Skip bailout id.
    1496       11739 :       jsframe_count--;
    1497             : 
    1498             :       // The second operand of the frame points to the function.
    1499       11739 :       Object* shared = literal_array->get(it.Next());
    1500       23478 :       functions->push_back(SharedFunctionInfo::cast(shared));
    1501             : 
    1502             :       // Skip over remaining operands to advance to the next opcode.
    1503       11739 :       it.Skip(Translation::NumberOfOperandsFor(opcode) - 2);
    1504             :     } else {
    1505             :       // Skip over operands to advance to the next opcode.
    1506         301 :       it.Skip(Translation::NumberOfOperandsFor(opcode));
    1507             :     }
    1508             :   }
    1509             : }
    1510             : 
    1511             : 
    1512     7896660 : int OptimizedFrame::StackSlotOffsetRelativeToFp(int slot_index) {
    1513     7896660 :   return StandardFrameConstants::kCallerSPOffset -
    1514     7896660 :          ((slot_index + 1) * kPointerSize);
    1515             : }
    1516             : 
    1517             : 
    1518           0 : Object* OptimizedFrame::StackSlotAt(int index) const {
    1519           0 :   return Memory::Object_at(fp() + StackSlotOffsetRelativeToFp(index));
    1520             : }
    1521             : 
    1522           0 : int InterpretedFrame::position() const {
    1523             :   AbstractCode* code = AbstractCode::cast(GetBytecodeArray());
    1524             :   int code_offset = GetBytecodeOffset();
    1525           0 :   return code->SourcePosition(code_offset);
    1526             : }
    1527             : 
    1528    14512063 : int InterpretedFrame::LookupExceptionHandlerInTable(
    1529             :     int* context_register, HandlerTable::CatchPrediction* prediction) {
    1530    14512063 :   BytecodeArray* bytecode = function()->shared()->bytecode_array();
    1531             :   HandlerTable* table = HandlerTable::cast(bytecode->handler_table());
    1532    14512063 :   return table->LookupRange(GetBytecodeOffset(), context_register, prediction);
    1533             : }
    1534             : 
    1535       64370 : int InterpretedFrame::GetBytecodeOffset() const {
    1536             :   const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
    1537             :   DCHECK_EQ(
    1538             :       InterpreterFrameConstants::kBytecodeOffsetFromFp,
    1539             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1540    20064442 :   int raw_offset = Smi::ToInt(GetExpression(index));
    1541    20064451 :   return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
    1542             : }
    1543             : 
    1544           0 : int InterpretedFrame::GetBytecodeOffset(Address fp) {
    1545             :   const int offset = InterpreterFrameConstants::kExpressionsOffset;
    1546             :   const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
    1547             :   DCHECK_EQ(
    1548             :       InterpreterFrameConstants::kBytecodeOffsetFromFp,
    1549             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1550             :   Address expression_offset = fp + offset - index * kPointerSize;
    1551           0 :   int raw_offset = Smi::ToInt(Memory::Object_at(expression_offset));
    1552           0 :   return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
    1553             : }
    1554             : 
    1555      791862 : void InterpretedFrame::PatchBytecodeOffset(int new_offset) {
    1556             :   const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
    1557             :   DCHECK_EQ(
    1558             :       InterpreterFrameConstants::kBytecodeOffsetFromFp,
    1559             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1560      791862 :   int raw_offset = new_offset + BytecodeArray::kHeaderSize - kHeapObjectTag;
    1561      791862 :   SetExpression(index, Smi::FromInt(raw_offset));
    1562      791862 : }
    1563             : 
    1564    14253883 : BytecodeArray* InterpretedFrame::GetBytecodeArray() const {
    1565             :   const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
    1566             :   DCHECK_EQ(
    1567             :       InterpreterFrameConstants::kBytecodeArrayFromFp,
    1568             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1569    28507775 :   return BytecodeArray::cast(GetExpression(index));
    1570             : }
    1571             : 
    1572        8452 : void InterpretedFrame::PatchBytecodeArray(BytecodeArray* bytecode_array) {
    1573             :   const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
    1574             :   DCHECK_EQ(
    1575             :       InterpreterFrameConstants::kBytecodeArrayFromFp,
    1576             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1577        8452 :   SetExpression(index, bytecode_array);
    1578        8452 : }
    1579             : 
    1580      791862 : Object* InterpretedFrame::ReadInterpreterRegister(int register_index) const {
    1581             :   const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
    1582             :   DCHECK_EQ(
    1583             :       InterpreterFrameConstants::kRegisterFileFromFp,
    1584             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1585     1583724 :   return GetExpression(index + register_index);
    1586             : }
    1587             : 
    1588           0 : void InterpretedFrame::WriteInterpreterRegister(int register_index,
    1589             :                                                 Object* value) {
    1590             :   const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
    1591             :   DCHECK_EQ(
    1592             :       InterpreterFrameConstants::kRegisterFileFromFp,
    1593             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1594           0 :   return SetExpression(index + register_index, value);
    1595             : }
    1596             : 
    1597     5488009 : void InterpretedFrame::Summarize(std::vector<FrameSummary>* functions) const {
    1598             :   DCHECK(functions->empty());
    1599             :   AbstractCode* abstract_code =
    1600     5488009 :       AbstractCode::cast(function()->shared()->bytecode_array());
    1601             :   FrameSummary::JavaScriptFrameSummary summary(
    1602    10976018 :       isolate(), receiver(), function(), abstract_code, GetBytecodeOffset(),
    1603    16464027 :       IsConstructor());
    1604     5488009 :   functions->push_back(summary);
    1605     5488009 : }
    1606             : 
    1607     1782631 : int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const {
    1608     3565262 :   return Smi::ToInt(GetExpression(0));
    1609             : }
    1610             : 
    1611           0 : int ArgumentsAdaptorFrame::GetLength(Address fp) {
    1612             :   const int offset = ArgumentsAdaptorFrameConstants::kLengthOffset;
    1613           8 :   return Smi::ToInt(Memory::Object_at(fp + offset));
    1614             : }
    1615             : 
    1616           0 : Code* ArgumentsAdaptorFrame::unchecked_code() const {
    1617             :   return isolate()->builtins()->builtin(
    1618           0 :       Builtins::kArgumentsAdaptorTrampoline);
    1619             : }
    1620             : 
    1621           0 : int BuiltinFrame::GetNumberOfIncomingArguments() const {
    1622           0 :   return Smi::ToInt(GetExpression(0));
    1623             : }
    1624             : 
    1625           0 : void BuiltinFrame::PrintFrameKind(StringStream* accumulator) const {
    1626           0 :   accumulator->Add("builtin frame: ");
    1627           0 : }
    1628             : 
    1629     2260611 : Address InternalFrame::GetCallerStackPointer() const {
    1630             :   // Internal frames have no arguments. The stack pointer of the
    1631             :   // caller is at a fixed offset from the frame pointer.
    1632     2260611 :   return fp() + StandardFrameConstants::kCallerSPOffset;
    1633             : }
    1634             : 
    1635           0 : Code* InternalFrame::unchecked_code() const {
    1636             :   const int offset = InternalFrameConstants::kCodeOffset;
    1637           0 :   Object* code = Memory::Object_at(fp() + offset);
    1638             :   DCHECK_NOT_NULL(code);
    1639           0 :   return reinterpret_cast<Code*>(code);
    1640             : }
    1641             : 
    1642             : 
    1643           0 : void WasmCompiledFrame::Print(StringStream* accumulator, PrintMode mode,
    1644             :                               int index) const {
    1645             :   PrintIndex(accumulator, mode, index);
    1646           0 :   accumulator->Add("WASM [");
    1647           0 :   Script* script = this->script();
    1648           0 :   accumulator->PrintName(script->name());
    1649           0 :   int pc = static_cast<int>(this->pc() - LookupCode()->instruction_start());
    1650           0 :   Object* instance = this->wasm_instance();
    1651             :   Vector<const uint8_t> raw_func_name =
    1652             :       WasmInstanceObject::cast(instance)->compiled_module()->GetRawFunctionName(
    1653           0 :           this->function_index());
    1654           0 :   const int kMaxPrintedFunctionName = 64;
    1655             :   char func_name[kMaxPrintedFunctionName + 1];
    1656           0 :   int func_name_len = std::min(kMaxPrintedFunctionName, raw_func_name.length());
    1657           0 :   memcpy(func_name, raw_func_name.start(), func_name_len);
    1658           0 :   func_name[func_name_len] = '\0';
    1659             :   accumulator->Add("], function #%u ('%s'), pc=%p, pos=%d\n",
    1660           0 :                    this->function_index(), func_name, pc, this->position());
    1661           0 :   if (mode != OVERVIEW) accumulator->Add("\n");
    1662           0 : }
    1663             : 
    1664           0 : Code* WasmCompiledFrame::unchecked_code() const {
    1665           0 :   return isolate()->FindCodeObject(pc());
    1666             : }
    1667             : 
    1668        6454 : void WasmCompiledFrame::Iterate(RootVisitor* v) const {
    1669        6454 :   IterateCompiledFrame(v);
    1670        6454 : }
    1671             : 
    1672     2857659 : Address WasmCompiledFrame::GetCallerStackPointer() const {
    1673     2857659 :   return fp() + ExitFrameConstants::kCallerSPOffset;
    1674             : }
    1675             : 
    1676       83512 : WasmInstanceObject* WasmCompiledFrame::wasm_instance() const {
    1677       83512 :   WasmInstanceObject* obj = WasmInstanceObject::GetOwningInstance(LookupCode());
    1678             :   // This is a live stack frame; it must have a live instance.
    1679             :   DCHECK_NOT_NULL(obj);
    1680       83512 :   return obj;
    1681             : }
    1682             : 
    1683          54 : uint32_t WasmCompiledFrame::function_index() const {
    1684          54 :   return FrameSummary::GetSingle(this).AsWasmCompiled().function_index();
    1685             : }
    1686             : 
    1687           0 : Script* WasmCompiledFrame::script() const {
    1688           0 :   return wasm_instance()->compiled_module()->script();
    1689             : }
    1690             : 
    1691          54 : int WasmCompiledFrame::position() const {
    1692          54 :   return FrameSummary::GetSingle(this).SourcePosition();
    1693             : }
    1694             : 
    1695       83404 : void WasmCompiledFrame::Summarize(std::vector<FrameSummary>* functions) const {
    1696             :   DCHECK(functions->empty());
    1697      250212 :   Handle<Code> code(LookupCode(), isolate());
    1698      166808 :   int offset = static_cast<int>(pc() - code->instruction_start());
    1699       83404 :   Handle<WasmInstanceObject> instance(wasm_instance(), isolate());
    1700             :   FrameSummary::WasmCompiledFrameSummary summary(
    1701       83404 :       isolate(), instance, code, offset, at_to_number_conversion());
    1702       83404 :   functions->push_back(summary);
    1703       83404 : }
    1704             : 
    1705       83894 : bool WasmCompiledFrame::at_to_number_conversion() const {
    1706             :   // Check whether our callee is a WASM_TO_JS frame, and this frame is at the
    1707             :   // ToNumber conversion call.
    1708       89496 :   Address callee_pc = reinterpret_cast<Address>(this->callee_pc());
    1709       89496 :   Code* code = callee_pc ? isolate()->FindCodeObject(callee_pc) : nullptr;
    1710       89496 :   if (!code || code->kind() != Code::WASM_TO_JS_FUNCTION) return false;
    1711         626 :   int offset = static_cast<int>(callee_pc - code->instruction_start());
    1712         626 :   int pos = AbstractCode::cast(code)->SourcePosition(offset);
    1713             :   DCHECK(pos == 0 || pos == 1);
    1714             :   // The imported call has position 0, ToNumber has position 1.
    1715         626 :   return !!pos;
    1716             : }
    1717             : 
    1718         280 : int WasmCompiledFrame::LookupExceptionHandlerInTable(int* stack_slots) {
    1719             :   DCHECK_NOT_NULL(stack_slots);
    1720             :   Code* code = LookupCode();
    1721             :   HandlerTable* table = HandlerTable::cast(code->handler_table());
    1722         280 :   int pc_offset = static_cast<int>(pc() - code->entry());
    1723         280 :   *stack_slots = code->stack_slots();
    1724         280 :   return table->LookupReturn(pc_offset);
    1725             : }
    1726             : 
    1727           3 : void WasmInterpreterEntryFrame::Iterate(RootVisitor* v) const {
    1728           3 :   IterateCompiledFrame(v);
    1729           3 : }
    1730             : 
    1731           0 : void WasmInterpreterEntryFrame::Print(StringStream* accumulator, PrintMode mode,
    1732             :                                       int index) const {
    1733             :   PrintIndex(accumulator, mode, index);
    1734           0 :   accumulator->Add("WASM INTERPRETER ENTRY [");
    1735           0 :   Script* script = this->script();
    1736           0 :   accumulator->PrintName(script->name());
    1737           0 :   accumulator->Add("]");
    1738           0 :   if (mode != OVERVIEW) accumulator->Add("\n");
    1739           0 : }
    1740             : 
    1741        2879 : void WasmInterpreterEntryFrame::Summarize(
    1742             :     std::vector<FrameSummary>* functions) const {
    1743     1320203 :   Handle<WasmInstanceObject> instance(wasm_instance(), isolate());
    1744             :   std::vector<std::pair<uint32_t, int>> interpreted_stack =
    1745        2879 :       instance->debug_info()->GetInterpretedStack(fp());
    1746             : 
    1747     1320203 :   for (auto& e : interpreted_stack) {
    1748             :     FrameSummary::WasmInterpretedFrameSummary summary(isolate(), instance,
    1749     1314445 :                                                       e.first, e.second);
    1750     1314445 :     functions->push_back(summary);
    1751             :   }
    1752        2879 : }
    1753             : 
    1754           0 : Code* WasmInterpreterEntryFrame::unchecked_code() const {
    1755           0 :   return isolate()->FindCodeObject(pc());
    1756             : }
    1757             : 
    1758        4559 : WasmInstanceObject* WasmInterpreterEntryFrame::wasm_instance() const {
    1759        4559 :   WasmInstanceObject* ret = WasmInstanceObject::GetOwningInstance(LookupCode());
    1760             :   // This is a live stack frame, there must be a live wasm instance available.
    1761             :   DCHECK_NOT_NULL(ret);
    1762        4559 :   return ret;
    1763             : }
    1764             : 
    1765           0 : Script* WasmInterpreterEntryFrame::script() const {
    1766           0 :   return wasm_instance()->compiled_module()->script();
    1767             : }
    1768             : 
    1769           0 : int WasmInterpreterEntryFrame::position() const {
    1770           0 :   return FrameSummary::GetBottom(this).AsWasmInterpreted().SourcePosition();
    1771             : }
    1772             : 
    1773         285 : Object* WasmInterpreterEntryFrame::context() const {
    1774         570 :   return wasm_instance()->compiled_module()->ptr_to_native_context();
    1775             : }
    1776             : 
    1777        3068 : Address WasmInterpreterEntryFrame::GetCallerStackPointer() const {
    1778        3068 :   return fp() + ExitFrameConstants::kCallerSPOffset;
    1779             : }
    1780             : 
    1781             : namespace {
    1782             : 
    1783             : 
    1784           0 : void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared,
    1785             :                          Code* code) {
    1786           0 :   if (FLAG_max_stack_trace_source_length != 0 && code != nullptr) {
    1787           0 :     std::ostringstream os;
    1788           0 :     os << "--------- s o u r c e   c o d e ---------\n"
    1789           0 :        << SourceCodeOf(shared, FLAG_max_stack_trace_source_length)
    1790           0 :        << "\n-----------------------------------------\n";
    1791           0 :     accumulator->Add(os.str().c_str());
    1792             :   }
    1793           0 : }
    1794             : 
    1795             : 
    1796             : }  // namespace
    1797             : 
    1798             : 
    1799          10 : void JavaScriptFrame::Print(StringStream* accumulator,
    1800             :                             PrintMode mode,
    1801             :                             int index) const {
    1802             :   DisallowHeapAllocation no_gc;
    1803          10 :   Object* receiver = this->receiver();
    1804          10 :   JSFunction* function = this->function();
    1805             : 
    1806          10 :   accumulator->PrintSecurityTokenIfChanged(function);
    1807             :   PrintIndex(accumulator, mode, index);
    1808          10 :   PrintFrameKind(accumulator);
    1809          10 :   Code* code = nullptr;
    1810          10 :   if (IsConstructor()) accumulator->Add("new ");
    1811          10 :   accumulator->PrintFunction(function, receiver, &code);
    1812             : 
    1813             :   // Get scope information for nicer output, if possible. If code is nullptr, or
    1814             :   // doesn't contain scope info, scope_info will return 0 for the number of
    1815             :   // parameters, stack local variables, context local variables, stack slots,
    1816             :   // or context slots.
    1817             :   SharedFunctionInfo* shared = function->shared();
    1818             :   ScopeInfo* scope_info = shared->scope_info();
    1819             :   Object* script_obj = shared->script();
    1820          10 :   if (script_obj->IsScript()) {
    1821             :     Script* script = Script::cast(script_obj);
    1822          10 :     accumulator->Add(" [");
    1823          10 :     accumulator->PrintName(script->name());
    1824             : 
    1825             :     Address pc = this->pc();
    1826          20 :     if (is_interpreted()) {
    1827             :       const InterpretedFrame* iframe =
    1828             :           reinterpret_cast<const InterpretedFrame*>(this);
    1829             :       BytecodeArray* bytecodes = iframe->GetBytecodeArray();
    1830             :       int offset = iframe->GetBytecodeOffset();
    1831           9 :       int source_pos = AbstractCode::cast(bytecodes)->SourcePosition(offset);
    1832           9 :       int line = script->GetLineNumber(source_pos) + 1;
    1833           9 :       accumulator->Add(":%d] [bytecode=%p offset=%d]", line, bytecodes, offset);
    1834             :     } else {
    1835             :       int function_start_pos = shared->start_position();
    1836           1 :       int line = script->GetLineNumber(function_start_pos) + 1;
    1837           1 :       accumulator->Add(":~%d] [pc=%p]", line, pc);
    1838             :     }
    1839             :   }
    1840             : 
    1841          10 :   accumulator->Add("(this=%o", receiver);
    1842             : 
    1843             :   // Print the parameters.
    1844          10 :   int parameters_count = ComputeParametersCount();
    1845          10 :   for (int i = 0; i < parameters_count; i++) {
    1846           0 :     accumulator->Add(",");
    1847             :     // If we have a name for the parameter we print it. Nameless
    1848             :     // parameters are either because we have more actual parameters
    1849             :     // than formal parameters or because we have no scope information.
    1850           0 :     if (i < scope_info->ParameterCount()) {
    1851           0 :       accumulator->PrintName(scope_info->ParameterName(i));
    1852           0 :       accumulator->Add("=");
    1853             :     }
    1854           0 :     accumulator->Add("%o", GetParameter(i));
    1855             :   }
    1856             : 
    1857          10 :   accumulator->Add(")");
    1858          10 :   if (mode == OVERVIEW) {
    1859          10 :     accumulator->Add("\n");
    1860          10 :     return;
    1861             :   }
    1862           0 :   if (is_optimized()) {
    1863           0 :     accumulator->Add(" {\n// optimized frame\n");
    1864           0 :     PrintFunctionSource(accumulator, shared, code);
    1865           0 :     accumulator->Add("}\n");
    1866           0 :     return;
    1867             :   }
    1868           0 :   accumulator->Add(" {\n");
    1869             : 
    1870             :   // Compute the number of locals and expression stack elements.
    1871           0 :   int stack_locals_count = scope_info->StackLocalCount();
    1872           0 :   int heap_locals_count = scope_info->ContextLocalCount();
    1873           0 :   int expressions_count = ComputeExpressionsCount();
    1874             : 
    1875             :   // Print stack-allocated local variables.
    1876           0 :   if (stack_locals_count > 0) {
    1877           0 :     accumulator->Add("  // stack-allocated locals\n");
    1878             :   }
    1879           0 :   for (int i = 0; i < stack_locals_count; i++) {
    1880           0 :     accumulator->Add("  var ");
    1881           0 :     accumulator->PrintName(scope_info->StackLocalName(i));
    1882           0 :     accumulator->Add(" = ");
    1883           0 :     if (i < expressions_count) {
    1884           0 :       accumulator->Add("%o", GetExpression(i));
    1885             :     } else {
    1886           0 :       accumulator->Add("// no expression found - inconsistent frame?");
    1887             :     }
    1888           0 :     accumulator->Add("\n");
    1889             :   }
    1890             : 
    1891             :   // Try to get hold of the context of this frame.
    1892             :   Context* context = nullptr;
    1893           0 :   if (this->context() != nullptr && this->context()->IsContext()) {
    1894           0 :     context = Context::cast(this->context());
    1895             :   }
    1896           0 :   while (context->IsWithContext()) {
    1897             :     context = context->previous();
    1898             :     DCHECK_NOT_NULL(context);
    1899             :   }
    1900             : 
    1901             :   // Print heap-allocated local variables.
    1902           0 :   if (heap_locals_count > 0) {
    1903           0 :     accumulator->Add("  // heap-allocated locals\n");
    1904             :   }
    1905           0 :   for (int i = 0; i < heap_locals_count; i++) {
    1906           0 :     accumulator->Add("  var ");
    1907           0 :     accumulator->PrintName(scope_info->ContextLocalName(i));
    1908           0 :     accumulator->Add(" = ");
    1909           0 :     if (context != nullptr) {
    1910           0 :       int index = Context::MIN_CONTEXT_SLOTS + i;
    1911           0 :       if (index < context->length()) {
    1912           0 :         accumulator->Add("%o", context->get(index));
    1913             :       } else {
    1914             :         accumulator->Add(
    1915           0 :             "// warning: missing context slot - inconsistent frame?");
    1916             :       }
    1917             :     } else {
    1918           0 :       accumulator->Add("// warning: no context found - inconsistent frame?");
    1919             :     }
    1920           0 :     accumulator->Add("\n");
    1921             :   }
    1922             : 
    1923             :   // Print the expression stack.
    1924             :   int expressions_start = stack_locals_count;
    1925           0 :   if (expressions_start < expressions_count) {
    1926           0 :     accumulator->Add("  // expression stack (top to bottom)\n");
    1927             :   }
    1928           0 :   for (int i = expressions_count - 1; i >= expressions_start; i--) {
    1929           0 :     accumulator->Add("  [%02d] : %o\n", i, GetExpression(i));
    1930             :   }
    1931             : 
    1932           0 :   PrintFunctionSource(accumulator, shared, code);
    1933             : 
    1934           0 :   accumulator->Add("}\n\n");
    1935             : }
    1936             : 
    1937             : 
    1938           0 : void ArgumentsAdaptorFrame::Print(StringStream* accumulator,
    1939             :                                   PrintMode mode,
    1940             :                                   int index) const {
    1941           0 :   int actual = ComputeParametersCount();
    1942             :   int expected = -1;
    1943           0 :   JSFunction* function = this->function();
    1944             :   expected = function->shared()->internal_formal_parameter_count();
    1945             : 
    1946             :   PrintIndex(accumulator, mode, index);
    1947           0 :   accumulator->Add("arguments adaptor frame: %d->%d", actual, expected);
    1948           0 :   if (mode == OVERVIEW) {
    1949           0 :     accumulator->Add("\n");
    1950           0 :     return;
    1951             :   }
    1952           0 :   accumulator->Add(" {\n");
    1953             : 
    1954             :   // Print actual arguments.
    1955           0 :   if (actual > 0) accumulator->Add("  // actual arguments\n");
    1956           0 :   for (int i = 0; i < actual; i++) {
    1957           0 :     accumulator->Add("  [%02d] : %o", i, GetParameter(i));
    1958           0 :     if (expected != -1 && i >= expected) {
    1959           0 :       accumulator->Add("  // not passed to callee");
    1960             :     }
    1961           0 :     accumulator->Add("\n");
    1962             :   }
    1963             : 
    1964           0 :   accumulator->Add("}\n\n");
    1965             : }
    1966             : 
    1967      119488 : void EntryFrame::Iterate(RootVisitor* v) const {
    1968      119488 :   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
    1969      119488 : }
    1970             : 
    1971           0 : void StandardFrame::IterateExpressions(RootVisitor* v) const {
    1972             :   const int offset = StandardFrameConstants::kLastObjectOffset;
    1973     2019733 :   Object** base = &Memory::Object_at(sp());
    1974             :   Object** limit = &Memory::Object_at(fp() + offset) + 1;
    1975     2019733 :   v->VisitRootPointers(Root::kTop, base, limit);
    1976           0 : }
    1977             : 
    1978     1884407 : void JavaScriptFrame::Iterate(RootVisitor* v) const {
    1979             :   IterateExpressions(v);
    1980     1884407 :   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
    1981     1884407 : }
    1982             : 
    1983      135326 : void InternalFrame::Iterate(RootVisitor* v) const {
    1984      135326 :   Code* code = LookupCode();
    1985             :   IteratePc(v, pc_address(), constant_pool_address(), code);
    1986             :   // Internal frames typically do not receive any arguments, hence their stack
    1987             :   // only contains tagged pointers.
    1988             :   // We are misusing the has_tagged_params flag here to tell us whether
    1989             :   // the full stack frame contains only tagged pointers or only raw values.
    1990             :   // This is used for the WasmCompileLazy builtin, where we actually pass
    1991             :   // untagged arguments and also store untagged values on the stack.
    1992      135326 :   if (code->has_tagged_params()) IterateExpressions(v);
    1993      135326 : }
    1994             : 
    1995             : // -------------------------------------------------------------------------
    1996             : 
    1997     8947472 : static Map* GcSafeMapOfCodeSpaceObject(HeapObject* object) {
    1998             :   MapWord map_word = object->map_word();
    1999             :   return map_word.IsForwardingAddress() ?
    2000    17894944 :       map_word.ToForwardingAddress()->map() : map_word.ToMap();
    2001             : }
    2002             : 
    2003             : 
    2004     8947472 : static int GcSafeSizeOfCodeSpaceObject(HeapObject* object) {
    2005     8947472 :   return object->SizeFromMap(GcSafeMapOfCodeSpaceObject(object));
    2006             : }
    2007             : 
    2008             : 
    2009             : #ifdef DEBUG
    2010             : static bool GcSafeCodeContains(HeapObject* code, Address addr) {
    2011             :   Map* map = GcSafeMapOfCodeSpaceObject(code);
    2012             :   DCHECK(map == code->GetHeap()->code_map());
    2013             :   Address start = code->address();
    2014             :   Address end = code->address() + code->SizeFromMap(map);
    2015             :   return start <= addr && addr < end;
    2016             : }
    2017             : #endif
    2018             : 
    2019             : 
    2020           0 : Code* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object,
    2021             :                                                 Address inner_pointer) {
    2022             :   Code* code = reinterpret_cast<Code*>(object);
    2023             :   DCHECK(code != nullptr && GcSafeCodeContains(code, inner_pointer));
    2024           0 :   return code;
    2025             : }
    2026             : 
    2027             : 
    2028     1472176 : Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer(
    2029             :     Address inner_pointer) {
    2030     5888701 :   Heap* heap = isolate_->heap();
    2031             : 
    2032             :   // Check if the inner pointer points into a large object chunk.
    2033     1472176 :   LargePage* large_page = heap->lo_space()->FindPage(inner_pointer);
    2034     1472176 :   if (large_page != nullptr) {
    2035           1 :     return GcSafeCastToCode(large_page->GetObject(), inner_pointer);
    2036             :   }
    2037             : 
    2038     1472175 :   if (!heap->code_space()->Contains(inner_pointer)) {
    2039             :     return nullptr;
    2040             :   }
    2041             : 
    2042             :   // Iterate through the page until we reach the end or find an object starting
    2043             :   // after the inner pointer.
    2044             :   Page* page = Page::FromAddress(inner_pointer);
    2045             : 
    2046             :   DCHECK_EQ(page->owner(), heap->code_space());
    2047     1472175 :   heap->mark_compact_collector()->sweeper().SweepOrWaitUntilSweepingCompleted(
    2048     1472175 :       page);
    2049             : 
    2050     1472175 :   Address addr = page->skip_list()->StartFor(inner_pointer);
    2051             : 
    2052             :   Address top = heap->code_space()->top();
    2053             :   Address limit = heap->code_space()->limit();
    2054             : 
    2055             :   while (true) {
    2056     8947587 :     if (addr == top && addr != limit) {
    2057             :       addr = limit;
    2058             :       continue;
    2059             :     }
    2060             : 
    2061     8947472 :     HeapObject* obj = HeapObject::FromAddress(addr);
    2062     8947472 :     int obj_size = GcSafeSizeOfCodeSpaceObject(obj);
    2063     8947472 :     Address next_addr = addr + obj_size;
    2064     8947472 :     if (next_addr > inner_pointer) return GcSafeCastToCode(obj, inner_pointer);
    2065             :     addr = next_addr;
    2066             :   }
    2067             : }
    2068             : 
    2069             : 
    2070             : InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
    2071    63929825 :     InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
    2072   127859650 :   isolate_->counters()->pc_to_code()->Increment();
    2073             :   DCHECK(base::bits::IsPowerOfTwo(kInnerPointerToCodeCacheSize));
    2074             :   uint32_t hash = ComputeIntegerHash(ObjectAddressForHashing(inner_pointer));
    2075    63929829 :   uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
    2076    63929829 :   InnerPointerToCodeCacheEntry* entry = cache(index);
    2077    63929829 :   if (entry->inner_pointer == inner_pointer) {
    2078   125379188 :     isolate_->counters()->pc_to_code_cached()->Increment();
    2079             :     DCHECK(entry->code == GcSafeFindCodeForInnerPointer(inner_pointer));
    2080             :   } else {
    2081             :     // Because this code may be interrupted by a profiling signal that
    2082             :     // also queries the cache, we cannot update inner_pointer before the code
    2083             :     // has been set. Otherwise, we risk trying to use a cache entry before
    2084             :     // the code has been computed.
    2085     1240235 :     entry->code = GcSafeFindCodeForInnerPointer(inner_pointer);
    2086             :     entry->safepoint_entry.Reset();
    2087     1240235 :     entry->inner_pointer = inner_pointer;
    2088             :   }
    2089    63929828 :   return entry;
    2090             : }
    2091             : 
    2092             : 
    2093             : // -------------------------------------------------------------------------
    2094             : 
    2095             : 
    2096             : #define DEFINE_WRAPPER(type, field)                              \
    2097             : class field##_Wrapper : public ZoneObject {                      \
    2098             :  public:  /* NOLINT */                                           \
    2099             :   field##_Wrapper(const field& original) : frame_(original) {    \
    2100             :   }                                                              \
    2101             :   field frame_;                                                  \
    2102             : };
    2103             : STACK_FRAME_TYPE_LIST(DEFINE_WRAPPER)
    2104             : #undef DEFINE_WRAPPER
    2105             : 
    2106       13512 : static StackFrame* AllocateFrameCopy(StackFrame* frame, Zone* zone) {
    2107             : #define FRAME_TYPE_CASE(type, field) \
    2108             :   case StackFrame::type: { \
    2109             :     field##_Wrapper* wrapper = \
    2110             :         new(zone) field##_Wrapper(*(reinterpret_cast<field*>(frame))); \
    2111             :     return &wrapper->frame_; \
    2112             :   }
    2113             : 
    2114       13512 :   switch (frame->type()) {
    2115       13512 :     STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
    2116           0 :     default: UNREACHABLE();
    2117             :   }
    2118             : #undef FRAME_TYPE_CASE
    2119             :   return nullptr;
    2120             : }
    2121             : 
    2122             : 
    2123         622 : Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone) {
    2124         622 :   ZoneList<StackFrame*> list(10, zone);
    2125       14134 :   for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
    2126       13512 :     StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
    2127       13512 :     list.Add(frame, zone);
    2128             :   }
    2129        1244 :   return list.ToVector();
    2130             : }
    2131             : 
    2132             : 
    2133             : }  // namespace internal
    2134             : }  // namespace v8

Generated by: LCOV version 1.10