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