LCOV - code coverage report
Current view: top level - src - frames.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 655 908 72.1 %
Date: 2017-04-26 Functions: 128 189 67.7 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/frames.h"
       6             : 
       7             : #include <memory>
       8             : #include <sstream>
       9             : 
      10             : #include "src/base/bits.h"
      11             : #include "src/deoptimizer.h"
      12             : #include "src/frames-inl.h"
      13             : #include "src/full-codegen/full-codegen.h"
      14             : #include "src/ic/ic-stats.h"
      15             : #include "src/register-configuration.h"
      16             : #include "src/safepoint-table.h"
      17             : #include "src/string-stream.h"
      18             : #include "src/visitors.h"
      19             : #include "src/vm-state-inl.h"
      20             : #include "src/wasm/wasm-module.h"
      21             : #include "src/wasm/wasm-objects.h"
      22             : 
      23             : namespace v8 {
      24             : namespace internal {
      25             : 
      26             : ReturnAddressLocationResolver
      27             :     StackFrame::return_address_location_resolver_ = NULL;
      28             : 
      29             : 
      30             : // Iterator that supports traversing the stack handlers of a
      31             : // particular frame. Needs to know the top of the handler chain.
      32             : class StackHandlerIterator BASE_EMBEDDED {
      33             :  public:
      34    92029163 :   StackHandlerIterator(const StackFrame* frame, StackHandler* handler)
      35             :       : limit_(frame->fp()), handler_(handler) {
      36             :     // Make sure the handler has already been unwound to this frame.
      37             :     DCHECK(frame->sp() <= handler->address());
      38             :   }
      39             : 
      40             :   StackHandler* handler() const { return handler_; }
      41             : 
      42             :   bool done() {
      43    95144938 :     return handler_ == NULL || handler_->address() > limit_;
      44             :   }
      45             :   void Advance() {
      46             :     DCHECK(!done());
      47             :     handler_ = handler_->next();
      48             :   }
      49             : 
      50             :  private:
      51             :   const Address limit_;
      52             :   StackHandler* handler_;
      53             : };
      54             : 
      55             : 
      56             : // -------------------------------------------------------------------------
      57             : 
      58             : 
      59             : #define INITIALIZE_SINGLETON(type, field) field##_(this),
      60    19501262 : StackFrameIteratorBase::StackFrameIteratorBase(Isolate* isolate,
      61             :                                                bool can_access_heap_objects)
      62             :     : isolate_(isolate),
      63             :       STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
      64             :       frame_(NULL), handler_(NULL),
      65    39002524 :       can_access_heap_objects_(can_access_heap_objects) {
      66    19501262 : }
      67             : #undef INITIALIZE_SINGLETON
      68             : 
      69    18849709 : StackFrameIterator::StackFrameIterator(Isolate* isolate)
      70    37699421 :     : StackFrameIterator(isolate, isolate->thread_local_top()) {}
      71             : 
      72      416500 : StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
      73    19266209 :     : StackFrameIteratorBase(isolate, true) {
      74    19266212 :   Reset(t);
      75      416499 : }
      76             : 
      77    92029164 : void StackFrameIterator::Advance() {
      78             :   DCHECK(!done());
      79             :   // Compute the state of the calling frame before restoring
      80             :   // callee-saved registers and unwinding handlers. This allows the
      81             :   // frame code that computes the caller state to access the top
      82             :   // handler and the value of any callee-saved register if needed.
      83    92029164 :   StackFrame::State state;
      84    92029164 :   StackFrame::Type type = frame_->GetCallerState(&state);
      85             : 
      86             :   // Unwind handlers corresponding to the current frame.
      87    92029163 :   StackHandlerIterator it(frame_, handler_);
      88    95144938 :   while (!it.done()) it.Advance();
      89    92029163 :   handler_ = it.handler();
      90             : 
      91             :   // Advance to the calling frame.
      92    92029163 :   frame_ = SingletonFor(type, &state);
      93             : 
      94             :   // When we're done iterating over the stack frames, the handler
      95             :   // chain must have been completely unwound.
      96             :   DCHECK(!done() || handler_ == NULL);
      97    92029159 : }
      98             : 
      99             : 
     100    57798636 : void StackFrameIterator::Reset(ThreadLocalTop* top) {
     101    19266212 :   StackFrame::State state;
     102             :   StackFrame::Type type = ExitFrame::GetStateForFramePointer(
     103    19266212 :       Isolate::c_entry_fp(top), &state);
     104    19266212 :   handler_ = StackHandler::FromAddress(Isolate::handler(top));
     105    19266212 :   frame_ = SingletonFor(type, &state);
     106    19266212 : }
     107             : 
     108             : 
     109   112437067 : StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type,
     110             :                                              StackFrame::State* state) {
     111   112437067 :   StackFrame* result = SingletonFor(type);
     112             :   DCHECK((!result) == (type == StackFrame::NONE));
     113   112437061 :   if (result) result->state_ = *state;
     114   112437061 :   return result;
     115             : }
     116             : 
     117             : 
     118   113346020 : StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type) {
     119             : #define FRAME_TYPE_CASE(type, field) \
     120             :   case StackFrame::type:             \
     121             :     return &field##_;
     122             : 
     123   113346020 :   switch (type) {
     124             :     case StackFrame::NONE: return NULL;
     125     3674295 :     STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
     126             :     default: break;
     127             :   }
     128             :   return NULL;
     129             : 
     130             : #undef FRAME_TYPE_CASE
     131             : }
     132             : 
     133             : // -------------------------------------------------------------------------
     134             : 
     135     4287948 : void JavaScriptFrameIterator::Advance() {
     136     7630474 :   do {
     137     7630474 :     iterator_.Advance();
     138     7630474 :   } while (!iterator_.done() && !iterator_.frame()->is_java_script());
     139     4287948 : }
     140             : 
     141             : 
     142       84294 : void JavaScriptFrameIterator::AdvanceToArgumentsFrame() {
     143      168588 :   if (!frame()->has_adapted_arguments()) return;
     144        4663 :   iterator_.Advance();
     145             :   DCHECK(iterator_.frame()->is_arguments_adaptor());
     146             : }
     147             : 
     148             : 
     149             : // -------------------------------------------------------------------------
     150             : 
     151     3068091 : StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
     152     3068091 :     : iterator_(isolate) {
     153     3068091 :   if (!done() && !IsValidFrame(iterator_.frame())) Advance();
     154     3068091 : }
     155             : 
     156      990477 : StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate,
     157             :                                                  StackFrame::Id id)
     158      990477 :     : StackTraceFrameIterator(isolate) {
     159     6697415 :   while (!done() && frame()->id() != id) Advance();
     160      990477 : }
     161             : 
     162    11886311 : void StackTraceFrameIterator::Advance() {
     163    30544443 :   do {
     164    30544443 :     iterator_.Advance();
     165    30544443 :   } while (!done() && !IsValidFrame(iterator_.frame()));
     166    11886311 : }
     167             : 
     168    32918329 : bool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) const {
     169    32918329 :   if (frame->is_java_script()) {
     170             :     JavaScriptFrame* jsFrame = static_cast<JavaScriptFrame*>(frame);
     171    28652330 :     if (!jsFrame->function()->IsJSFunction()) return false;
     172    28652330 :     return jsFrame->function()->shared()->IsSubjectToDebugging();
     173             :   }
     174             :   // apart from javascript, only wasm is valid
     175    18592164 :   return frame->is_wasm();
     176             : }
     177             : 
     178       16015 : void StackTraceFrameIterator::AdvanceToArgumentsFrame() {
     179       48045 :   if (!is_javascript() || !javascript_frame()->has_adapted_arguments()) return;
     180       16015 :   iterator_.Advance();
     181             :   DCHECK(iterator_.frame()->is_arguments_adaptor());
     182             : }
     183             : 
     184             : // -------------------------------------------------------------------------
     185             : 
     186             : namespace {
     187             : 
     188      554563 : bool IsInterpreterFramePc(Isolate* isolate, Address pc) {
     189             :   Code* interpreter_entry_trampoline =
     190             :       isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline);
     191             :   Code* interpreter_bytecode_advance =
     192             :       isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeAdvance);
     193             :   Code* interpreter_bytecode_dispatch =
     194             :       isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
     195             : 
     196     1093906 :   return (pc >= interpreter_entry_trampoline->instruction_start() &&
     197      192761 :           pc < interpreter_entry_trampoline->instruction_end()) ||
     198      370302 :          (pc >= interpreter_bytecode_advance->instruction_start() &&
     199      747324 :           pc < interpreter_bytecode_advance->instruction_end()) ||
     200      370302 :          (pc >= interpreter_bytecode_dispatch->instruction_start() &&
     201      554563 :           pc < interpreter_bytecode_dispatch->instruction_end());
     202             : }
     203             : 
     204             : DISABLE_ASAN Address ReadMemoryAt(Address address) {
     205       24487 :   return Memory::Address_at(address);
     206             : }
     207             : 
     208             : }  // namespace
     209             : 
     210      235053 : SafeStackFrameIterator::SafeStackFrameIterator(
     211      235053 :     Isolate* isolate,
     212       51273 :     Address fp, Address sp, Address js_entry_sp)
     213             :     : StackFrameIteratorBase(isolate, false),
     214             :       low_bound_(sp),
     215             :       high_bound_(js_entry_sp),
     216             :       top_frame_type_(StackFrame::NONE),
     217      470106 :       external_callback_scope_(isolate->external_callback_scope()) {
     218      235053 :   StackFrame::State state;
     219             :   StackFrame::Type type;
     220      443320 :   ThreadLocalTop* top = isolate->thread_local_top();
     221             :   bool advance_frame = true;
     222      235053 :   if (IsValidTop(top)) {
     223      208267 :     type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
     224      208267 :     top_frame_type_ = type;
     225       26786 :   } else if (IsValidStackAddress(fp)) {
     226             :     DCHECK(fp != NULL);
     227       24487 :     state.fp = fp;
     228       24487 :     state.sp = sp;
     229             :     state.pc_address = StackFrame::ResolveReturnAddressLocation(
     230       48974 :         reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
     231             : 
     232             :     // If the top of stack is a return address to the interpreter trampoline,
     233             :     // then we are likely in a bytecode handler with elided frame. In that
     234             :     // case, set the PC properly and make sure we do not drop the frame.
     235       24487 :     if (IsValidStackAddress(sp)) {
     236             :       MSAN_MEMORY_IS_INITIALIZED(sp, kPointerSize);
     237             :       Address tos = ReadMemoryAt(reinterpret_cast<Address>(sp));
     238       24487 :       if (IsInterpreterFramePc(isolate, tos)) {
     239        9786 :         state.pc_address = reinterpret_cast<Address*>(sp);
     240             :         advance_frame = false;
     241             :       }
     242             :     }
     243             : 
     244             :     // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset,
     245             :     // we check only that kMarkerOffset is within the stack bounds and do
     246             :     // compile time check that kContextOffset slot is pushed on the stack before
     247             :     // kMarkerOffset.
     248             :     STATIC_ASSERT(StandardFrameConstants::kFunctionOffset <
     249             :                   StandardFrameConstants::kContextOffset);
     250       24487 :     Address frame_marker = fp + StandardFrameConstants::kFunctionOffset;
     251       24487 :     if (IsValidStackAddress(frame_marker)) {
     252       23236 :       type = StackFrame::ComputeType(this, &state);
     253       23236 :       top_frame_type_ = type;
     254             :       // We only keep the top frame if we believe it to be interpreted frame.
     255       23236 :       if (type != StackFrame::INTERPRETED) {
     256             :         advance_frame = true;
     257             :       }
     258             :     } else {
     259             :       // Mark the frame as JAVA_SCRIPT if we cannot determine its type.
     260             :       // The frame anyways will be skipped.
     261             :       type = StackFrame::JAVA_SCRIPT;
     262             :       // Top frame is incomplete so we cannot reliably determine its type.
     263        1251 :       top_frame_type_ = StackFrame::NONE;
     264             :     }
     265             :   } else {
     266        2299 :     return;
     267             :   }
     268      232754 :   frame_ = SingletonFor(type, &state);
     269      232754 :   if (advance_frame && frame_) Advance();
     270             : }
     271             : 
     272             : 
     273      447993 : bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const {
     274             :   Address c_entry_fp = Isolate::c_entry_fp(top);
     275      235053 :   if (!IsValidExitFrame(c_entry_fp)) return false;
     276             :   // There should be at least one JS_ENTRY stack handler.
     277             :   Address handler = Isolate::handler(top);
     278      212940 :   if (handler == NULL) return false;
     279             :   // Check that there are no js frames on top of the native frames.
     280      212940 :   return c_entry_fp < handler;
     281             : }
     282             : 
     283             : 
     284     1141700 : void SafeStackFrameIterator::AdvanceOneFrame() {
     285             :   DCHECK(!done());
     286     1141700 :   StackFrame* last_frame = frame_;
     287             :   Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
     288             :   // Before advancing to the next stack frame, perform pointer validity tests.
     289     1141700 :   if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) {
     290      232747 :     frame_ = NULL;
     291      465494 :     return;
     292             :   }
     293             : 
     294             :   // Advance to the previous frame.
     295      908953 :   StackFrame::State state;
     296     2726859 :   StackFrame::Type type = frame_->GetCallerState(&state);
     297      908953 :   frame_ = SingletonFor(type, &state);
     298      908953 :   if (!frame_) return;
     299             : 
     300             :   // Check that we have actually moved to the previous frame in the stack.
     301     1817906 :   if (frame_->sp() < last_sp || frame_->fp() < last_fp) {
     302           0 :     frame_ = NULL;
     303             :   }
     304             : }
     305             : 
     306             : 
     307     1141700 : bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const {
     308     2283400 :   return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
     309             : }
     310             : 
     311             : 
     312     2288544 : bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
     313     1141700 :   StackFrame::State state;
     314     2045509 :   if (frame->is_entry() || frame->is_entry_construct()) {
     315             :     // See EntryFrame::GetCallerState. It computes the caller FP address
     316             :     // and calls ExitFrame::GetStateForFramePointer on it. We need to be
     317             :     // sure that caller FP address is valid.
     318             :     Address caller_fp = Memory::Address_at(
     319      237891 :         frame->fp() + EntryFrameConstants::kCallerFPOffset);
     320      237891 :     if (!IsValidExitFrame(caller_fp)) return false;
     321      903809 :   } else if (frame->is_arguments_adaptor()) {
     322             :     // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that
     323             :     // the number of arguments is stored on stack as Smi. We need to check
     324             :     // that it really an Smi.
     325             :     Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)->
     326        4425 :         GetExpression(0);
     327        4425 :     if (!number_of_args->IsSmi()) {
     328             :       return false;
     329             :     }
     330             :   }
     331      908953 :   frame->ComputeCallerState(&state);
     332     3635812 :   return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) &&
     333     1817906 :       SingletonFor(frame->GetCallerState(&state)) != NULL;
     334             : }
     335             : 
     336             : 
     337      472944 : bool SafeStackFrameIterator::IsValidExitFrame(Address fp) const {
     338      472944 :   if (!IsValidStackAddress(fp)) return false;
     339             :   Address sp = ExitFrame::ComputeStackPointer(fp);
     340      218585 :   if (!IsValidStackAddress(sp)) return false;
     341             :   StackFrame::State state;
     342             :   ExitFrame::FillState(fp, sp, &state);
     343             :   MSAN_MEMORY_IS_INITIALIZED(state.pc_address, sizeof(state.pc_address));
     344      218084 :   return *state.pc_address != nullptr;
     345             : }
     346             : 
     347             : 
     348      494399 : void SafeStackFrameIterator::Advance() {
     349             :   while (true) {
     350     1141700 :     AdvanceOneFrame();
     351     1141700 :     if (done()) break;
     352             :     ExternalCallbackScope* last_callback_scope = NULL;
     353      997989 :     while (external_callback_scope_ != NULL &&
     354       55959 :            external_callback_scope_->scope_address() < frame_->fp()) {
     355             :       // As long as the setup of a frame is not atomic, we may happen to be
     356             :       // in an interval where an ExternalCallbackScope is already created,
     357             :       // but the frame is not yet entered. So we are actually observing
     358             :       // the previous frame.
     359             :       // Skip all the ExternalCallbackScope's that are below the current fp.
     360             :       last_callback_scope = external_callback_scope_;
     361       33077 :       external_callback_scope_ = external_callback_scope_->previous();
     362             :     }
     363      908953 :     if (frame_->is_java_script()) break;
     364     1952191 :     if (frame_->is_exit() || frame_->is_builtin_exit()) {
     365             :       // Some of the EXIT frames may have ExternalCallbackScope allocated on
     366             :       // top of them. In that case the scope corresponds to the first EXIT
     367             :       // frame beneath it. There may be other EXIT frames on top of the
     368             :       // ExternalCallbackScope, just skip them as we cannot collect any useful
     369             :       // information about them.
     370        5144 :       if (last_callback_scope) {
     371             :         frame_->state_.pc_address =
     372       10288 :             last_callback_scope->callback_entrypoint_address();
     373             :       }
     374             :       break;
     375             :     }
     376             :   }
     377      494399 : }
     378             : 
     379             : 
     380             : // -------------------------------------------------------------------------
     381             : 
     382             : 
     383     1665019 : Code* StackFrame::GetSafepointData(Isolate* isolate,
     384             :                                    Address inner_pointer,
     385             :                                    SafepointEntry* safepoint_entry,
     386             :                                    unsigned* stack_slots) {
     387             :   InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry =
     388     1665019 :       isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer);
     389     1665019 :   if (!entry->safepoint_entry.is_valid()) {
     390      104304 :     entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer);
     391             :     DCHECK(entry->safepoint_entry.is_valid());
     392             :   } else {
     393             :     DCHECK(entry->safepoint_entry.Equals(
     394             :         entry->code->GetSafepointEntry(inner_pointer)));
     395             :   }
     396             : 
     397             :   // Fill in the results and return the code.
     398     1665019 :   Code* code = entry->code;
     399     1665019 :   *safepoint_entry = entry->safepoint_entry;
     400     1665019 :   *stack_slots = code->stack_slots();
     401     1665019 :   return code;
     402             : }
     403             : 
     404             : 
     405             : #ifdef DEBUG
     406             : static bool GcSafeCodeContains(HeapObject* object, Address addr);
     407             : #endif
     408             : 
     409           0 : void StackFrame::IteratePc(RootVisitor* v, Address* pc_address,
     410             :                            Address* constant_pool_address, Code* holder) {
     411     4513003 :   Address pc = *pc_address;
     412             :   DCHECK(GcSafeCodeContains(holder, pc));
     413     4513003 :   unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start());
     414     4513003 :   Object* code = holder;
     415     4513003 :   v->VisitRootPointer(Root::kTop, &code);
     416     9025640 :   if (code == holder) return;
     417             :   holder = reinterpret_cast<Code*>(code);
     418         366 :   pc = holder->instruction_start() + pc_offset;
     419         366 :   *pc_address = pc;
     420             :   if (FLAG_enable_embedded_constant_pool && constant_pool_address) {
     421             :     *constant_pool_address = holder->constant_pool();
     422             :   }
     423             : }
     424             : 
     425             : 
     426           0 : void StackFrame::SetReturnAddressLocationResolver(
     427             :     ReturnAddressLocationResolver resolver) {
     428             :   DCHECK(return_address_location_resolver_ == NULL);
     429           0 :   return_address_location_resolver_ = resolver;
     430           0 : }
     431             : 
     432   180187704 : StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
     433             :                                          State* state) {
     434             :   DCHECK(state->fp != NULL);
     435             : 
     436             :   MSAN_MEMORY_IS_INITIALIZED(
     437             :       state->fp + CommonFrameConstants::kContextOrFrameTypeOffset,
     438             :       kPointerSize);
     439             :   intptr_t marker = Memory::intptr_at(
     440    90744241 :       state->fp + CommonFrameConstants::kContextOrFrameTypeOffset);
     441    90744241 :   if (!iterator->can_access_heap_objects_) {
     442             :     // TODO(titzer): "can_access_heap_objects" is kind of bogus. It really
     443             :     // means that we are being called from the profiler, which can interrupt
     444             :     // the VM with a signal at any arbitrary instruction, with essentially
     445             :     // anything on the stack. So basically none of these checks are 100%
     446             :     // reliable.
     447             :     MSAN_MEMORY_IS_INITIALIZED(
     448             :         state->fp + StandardFrameConstants::kFunctionOffset, kPointerSize);
     449             :     Object* maybe_function =
     450     1830854 :         Memory::Object_at(state->fp + StandardFrameConstants::kFunctionOffset);
     451     1830854 :     if (!StackFrame::IsTypeMarker(marker)) {
     452      530076 :       if (maybe_function->IsSmi()) {
     453             :         return NONE;
     454      530076 :       } else if (IsInterpreterFramePc(iterator->isolate(),
     455      530076 :                                       *(state->pc_address))) {
     456             :         return INTERPRETED;
     457             :       } else {
     458      178060 :         return JAVA_SCRIPT;
     459             :       }
     460             :     }
     461             :   } else {
     462             :     // Look up the code object to figure out the type of the stack frame.
     463             :     Code* code_obj =
     464    88913387 :         GetContainingCode(iterator->isolate(), *(state->pc_address));
     465    88913387 :     if (code_obj != nullptr) {
     466    88913386 :       switch (code_obj->kind()) {
     467             :         case Code::BUILTIN:
     468    37113721 :           if (StackFrame::IsTypeMarker(marker)) break;
     469    28793663 :           if (code_obj->is_interpreter_trampoline_builtin()) {
     470             :             return INTERPRETED;
     471             :           }
     472      878144 :           if (code_obj->is_turbofanned()) {
     473             :             // TODO(bmeurer): We treat frames for BUILTIN Code objects as
     474             :             // OptimizedFrame for now (all the builtins with JavaScript
     475             :             // linkage are actually generated with TurboFan currently, so
     476             :             // this is sound).
     477             :             return OPTIMIZED;
     478             :           }
     479       12947 :           return BUILTIN;
     480             :         case Code::FUNCTION:
     481             :           return JAVA_SCRIPT;
     482             :         case Code::OPTIMIZED_FUNCTION:
     483     5656051 :           return OPTIMIZED;
     484             :         case Code::WASM_FUNCTION:
     485     2538567 :           return WASM_COMPILED;
     486             :         case Code::WASM_TO_JS_FUNCTION:
     487       18791 :           return WASM_TO_JS;
     488             :         case Code::JS_TO_WASM_FUNCTION:
     489      103551 :           return JS_TO_WASM;
     490             :         case Code::WASM_INTERPRETER_ENTRY:
     491       56465 :           return WASM_INTERPRETER_ENTRY;
     492             :         default:
     493             :           // All other types should have an explicit marker
     494             :           break;
     495             :       }
     496             :     } else {
     497             :       return NONE;
     498             :     }
     499             :   }
     500             : 
     501             :   DCHECK(StackFrame::IsTypeMarker(marker));
     502             :   StackFrame::Type candidate = StackFrame::MarkerToType(marker);
     503    40730621 :   switch (candidate) {
     504             :     case ENTRY:
     505             :     case ENTRY_CONSTRUCT:
     506             :     case EXIT:
     507             :     case BUILTIN_EXIT:
     508             :     case STUB:
     509             :     case STUB_FAILURE_TRAMPOLINE:
     510             :     case INTERNAL:
     511             :     case CONSTRUCT:
     512             :     case ARGUMENTS_ADAPTOR:
     513             :     case WASM_TO_JS:
     514             :     case WASM_COMPILED:
     515             :       return candidate;
     516             :     case JS_TO_WASM:
     517             :     case JAVA_SCRIPT:
     518             :     case OPTIMIZED:
     519             :     case INTERPRETED:
     520             :     default:
     521             :       // Unoptimized and optimized JavaScript frames, including
     522             :       // interpreted frames, should never have a StackFrame::Type
     523             :       // marker. If we find one, we're likely being called from the
     524             :       // profiler in a bogus stack frame.
     525             :       return NONE;
     526             :   }
     527             : }
     528             : 
     529             : 
     530             : #ifdef DEBUG
     531             : bool StackFrame::can_access_heap_objects() const {
     532             :   return iterator_->can_access_heap_objects_;
     533             : }
     534             : #endif
     535             : 
     536             : 
     537    90721014 : StackFrame::Type StackFrame::GetCallerState(State* state) const {
     538    90721014 :   ComputeCallerState(state);
     539    90721006 :   return ComputeType(iterator_, state);
     540             : }
     541             : 
     542             : 
     543           0 : Address StackFrame::UnpaddedFP() const {
     544           0 :   return fp();
     545             : }
     546             : 
     547             : 
     548       38370 : Code* EntryFrame::unchecked_code() const {
     549       38370 :   return isolate()->heap()->js_entry_code();
     550             : }
     551             : 
     552             : 
     553        5144 : void EntryFrame::ComputeCallerState(State* state) const {
     554        5144 :   GetCallerState(state);
     555        5144 : }
     556             : 
     557             : 
     558           0 : void EntryFrame::SetCallerFp(Address caller_fp) {
     559             :   const int offset = EntryFrameConstants::kCallerFPOffset;
     560           0 :   Memory::Address_at(this->fp() + offset) = caller_fp;
     561           0 : }
     562             : 
     563             : 
     564     3131207 : StackFrame::Type EntryFrame::GetCallerState(State* state) const {
     565             :   const int offset = EntryFrameConstants::kCallerFPOffset;
     566     3131207 :   Address fp = Memory::Address_at(this->fp() + offset);
     567     3131207 :   return ExitFrame::GetStateForFramePointer(fp, state);
     568             : }
     569             : 
     570             : 
     571          10 : Code* EntryConstructFrame::unchecked_code() const {
     572          10 :   return isolate()->heap()->js_construct_entry_code();
     573             : }
     574             : 
     575             : 
     576           0 : Object*& ExitFrame::code_slot() const {
     577             :   const int offset = ExitFrameConstants::kCodeOffset;
     578      191799 :   return Memory::Object_at(fp() + offset);
     579             : }
     580             : 
     581       38380 : Code* ExitFrame::unchecked_code() const {
     582       38380 :   return reinterpret_cast<Code*>(code_slot());
     583             : }
     584             : 
     585             : 
     586    20819122 : void ExitFrame::ComputeCallerState(State* state) const {
     587             :   // Set up the caller state.
     588    62457366 :   state->sp = caller_sp();
     589    20819122 :   state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);
     590             :   state->pc_address = ResolveReturnAddressLocation(
     591    41638244 :       reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
     592    20819122 :   state->callee_pc_address = nullptr;
     593             :   if (FLAG_enable_embedded_constant_pool) {
     594             :     state->constant_pool_address = reinterpret_cast<Address*>(
     595             :         fp() + ExitFrameConstants::kConstantPoolOffset);
     596             :   }
     597    20819122 : }
     598             : 
     599             : 
     600           0 : void ExitFrame::SetCallerFp(Address caller_fp) {
     601           0 :   Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp;
     602           0 : }
     603             : 
     604      153419 : void ExitFrame::Iterate(RootVisitor* v) const {
     605             :   // The arguments are traversed as part of the expression stack of
     606             :   // the calling frame.
     607      153419 :   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
     608      306838 :   v->VisitRootPointer(Root::kTop, &code_slot());
     609      153419 : }
     610             : 
     611             : 
     612    20820822 : Address ExitFrame::GetCallerStackPointer() const {
     613    20820822 :   return fp() + ExitFrameConstants::kCallerSPOffset;
     614             : }
     615             : 
     616             : 
     617    22605686 : StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
     618    22605686 :   if (fp == 0) return NONE;
     619             :   Address sp = ComputeStackPointer(fp);
     620             :   FillState(fp, sp, state);
     621             :   DCHECK_NOT_NULL(*state->pc_address);
     622             : 
     623    20401207 :   return ComputeFrameType(fp);
     624             : }
     625             : 
     626           0 : StackFrame::Type ExitFrame::ComputeFrameType(Address fp) {
     627             :   // Distinguish between between regular and builtin exit frames.
     628             :   // Default to EXIT in all hairy cases (e.g., when called from profiler).
     629             :   const int offset = ExitFrameConstants::kFrameTypeOffset;
     630    20401207 :   Object* marker = Memory::Object_at(fp + offset);
     631             : 
     632    20401207 :   if (!marker->IsSmi()) {
     633             :     return EXIT;
     634             :   }
     635             : 
     636             :   intptr_t marker_int = bit_cast<intptr_t>(marker);
     637             : 
     638    20401207 :   StackFrame::Type frame_type = static_cast<StackFrame::Type>(marker_int >> 1);
     639    20401207 :   if (frame_type == EXIT || frame_type == BUILTIN_EXIT) {
     640           0 :     return frame_type;
     641             :   }
     642             : 
     643             :   return EXIT;
     644             : }
     645             : 
     646           0 : Address ExitFrame::ComputeStackPointer(Address fp) {
     647             :   MSAN_MEMORY_IS_INITIALIZED(fp + ExitFrameConstants::kSPOffset, kPointerSize);
     648    20619792 :   return Memory::Address_at(fp + ExitFrameConstants::kSPOffset);
     649             : }
     650             : 
     651           0 : void ExitFrame::FillState(Address fp, Address sp, State* state) {
     652    20401207 :   state->sp = sp;
     653    20401207 :   state->fp = fp;
     654             :   state->pc_address = ResolveReturnAddressLocation(
     655    41020498 :       reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize));
     656    20401207 :   state->callee_pc_address = nullptr;
     657             :   // The constant pool recorded in the exit frame is not associated
     658             :   // with the pc in this state (the return address into a C entry
     659             :   // stub).  ComputeCallerState will retrieve the constant pool
     660             :   // together with the associated caller pc.
     661    20401207 :   state->constant_pool_address = nullptr;
     662           0 : }
     663             : 
     664      110478 : JSFunction* BuiltinExitFrame::function() const {
     665      110478 :   return JSFunction::cast(target_slot_object());
     666             : }
     667             : 
     668      106080 : Object* BuiltinExitFrame::receiver() const { return receiver_slot_object(); }
     669             : 
     670       53040 : bool BuiltinExitFrame::IsConstructor() const {
     671      106080 :   return !new_target_slot_object()->IsUndefined(isolate());
     672             : }
     673             : 
     674           0 : Object* BuiltinExitFrame::GetParameter(int i) const {
     675             :   DCHECK(i >= 0 && i < ComputeParametersCount());
     676           0 :   int offset = BuiltinExitFrameConstants::kArgcOffset + (i + 1) * kPointerSize;
     677           0 :   return Memory::Object_at(fp() + offset);
     678             : }
     679             : 
     680           0 : int BuiltinExitFrame::ComputeParametersCount() const {
     681             :   Object* argc_slot = argc_slot_object();
     682             :   DCHECK(argc_slot->IsSmi());
     683             :   // Argc also counts the receiver, target, new target, and argc itself as args,
     684             :   // therefore the real argument count is argc - 4.
     685           0 :   int argc = Smi::cast(argc_slot)->value() - 4;
     686             :   DCHECK(argc >= 0);
     687           0 :   return argc;
     688             : }
     689             : 
     690           0 : void BuiltinExitFrame::Print(StringStream* accumulator, PrintMode mode,
     691             :                              int index) const {
     692             :   DisallowHeapAllocation no_gc;
     693             :   Object* receiver = this->receiver();
     694             :   JSFunction* function = this->function();
     695             : 
     696           0 :   accumulator->PrintSecurityTokenIfChanged(function);
     697             :   PrintIndex(accumulator, mode, index);
     698           0 :   accumulator->Add("builtin exit frame: ");
     699           0 :   Code* code = NULL;
     700           0 :   if (IsConstructor()) accumulator->Add("new ");
     701           0 :   accumulator->PrintFunction(function, receiver, &code);
     702             : 
     703           0 :   accumulator->Add("(this=%o", receiver);
     704             : 
     705             :   // Print the parameters.
     706             :   int parameters_count = ComputeParametersCount();
     707           0 :   for (int i = 0; i < parameters_count; i++) {
     708           0 :     accumulator->Add(",%o", GetParameter(i));
     709             :   }
     710             : 
     711           0 :   accumulator->Add(")\n\n");
     712           0 : }
     713             : 
     714     6115621 : Address StandardFrame::GetExpressionAddress(int n) const {
     715             :   const int offset = StandardFrameConstants::kExpressionsOffset;
     716     6115621 :   return fp() + offset - n * kPointerSize;
     717             : }
     718             : 
     719    27386800 : Address InterpretedFrame::GetExpressionAddress(int n) const {
     720             :   const int offset = InterpreterFrameConstants::kExpressionsOffset;
     721    27386800 :   return fp() + offset - n * kPointerSize;
     722             : }
     723             : 
     724           0 : Script* StandardFrame::script() const {
     725             :   // This should only be called on frames which override this method.
     726             :   DCHECK(false);
     727           0 :   return nullptr;
     728             : }
     729             : 
     730           0 : Object* StandardFrame::receiver() const {
     731           0 :   return isolate()->heap()->undefined_value();
     732             : }
     733             : 
     734          98 : Object* StandardFrame::context() const {
     735          98 :   return isolate()->heap()->undefined_value();
     736             : }
     737             : 
     738           0 : int StandardFrame::position() const {
     739             :   AbstractCode* code = AbstractCode::cast(LookupCode());
     740           0 :   int code_offset = static_cast<int>(pc() - code->instruction_start());
     741           0 :   return code->SourcePosition(code_offset);
     742             : }
     743             : 
     744           0 : int StandardFrame::ComputeExpressionsCount() const {
     745          10 :   Address base = GetExpressionAddress(0);
     746          10 :   Address limit = sp() - kPointerSize;
     747             :   DCHECK(base >= limit);  // stack grows downwards
     748             :   // Include register-allocated locals in number of expressions.
     749          10 :   return static_cast<int>((base - limit) / kPointerSize);
     750             : }
     751             : 
     752           0 : Object* StandardFrame::GetParameter(int index) const {
     753             :   // StandardFrame does not define any parameters.
     754           0 :   UNREACHABLE();
     755             :   return nullptr;
     756             : }
     757             : 
     758           0 : int StandardFrame::ComputeParametersCount() const { return 0; }
     759             : 
     760    70805707 : void StandardFrame::ComputeCallerState(State* state) const {
     761   354028535 :   state->sp = caller_sp();
     762    70805707 :   state->fp = caller_fp();
     763             :   state->pc_address = ResolveReturnAddressLocation(
     764   141611414 :       reinterpret_cast<Address*>(ComputePCAddress(fp())));
     765    70805707 :   state->callee_pc_address = pc_address();
     766             :   state->constant_pool_address =
     767    70805707 :       reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp()));
     768    70805707 : }
     769             : 
     770             : 
     771           0 : void StandardFrame::SetCallerFp(Address caller_fp) {
     772           0 :   Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) =
     773           0 :       caller_fp;
     774           0 : }
     775             : 
     776           0 : bool StandardFrame::IsConstructor() const { return false; }
     777             : 
     778           0 : void StandardFrame::Summarize(List<FrameSummary>* functions,
     779             :                               FrameSummary::Mode mode) const {
     780             :   // This should only be called on frames which override this method.
     781           0 :   UNREACHABLE();
     782             : }
     783             : 
     784     1665019 : void StandardFrame::IterateCompiledFrame(RootVisitor* v) const {
     785             :   // Make sure that we're not doing "safe" stack frame iteration. We cannot
     786             :   // possibly find pointers in optimized frames in that state.
     787             :   DCHECK(can_access_heap_objects());
     788             : 
     789             :   // Compute the safepoint information.
     790     1665019 :   unsigned stack_slots = 0;
     791             :   SafepointEntry safepoint_entry;
     792             :   Code* code = StackFrame::GetSafepointData(
     793     6660076 :       isolate(), pc(), &safepoint_entry, &stack_slots);
     794     1665019 :   unsigned slot_space = stack_slots * kPointerSize;
     795             : 
     796             :   // Determine the fixed header and spill slot area size.
     797             :   int frame_header_size = StandardFrameConstants::kFixedFrameSizeFromFp;
     798             :   intptr_t marker =
     799     1665019 :       Memory::intptr_at(fp() + CommonFrameConstants::kContextOrFrameTypeOffset);
     800     1665019 :   if (StackFrame::IsTypeMarker(marker)) {
     801             :     StackFrame::Type candidate = StackFrame::MarkerToType(marker);
     802     1339156 :     switch (candidate) {
     803             :       case ENTRY:
     804             :       case ENTRY_CONSTRUCT:
     805             :       case EXIT:
     806             :       case BUILTIN_EXIT:
     807             :       case STUB_FAILURE_TRAMPOLINE:
     808             :       case ARGUMENTS_ADAPTOR:
     809             :       case STUB:
     810             :       case INTERNAL:
     811             :       case CONSTRUCT:
     812             :       case JS_TO_WASM:
     813             :       case WASM_TO_JS:
     814             :       case WASM_COMPILED:
     815             :       case WASM_INTERPRETER_ENTRY:
     816             :         frame_header_size = TypedFrameConstants::kFixedFrameSizeFromFp;
     817     1339156 :         break;
     818             :       case JAVA_SCRIPT:
     819             :       case OPTIMIZED:
     820             :       case INTERPRETED:
     821             :       case BUILTIN:
     822             :         // These frame types have a context, but they are actually stored
     823             :         // in the place on the stack that one finds the frame type.
     824           0 :         UNREACHABLE();
     825             :         break;
     826             :       case NONE:
     827             :       case NUMBER_OF_TYPES:
     828             :       case MANUAL:
     829           0 :         UNREACHABLE();
     830             :         break;
     831             :     }
     832             :   }
     833             :   slot_space -=
     834     1665019 :       (frame_header_size + StandardFrameConstants::kFixedFrameSizeAboveFp);
     835             : 
     836     1665019 :   Object** frame_header_base = &Memory::Object_at(fp() - frame_header_size);
     837             :   Object** frame_header_limit =
     838             :       &Memory::Object_at(fp() - StandardFrameConstants::kCPSlotSize);
     839             :   Object** parameters_base = &Memory::Object_at(sp());
     840     1665019 :   Object** parameters_limit = frame_header_base - slot_space / kPointerSize;
     841             : 
     842             :   // Visit the parameters that may be on top of the saved registers.
     843     3330038 :   if (safepoint_entry.argument_count() > 0) {
     844             :     v->VisitRootPointers(Root::kTop, parameters_base,
     845         681 :                          parameters_base + safepoint_entry.argument_count());
     846        1362 :     parameters_base += safepoint_entry.argument_count();
     847             :   }
     848             : 
     849             :   // Skip saved double registers.
     850     3330038 :   if (safepoint_entry.has_doubles()) {
     851             :     // Number of doubles not known at snapshot time.
     852             :     DCHECK(!isolate()->serializer_enabled());
     853           0 :     parameters_base += RegisterConfiguration::Crankshaft()
     854             :                            ->num_allocatable_double_registers() *
     855           0 :                        kDoubleSize / kPointerSize;
     856             :   }
     857             : 
     858             :   // Visit the registers that contain pointers if any.
     859     1665019 :   if (safepoint_entry.HasRegisters()) {
     860      241920 :     for (int i = kNumSafepointRegisters - 1; i >=0; i--) {
     861      241920 :       if (safepoint_entry.HasRegisterAt(i)) {
     862             :         int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(i);
     863       56138 :         v->VisitRootPointer(Root::kTop, parameters_base + reg_stack_index);
     864             :       }
     865             :     }
     866             :     // Skip the words containing the register values.
     867       15120 :     parameters_base += kNumSafepointRegisters;
     868             :   }
     869             : 
     870             :   // We're done dealing with the register bits.
     871     1665019 :   uint8_t* safepoint_bits = safepoint_entry.bits();
     872     1665019 :   safepoint_bits += kNumSafepointRegisters >> kBitsPerByteLog2;
     873             : 
     874             :   // Visit the rest of the parameters if they are tagged.
     875     1665019 :   if (code->has_tagged_params()) {
     876     1646140 :     v->VisitRootPointers(Root::kTop, parameters_base, parameters_limit);
     877             :   }
     878             : 
     879             :   // Visit pointer spill slots and locals.
     880     7196484 :   for (unsigned index = 0; index < stack_slots; index++) {
     881     7196484 :     int byte_index = index >> kBitsPerByteLog2;
     882     7196484 :     int bit_index = index & (kBitsPerByte - 1);
     883     7196484 :     if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) {
     884      321064 :       v->VisitRootPointer(Root::kTop, parameters_limit + index);
     885             :     }
     886             :   }
     887             : 
     888             :   // Visit the return address in the callee and incoming arguments.
     889             :   IteratePc(v, pc_address(), constant_pool_address(), code);
     890             : 
     891     4985650 :   if (!is_wasm() && !is_wasm_to_js()) {
     892             :     // If this frame has JavaScript ABI, visit the context (in stub and JS
     893             :     // frames) and the function (in JS frames).
     894     1646296 :     v->VisitRootPointers(Root::kTop, frame_header_base, frame_header_limit);
     895             :   }
     896     1665019 : }
     897             : 
     898     1339221 : void StubFrame::Iterate(RootVisitor* v) const { IterateCompiledFrame(v); }
     899             : 
     900      219176 : Code* StubFrame::unchecked_code() const {
     901      219176 :   return isolate()->FindCodeObject(pc());
     902             : }
     903             : 
     904             : 
     905    28793676 : Address StubFrame::GetCallerStackPointer() const {
     906    28793676 :   return fp() + ExitFrameConstants::kCallerSPOffset;
     907             : }
     908             : 
     909             : 
     910           0 : int StubFrame::GetNumberOfIncomingArguments() const {
     911           0 :   return 0;
     912             : }
     913             : 
     914          54 : int StubFrame::LookupExceptionHandlerInTable(int* stack_slots) {
     915             :   Code* code = LookupCode();
     916             :   DCHECK(code->is_turbofanned());
     917             :   DCHECK_EQ(code->kind(), Code::BUILTIN);
     918             :   HandlerTable* table = HandlerTable::cast(code->handler_table());
     919          54 :   int pc_offset = static_cast<int>(pc() - code->entry());
     920          54 :   *stack_slots = code->stack_slots();
     921          54 :   return table->LookupReturn(pc_offset);
     922             : }
     923             : 
     924      316391 : void OptimizedFrame::Iterate(RootVisitor* v) const { IterateCompiledFrame(v); }
     925             : 
     926        2448 : void JavaScriptFrame::SetParameterValue(int index, Object* value) const {
     927        2448 :   Memory::Object_at(GetParameterSlot(index)) = value;
     928        2448 : }
     929             : 
     930             : 
     931    14160732 : bool JavaScriptFrame::IsConstructor() const {
     932             :   Address fp = caller_fp();
     933    14160732 :   if (has_adapted_arguments()) {
     934             :     // Skip the arguments adaptor frame and look at the real caller.
     935     1182874 :     fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset);
     936             :   }
     937    14160732 :   return IsConstructFrame(fp);
     938             : }
     939             : 
     940             : 
     941           0 : bool JavaScriptFrame::HasInlinedFrames() const {
     942             :   List<SharedFunctionInfo*> functions(1);
     943           0 :   GetFunctions(&functions);
     944           0 :   return functions.length() > 1;
     945             : }
     946             : 
     947             : 
     948          12 : int JavaScriptFrame::GetArgumentsLength() const {
     949             :   // If there is an arguments adaptor frame get the arguments length from it.
     950          12 :   if (has_adapted_arguments()) {
     951          12 :     return ArgumentsAdaptorFrame::GetLength(caller_fp());
     952             :   } else {
     953           0 :     return GetNumberOfIncomingArguments();
     954             :   }
     955             : }
     956             : 
     957             : 
     958      373023 : Code* JavaScriptFrame::unchecked_code() const {
     959      746046 :   return function()->code();
     960             : }
     961             : 
     962             : 
     963    13144112 : int JavaScriptFrame::GetNumberOfIncomingArguments() const {
     964             :   DCHECK(can_access_heap_objects() &&
     965             :          isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
     966             : 
     967    26288224 :   return function()->shared()->internal_formal_parameter_count();
     968             : }
     969             : 
     970             : 
     971    53731287 : Address JavaScriptFrame::GetCallerStackPointer() const {
     972    53731287 :   return fp() + StandardFrameConstants::kCallerSPOffset;
     973             : }
     974             : 
     975      483964 : void JavaScriptFrame::GetFunctions(List<SharedFunctionInfo*>* functions) const {
     976             :   DCHECK(functions->length() == 0);
     977      967928 :   functions->Add(function()->shared());
     978      483964 : }
     979             : 
     980       54086 : void JavaScriptFrame::GetFunctions(
     981             :     List<Handle<SharedFunctionInfo>>* functions) const {
     982             :   DCHECK(functions->length() == 0);
     983             :   List<SharedFunctionInfo*> raw_functions;
     984       54086 :   GetFunctions(&raw_functions);
     985      162427 :   for (const auto& raw_function : raw_functions) {
     986      108510 :     functions->Add(Handle<SharedFunctionInfo>(raw_function));
     987             :   }
     988       54086 : }
     989             : 
     990     3202926 : void JavaScriptFrame::Summarize(List<FrameSummary>* functions,
     991             :                                 FrameSummary::Mode mode) const {
     992             :   DCHECK(functions->length() == 0);
     993     3202926 :   Code* code = LookupCode();
     994     3202926 :   int offset = static_cast<int>(pc() - code->instruction_start());
     995             :   AbstractCode* abstract_code = AbstractCode::cast(code);
     996     3202926 :   FrameSummary::JavaScriptFrameSummary summary(isolate(), receiver(),
     997     3202926 :                                                function(), abstract_code,
     998    12811704 :                                                offset, IsConstructor(), mode);
     999     3202926 :   functions->Add(summary);
    1000     3202926 : }
    1001             : 
    1002    86176654 : JSFunction* JavaScriptFrame::function() const {
    1003    86176654 :   return JSFunction::cast(function_slot_object());
    1004             : }
    1005             : 
    1006    12603414 : Object* JavaScriptFrame::receiver() const { return GetParameter(-1); }
    1007             : 
    1008      808886 : Object* JavaScriptFrame::context() const {
    1009             :   const int offset = StandardFrameConstants::kContextOffset;
    1010      808886 :   Object* maybe_result = Memory::Object_at(fp() + offset);
    1011             :   DCHECK(!maybe_result->IsSmi());
    1012      808886 :   return maybe_result;
    1013             : }
    1014             : 
    1015           0 : Script* JavaScriptFrame::script() const {
    1016           0 :   return Script::cast(function()->shared()->script());
    1017             : }
    1018             : 
    1019     3428070 : int JavaScriptFrame::LookupExceptionHandlerInTable(
    1020             :     int* stack_depth, HandlerTable::CatchPrediction* prediction) {
    1021             :   DCHECK_EQ(0, LookupCode()->handler_table()->length());
    1022             :   DCHECK(!LookupCode()->is_optimized_code());
    1023     3428070 :   return -1;
    1024             : }
    1025             : 
    1026           0 : void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function,
    1027             :                                              AbstractCode* code,
    1028             :                                              int code_offset, FILE* file,
    1029             :                                              bool print_line_number) {
    1030           0 :   PrintF(file, "%s", function->IsOptimized() ? "*" : "~");
    1031           0 :   function->PrintName(file);
    1032           0 :   PrintF(file, "+%d", code_offset);
    1033           0 :   if (print_line_number) {
    1034             :     SharedFunctionInfo* shared = function->shared();
    1035           0 :     int source_pos = code->SourcePosition(code_offset);
    1036             :     Object* maybe_script = shared->script();
    1037           0 :     if (maybe_script->IsScript()) {
    1038             :       Script* script = Script::cast(maybe_script);
    1039           0 :       int line = script->GetLineNumber(source_pos) + 1;
    1040             :       Object* script_name_raw = script->name();
    1041           0 :       if (script_name_raw->IsString()) {
    1042             :         String* script_name = String::cast(script->name());
    1043             :         std::unique_ptr<char[]> c_script_name =
    1044           0 :             script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
    1045           0 :         PrintF(file, " at %s:%d", c_script_name.get(), line);
    1046             :       } else {
    1047           0 :         PrintF(file, " at <unknown>:%d", line);
    1048             :       }
    1049             :     } else {
    1050           0 :       PrintF(file, " at <unknown>:<unknown>");
    1051             :     }
    1052             :   }
    1053           0 : }
    1054             : 
    1055           0 : void JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file, bool print_args,
    1056             :                                bool print_line_number) {
    1057             :   // constructor calls
    1058             :   DisallowHeapAllocation no_allocation;
    1059           0 :   JavaScriptFrameIterator it(isolate);
    1060           0 :   while (!it.done()) {
    1061           0 :     if (it.frame()->is_java_script()) {
    1062             :       JavaScriptFrame* frame = it.frame();
    1063           0 :       if (frame->IsConstructor()) PrintF(file, "new ");
    1064           0 :       JSFunction* function = frame->function();
    1065             :       int code_offset = 0;
    1066           0 :       if (frame->is_interpreted()) {
    1067             :         InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame);
    1068             :         code_offset = iframe->GetBytecodeOffset();
    1069             :       } else {
    1070           0 :         Code* code = frame->unchecked_code();
    1071           0 :         code_offset = static_cast<int>(frame->pc() - code->instruction_start());
    1072             :       }
    1073             :       PrintFunctionAndOffset(function, function->abstract_code(), code_offset,
    1074           0 :                              file, print_line_number);
    1075           0 :       if (print_args) {
    1076             :         // function arguments
    1077             :         // (we are intentionally only printing the actually
    1078             :         // supplied parameters, not all parameters required)
    1079           0 :         PrintF(file, "(this=");
    1080           0 :         frame->receiver()->ShortPrint(file);
    1081           0 :         const int length = frame->ComputeParametersCount();
    1082           0 :         for (int i = 0; i < length; i++) {
    1083           0 :           PrintF(file, ", ");
    1084           0 :           frame->GetParameter(i)->ShortPrint(file);
    1085             :         }
    1086           0 :         PrintF(file, ")");
    1087             :       }
    1088             :       break;
    1089             :     }
    1090           0 :     it.Advance();
    1091             :   }
    1092           0 : }
    1093             : 
    1094           0 : void JavaScriptFrame::CollectFunctionAndOffsetForICStats(JSFunction* function,
    1095             :                                                          AbstractCode* code,
    1096             :                                                          int code_offset) {
    1097             :   auto ic_stats = ICStats::instance();
    1098             :   ICInfo& ic_info = ic_stats->Current();
    1099             :   SharedFunctionInfo* shared = function->shared();
    1100             : 
    1101           0 :   ic_info.function_name = ic_stats->GetOrCacheFunctionName(function);
    1102           0 :   ic_info.script_offset = code_offset;
    1103             : 
    1104           0 :   int source_pos = code->SourcePosition(code_offset);
    1105             :   Object* maybe_script = shared->script();
    1106           0 :   if (maybe_script->IsScript()) {
    1107             :     Script* script = Script::cast(maybe_script);
    1108           0 :     ic_info.line_num = script->GetLineNumber(source_pos) + 1;
    1109           0 :     ic_info.script_name = ic_stats->GetOrCacheScriptName(script);
    1110             :   }
    1111           0 : }
    1112             : 
    1113           0 : void JavaScriptFrame::CollectTopFrameForICStats(Isolate* isolate) {
    1114             :   // constructor calls
    1115             :   DisallowHeapAllocation no_allocation;
    1116           0 :   JavaScriptFrameIterator it(isolate);
    1117             :   ICInfo& ic_info = ICStats::instance()->Current();
    1118           0 :   while (!it.done()) {
    1119           0 :     if (it.frame()->is_java_script()) {
    1120             :       JavaScriptFrame* frame = it.frame();
    1121           0 :       if (frame->IsConstructor()) ic_info.is_constructor = true;
    1122           0 :       JSFunction* function = frame->function();
    1123             :       int code_offset = 0;
    1124           0 :       if (frame->is_interpreted()) {
    1125             :         InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame);
    1126             :         code_offset = iframe->GetBytecodeOffset();
    1127             :       } else {
    1128           0 :         Code* code = frame->unchecked_code();
    1129           0 :         code_offset = static_cast<int>(frame->pc() - code->instruction_start());
    1130             :       }
    1131             :       CollectFunctionAndOffsetForICStats(function, function->abstract_code(),
    1132           0 :                                          code_offset);
    1133           0 :       return;
    1134             :     }
    1135           0 :     it.Advance();
    1136             :   }
    1137             : }
    1138             : 
    1139    15520628 : Object* JavaScriptFrame::GetParameter(int index) const {
    1140    15520628 :   return Memory::Object_at(GetParameterSlot(index));
    1141             : }
    1142             : 
    1143    15905286 : int JavaScriptFrame::ComputeParametersCount() const {
    1144    15905286 :   return GetNumberOfIncomingArguments();
    1145             : }
    1146             : 
    1147             : namespace {
    1148             : 
    1149             : bool CannotDeoptFromAsmCode(Code* code, JSFunction* function) {
    1150     2619568 :   return code->is_turbofanned() && function->shared()->asm_function();
    1151             : }
    1152             : 
    1153             : }  // namespace
    1154             : 
    1155    14369805 : FrameSummary::JavaScriptFrameSummary::JavaScriptFrameSummary(
    1156             :     Isolate* isolate, Object* receiver, JSFunction* function,
    1157             :     AbstractCode* abstract_code, int code_offset, bool is_constructor,
    1158             :     Mode mode)
    1159             :     : FrameSummaryBase(isolate, JAVA_SCRIPT),
    1160             :       receiver_(receiver, isolate),
    1161             :       function_(function, isolate),
    1162             :       abstract_code_(abstract_code, isolate),
    1163             :       code_offset_(code_offset),
    1164    14369805 :       is_constructor_(is_constructor) {
    1165             :   DCHECK(abstract_code->IsBytecodeArray() ||
    1166             :          Code::cast(abstract_code)->kind() != Code::OPTIMIZED_FUNCTION ||
    1167             :          CannotDeoptFromAsmCode(Code::cast(abstract_code), function) ||
    1168             :          mode == kApproximateSummary);
    1169    14369805 : }
    1170             : 
    1171           0 : bool FrameSummary::JavaScriptFrameSummary::is_subject_to_debugging() const {
    1172     6240134 :   return function()->shared()->IsSubjectToDebugging();
    1173             : }
    1174             : 
    1175     1410161 : int FrameSummary::JavaScriptFrameSummary::SourcePosition() const {
    1176     1410161 :   return abstract_code()->SourcePosition(code_offset());
    1177             : }
    1178             : 
    1179       65971 : int FrameSummary::JavaScriptFrameSummary::SourceStatementPosition() const {
    1180       65971 :   return abstract_code()->SourceStatementPosition(code_offset());
    1181             : }
    1182             : 
    1183     1215219 : Handle<Object> FrameSummary::JavaScriptFrameSummary::script() const {
    1184     2430438 :   return handle(function_->shared()->script(), isolate());
    1185             : }
    1186             : 
    1187       47006 : Handle<String> FrameSummary::JavaScriptFrameSummary::FunctionName() const {
    1188       47006 :   return JSFunction::GetDebugName(function_);
    1189             : }
    1190             : 
    1191       12655 : Handle<Context> FrameSummary::JavaScriptFrameSummary::native_context() const {
    1192       25310 :   return handle(function_->context()->native_context(), isolate());
    1193             : }
    1194             : 
    1195           0 : FrameSummary::WasmFrameSummary::WasmFrameSummary(
    1196             :     Isolate* isolate, FrameSummary::Kind kind,
    1197             :     Handle<WasmInstanceObject> instance, bool at_to_number_conversion)
    1198             :     : FrameSummaryBase(isolate, kind),
    1199             :       wasm_instance_(instance),
    1200       75647 :       at_to_number_conversion_(at_to_number_conversion) {}
    1201             : 
    1202           0 : Handle<Object> FrameSummary::WasmFrameSummary::receiver() const {
    1203           0 :   return wasm_instance_->GetIsolate()->global_proxy();
    1204             : }
    1205             : 
    1206             : #define WASM_SUMMARY_DISPATCH(type, name)                                      \
    1207             :   type FrameSummary::WasmFrameSummary::name() const {                          \
    1208             :     DCHECK(kind() == Kind::WASM_COMPILED || kind() == Kind::WASM_INTERPRETED); \
    1209             :     return kind() == Kind::WASM_COMPILED                                       \
    1210             :                ? static_cast<const WasmCompiledFrameSummary*>(this)->name()    \
    1211             :                : static_cast<const WasmInterpretedFrameSummary*>(this)         \
    1212             :                      ->name();                                                 \
    1213             :   }
    1214             : 
    1215       38058 : WASM_SUMMARY_DISPATCH(uint32_t, function_index)
    1216       38076 : WASM_SUMMARY_DISPATCH(int, byte_offset)
    1217             : 
    1218             : #undef WASM_SUMMARY_DISPATCH
    1219             : 
    1220       37361 : int FrameSummary::WasmFrameSummary::SourcePosition() const {
    1221       37214 :   int offset = byte_offset();
    1222             :   Handle<WasmCompiledModule> compiled_module(wasm_instance()->compiled_module(),
    1223       74428 :                                              isolate());
    1224       37214 :   if (compiled_module->is_asm_js()) {
    1225             :     offset = WasmCompiledModule::GetAsmJsSourcePosition(
    1226         294 :         compiled_module, function_index(), offset, at_to_number_conversion());
    1227             :   } else {
    1228       37067 :     offset += compiled_module->GetFunctionOffset(function_index());
    1229             :   }
    1230       37214 :   return offset;
    1231             : }
    1232             : 
    1233       37449 : Handle<Script> FrameSummary::WasmFrameSummary::script() const {
    1234       74898 :   return handle(wasm_instance()->compiled_module()->script());
    1235             : }
    1236             : 
    1237         374 : Handle<String> FrameSummary::WasmFrameSummary::FunctionName() const {
    1238             :   Handle<WasmCompiledModule> compiled_module(
    1239         374 :       wasm_instance()->compiled_module());
    1240             :   return WasmCompiledModule::GetFunctionName(compiled_module->GetIsolate(),
    1241         374 :                                              compiled_module, function_index());
    1242             : }
    1243             : 
    1244          49 : Handle<Context> FrameSummary::WasmFrameSummary::native_context() const {
    1245          49 :   return wasm_instance()->compiled_module()->native_context();
    1246             : }
    1247             : 
    1248           0 : FrameSummary::WasmCompiledFrameSummary::WasmCompiledFrameSummary(
    1249             :     Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> code,
    1250             :     int code_offset, bool at_to_number_conversion)
    1251             :     : WasmFrameSummary(isolate, WASM_COMPILED, instance,
    1252             :                        at_to_number_conversion),
    1253             :       code_(code),
    1254           0 :       code_offset_(code_offset) {}
    1255             : 
    1256       74308 : uint32_t FrameSummary::WasmCompiledFrameSummary::function_index() const {
    1257             :   FixedArray* deopt_data = code()->deoptimization_data();
    1258             :   DCHECK_EQ(2, deopt_data->length());
    1259             :   DCHECK(deopt_data->get(1)->IsSmi());
    1260             :   int val = Smi::cast(deopt_data->get(1))->value();
    1261             :   DCHECK_LE(0, val);
    1262       74308 :   return static_cast<uint32_t>(val);
    1263             : }
    1264             : 
    1265       36822 : int FrameSummary::WasmCompiledFrameSummary::byte_offset() const {
    1266       36822 :   return AbstractCode::cast(*code())->SourcePosition(code_offset());
    1267             : }
    1268             : 
    1269           0 : FrameSummary::WasmInterpretedFrameSummary::WasmInterpretedFrameSummary(
    1270             :     Isolate* isolate, Handle<WasmInstanceObject> instance,
    1271             :     uint32_t function_index, int byte_offset)
    1272             :     : WasmFrameSummary(isolate, WASM_INTERPRETED, instance, false),
    1273             :       function_index_(function_index),
    1274           0 :       byte_offset_(byte_offset) {}
    1275             : 
    1276    21936970 : FrameSummary::~FrameSummary() {
    1277             : #define FRAME_SUMMARY_DESTR(kind, type, field, desc) \
    1278             :   case kind:                                         \
    1279             :     field.~type();                                   \
    1280             :     break;
    1281    21936970 :   switch (base_.kind()) {
    1282             :     FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_DESTR)
    1283             :     default:
    1284           0 :       UNREACHABLE();
    1285             :   }
    1286             : #undef FRAME_SUMMARY_DESTR
    1287    21936970 : }
    1288             : 
    1289     1070685 : FrameSummary FrameSummary::GetTop(const StandardFrame* frame) {
    1290     1070685 :   List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
    1291     1070685 :   frame->Summarize(&frames);
    1292             :   DCHECK_LT(0, frames.length());
    1293     2141370 :   return frames.last();
    1294             : }
    1295             : 
    1296           0 : FrameSummary FrameSummary::GetBottom(const StandardFrame* frame) {
    1297           0 :   return Get(frame, 0);
    1298             : }
    1299             : 
    1300       37339 : FrameSummary FrameSummary::GetSingle(const StandardFrame* frame) {
    1301             :   List<FrameSummary> frames(1);
    1302       37339 :   frame->Summarize(&frames);
    1303             :   DCHECK_EQ(1, frames.length());
    1304       74678 :   return frames.first();
    1305             : }
    1306             : 
    1307      451502 : FrameSummary FrameSummary::Get(const StandardFrame* frame, int index) {
    1308             :   DCHECK_LE(0, index);
    1309      451502 :   List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
    1310      451502 :   frame->Summarize(&frames);
    1311             :   DCHECK_GT(frames.length(), index);
    1312     1354506 :   return frames[index];
    1313             : }
    1314             : 
    1315             : #define FRAME_SUMMARY_DISPATCH(ret, name)        \
    1316             :   ret FrameSummary::name() const {               \
    1317             :     switch (base_.kind()) {                      \
    1318             :       case JAVA_SCRIPT:                          \
    1319             :         return java_script_summary_.name();      \
    1320             :       case WASM_COMPILED:                        \
    1321             :         return wasm_compiled_summary_.name();    \
    1322             :       case WASM_INTERPRETED:                     \
    1323             :         return wasm_interpreted_summary_.name(); \
    1324             :       default:                                   \
    1325             :         UNREACHABLE();                           \
    1326             :         return ret{};                            \
    1327             :     }                                            \
    1328             :   }
    1329             : 
    1330     4906594 : FRAME_SUMMARY_DISPATCH(Handle<Object>, receiver)
    1331     5156146 : FRAME_SUMMARY_DISPATCH(int, code_offset)
    1332      229173 : FRAME_SUMMARY_DISPATCH(bool, is_constructor)
    1333     6243772 : FRAME_SUMMARY_DISPATCH(bool, is_subject_to_debugging)
    1334     1239778 : FRAME_SUMMARY_DISPATCH(Handle<Object>, script)
    1335     1471493 : FRAME_SUMMARY_DISPATCH(int, SourcePosition)
    1336       65971 : FRAME_SUMMARY_DISPATCH(int, SourceStatementPosition)
    1337         472 : FRAME_SUMMARY_DISPATCH(Handle<String>, FunctionName)
    1338       12704 : FRAME_SUMMARY_DISPATCH(Handle<Context>, native_context)
    1339             : 
    1340             : #undef FRAME_SUMMARY_DISPATCH
    1341             : 
    1342     1588993 : void OptimizedFrame::Summarize(List<FrameSummary>* frames,
    1343             :                                FrameSummary::Mode mode) const {
    1344             :   DCHECK(frames->length() == 0);
    1345             :   DCHECK(is_optimized());
    1346             : 
    1347             :   // Delegate to JS frame in absence of turbofan deoptimization.
    1348             :   // TODO(turbofan): Revisit once we support deoptimization across the board.
    1349     1609142 :   Code* code = LookupCode();
    1350     2961777 :   if (code->kind() == Code::BUILTIN ||
    1351     1372784 :       CannotDeoptFromAsmCode(code, function())) {
    1352      433306 :     return JavaScriptFrame::Summarize(frames);
    1353             :   }
    1354             : 
    1355             :   DisallowHeapAllocation no_gc;
    1356     1372340 :   int deopt_index = Safepoint::kNoDeoptimizationIndex;
    1357     1372340 :   DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index);
    1358     1372340 :   if (deopt_index == Safepoint::kNoDeoptimizationIndex) {
    1359             :     DCHECK(data == nullptr);
    1360           0 :     if (mode == FrameSummary::kApproximateSummary) {
    1361           0 :       return JavaScriptFrame::Summarize(frames, mode);
    1362             :     }
    1363           0 :     FATAL("Missing deoptimization information for OptimizedFrame::Summarize.");
    1364             :   }
    1365             :   FixedArray* const literal_array = data->LiteralArray();
    1366             : 
    1367             :   TranslationIterator it(data->TranslationByteArray(),
    1368     1372340 :                          data->TranslationIndex(deopt_index)->value());
    1369             :   Translation::Opcode frame_opcode =
    1370     1372340 :       static_cast<Translation::Opcode>(it.Next());
    1371             :   DCHECK_EQ(Translation::BEGIN, frame_opcode);
    1372     1372340 :   it.Next();  // Drop frame count.
    1373     1372340 :   int jsframe_count = it.Next();
    1374             : 
    1375             :   // We create the summary in reverse order because the frames
    1376             :   // in the deoptimization translation are ordered bottom-to-top.
    1377     1372340 :   bool is_constructor = IsConstructor();
    1378     6445741 :   while (jsframe_count != 0) {
    1379     3701061 :     frame_opcode = static_cast<Translation::Opcode>(it.Next());
    1380     3701061 :     if (frame_opcode == Translation::JS_FRAME ||
    1381             :         frame_opcode == Translation::INTERPRETED_FRAME) {
    1382     1581455 :       jsframe_count--;
    1383     1581455 :       BailoutId const bailout_id = BailoutId(it.Next());
    1384             :       SharedFunctionInfo* const shared_info =
    1385     1581455 :           SharedFunctionInfo::cast(literal_array->get(it.Next()));
    1386     1581455 :       it.Next();  // Skip height.
    1387             : 
    1388             :       // The translation commands are ordered and the function is always
    1389             :       // at the first position, and the receiver is next.
    1390     1581455 :       Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
    1391             : 
    1392             :       // Get the correct function in the optimized frame.
    1393             :       JSFunction* function;
    1394     1581455 :       if (opcode == Translation::LITERAL) {
    1395      160499 :         function = JSFunction::cast(literal_array->get(it.Next()));
    1396             :       } else {
    1397     1420956 :         CHECK_EQ(opcode, Translation::STACK_SLOT);
    1398     1420956 :         function = JSFunction::cast(StackSlotAt(it.Next()));
    1399             :       }
    1400             :       DCHECK_EQ(shared_info, function->shared());
    1401             : 
    1402             :       // If we are at a call, the receiver is always in a stack slot.
    1403             :       // Otherwise we are not guaranteed to get the receiver value.
    1404     1581455 :       opcode = static_cast<Translation::Opcode>(it.Next());
    1405             : 
    1406             :       // Get the correct receiver in the optimized frame.
    1407             :       Object* receiver;
    1408     1581455 :       if (opcode == Translation::LITERAL) {
    1409      135083 :         receiver = literal_array->get(it.Next());
    1410     1446372 :       } else if (opcode == Translation::STACK_SLOT) {
    1411     1418685 :         receiver = StackSlotAt(it.Next());
    1412             :       } else {
    1413             :         // The receiver is not in a stack slot nor in a literal.  We give up.
    1414       27687 :         it.Skip(Translation::NumberOfOperandsFor(opcode));
    1415             :         // TODO(3029): Materializing a captured object (or duplicated
    1416             :         // object) is hard, we return undefined for now. This breaks the
    1417             :         // produced stack trace, as constructor frames aren't marked as
    1418             :         // such anymore.
    1419       27687 :         receiver = isolate()->heap()->undefined_value();
    1420             :       }
    1421             : 
    1422             :       AbstractCode* abstract_code;
    1423             : 
    1424             :       unsigned code_offset;
    1425     1581455 :       if (frame_opcode == Translation::JS_FRAME) {
    1426             :         Code* code = shared_info->code();
    1427             :         DeoptimizationOutputData* const output_data =
    1428             :             DeoptimizationOutputData::cast(code->deoptimization_data());
    1429             :         unsigned const entry =
    1430      534365 :             Deoptimizer::GetOutputInfo(output_data, bailout_id, shared_info);
    1431             :         code_offset = FullCodeGenerator::PcField::decode(entry);
    1432             :         abstract_code = AbstractCode::cast(code);
    1433             :       } else {
    1434             :         DCHECK_EQ(frame_opcode, Translation::INTERPRETED_FRAME);
    1435     1047090 :         code_offset = bailout_id.ToInt();  // Points to current bytecode.
    1436             :         abstract_code = AbstractCode::cast(shared_info->bytecode_array());
    1437             :       }
    1438             :       FrameSummary::JavaScriptFrameSummary summary(isolate(), receiver,
    1439             :                                                    function, abstract_code,
    1440     3162910 :                                                    code_offset, is_constructor);
    1441     1581455 :       frames->Add(summary);
    1442             :       is_constructor = false;
    1443     2119606 :     } else if (frame_opcode == Translation::CONSTRUCT_STUB_FRAME) {
    1444             :       // The next encountered JS_FRAME will be marked as a constructor call.
    1445       18121 :       it.Skip(Translation::NumberOfOperandsFor(frame_opcode));
    1446             :       DCHECK(!is_constructor);
    1447             :       is_constructor = true;
    1448             :     } else {
    1449             :       // Skip over operands to advance to the next opcode.
    1450     2101485 :       it.Skip(Translation::NumberOfOperandsFor(frame_opcode));
    1451             :     }
    1452             :   }
    1453             :   DCHECK(!is_constructor);
    1454             : }
    1455             : 
    1456             : 
    1457     2088497 : int OptimizedFrame::LookupExceptionHandlerInTable(
    1458             :     int* stack_slots, HandlerTable::CatchPrediction* prediction) {
    1459             :   // We cannot perform exception prediction on optimized code. Instead, we need
    1460             :   // to use FrameSummary to find the corresponding code offset in unoptimized
    1461             :   // code to perform prediction there.
    1462             :   DCHECK_NULL(prediction);
    1463             :   Code* code = LookupCode();
    1464             :   HandlerTable* table = HandlerTable::cast(code->handler_table());
    1465     2088497 :   int pc_offset = static_cast<int>(pc() - code->entry());
    1466     4077656 :   if (stack_slots) *stack_slots = code->stack_slots();
    1467     2088497 :   return table->LookupReturn(pc_offset);
    1468             : }
    1469             : 
    1470             : 
    1471     1628175 : DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData(
    1472             :     int* deopt_index) const {
    1473             :   DCHECK(is_optimized());
    1474             : 
    1475     1628175 :   JSFunction* opt_function = function();
    1476     1628175 :   Code* code = opt_function->code();
    1477             : 
    1478             :   // The code object may have been replaced by lazy deoptimization. Fall
    1479             :   // back to a slow search in this case to find the original optimized
    1480             :   // code object.
    1481     1800365 :   if (!code->contains(pc())) {
    1482             :     code = isolate()->inner_pointer_to_code_cache()->
    1483      172190 :         GcSafeFindCodeForInnerPointer(pc());
    1484             :   }
    1485             :   DCHECK(code != NULL);
    1486             :   DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
    1487             : 
    1488     1628175 :   SafepointEntry safepoint_entry = code->GetSafepointEntry(pc());
    1489     3256350 :   *deopt_index = safepoint_entry.deoptimization_index();
    1490     1628175 :   if (*deopt_index != Safepoint::kNoDeoptimizationIndex) {
    1491     1628175 :     return DeoptimizationInputData::cast(code->deoptimization_data());
    1492             :   }
    1493             :   return nullptr;
    1494             : }
    1495             : 
    1496      229223 : Object* OptimizedFrame::receiver() const {
    1497      216223 :   Code* code = LookupCode();
    1498      229223 :   if (code->kind() == Code::BUILTIN) {
    1499             :     Address argc_ptr = fp() + OptimizedBuiltinFrameConstants::kArgCOffset;
    1500      216223 :     intptr_t argc = *reinterpret_cast<intptr_t*>(argc_ptr);
    1501             :     intptr_t args_size =
    1502      216223 :         (StandardFrameConstants::kFixedSlotCountAboveFp + argc) * kPointerSize;
    1503      216223 :     Address receiver_ptr = fp() + args_size;
    1504      216223 :     return *reinterpret_cast<Object**>(receiver_ptr);
    1505             :   } else {
    1506       26000 :     return JavaScriptFrame::receiver();
    1507             :   }
    1508             : }
    1509             : 
    1510      196754 : void OptimizedFrame::GetFunctions(List<SharedFunctionInfo*>* functions) const {
    1511             :   DCHECK(functions->length() == 0);
    1512             :   DCHECK(is_optimized());
    1513             : 
    1514             :   // Delegate to JS frame in absence of turbofan deoptimization.
    1515             :   // TODO(turbofan): Revisit once we support deoptimization across the board.
    1516             :   Code* code = LookupCode();
    1517      390832 :   if (code->kind() == Code::BUILTIN ||
    1518      194078 :       CannotDeoptFromAsmCode(code, function())) {
    1519      200264 :     return JavaScriptFrame::GetFunctions(functions);
    1520             :   }
    1521             : 
    1522             :   DisallowHeapAllocation no_gc;
    1523      193244 :   int deopt_index = Safepoint::kNoDeoptimizationIndex;
    1524      193244 :   DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index);
    1525             :   DCHECK_NOT_NULL(data);
    1526             :   DCHECK_NE(Safepoint::kNoDeoptimizationIndex, deopt_index);
    1527             :   FixedArray* const literal_array = data->LiteralArray();
    1528             : 
    1529             :   TranslationIterator it(data->TranslationByteArray(),
    1530      193244 :                          data->TranslationIndex(deopt_index)->value());
    1531      193244 :   Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
    1532             :   DCHECK_EQ(Translation::BEGIN, opcode);
    1533      193244 :   it.Next();  // Skip frame count.
    1534      193244 :   int jsframe_count = it.Next();
    1535             : 
    1536             :   // We insert the frames in reverse order because the frames
    1537             :   // in the deoptimization translation are ordered bottom-to-top.
    1538      582273 :   while (jsframe_count != 0) {
    1539      195785 :     opcode = static_cast<Translation::Opcode>(it.Next());
    1540      195785 :     if (opcode == Translation::JS_FRAME ||
    1541             :         opcode == Translation::INTERPRETED_FRAME) {
    1542      193643 :       it.Next();  // Skip bailout id.
    1543      193643 :       jsframe_count--;
    1544             : 
    1545             :       // The second operand of the frame points to the function.
    1546      193643 :       Object* shared = literal_array->get(it.Next());
    1547      193643 :       functions->Add(SharedFunctionInfo::cast(shared));
    1548             : 
    1549             :       // Skip over remaining operands to advance to the next opcode.
    1550      193643 :       it.Skip(Translation::NumberOfOperandsFor(opcode) - 2);
    1551             :     } else {
    1552             :       // Skip over operands to advance to the next opcode.
    1553        2142 :       it.Skip(Translation::NumberOfOperandsFor(opcode));
    1554             :     }
    1555             :   }
    1556             : }
    1557             : 
    1558             : 
    1559     1224534 : int OptimizedFrame::StackSlotOffsetRelativeToFp(int slot_index) {
    1560     4064175 :   return StandardFrameConstants::kCallerSPOffset -
    1561     4064175 :          ((slot_index + 1) * kPointerSize);
    1562             : }
    1563             : 
    1564             : 
    1565           0 : Object* OptimizedFrame::StackSlotAt(int index) const {
    1566     5679282 :   return Memory::Object_at(fp() + StackSlotOffsetRelativeToFp(index));
    1567             : }
    1568             : 
    1569           0 : int InterpretedFrame::position() const {
    1570             :   AbstractCode* code = AbstractCode::cast(GetBytecodeArray());
    1571             :   int code_offset = GetBytecodeOffset();
    1572           0 :   return code->SourcePosition(code_offset);
    1573             : }
    1574             : 
    1575     4723091 : int InterpretedFrame::LookupExceptionHandlerInTable(
    1576             :     int* context_register, HandlerTable::CatchPrediction* prediction) {
    1577     4723091 :   BytecodeArray* bytecode = function()->shared()->bytecode_array();
    1578             :   HandlerTable* table = HandlerTable::cast(bytecode->handler_table());
    1579     4723091 :   return table->LookupRange(GetBytecodeOffset(), context_register, prediction);
    1580             : }
    1581             : 
    1582      252286 : int InterpretedFrame::GetBytecodeOffset() const {
    1583             :   const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
    1584             :   DCHECK_EQ(
    1585             :       InterpreterFrameConstants::kBytecodeOffsetFromFp,
    1586             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1587    14560801 :   int raw_offset = Smi::cast(GetExpression(index))->value();
    1588    14560817 :   return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
    1589             : }
    1590             : 
    1591           0 : int InterpretedFrame::GetBytecodeOffset(Address fp) {
    1592             :   const int offset = InterpreterFrameConstants::kExpressionsOffset;
    1593             :   const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
    1594             :   DCHECK_EQ(
    1595             :       InterpreterFrameConstants::kBytecodeOffsetFromFp,
    1596             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1597             :   Address expression_offset = fp + offset - index * kPointerSize;
    1598           0 :   int raw_offset = Smi::cast(Memory::Object_at(expression_offset))->value();
    1599           0 :   return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
    1600             : }
    1601             : 
    1602      919886 : void InterpretedFrame::PatchBytecodeOffset(int new_offset) {
    1603             :   const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
    1604             :   DCHECK_EQ(
    1605             :       InterpreterFrameConstants::kBytecodeOffsetFromFp,
    1606             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1607      919886 :   int raw_offset = new_offset + BytecodeArray::kHeaderSize - kHeapObjectTag;
    1608      919886 :   SetExpression(index, Smi::FromInt(raw_offset));
    1609      919886 : }
    1610             : 
    1611     4747968 : BytecodeArray* InterpretedFrame::GetBytecodeArray() const {
    1612             :   const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
    1613             :   DCHECK_EQ(
    1614             :       InterpreterFrameConstants::kBytecodeArrayFromFp,
    1615             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1616     9495952 :   return BytecodeArray::cast(GetExpression(index));
    1617             : }
    1618             : 
    1619        2196 : void InterpretedFrame::PatchBytecodeArray(BytecodeArray* bytecode_array) {
    1620             :   const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
    1621             :   DCHECK_EQ(
    1622             :       InterpreterFrameConstants::kBytecodeArrayFromFp,
    1623             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1624        2196 :   SetExpression(index, bytecode_array);
    1625        2196 : }
    1626             : 
    1627      919886 : Object* InterpretedFrame::ReadInterpreterRegister(int register_index) const {
    1628             :   const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
    1629             :   DCHECK_EQ(
    1630             :       InterpreterFrameConstants::kRegisterFileFromFp,
    1631             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1632     1839772 :   return GetExpression(index + register_index);
    1633             : }
    1634             : 
    1635           0 : void InterpretedFrame::WriteInterpreterRegister(int register_index,
    1636             :                                                 Object* value) {
    1637             :   const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
    1638             :   DCHECK_EQ(
    1639             :       InterpreterFrameConstants::kRegisterFileFromFp,
    1640             :       InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
    1641           0 :   return SetExpression(index + register_index, value);
    1642             : }
    1643             : 
    1644     9585424 : void InterpretedFrame::Summarize(List<FrameSummary>* functions,
    1645             :                                  FrameSummary::Mode mode) const {
    1646             :   DCHECK(functions->length() == 0);
    1647             :   AbstractCode* abstract_code =
    1648     9585424 :       AbstractCode::cast(function()->shared()->bytecode_array());
    1649             :   FrameSummary::JavaScriptFrameSummary summary(
    1650    19170848 :       isolate(), receiver(), function(), abstract_code, GetBytecodeOffset(),
    1651    28756272 :       IsConstructor());
    1652     9585424 :   functions->Add(summary);
    1653     9585424 : }
    1654             : 
    1655     2757075 : int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const {
    1656     5514150 :   return Smi::cast(GetExpression(0))->value();
    1657             : }
    1658             : 
    1659           0 : int ArgumentsAdaptorFrame::GetLength(Address fp) {
    1660             :   const int offset = ArgumentsAdaptorFrameConstants::kLengthOffset;
    1661          12 :   return Smi::cast(Memory::Object_at(fp + offset))->value();
    1662             : }
    1663             : 
    1664       40839 : Code* ArgumentsAdaptorFrame::unchecked_code() const {
    1665             :   return isolate()->builtins()->builtin(
    1666       81678 :       Builtins::kArgumentsAdaptorTrampoline);
    1667             : }
    1668             : 
    1669        4099 : int BuiltinFrame::GetNumberOfIncomingArguments() const {
    1670        8198 :   return Smi::cast(GetExpression(0))->value();
    1671             : }
    1672             : 
    1673           0 : void BuiltinFrame::PrintFrameKind(StringStream* accumulator) const {
    1674           0 :   accumulator->Add("builtin frame: ");
    1675           0 : }
    1676             : 
    1677     5483341 : Address InternalFrame::GetCallerStackPointer() const {
    1678             :   // Internal frames have no arguments. The stack pointer of the
    1679             :   // caller is at a fixed offset from the frame pointer.
    1680     5483341 :   return fp() + StandardFrameConstants::kCallerSPOffset;
    1681             : }
    1682             : 
    1683       47339 : Code* InternalFrame::unchecked_code() const {
    1684             :   const int offset = InternalFrameConstants::kCodeOffset;
    1685       47339 :   Object* code = Memory::Object_at(fp() + offset);
    1686             :   DCHECK(code != NULL);
    1687       47339 :   return reinterpret_cast<Code*>(code);
    1688             : }
    1689             : 
    1690             : 
    1691           0 : void StackFrame::PrintIndex(StringStream* accumulator,
    1692             :                             PrintMode mode,
    1693             :                             int index) {
    1694          42 :   accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index);
    1695           0 : }
    1696             : 
    1697           0 : void WasmCompiledFrame::Print(StringStream* accumulator, PrintMode mode,
    1698             :                               int index) const {
    1699             :   PrintIndex(accumulator, mode, index);
    1700           0 :   accumulator->Add("WASM [");
    1701           0 :   Script* script = this->script();
    1702           0 :   accumulator->PrintName(script->name());
    1703           0 :   int pc = static_cast<int>(this->pc() - LookupCode()->instruction_start());
    1704           0 :   Object* instance = this->wasm_instance();
    1705             :   Vector<const uint8_t> raw_func_name =
    1706             :       WasmInstanceObject::cast(instance)->compiled_module()->GetRawFunctionName(
    1707           0 :           this->function_index());
    1708           0 :   const int kMaxPrintedFunctionName = 64;
    1709             :   char func_name[kMaxPrintedFunctionName + 1];
    1710           0 :   int func_name_len = std::min(kMaxPrintedFunctionName, raw_func_name.length());
    1711           0 :   memcpy(func_name, raw_func_name.start(), func_name_len);
    1712           0 :   func_name[func_name_len] = '\0';
    1713             :   accumulator->Add("], function #%u ('%s'), pc=%p, pos=%d\n",
    1714           0 :                    this->function_index(), func_name, pc, this->position());
    1715           0 :   if (mode != OVERVIEW) accumulator->Add("\n");
    1716           0 : }
    1717             : 
    1718       42028 : Code* WasmCompiledFrame::unchecked_code() const {
    1719       42028 :   return isolate()->FindCodeObject(pc());
    1720             : }
    1721             : 
    1722        9407 : void WasmCompiledFrame::Iterate(RootVisitor* v) const {
    1723        9407 :   IterateCompiledFrame(v);
    1724        9407 : }
    1725             : 
    1726     2498610 : Address WasmCompiledFrame::GetCallerStackPointer() const {
    1727     2498610 :   return fp() + ExitFrameConstants::kCallerSPOffset;
    1728             : }
    1729             : 
    1730      112986 : WasmInstanceObject* WasmCompiledFrame::wasm_instance() const {
    1731      112986 :   WasmInstanceObject* obj = wasm::GetOwningWasmInstance(LookupCode());
    1732             :   // This is a live stack frame; it must have a live instance.
    1733             :   DCHECK_NOT_NULL(obj);
    1734      112986 :   return obj;
    1735             : }
    1736             : 
    1737       37339 : uint32_t WasmCompiledFrame::function_index() const {
    1738       37339 :   return FrameSummary::GetSingle(this).AsWasmCompiled().function_index();
    1739             : }
    1740             : 
    1741           0 : Script* WasmCompiledFrame::script() const {
    1742           0 :   return wasm_instance()->compiled_module()->script();
    1743             : }
    1744             : 
    1745           0 : int WasmCompiledFrame::position() const {
    1746           0 :   return FrameSummary::GetSingle(this).SourcePosition();
    1747             : }
    1748             : 
    1749       75647 : void WasmCompiledFrame::Summarize(List<FrameSummary>* functions,
    1750             :                                   FrameSummary::Mode mode) const {
    1751             :   DCHECK_EQ(0, functions->length());
    1752      226941 :   Handle<Code> code(LookupCode(), isolate());
    1753      151294 :   int offset = static_cast<int>(pc() - code->instruction_start());
    1754       75647 :   Handle<WasmInstanceObject> instance(wasm_instance(), isolate());
    1755             :   FrameSummary::WasmCompiledFrameSummary summary(
    1756       75647 :       isolate(), instance, code, offset, at_to_number_conversion());
    1757       75647 :   functions->Add(summary);
    1758       75647 : }
    1759             : 
    1760       76366 : bool WasmCompiledFrame::at_to_number_conversion() const {
    1761             :   // Check whether our callee is a WASM_TO_JS frame, and this frame is at the
    1762             :   // ToNumber conversion call.
    1763       79956 :   Address callee_pc = reinterpret_cast<Address>(this->callee_pc());
    1764       79956 :   Code* code = callee_pc ? isolate()->FindCodeObject(callee_pc) : nullptr;
    1765       79956 :   if (!code || code->kind() != Code::WASM_TO_JS_FUNCTION) return false;
    1766        1387 :   int offset = static_cast<int>(callee_pc - code->instruction_start());
    1767        1387 :   int pos = AbstractCode::cast(code)->SourcePosition(offset);
    1768             :   DCHECK(pos == 0 || pos == 1);
    1769             :   // The imported call has position 0, ToNumber has position 1.
    1770        1387 :   return !!pos;
    1771             : }
    1772             : 
    1773        1830 : int WasmCompiledFrame::LookupExceptionHandlerInTable(int* stack_slots) {
    1774             :   DCHECK_NOT_NULL(stack_slots);
    1775             :   Code* code = LookupCode();
    1776             :   HandlerTable* table = HandlerTable::cast(code->handler_table());
    1777        1830 :   int pc_offset = static_cast<int>(pc() - code->entry());
    1778        1830 :   *stack_slots = code->stack_slots();
    1779        1830 :   return table->LookupReturn(pc_offset);
    1780             : }
    1781             : 
    1782           0 : void WasmInterpreterEntryFrame::Iterate(RootVisitor* v) const {
    1783           0 :   IterateCompiledFrame(v);
    1784           0 : }
    1785             : 
    1786           0 : void WasmInterpreterEntryFrame::Print(StringStream* accumulator, PrintMode mode,
    1787             :                                       int index) const {
    1788             :   PrintIndex(accumulator, mode, index);
    1789           0 :   accumulator->Add("WASM INTERPRETER ENTRY [");
    1790           0 :   Script* script = this->script();
    1791           0 :   accumulator->PrintName(script->name());
    1792           0 :   accumulator->Add("]");
    1793           0 :   if (mode != OVERVIEW) accumulator->Add("\n");
    1794           0 : }
    1795             : 
    1796        2470 : void WasmInterpreterEntryFrame::Summarize(List<FrameSummary>* functions,
    1797             :                                           FrameSummary::Mode mode) const {
    1798      991324 :   Handle<WasmInstanceObject> instance(wasm_instance(), isolate());
    1799             :   std::vector<std::pair<uint32_t, int>> interpreted_stack =
    1800        2470 :       instance->debug_info()->GetInterpretedStack(fp());
    1801             : 
    1802      991324 :   for (auto& e : interpreted_stack) {
    1803             :     FrameSummary::WasmInterpretedFrameSummary summary(isolate(), instance,
    1804      986384 :                                                       e.first, e.second);
    1805      986384 :     functions->Add(summary);
    1806             :   }
    1807        2470 : }
    1808             : 
    1809           0 : Code* WasmInterpreterEntryFrame::unchecked_code() const {
    1810           0 :   return isolate()->FindCodeObject(pc());
    1811             : }
    1812             : 
    1813        4101 : WasmInstanceObject* WasmInterpreterEntryFrame::wasm_instance() const {
    1814        4101 :   WasmInstanceObject* ret = wasm::GetOwningWasmInstance(LookupCode());
    1815             :   // This is a live stack frame, there must be a live wasm instance available.
    1816             :   DCHECK_NOT_NULL(ret);
    1817        4101 :   return ret;
    1818             : }
    1819             : 
    1820           0 : Script* WasmInterpreterEntryFrame::script() const {
    1821           0 :   return wasm_instance()->compiled_module()->script();
    1822             : }
    1823             : 
    1824           0 : int WasmInterpreterEntryFrame::position() const {
    1825           0 :   return FrameSummary::GetBottom(this).AsWasmInterpreted().SourcePosition();
    1826             : }
    1827             : 
    1828           0 : Object* WasmInterpreterEntryFrame::context() const {
    1829           0 :   return wasm_instance()->compiled_module()->ptr_to_native_context();
    1830             : }
    1831             : 
    1832        6319 : Address WasmInterpreterEntryFrame::GetCallerStackPointer() const {
    1833        6319 :   return fp() + ExitFrameConstants::kCallerSPOffset;
    1834             : }
    1835             : 
    1836             : namespace {
    1837             : 
    1838             : 
    1839          21 : void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared,
    1840             :                          Code* code) {
    1841          21 :   if (FLAG_max_stack_trace_source_length != 0 && code != NULL) {
    1842          21 :     std::ostringstream os;
    1843          21 :     os << "--------- s o u r c e   c o d e ---------\n"
    1844          63 :        << SourceCodeOf(shared, FLAG_max_stack_trace_source_length)
    1845          21 :        << "\n-----------------------------------------\n";
    1846          42 :     accumulator->Add(os.str().c_str());
    1847             :   }
    1848          21 : }
    1849             : 
    1850             : 
    1851             : }  // namespace
    1852             : 
    1853             : 
    1854          42 : void JavaScriptFrame::Print(StringStream* accumulator,
    1855             :                             PrintMode mode,
    1856             :                             int index) const {
    1857             :   DisallowHeapAllocation no_gc;
    1858          42 :   Object* receiver = this->receiver();
    1859          42 :   JSFunction* function = this->function();
    1860             : 
    1861          42 :   accumulator->PrintSecurityTokenIfChanged(function);
    1862             :   PrintIndex(accumulator, mode, index);
    1863          42 :   PrintFrameKind(accumulator);
    1864          42 :   Code* code = NULL;
    1865          42 :   if (IsConstructor()) accumulator->Add("new ");
    1866          42 :   accumulator->PrintFunction(function, receiver, &code);
    1867             : 
    1868             :   // Get scope information for nicer output, if possible. If code is NULL, or
    1869             :   // doesn't contain scope info, scope_info will return 0 for the number of
    1870             :   // parameters, stack local variables, context local variables, stack slots,
    1871             :   // or context slots.
    1872             :   SharedFunctionInfo* shared = function->shared();
    1873             :   ScopeInfo* scope_info = shared->scope_info();
    1874             :   Object* script_obj = shared->script();
    1875          42 :   if (script_obj->IsScript()) {
    1876             :     Script* script = Script::cast(script_obj);
    1877          28 :     accumulator->Add(" [");
    1878          28 :     accumulator->PrintName(script->name());
    1879             : 
    1880             :     Address pc = this->pc();
    1881          88 :     if (code != NULL && code->kind() == Code::FUNCTION &&
    1882          36 :         pc >= code->instruction_start() && pc < code->instruction_end()) {
    1883           4 :       int offset = static_cast<int>(pc - code->instruction_start());
    1884           4 :       int source_pos = AbstractCode::cast(code)->SourcePosition(offset);
    1885           4 :       int line = script->GetLineNumber(source_pos) + 1;
    1886           4 :       accumulator->Add(":%d] [pc=%p]", line, pc);
    1887          48 :     } else if (is_interpreted()) {
    1888             :       const InterpretedFrame* iframe =
    1889             :           reinterpret_cast<const InterpretedFrame*>(this);
    1890             :       BytecodeArray* bytecodes = iframe->GetBytecodeArray();
    1891             :       int offset = iframe->GetBytecodeOffset();
    1892          16 :       int source_pos = AbstractCode::cast(bytecodes)->SourcePosition(offset);
    1893          16 :       int line = script->GetLineNumber(source_pos) + 1;
    1894          16 :       accumulator->Add(":%d] [bytecode=%p offset=%d]", line, bytecodes, offset);
    1895             :     } else {
    1896             :       int function_start_pos = shared->start_position();
    1897           8 :       int line = script->GetLineNumber(function_start_pos) + 1;
    1898           8 :       accumulator->Add(":~%d] [pc=%p]", line, pc);
    1899             :     }
    1900             :   }
    1901             : 
    1902          42 :   accumulator->Add("(this=%o", receiver);
    1903             : 
    1904             :   // Print the parameters.
    1905          42 :   int parameters_count = ComputeParametersCount();
    1906         140 :   for (int i = 0; i < parameters_count; i++) {
    1907          98 :     accumulator->Add(",");
    1908             :     // If we have a name for the parameter we print it. Nameless
    1909             :     // parameters are either because we have more actual parameters
    1910             :     // than formal parameters or because we have no scope information.
    1911          98 :     if (i < scope_info->ParameterCount()) {
    1912           0 :       accumulator->PrintName(scope_info->ParameterName(i));
    1913           0 :       accumulator->Add("=");
    1914             :     }
    1915          98 :     accumulator->Add("%o", GetParameter(i));
    1916             :   }
    1917             : 
    1918          42 :   accumulator->Add(")");
    1919          42 :   if (mode == OVERVIEW) {
    1920          21 :     accumulator->Add("\n");
    1921          21 :     return;
    1922             :   }
    1923          42 :   if (is_optimized()) {
    1924          11 :     accumulator->Add(" {\n// optimized frame\n");
    1925          11 :     PrintFunctionSource(accumulator, shared, code);
    1926          11 :     accumulator->Add("}\n");
    1927          11 :     return;
    1928             :   }
    1929          10 :   accumulator->Add(" {\n");
    1930             : 
    1931             :   // Compute the number of locals and expression stack elements.
    1932          10 :   int stack_locals_count = scope_info->StackLocalCount();
    1933          10 :   int heap_locals_count = scope_info->ContextLocalCount();
    1934          10 :   int expressions_count = ComputeExpressionsCount();
    1935             : 
    1936             :   // Print stack-allocated local variables.
    1937          10 :   if (stack_locals_count > 0) {
    1938           0 :     accumulator->Add("  // stack-allocated locals\n");
    1939             :   }
    1940           0 :   for (int i = 0; i < stack_locals_count; i++) {
    1941           0 :     accumulator->Add("  var ");
    1942           0 :     accumulator->PrintName(scope_info->StackLocalName(i));
    1943           0 :     accumulator->Add(" = ");
    1944           0 :     if (i < expressions_count) {
    1945           0 :       accumulator->Add("%o", GetExpression(i));
    1946             :     } else {
    1947           0 :       accumulator->Add("// no expression found - inconsistent frame?");
    1948             :     }
    1949           0 :     accumulator->Add("\n");
    1950             :   }
    1951             : 
    1952             :   // Try to get hold of the context of this frame.
    1953             :   Context* context = NULL;
    1954          20 :   if (this->context() != NULL && this->context()->IsContext()) {
    1955          10 :     context = Context::cast(this->context());
    1956             :   }
    1957          10 :   while (context->IsWithContext()) {
    1958             :     context = context->previous();
    1959             :     DCHECK(context != NULL);
    1960             :   }
    1961             : 
    1962             :   // Print heap-allocated local variables.
    1963          10 :   if (heap_locals_count > 0) {
    1964           0 :     accumulator->Add("  // heap-allocated locals\n");
    1965             :   }
    1966           0 :   for (int i = 0; i < heap_locals_count; i++) {
    1967           0 :     accumulator->Add("  var ");
    1968           0 :     accumulator->PrintName(scope_info->ContextLocalName(i));
    1969           0 :     accumulator->Add(" = ");
    1970           0 :     if (context != NULL) {
    1971           0 :       int index = Context::MIN_CONTEXT_SLOTS + i;
    1972           0 :       if (index < context->length()) {
    1973           0 :         accumulator->Add("%o", context->get(index));
    1974             :       } else {
    1975             :         accumulator->Add(
    1976           0 :             "// warning: missing context slot - inconsistent frame?");
    1977             :       }
    1978             :     } else {
    1979           0 :       accumulator->Add("// warning: no context found - inconsistent frame?");
    1980             :     }
    1981           0 :     accumulator->Add("\n");
    1982             :   }
    1983             : 
    1984             :   // Print the expression stack.
    1985             :   int expressions_start = stack_locals_count;
    1986          10 :   if (expressions_start < expressions_count) {
    1987           0 :     accumulator->Add("  // expression stack (top to bottom)\n");
    1988             :   }
    1989          10 :   for (int i = expressions_count - 1; i >= expressions_start; i--) {
    1990           0 :     accumulator->Add("  [%02d] : %o\n", i, GetExpression(i));
    1991             :   }
    1992             : 
    1993          10 :   PrintFunctionSource(accumulator, shared, code);
    1994             : 
    1995          10 :   accumulator->Add("}\n\n");
    1996             : }
    1997             : 
    1998             : 
    1999           0 : void ArgumentsAdaptorFrame::Print(StringStream* accumulator,
    2000             :                                   PrintMode mode,
    2001             :                                   int index) const {
    2002           0 :   int actual = ComputeParametersCount();
    2003             :   int expected = -1;
    2004           0 :   JSFunction* function = this->function();
    2005             :   expected = function->shared()->internal_formal_parameter_count();
    2006             : 
    2007             :   PrintIndex(accumulator, mode, index);
    2008           0 :   accumulator->Add("arguments adaptor frame: %d->%d", actual, expected);
    2009           0 :   if (mode == OVERVIEW) {
    2010           0 :     accumulator->Add("\n");
    2011           0 :     return;
    2012             :   }
    2013           0 :   accumulator->Add(" {\n");
    2014             : 
    2015             :   // Print actual arguments.
    2016           0 :   if (actual > 0) accumulator->Add("  // actual arguments\n");
    2017           0 :   for (int i = 0; i < actual; i++) {
    2018           0 :     accumulator->Add("  [%02d] : %o", i, GetParameter(i));
    2019           0 :     if (expected != -1 && i >= expected) {
    2020           0 :       accumulator->Add("  // not passed to callee");
    2021             :     }
    2022           0 :     accumulator->Add("\n");
    2023             :   }
    2024             : 
    2025           0 :   accumulator->Add("}\n\n");
    2026             : }
    2027             : 
    2028      153419 : void EntryFrame::Iterate(RootVisitor* v) const {
    2029      153419 :   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
    2030      153419 : }
    2031             : 
    2032           0 : void StandardFrame::IterateExpressions(RootVisitor* v) const {
    2033             :   const int offset = StandardFrameConstants::kLastObjectOffset;
    2034     2541146 :   Object** base = &Memory::Object_at(sp());
    2035             :   Object** limit = &Memory::Object_at(fp() + offset) + 1;
    2036     2541146 :   v->VisitRootPointers(Root::kTop, base, limit);
    2037           0 : }
    2038             : 
    2039     2365644 : void JavaScriptFrame::Iterate(RootVisitor* v) const {
    2040             :   IterateExpressions(v);
    2041     2365644 :   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
    2042     2365644 : }
    2043             : 
    2044      175502 : void InternalFrame::Iterate(RootVisitor* v) const {
    2045      175502 :   Code* code = LookupCode();
    2046             :   IteratePc(v, pc_address(), constant_pool_address(), code);
    2047             :   // Internal frames typically do not receive any arguments, hence their stack
    2048             :   // only contains tagged pointers.
    2049             :   // We are misusing the has_tagged_params flag here to tell us whether
    2050             :   // the full stack frame contains only tagged pointers or only raw values.
    2051             :   // This is used for the WasmCompileLazy builtin, where we actually pass
    2052             :   // untagged arguments and also store untagged values on the stack.
    2053      175502 :   if (code->has_tagged_params()) IterateExpressions(v);
    2054      175502 : }
    2055             : 
    2056           0 : void StubFailureTrampolineFrame::Iterate(RootVisitor* v) const {
    2057           0 :   Object** base = &Memory::Object_at(sp());
    2058             :   Object** limit = &Memory::Object_at(
    2059           0 :       fp() + StubFailureTrampolineFrameConstants::kFixedHeaderBottomOffset);
    2060           0 :   v->VisitRootPointers(Root::kTop, base, limit);
    2061           0 :   base = &Memory::Object_at(fp() + StandardFrameConstants::kFunctionOffset);
    2062             :   const int offset = StandardFrameConstants::kLastObjectOffset;
    2063             :   limit = &Memory::Object_at(fp() + offset) + 1;
    2064           0 :   v->VisitRootPointers(Root::kTop, base, limit);
    2065             :   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
    2066           0 : }
    2067             : 
    2068             : 
    2069         219 : Address StubFailureTrampolineFrame::GetCallerStackPointer() const {
    2070         219 :   return fp() + StandardFrameConstants::kCallerSPOffset;
    2071             : }
    2072             : 
    2073             : 
    2074           0 : Code* StubFailureTrampolineFrame::unchecked_code() const {
    2075             :   Code* trampoline;
    2076             :   StubFailureTrampolineStub(isolate(), NOT_JS_FUNCTION_STUB_MODE).
    2077           0 :       FindCodeInCache(&trampoline);
    2078           0 :   if (trampoline->contains(pc())) {
    2079           0 :     return trampoline;
    2080             :   }
    2081             : 
    2082             :   StubFailureTrampolineStub(isolate(), JS_FUNCTION_STUB_MODE).
    2083           0 :       FindCodeInCache(&trampoline);
    2084           0 :   if (trampoline->contains(pc())) {
    2085           0 :     return trampoline;
    2086             :   }
    2087             : 
    2088           0 :   UNREACHABLE();
    2089             :   return NULL;
    2090             : }
    2091             : 
    2092             : 
    2093             : // -------------------------------------------------------------------------
    2094             : 
    2095             : 
    2096           0 : JavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) {
    2097             :   DCHECK(n >= 0);
    2098           0 :   for (int i = 0; i <= n; i++) {
    2099           0 :     while (!iterator_.frame()->is_java_script()) iterator_.Advance();
    2100           0 :     if (i == n) return JavaScriptFrame::cast(iterator_.frame());
    2101           0 :     iterator_.Advance();
    2102             :   }
    2103           0 :   UNREACHABLE();
    2104             :   return NULL;
    2105             : }
    2106             : 
    2107             : 
    2108             : // -------------------------------------------------------------------------
    2109             : 
    2110             : 
    2111    33061803 : static Map* GcSafeMapOfCodeSpaceObject(HeapObject* object) {
    2112             :   MapWord map_word = object->map_word();
    2113             :   return map_word.IsForwardingAddress() ?
    2114    66123606 :       map_word.ToForwardingAddress()->map() : map_word.ToMap();
    2115             : }
    2116             : 
    2117             : 
    2118    33061803 : static int GcSafeSizeOfCodeSpaceObject(HeapObject* object) {
    2119    33061803 :   return object->SizeFromMap(GcSafeMapOfCodeSpaceObject(object));
    2120             : }
    2121             : 
    2122             : 
    2123             : #ifdef DEBUG
    2124             : static bool GcSafeCodeContains(HeapObject* code, Address addr) {
    2125             :   Map* map = GcSafeMapOfCodeSpaceObject(code);
    2126             :   DCHECK(map == code->GetHeap()->code_map());
    2127             :   Address start = code->address();
    2128             :   Address end = code->address() + code->SizeFromMap(map);
    2129             :   return start <= addr && addr < end;
    2130             : }
    2131             : #endif
    2132             : 
    2133             : 
    2134           0 : Code* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object,
    2135             :                                                 Address inner_pointer) {
    2136             :   Code* code = reinterpret_cast<Code*>(object);
    2137             :   DCHECK(code != NULL && GcSafeCodeContains(code, inner_pointer));
    2138           0 :   return code;
    2139             : }
    2140             : 
    2141             : 
    2142     5663013 : Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer(
    2143             :     Address inner_pointer) {
    2144    22652011 :   Heap* heap = isolate_->heap();
    2145             : 
    2146             :   // Check if the inner pointer points into a large object chunk.
    2147     5663013 :   LargePage* large_page = heap->lo_space()->FindPage(inner_pointer);
    2148     5663013 :   if (large_page != NULL) {
    2149          10 :     return GcSafeCastToCode(large_page->GetObject(), inner_pointer);
    2150             :   }
    2151             : 
    2152     5663003 :   if (!heap->code_space()->Contains(inner_pointer)) {
    2153             :     return nullptr;
    2154             :   }
    2155             : 
    2156             :   // Iterate through the page until we reach the end or find an object starting
    2157             :   // after the inner pointer.
    2158             :   Page* page = Page::FromAddress(inner_pointer);
    2159             : 
    2160             :   DCHECK_EQ(page->owner(), heap->code_space());
    2161     5662999 :   heap->mark_compact_collector()->sweeper().SweepOrWaitUntilSweepingCompleted(
    2162     5662999 :       page);
    2163             : 
    2164     5662996 :   Address addr = page->skip_list()->StartFor(inner_pointer);
    2165             : 
    2166             :   Address top = heap->code_space()->top();
    2167             :   Address limit = heap->code_space()->limit();
    2168             : 
    2169             :   while (true) {
    2170    33064562 :     if (addr == top && addr != limit) {
    2171             :       addr = limit;
    2172             :       continue;
    2173             :     }
    2174             : 
    2175    33061803 :     HeapObject* obj = HeapObject::FromAddress(addr);
    2176    33061803 :     int obj_size = GcSafeSizeOfCodeSpaceObject(obj);
    2177    33061802 :     Address next_addr = addr + obj_size;
    2178    33061802 :     if (next_addr > inner_pointer) return GcSafeCastToCode(obj, inner_pointer);
    2179             :     addr = next_addr;
    2180             :   }
    2181             : }
    2182             : 
    2183             : 
    2184             : InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
    2185   117966569 :     InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
    2186   230802763 :   isolate_->counters()->pc_to_code()->Increment();
    2187             :   DCHECK(base::bits::IsPowerOfTwo32(kInnerPointerToCodeCacheSize));
    2188             :   uint32_t hash = ComputeIntegerHash(ObjectAddressForHashing(inner_pointer),
    2189             :                                      v8::internal::kZeroHashSeed);
    2190   117966579 :   uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
    2191   117966579 :   InnerPointerToCodeCacheEntry* entry = cache(index);
    2192   117966579 :   if (entry->inner_pointer == inner_pointer) {
    2193   225672388 :     isolate_->counters()->pc_to_code_cached()->Increment();
    2194             :     DCHECK(entry->code == GcSafeFindCodeForInnerPointer(inner_pointer));
    2195             :   } else {
    2196             :     // Because this code may be interrupted by a profiling signal that
    2197             :     // also queries the cache, we cannot update inner_pointer before the code
    2198             :     // has been set. Otherwise, we risk trying to use a cache entry before
    2199             :     // the code has been computed.
    2200     5130385 :     entry->code = GcSafeFindCodeForInnerPointer(inner_pointer);
    2201             :     entry->safepoint_entry.Reset();
    2202     5130379 :     entry->inner_pointer = inner_pointer;
    2203             :   }
    2204   117966574 :   return entry;
    2205             : }
    2206             : 
    2207             : 
    2208             : // -------------------------------------------------------------------------
    2209             : 
    2210             : 
    2211           0 : int NumRegs(RegList reglist) { return base::bits::CountPopulation(reglist); }
    2212             : 
    2213             : 
    2214             : struct JSCallerSavedCodeData {
    2215             :   int reg_code[kNumJSCallerSaved];
    2216             : };
    2217             : 
    2218             : JSCallerSavedCodeData caller_saved_code_data;
    2219             : 
    2220       59461 : void SetUpJSCallerSavedCodeData() {
    2221             :   int i = 0;
    2222     1010837 :   for (int r = 0; r < kNumRegs; r++)
    2223      951376 :     if ((kJSCallerSaved & (1 << r)) != 0)
    2224      297305 :       caller_saved_code_data.reg_code[i++] = r;
    2225             : 
    2226             :   DCHECK(i == kNumJSCallerSaved);
    2227       59461 : }
    2228             : 
    2229             : 
    2230           0 : int JSCallerSavedCode(int n) {
    2231             :   DCHECK(0 <= n && n < kNumJSCallerSaved);
    2232           0 :   return caller_saved_code_data.reg_code[n];
    2233             : }
    2234             : 
    2235             : 
    2236             : #define DEFINE_WRAPPER(type, field)                              \
    2237             : class field##_Wrapper : public ZoneObject {                      \
    2238             :  public:  /* NOLINT */                                           \
    2239             :   field##_Wrapper(const field& original) : frame_(original) {    \
    2240             :   }                                                              \
    2241             :   field frame_;                                                  \
    2242             : };
    2243             : STACK_FRAME_TYPE_LIST(DEFINE_WRAPPER)
    2244             : #undef DEFINE_WRAPPER
    2245             : 
    2246       26844 : static StackFrame* AllocateFrameCopy(StackFrame* frame, Zone* zone) {
    2247             : #define FRAME_TYPE_CASE(type, field) \
    2248             :   case StackFrame::type: { \
    2249             :     field##_Wrapper* wrapper = \
    2250             :         new(zone) field##_Wrapper(*(reinterpret_cast<field*>(frame))); \
    2251             :     return &wrapper->frame_; \
    2252             :   }
    2253             : 
    2254       26844 :   switch (frame->type()) {
    2255       26844 :     STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
    2256           0 :     default: UNREACHABLE();
    2257             :   }
    2258             : #undef FRAME_TYPE_CASE
    2259             :   return NULL;
    2260             : }
    2261             : 
    2262             : 
    2263         894 : Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone) {
    2264         894 :   ZoneList<StackFrame*> list(10, zone);
    2265       27738 :   for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
    2266       26844 :     StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
    2267             :     list.Add(frame, zone);
    2268             :   }
    2269         894 :   return list.ToVector();
    2270             : }
    2271             : 
    2272             : 
    2273             : }  // namespace internal
    2274             : }  // namespace v8

Generated by: LCOV version 1.10