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