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