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 <sstream>
      8 
      9 #include "src/ast/ast.h"
     10 #include "src/ast/scopeinfo.h"
     11 #include "src/base/bits.h"
     12 #include "src/deoptimizer.h"
     13 #include "src/frames-inl.h"
     14 #include "src/full-codegen/full-codegen.h"
     15 #include "src/register-configuration.h"
     16 #include "src/safepoint-table.h"
     17 #include "src/string-stream.h"
     18 #include "src/vm-state-inl.h"
     19 
     20 namespace v8 {
     21 namespace internal {
     22 
     23 ReturnAddressLocationResolver
     24     StackFrame::return_address_location_resolver_ = NULL;
     25 
     26 
     27 // Iterator that supports traversing the stack handlers of a
     28 // particular frame. Needs to know the top of the handler chain.
     29 class StackHandlerIterator BASE_EMBEDDED {
     30  public:
     31   StackHandlerIterator(const StackFrame* frame, StackHandler* handler)
     32       : limit_(frame->fp()), handler_(handler) {
     33     // Make sure the handler has already been unwound to this frame.
     34     DCHECK(frame->sp() <= handler->address());
     35   }
     36 
     37   StackHandler* handler() const { return handler_; }
     38 
     39   bool done() {
     40     return handler_ == NULL || handler_->address() > limit_;
     41   }
     42   void Advance() {
     43     DCHECK(!done());
     44     handler_ = handler_->next();
     45   }
     46 
     47  private:
     48   const Address limit_;
     49   StackHandler* handler_;
     50 };
     51 
     52 
     53 // -------------------------------------------------------------------------
     54 
     55 
     56 #define INITIALIZE_SINGLETON(type, field) field##_(this),
     57 StackFrameIteratorBase::StackFrameIteratorBase(Isolate* isolate,
     58                                                bool can_access_heap_objects)
     59     : isolate_(isolate),
     60       STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
     61       frame_(NULL), handler_(NULL),
     62       can_access_heap_objects_(can_access_heap_objects) {
     63 }
     64 #undef INITIALIZE_SINGLETON
     65 
     66 
     67 StackFrameIterator::StackFrameIterator(Isolate* isolate)
     68     : StackFrameIteratorBase(isolate, true) {
     69   Reset(isolate->thread_local_top());
     70 }
     71 
     72 
     73 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
     74     : StackFrameIteratorBase(isolate, true) {
     75   Reset(t);
     76 }
     77 
     78 
     79 void StackFrameIterator::Advance() {
     80   DCHECK(!done());
     81   // Compute the state of the calling frame before restoring
     82   // callee-saved registers and unwinding handlers. This allows the
     83   // frame code that computes the caller state to access the top
     84   // handler and the value of any callee-saved register if needed.
     85   StackFrame::State state;
     86   StackFrame::Type type = frame_->GetCallerState(&state);
     87 
     88   // Unwind handlers corresponding to the current frame.
     89   StackHandlerIterator it(frame_, handler_);
     90   while (!it.done()) it.Advance();
     91   handler_ = it.handler();
     92 
     93   // Advance to the calling frame.
     94   frame_ = SingletonFor(type, &state);
     95 
     96   // When we're done iterating over the stack frames, the handler
     97   // chain must have been completely unwound.
     98   DCHECK(!done() || handler_ == NULL);
     99 }
    100 
    101 
    102 void StackFrameIterator::Reset(ThreadLocalTop* top) {
    103   StackFrame::State state;
    104   StackFrame::Type type = ExitFrame::GetStateForFramePointer(
    105       Isolate::c_entry_fp(top), &state);
    106   handler_ = StackHandler::FromAddress(Isolate::handler(top));
    107   if (SingletonFor(type) == NULL) return;
    108   frame_ = SingletonFor(type, &state);
    109 }
    110 
    111 
    112 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type,
    113                                              StackFrame::State* state) {
    114   if (type == StackFrame::NONE) return NULL;
    115   StackFrame* result = SingletonFor(type);
    116   DCHECK(result != NULL);
    117   result->state_ = *state;
    118   return result;
    119 }
    120 
    121 
    122 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type) {
    123 #define FRAME_TYPE_CASE(type, field) \
    124   case StackFrame::type: result = &field##_; break;
    125 
    126   StackFrame* result = NULL;
    127   switch (type) {
    128     case StackFrame::NONE: return NULL;
    129     STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
    130     default: break;
    131   }
    132   return result;
    133 
    134 #undef FRAME_TYPE_CASE
    135 }
    136 
    137 
    138 // -------------------------------------------------------------------------
    139 
    140 
    141 JavaScriptFrameIterator::JavaScriptFrameIterator(
    142     Isolate* isolate, StackFrame::Id id)
    143     : iterator_(isolate) {
    144   while (!done()) {
    145     Advance();
    146     if (frame()->id() == id) return;
    147   }
    148 }
    149 
    150 
    151 void JavaScriptFrameIterator::Advance() {
    152   do {
    153     iterator_.Advance();
    154   } while (!iterator_.done() && !iterator_.frame()->is_java_script());
    155 }
    156 
    157 
    158 void JavaScriptFrameIterator::AdvanceToArgumentsFrame() {
    159   if (!frame()->has_adapted_arguments()) return;
    160   iterator_.Advance();
    161   DCHECK(iterator_.frame()->is_arguments_adaptor());
    162 }
    163 
    164 
    165 // -------------------------------------------------------------------------
    166 
    167 
    168 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
    169     : JavaScriptFrameIterator(isolate) {
    170   if (!done() && !IsValidFrame()) Advance();
    171 }
    172 
    173 
    174 void StackTraceFrameIterator::Advance() {
    175   while (true) {
    176     JavaScriptFrameIterator::Advance();
    177     if (done()) return;
    178     if (IsValidFrame()) return;
    179   }
    180 }
    181 
    182 
    183 bool StackTraceFrameIterator::IsValidFrame() {
    184     if (!frame()->function()->IsJSFunction()) return false;
    185     Object* script = frame()->function()->shared()->script();
    186     // Don't show functions from native scripts to user.
    187     return (script->IsScript() &&
    188             Script::TYPE_NATIVE != Script::cast(script)->type());
    189 }
    190 
    191 
    192 // -------------------------------------------------------------------------
    193 
    194 
    195 SafeStackFrameIterator::SafeStackFrameIterator(
    196     Isolate* isolate,
    197     Address fp, Address sp, Address js_entry_sp)
    198     : StackFrameIteratorBase(isolate, false),
    199       low_bound_(sp),
    200       high_bound_(js_entry_sp),
    201       top_frame_type_(StackFrame::NONE),
    202       external_callback_scope_(isolate->external_callback_scope()) {
    203   StackFrame::State state;
    204   StackFrame::Type type;
    205   ThreadLocalTop* top = isolate->thread_local_top();
    206   if (IsValidTop(top)) {
    207     type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
    208     top_frame_type_ = type;
    209   } else if (IsValidStackAddress(fp)) {
    210     DCHECK(fp != NULL);
    211     state.fp = fp;
    212     state.sp = sp;
    213     state.pc_address = StackFrame::ResolveReturnAddressLocation(
    214         reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
    215     // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset,
    216     // we check only that kMarkerOffset is within the stack bounds and do
    217     // compile time check that kContextOffset slot is pushed on the stack before
    218     // kMarkerOffset.
    219     STATIC_ASSERT(StandardFrameConstants::kMarkerOffset <
    220                   StandardFrameConstants::kContextOffset);
    221     Address frame_marker = fp + StandardFrameConstants::kMarkerOffset;
    222     if (IsValidStackAddress(frame_marker)) {
    223       type = StackFrame::ComputeType(this, &state);
    224       top_frame_type_ = type;
    225     } else {
    226       // Mark the frame as JAVA_SCRIPT if we cannot determine its type.
    227       // The frame anyways will be skipped.
    228       type = StackFrame::JAVA_SCRIPT;
    229       // Top frame is incomplete so we cannot reliably determine its type.
    230       top_frame_type_ = StackFrame::NONE;
    231     }
    232   } else {
    233     return;
    234   }
    235   if (SingletonFor(type) == NULL) return;
    236   frame_ = SingletonFor(type, &state);
    237   if (frame_ == NULL) return;
    238 
    239   Advance();
    240 
    241   if (frame_ != NULL && !frame_->is_exit() &&
    242       external_callback_scope_ != NULL &&
    243       external_callback_scope_->scope_address() < frame_->fp()) {
    244     // Skip top ExternalCallbackScope if we already advanced to a JS frame
    245     // under it. Sampler will anyways take this top external callback.
    246     external_callback_scope_ = external_callback_scope_->previous();
    247   }
    248 }
    249 
    250 
    251 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const {
    252   Address c_entry_fp = Isolate::c_entry_fp(top);
    253   if (!IsValidExitFrame(c_entry_fp)) return false;
    254   // There should be at least one JS_ENTRY stack handler.
    255   Address handler = Isolate::handler(top);
    256   if (handler == NULL) return false;
    257   // Check that there are no js frames on top of the native frames.
    258   return c_entry_fp < handler;
    259 }
    260 
    261 
    262 void SafeStackFrameIterator::AdvanceOneFrame() {
    263   DCHECK(!done());
    264   StackFrame* last_frame = frame_;
    265   Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
    266   // Before advancing to the next stack frame, perform pointer validity tests.
    267   if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) {
    268     frame_ = NULL;
    269     return;
    270   }
    271 
    272   // Advance to the previous frame.
    273   StackFrame::State state;
    274   StackFrame::Type type = frame_->GetCallerState(&state);
    275   frame_ = SingletonFor(type, &state);
    276   if (frame_ == NULL) return;
    277 
    278   // Check that we have actually moved to the previous frame in the stack.
    279   if (frame_->sp() < last_sp || frame_->fp() < last_fp) {
    280     frame_ = NULL;
    281   }
    282 }
    283 
    284 
    285 bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const {
    286   return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
    287 }
    288 
    289 
    290 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
    291   StackFrame::State state;
    292   if (frame->is_entry() || frame->is_entry_construct()) {
    293     // See EntryFrame::GetCallerState. It computes the caller FP address
    294     // and calls ExitFrame::GetStateForFramePointer on it. We need to be
    295     // sure that caller FP address is valid.
    296     Address caller_fp = Memory::Address_at(
    297         frame->fp() + EntryFrameConstants::kCallerFPOffset);
    298     if (!IsValidExitFrame(caller_fp)) return false;
    299   } else if (frame->is_arguments_adaptor()) {
    300     // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that
    301     // the number of arguments is stored on stack as Smi. We need to check
    302     // that it really an Smi.
    303     Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)->
    304         GetExpression(0);
    305     if (!number_of_args->IsSmi()) {
    306       return false;
    307     }
    308   }
    309   frame->ComputeCallerState(&state);
    310   return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) &&
    311       SingletonFor(frame->GetCallerState(&state)) != NULL;
    312 }
    313 
    314 
    315 bool SafeStackFrameIterator::IsValidExitFrame(Address fp) const {
    316   if (!IsValidStackAddress(fp)) return false;
    317   Address sp = ExitFrame::ComputeStackPointer(fp);
    318   if (!IsValidStackAddress(sp)) return false;
    319   StackFrame::State state;
    320   ExitFrame::FillState(fp, sp, &state);
    321   return *state.pc_address != NULL;
    322 }
    323 
    324 
    325 void SafeStackFrameIterator::Advance() {
    326   while (true) {
    327     AdvanceOneFrame();
    328     if (done()) return;
    329     if (frame_->is_java_script()) return;
    330     if (frame_->is_exit() && external_callback_scope_) {
    331       // Some of the EXIT frames may have ExternalCallbackScope allocated on
    332       // top of them. In that case the scope corresponds to the first EXIT
    333       // frame beneath it. There may be other EXIT frames on top of the
    334       // ExternalCallbackScope, just skip them as we cannot collect any useful
    335       // information about them.
    336       if (external_callback_scope_->scope_address() < frame_->fp()) {
    337         frame_->state_.pc_address =
    338             external_callback_scope_->callback_entrypoint_address();
    339         external_callback_scope_ = external_callback_scope_->previous();
    340         DCHECK(external_callback_scope_ == NULL ||
    341                external_callback_scope_->scope_address() > frame_->fp());
    342         return;
    343       }
    344     }
    345   }
    346 }
    347 
    348 
    349 // -------------------------------------------------------------------------
    350 
    351 
    352 Code* StackFrame::GetSafepointData(Isolate* isolate,
    353                                    Address inner_pointer,
    354                                    SafepointEntry* safepoint_entry,
    355                                    unsigned* stack_slots) {
    356   InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry =
    357       isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer);
    358   if (!entry->safepoint_entry.is_valid()) {
    359     entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer);
    360     DCHECK(entry->safepoint_entry.is_valid());
    361   } else {
    362     DCHECK(entry->safepoint_entry.Equals(
    363         entry->code->GetSafepointEntry(inner_pointer)));
    364   }
    365 
    366   // Fill in the results and return the code.
    367   Code* code = entry->code;
    368   *safepoint_entry = entry->safepoint_entry;
    369   *stack_slots = code->stack_slots();
    370   return code;
    371 }
    372 
    373 
    374 #ifdef DEBUG
    375 static bool GcSafeCodeContains(HeapObject* object, Address addr);
    376 #endif
    377 
    378 
    379 void StackFrame::IteratePc(ObjectVisitor* v, Address* pc_address,
    380                            Address* constant_pool_address, Code* holder) {
    381   Address pc = *pc_address;
    382   DCHECK(GcSafeCodeContains(holder, pc));
    383   unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start());
    384   Object* code = holder;
    385   v->VisitPointer(&code);
    386   if (code != holder) {
    387     holder = reinterpret_cast<Code*>(code);
    388     pc = holder->instruction_start() + pc_offset;
    389     *pc_address = pc;
    390     if (FLAG_enable_embedded_constant_pool && constant_pool_address) {
    391       *constant_pool_address = holder->constant_pool();
    392     }
    393   }
    394 }
    395 
    396 
    397 void StackFrame::SetReturnAddressLocationResolver(
    398     ReturnAddressLocationResolver resolver) {
    399   DCHECK(return_address_location_resolver_ == NULL);
    400   return_address_location_resolver_ = resolver;
    401 }
    402 
    403 
    404 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
    405                                          State* state) {
    406   DCHECK(state->fp != NULL);
    407 
    408   if (!iterator->can_access_heap_objects_) {
    409     // TODO(titzer): "can_access_heap_objects" is kind of bogus. It really
    410     // means that we are being called from the profiler, which can interrupt
    411     // the VM with a signal at any arbitrary instruction, with essentially
    412     // anything on the stack. So basically none of these checks are 100%
    413     // reliable.
    414     if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
    415       // An adapter frame has a special SMI constant for the context and
    416       // is not distinguished through the marker.
    417       return ARGUMENTS_ADAPTOR;
    418     }
    419     Object* marker =
    420         Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset);
    421     if (marker->IsSmi()) {
    422       return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
    423     } else {
    424       return JAVA_SCRIPT;
    425     }
    426   }
    427 
    428   // Look up the code object to figure out the type of the stack frame.
    429   Code* code_obj = GetContainingCode(iterator->isolate(), *(state->pc_address));
    430 
    431   Object* marker =
    432       Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset);
    433   if (code_obj != nullptr) {
    434     switch (code_obj->kind()) {
    435       case Code::FUNCTION:
    436         return JAVA_SCRIPT;
    437       case Code::OPTIMIZED_FUNCTION:
    438         return OPTIMIZED;
    439       case Code::WASM_FUNCTION:
    440         return STUB;
    441       case Code::BUILTIN:
    442         if (!marker->IsSmi()) {
    443           if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
    444             // An adapter frame has a special SMI constant for the context and
    445             // is not distinguished through the marker.
    446             return ARGUMENTS_ADAPTOR;
    447           } else {
    448             // The interpreter entry trampoline has a non-SMI marker.
    449             DCHECK(code_obj->is_interpreter_entry_trampoline());
    450             return INTERPRETED;
    451           }
    452         }
    453         break;  // Marker encodes the frame type.
    454       case Code::HANDLER:
    455         if (!marker->IsSmi()) {
    456           // Only hydrogen code stub handlers can have a non-SMI marker.
    457           DCHECK(code_obj->is_hydrogen_stub());
    458           return OPTIMIZED;
    459         }
    460         break;  // Marker encodes the frame type.
    461       default:
    462         break;  // Marker encodes the frame type.
    463     }
    464   }
    465 
    466   // Didn't find a code object, or the code kind wasn't specific enough.
    467   // The marker should encode the frame type.
    468   return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
    469 }
    470 
    471 
    472 #ifdef DEBUG
    473 bool StackFrame::can_access_heap_objects() const {
    474   return iterator_->can_access_heap_objects_;
    475 }
    476 #endif
    477 
    478 
    479 StackFrame::Type StackFrame::GetCallerState(State* state) const {
    480   ComputeCallerState(state);
    481   return ComputeType(iterator_, state);
    482 }
    483 
    484 
    485 Address StackFrame::UnpaddedFP() const {
    486 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
    487   if (!is_optimized()) return fp();
    488   int32_t alignment_state = Memory::int32_at(
    489     fp() + JavaScriptFrameConstants::kDynamicAlignmentStateOffset);
    490 
    491   return (alignment_state == kAlignmentPaddingPushed) ?
    492     (fp() + kPointerSize) : fp();
    493 #else
    494   return fp();
    495 #endif
    496 }
    497 
    498 
    499 Code* EntryFrame::unchecked_code() const {
    500   return isolate()->heap()->js_entry_code();
    501 }
    502 
    503 
    504 void EntryFrame::ComputeCallerState(State* state) const {
    505   GetCallerState(state);
    506 }
    507 
    508 
    509 void EntryFrame::SetCallerFp(Address caller_fp) {
    510   const int offset = EntryFrameConstants::kCallerFPOffset;
    511   Memory::Address_at(this->fp() + offset) = caller_fp;
    512 }
    513 
    514 
    515 StackFrame::Type EntryFrame::GetCallerState(State* state) const {
    516   const int offset = EntryFrameConstants::kCallerFPOffset;
    517   Address fp = Memory::Address_at(this->fp() + offset);
    518   return ExitFrame::GetStateForFramePointer(fp, state);
    519 }
    520 
    521 
    522 Code* EntryConstructFrame::unchecked_code() const {
    523   return isolate()->heap()->js_construct_entry_code();
    524 }
    525 
    526 
    527 Object*& ExitFrame::code_slot() const {
    528   const int offset = ExitFrameConstants::kCodeOffset;
    529   return Memory::Object_at(fp() + offset);
    530 }
    531 
    532 
    533 Code* ExitFrame::unchecked_code() const {
    534   return reinterpret_cast<Code*>(code_slot());
    535 }
    536 
    537 
    538 void ExitFrame::ComputeCallerState(State* state) const {
    539   // Set up the caller state.
    540   state->sp = caller_sp();
    541   state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);
    542   state->pc_address = ResolveReturnAddressLocation(
    543       reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
    544   if (FLAG_enable_embedded_constant_pool) {
    545     state->constant_pool_address = reinterpret_cast<Address*>(
    546         fp() + ExitFrameConstants::kConstantPoolOffset);
    547   }
    548 }
    549 
    550 
    551 void ExitFrame::SetCallerFp(Address caller_fp) {
    552   Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp;
    553 }
    554 
    555 
    556 void ExitFrame::Iterate(ObjectVisitor* v) const {
    557   // The arguments are traversed as part of the expression stack of
    558   // the calling frame.
    559   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
    560   v->VisitPointer(&code_slot());
    561 }
    562 
    563 
    564 Address ExitFrame::GetCallerStackPointer() const {
    565   return fp() + ExitFrameConstants::kCallerSPDisplacement;
    566 }
    567 
    568 
    569 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
    570   if (fp == 0) return NONE;
    571   Address sp = ComputeStackPointer(fp);
    572   FillState(fp, sp, state);
    573   DCHECK(*state->pc_address != NULL);
    574   return EXIT;
    575 }
    576 
    577 
    578 Address ExitFrame::ComputeStackPointer(Address fp) {
    579   return Memory::Address_at(fp + ExitFrameConstants::kSPOffset);
    580 }
    581 
    582 
    583 void ExitFrame::FillState(Address fp, Address sp, State* state) {
    584   state->sp = sp;
    585   state->fp = fp;
    586   state->pc_address = ResolveReturnAddressLocation(
    587       reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize));
    588   // The constant pool recorded in the exit frame is not associated
    589   // with the pc in this state (the return address into a C entry
    590   // stub).  ComputeCallerState will retrieve the constant pool
    591   // together with the associated caller pc.
    592   state->constant_pool_address = NULL;
    593 }
    594 
    595 
    596 Address StandardFrame::GetExpressionAddress(int n) const {
    597   const int offset = StandardFrameConstants::kExpressionsOffset;
    598   return fp() + offset - n * kPointerSize;
    599 }
    600 
    601 
    602 Object* StandardFrame::GetExpression(Address fp, int index) {
    603   return Memory::Object_at(GetExpressionAddress(fp, index));
    604 }
    605 
    606 
    607 Address StandardFrame::GetExpressionAddress(Address fp, int n) {
    608   const int offset = StandardFrameConstants::kExpressionsOffset;
    609   return fp + offset - n * kPointerSize;
    610 }
    611 
    612 
    613 int StandardFrame::ComputeExpressionsCount() const {
    614   const int offset =
    615       StandardFrameConstants::kExpressionsOffset + kPointerSize;
    616   Address base = fp() + offset;
    617   Address limit = sp();
    618   DCHECK(base >= limit);  // stack grows downwards
    619   // Include register-allocated locals in number of expressions.
    620   return static_cast<int>((base - limit) / kPointerSize);
    621 }
    622 
    623 
    624 void StandardFrame::ComputeCallerState(State* state) const {
    625   state->sp = caller_sp();
    626   state->fp = caller_fp();
    627   state->pc_address = ResolveReturnAddressLocation(
    628       reinterpret_cast<Address*>(ComputePCAddress(fp())));
    629   state->constant_pool_address =
    630       reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp()));
    631 }
    632 
    633 
    634 void StandardFrame::SetCallerFp(Address caller_fp) {
    635   Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) =
    636       caller_fp;
    637 }
    638 
    639 
    640 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
    641   // Make sure that we're not doing "safe" stack frame iteration. We cannot
    642   // possibly find pointers in optimized frames in that state.
    643   DCHECK(can_access_heap_objects());
    644 
    645   // Compute the safepoint information.
    646   unsigned stack_slots = 0;
    647   SafepointEntry safepoint_entry;
    648   Code* code = StackFrame::GetSafepointData(
    649       isolate(), pc(), &safepoint_entry, &stack_slots);
    650   unsigned slot_space = stack_slots * kPointerSize;
    651 
    652   // Visit the outgoing parameters.
    653   Object** parameters_base = &Memory::Object_at(sp());
    654   Object** parameters_limit = &Memory::Object_at(
    655       fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space);
    656 
    657   // Visit the parameters that may be on top of the saved registers.
    658   if (safepoint_entry.argument_count() > 0) {
    659     v->VisitPointers(parameters_base,
    660                      parameters_base + safepoint_entry.argument_count());
    661     parameters_base += safepoint_entry.argument_count();
    662   }
    663 
    664   // Skip saved double registers.
    665   if (safepoint_entry.has_doubles()) {
    666     // Number of doubles not known at snapshot time.
    667     DCHECK(!isolate()->serializer_enabled());
    668     parameters_base +=
    669         RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT)
    670             ->num_allocatable_double_registers() *
    671         kDoubleSize / kPointerSize;
    672   }
    673 
    674   // Visit the registers that contain pointers if any.
    675   if (safepoint_entry.HasRegisters()) {
    676     for (int i = kNumSafepointRegisters - 1; i >=0; i--) {
    677       if (safepoint_entry.HasRegisterAt(i)) {
    678         int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(i);
    679         v->VisitPointer(parameters_base + reg_stack_index);
    680       }
    681     }
    682     // Skip the words containing the register values.
    683     parameters_base += kNumSafepointRegisters;
    684   }
    685 
    686   // We're done dealing with the register bits.
    687   uint8_t* safepoint_bits = safepoint_entry.bits();
    688   safepoint_bits += kNumSafepointRegisters >> kBitsPerByteLog2;
    689 
    690   // Visit the rest of the parameters.
    691   v->VisitPointers(parameters_base, parameters_limit);
    692 
    693   // Visit pointer spill slots and locals.
    694   for (unsigned index = 0; index < stack_slots; index++) {
    695     int byte_index = index >> kBitsPerByteLog2;
    696     int bit_index = index & (kBitsPerByte - 1);
    697     if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) {
    698       v->VisitPointer(parameters_limit + index);
    699     }
    700   }
    701 
    702   // Visit the return address in the callee and incoming arguments.
    703   IteratePc(v, pc_address(), constant_pool_address(), code);
    704 
    705   // Visit the context in stub frame and JavaScript frame.
    706   // Visit the function in JavaScript frame.
    707   Object** fixed_base = &Memory::Object_at(
    708       fp() + StandardFrameConstants::kMarkerOffset);
    709   Object** fixed_limit = &Memory::Object_at(fp());
    710   v->VisitPointers(fixed_base, fixed_limit);
    711 }
    712 
    713 
    714 void StubFrame::Iterate(ObjectVisitor* v) const {
    715   IterateCompiledFrame(v);
    716 }
    717 
    718 
    719 Code* StubFrame::unchecked_code() const {
    720   return static_cast<Code*>(isolate()->FindCodeObject(pc()));
    721 }
    722 
    723 
    724 Address StubFrame::GetCallerStackPointer() const {
    725   return fp() + ExitFrameConstants::kCallerSPDisplacement;
    726 }
    727 
    728 
    729 int StubFrame::GetNumberOfIncomingArguments() const {
    730   return 0;
    731 }
    732 
    733 
    734 void OptimizedFrame::Iterate(ObjectVisitor* v) const {
    735   IterateCompiledFrame(v);
    736 }
    737 
    738 
    739 void JavaScriptFrame::SetParameterValue(int index, Object* value) const {
    740   Memory::Object_at(GetParameterSlot(index)) = value;
    741 }
    742 
    743 
    744 bool JavaScriptFrame::IsConstructor() const {
    745   Address fp = caller_fp();
    746   if (has_adapted_arguments()) {
    747     // Skip the arguments adaptor frame and look at the real caller.
    748     fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset);
    749   }
    750   return IsConstructFrame(fp);
    751 }
    752 
    753 
    754 bool JavaScriptFrame::HasInlinedFrames() const {
    755   List<JSFunction*> functions(1);
    756   GetFunctions(&functions);
    757   return functions.length() > 1;
    758 }
    759 
    760 
    761 int JavaScriptFrame::GetArgumentsLength() const {
    762   // If there is an arguments adaptor frame get the arguments length from it.
    763   if (has_adapted_arguments()) {
    764     STATIC_ASSERT(ArgumentsAdaptorFrameConstants::kLengthOffset ==
    765                   StandardFrameConstants::kExpressionsOffset);
    766     return Smi::cast(GetExpression(caller_fp(), 0))->value();
    767   } else {
    768     return GetNumberOfIncomingArguments();
    769   }
    770 }
    771 
    772 
    773 Code* JavaScriptFrame::unchecked_code() const {
    774   return function()->code();
    775 }
    776 
    777 
    778 int JavaScriptFrame::GetNumberOfIncomingArguments() const {
    779   DCHECK(can_access_heap_objects() &&
    780          isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
    781 
    782   return function()->shared()->internal_formal_parameter_count();
    783 }
    784 
    785 
    786 Address JavaScriptFrame::GetCallerStackPointer() const {
    787   return fp() + StandardFrameConstants::kCallerSPOffset;
    788 }
    789 
    790 
    791 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const {
    792   DCHECK(functions->length() == 0);
    793   functions->Add(function());
    794 }
    795 
    796 
    797 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) {
    798   DCHECK(functions->length() == 0);
    799   Code* code_pointer = LookupCode();
    800   int offset = static_cast<int>(pc() - code_pointer->address());
    801   FrameSummary summary(receiver(),
    802                        function(),
    803                        code_pointer,
    804                        offset,
    805                        IsConstructor());
    806   functions->Add(summary);
    807 }
    808 
    809 
    810 int JavaScriptFrame::LookupExceptionHandlerInTable(
    811     int* stack_slots, HandlerTable::CatchPrediction* prediction) {
    812   Code* code = LookupCode();
    813   DCHECK(!code->is_optimized_code());
    814   HandlerTable* table = HandlerTable::cast(code->handler_table());
    815   int pc_offset = static_cast<int>(pc() - code->entry());
    816   return table->LookupRange(pc_offset, stack_slots, prediction);
    817 }
    818 
    819 
    820 void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function, Code* code,
    821                                              Address pc, FILE* file,
    822                                              bool print_line_number) {
    823   PrintF(file, "%s", function->IsOptimized() ? "*" : "~");
    824   function->PrintName(file);
    825   int code_offset = static_cast<int>(pc - code->instruction_start());
    826   PrintF(file, "+%d", code_offset);
    827   if (print_line_number) {
    828     SharedFunctionInfo* shared = function->shared();
    829     int source_pos = code->SourcePosition(pc);
    830     Object* maybe_script = shared->script();
    831     if (maybe_script->IsScript()) {
    832       Script* script = Script::cast(maybe_script);
    833       int line = script->GetLineNumber(source_pos) + 1;
    834       Object* script_name_raw = script->name();
    835       if (script_name_raw->IsString()) {
    836         String* script_name = String::cast(script->name());
    837         base::SmartArrayPointer<char> c_script_name =
    838             script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
    839         PrintF(file, " at %s:%d", c_script_name.get(), line);
    840       } else {
    841         PrintF(file, " at <unknown>:%d", line);
    842       }
    843     } else {
    844       PrintF(file, " at <unknown>:<unknown>");
    845     }
    846   }
    847 }
    848 
    849 
    850 void JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file, bool print_args,
    851                                bool print_line_number) {
    852   // constructor calls
    853   DisallowHeapAllocation no_allocation;
    854   JavaScriptFrameIterator it(isolate);
    855   while (!it.done()) {
    856     if (it.frame()->is_java_script()) {
    857       JavaScriptFrame* frame = it.frame();
    858       if (frame->IsConstructor()) PrintF(file, "new ");
    859       PrintFunctionAndOffset(frame->function(), frame->unchecked_code(),
    860                              frame->pc(), file, print_line_number);
    861       if (print_args) {
    862         // function arguments
    863         // (we are intentionally only printing the actually
    864         // supplied parameters, not all parameters required)
    865         PrintF(file, "(this=");
    866         frame->receiver()->ShortPrint(file);
    867         const int length = frame->ComputeParametersCount();
    868         for (int i = 0; i < length; i++) {
    869           PrintF(file, ", ");
    870           frame->GetParameter(i)->ShortPrint(file);
    871         }
    872         PrintF(file, ")");
    873       }
    874       break;
    875     }
    876     it.Advance();
    877   }
    878 }
    879 
    880 
    881 void JavaScriptFrame::SaveOperandStack(FixedArray* store) const {
    882   int operands_count = store->length();
    883   DCHECK_LE(operands_count, ComputeOperandsCount());
    884   for (int i = 0; i < operands_count; i++) {
    885     store->set(i, GetOperand(i));
    886   }
    887 }
    888 
    889 
    890 void JavaScriptFrame::RestoreOperandStack(FixedArray* store) {
    891   int operands_count = store->length();
    892   DCHECK_LE(operands_count, ComputeOperandsCount());
    893   for (int i = 0; i < operands_count; i++) {
    894     DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
    895     Memory::Object_at(GetOperandSlot(i)) = store->get(i);
    896   }
    897 }
    898 
    899 
    900 FrameSummary::FrameSummary(Object* receiver, JSFunction* function, Code* code,
    901                            int offset, bool is_constructor)
    902     : receiver_(receiver, function->GetIsolate()),
    903       function_(function),
    904       code_(code),
    905       offset_(offset),
    906       is_constructor_(is_constructor) {}
    907 
    908 
    909 void FrameSummary::Print() {
    910   PrintF("receiver: ");
    911   receiver_->ShortPrint();
    912   PrintF("\nfunction: ");
    913   function_->shared()->DebugName()->ShortPrint();
    914   PrintF("\ncode: ");
    915   code_->ShortPrint();
    916   if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT");
    917   if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT");
    918   PrintF("\npc: %d\n", offset_);
    919 }
    920 
    921 
    922 void OptimizedFrame::Summarize(List<FrameSummary>* frames) {
    923   DCHECK(frames->length() == 0);
    924   DCHECK(is_optimized());
    925 
    926   // Delegate to JS frame in absence of turbofan deoptimization.
    927   // TODO(turbofan): Revisit once we support deoptimization across the board.
    928   if (LookupCode()->is_turbofanned() && function()->shared()->asm_function() &&
    929       !FLAG_turbo_asm_deoptimization) {
    930     return JavaScriptFrame::Summarize(frames);
    931   }
    932 
    933   DisallowHeapAllocation no_gc;
    934   int deopt_index = Safepoint::kNoDeoptimizationIndex;
    935   DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index);
    936   FixedArray* const literal_array = data->LiteralArray();
    937 
    938   TranslationIterator it(data->TranslationByteArray(),
    939                          data->TranslationIndex(deopt_index)->value());
    940   Translation::Opcode frame_opcode =
    941       static_cast<Translation::Opcode>(it.Next());
    942   DCHECK_EQ(Translation::BEGIN, frame_opcode);
    943   it.Next();  // Drop frame count.
    944   int jsframe_count = it.Next();
    945 
    946   // We create the summary in reverse order because the frames
    947   // in the deoptimization translation are ordered bottom-to-top.
    948   bool is_constructor = IsConstructor();
    949   while (jsframe_count != 0) {
    950     frame_opcode = static_cast<Translation::Opcode>(it.Next());
    951     if (frame_opcode == Translation::JS_FRAME ||
    952         frame_opcode == Translation::INTERPRETED_FRAME) {
    953       jsframe_count--;
    954       BailoutId const ast_id = BailoutId(it.Next());
    955       SharedFunctionInfo* const shared_info =
    956           SharedFunctionInfo::cast(literal_array->get(it.Next()));
    957       it.Next();  // Skip height.
    958 
    959       // The translation commands are ordered and the function is always
    960       // at the first position, and the receiver is next.
    961       Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
    962 
    963       // Get the correct function in the optimized frame.
    964       JSFunction* function;
    965       if (opcode == Translation::LITERAL) {
    966         function = JSFunction::cast(literal_array->get(it.Next()));
    967       } else if (opcode == Translation::STACK_SLOT) {
    968         function = JSFunction::cast(StackSlotAt(it.Next()));
    969       } else {
    970         CHECK_EQ(Translation::JS_FRAME_FUNCTION, opcode);
    971         function = this->function();
    972       }
    973       DCHECK_EQ(shared_info, function->shared());
    974 
    975       // If we are at a call, the receiver is always in a stack slot.
    976       // Otherwise we are not guaranteed to get the receiver value.
    977       opcode = static_cast<Translation::Opcode>(it.Next());
    978 
    979       // Get the correct receiver in the optimized frame.
    980       Object* receiver;
    981       if (opcode == Translation::LITERAL) {
    982         receiver = literal_array->get(it.Next());
    983       } else if (opcode == Translation::STACK_SLOT) {
    984         receiver = StackSlotAt(it.Next());
    985       } else if (opcode == Translation::JS_FRAME_FUNCTION) {
    986         receiver = this->function();
    987       } else {
    988         // The receiver is not in a stack slot nor in a literal.  We give up.
    989         it.Skip(Translation::NumberOfOperandsFor(opcode));
    990         // TODO(3029): Materializing a captured object (or duplicated
    991         // object) is hard, we return undefined for now. This breaks the
    992         // produced stack trace, as constructor frames aren't marked as
    993         // such anymore.
    994         receiver = isolate()->heap()->undefined_value();
    995       }
    996 
    997       Code* const code = shared_info->code();
    998 
    999       unsigned pc_offset;
   1000       if (frame_opcode == Translation::JS_FRAME) {
   1001         DeoptimizationOutputData* const output_data =
   1002             DeoptimizationOutputData::cast(code->deoptimization_data());
   1003         unsigned const entry =
   1004             Deoptimizer::GetOutputInfo(output_data, ast_id, shared_info);
   1005         pc_offset =
   1006             FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize;
   1007         DCHECK_NE(0U, pc_offset);
   1008       } else {
   1009         // TODO(rmcilroy): Modify FrameSummary to enable us to summarize
   1010         // based on the BytecodeArray and bytecode offset.
   1011         DCHECK_EQ(frame_opcode, Translation::INTERPRETED_FRAME);
   1012         pc_offset = 0;
   1013       }
   1014       FrameSummary summary(receiver, function, code, pc_offset, is_constructor);
   1015       frames->Add(summary);
   1016       is_constructor = false;
   1017     } else if (frame_opcode == Translation::CONSTRUCT_STUB_FRAME) {
   1018       // The next encountered JS_FRAME will be marked as a constructor call.
   1019       it.Skip(Translation::NumberOfOperandsFor(frame_opcode));
   1020       DCHECK(!is_constructor);
   1021       is_constructor = true;
   1022     } else {
   1023       // Skip over operands to advance to the next opcode.
   1024       it.Skip(Translation::NumberOfOperandsFor(frame_opcode));
   1025     }
   1026   }
   1027   DCHECK(!is_constructor);
   1028 }
   1029 
   1030 
   1031 int OptimizedFrame::LookupExceptionHandlerInTable(
   1032     int* stack_slots, HandlerTable::CatchPrediction* prediction) {
   1033   Code* code = LookupCode();
   1034   DCHECK(code->is_optimized_code());
   1035   HandlerTable* table = HandlerTable::cast(code->handler_table());
   1036   int pc_offset = static_cast<int>(pc() - code->entry());
   1037   *stack_slots = code->stack_slots();
   1038   return table->LookupReturn(pc_offset, prediction);
   1039 }
   1040 
   1041 
   1042 DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData(
   1043     int* deopt_index) const {
   1044   DCHECK(is_optimized());
   1045 
   1046   JSFunction* opt_function = function();
   1047   Code* code = opt_function->code();
   1048 
   1049   // The code object may have been replaced by lazy deoptimization. Fall
   1050   // back to a slow search in this case to find the original optimized
   1051   // code object.
   1052   if (!code->contains(pc())) {
   1053     code = isolate()->inner_pointer_to_code_cache()->
   1054         GcSafeFindCodeForInnerPointer(pc());
   1055   }
   1056   DCHECK(code != NULL);
   1057   DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
   1058 
   1059   SafepointEntry safepoint_entry = code->GetSafepointEntry(pc());
   1060   *deopt_index = safepoint_entry.deoptimization_index();
   1061   DCHECK(*deopt_index != Safepoint::kNoDeoptimizationIndex);
   1062 
   1063   return DeoptimizationInputData::cast(code->deoptimization_data());
   1064 }
   1065 
   1066 
   1067 void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) const {
   1068   DCHECK(functions->length() == 0);
   1069   DCHECK(is_optimized());
   1070 
   1071   // Delegate to JS frame in absence of turbofan deoptimization.
   1072   // TODO(turbofan): Revisit once we support deoptimization across the board.
   1073   if (LookupCode()->is_turbofanned() && function()->shared()->asm_function() &&
   1074       !FLAG_turbo_asm_deoptimization) {
   1075     return JavaScriptFrame::GetFunctions(functions);
   1076   }
   1077 
   1078   DisallowHeapAllocation no_gc;
   1079   int deopt_index = Safepoint::kNoDeoptimizationIndex;
   1080   DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index);
   1081   FixedArray* const literal_array = data->LiteralArray();
   1082 
   1083   TranslationIterator it(data->TranslationByteArray(),
   1084                          data->TranslationIndex(deopt_index)->value());
   1085   Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
   1086   DCHECK_EQ(Translation::BEGIN, opcode);
   1087   it.Next();  // Skip frame count.
   1088   int jsframe_count = it.Next();
   1089 
   1090   // We insert the frames in reverse order because the frames
   1091   // in the deoptimization translation are ordered bottom-to-top.
   1092   while (jsframe_count != 0) {
   1093     opcode = static_cast<Translation::Opcode>(it.Next());
   1094     // Skip over operands to advance to the next opcode.
   1095     it.Skip(Translation::NumberOfOperandsFor(opcode));
   1096     if (opcode == Translation::JS_FRAME ||
   1097         opcode == Translation::INTERPRETED_FRAME) {
   1098       jsframe_count--;
   1099 
   1100       // The translation commands are ordered and the function is always at the
   1101       // first position.
   1102       opcode = static_cast<Translation::Opcode>(it.Next());
   1103 
   1104       // Get the correct function in the optimized frame.
   1105       Object* function;
   1106       if (opcode == Translation::LITERAL) {
   1107         function = literal_array->get(it.Next());
   1108       } else if (opcode == Translation::STACK_SLOT) {
   1109         function = StackSlotAt(it.Next());
   1110       } else {
   1111         CHECK_EQ(Translation::JS_FRAME_FUNCTION, opcode);
   1112         function = this->function();
   1113       }
   1114       functions->Add(JSFunction::cast(function));
   1115     }
   1116   }
   1117 }
   1118 
   1119 
   1120 int OptimizedFrame::StackSlotOffsetRelativeToFp(int slot_index) {
   1121   return StandardFrameConstants::kCallerSPOffset -
   1122          ((slot_index + 1) * kPointerSize);
   1123 }
   1124 
   1125 
   1126 Object* OptimizedFrame::StackSlotAt(int index) const {
   1127   return Memory::Object_at(fp() + StackSlotOffsetRelativeToFp(index));
   1128 }
   1129 
   1130 
   1131 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const {
   1132   return Smi::cast(GetExpression(0))->value();
   1133 }
   1134 
   1135 
   1136 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const {
   1137   return fp() + StandardFrameConstants::kCallerSPOffset;
   1138 }
   1139 
   1140 
   1141 Address InternalFrame::GetCallerStackPointer() const {
   1142   // Internal frames have no arguments. The stack pointer of the
   1143   // caller is at a fixed offset from the frame pointer.
   1144   return fp() + StandardFrameConstants::kCallerSPOffset;
   1145 }
   1146 
   1147 
   1148 Code* ArgumentsAdaptorFrame::unchecked_code() const {
   1149   return isolate()->builtins()->builtin(
   1150       Builtins::kArgumentsAdaptorTrampoline);
   1151 }
   1152 
   1153 
   1154 Code* InternalFrame::unchecked_code() const {
   1155   const int offset = InternalFrameConstants::kCodeOffset;
   1156   Object* code = Memory::Object_at(fp() + offset);
   1157   DCHECK(code != NULL);
   1158   return reinterpret_cast<Code*>(code);
   1159 }
   1160 
   1161 
   1162 void StackFrame::PrintIndex(StringStream* accumulator,
   1163                             PrintMode mode,
   1164                             int index) {
   1165   accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index);
   1166 }
   1167 
   1168 
   1169 namespace {
   1170 
   1171 
   1172 void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared,
   1173                          Code* code) {
   1174   if (FLAG_max_stack_trace_source_length != 0 && code != NULL) {
   1175     std::ostringstream os;
   1176     os << "--------- s o u r c e   c o d e ---------\n"
   1177        << SourceCodeOf(shared, FLAG_max_stack_trace_source_length)
   1178        << "\n-----------------------------------------\n";
   1179     accumulator->Add(os.str().c_str());
   1180   }
   1181 }
   1182 
   1183 
   1184 }  // namespace
   1185 
   1186 
   1187 void JavaScriptFrame::Print(StringStream* accumulator,
   1188                             PrintMode mode,
   1189                             int index) const {
   1190   DisallowHeapAllocation no_gc;
   1191   Object* receiver = this->receiver();
   1192   JSFunction* function = this->function();
   1193 
   1194   accumulator->PrintSecurityTokenIfChanged(function);
   1195   PrintIndex(accumulator, mode, index);
   1196   Code* code = NULL;
   1197   if (IsConstructor()) accumulator->Add("new ");
   1198   accumulator->PrintFunction(function, receiver, &code);
   1199 
   1200   // Get scope information for nicer output, if possible. If code is NULL, or
   1201   // doesn't contain scope info, scope_info will return 0 for the number of
   1202   // parameters, stack local variables, context local variables, stack slots,
   1203   // or context slots.
   1204   SharedFunctionInfo* shared = function->shared();
   1205   ScopeInfo* scope_info = shared->scope_info();
   1206   Object* script_obj = shared->script();
   1207   if (script_obj->IsScript()) {
   1208     Script* script = Script::cast(script_obj);
   1209     accumulator->Add(" [");
   1210     accumulator->PrintName(script->name());
   1211 
   1212     Address pc = this->pc();
   1213     if (code != NULL && code->kind() == Code::FUNCTION &&
   1214         pc >= code->instruction_start() && pc < code->instruction_end()) {
   1215       int source_pos = code->SourcePosition(pc);
   1216       int line = script->GetLineNumber(source_pos) + 1;
   1217       accumulator->Add(":%d", line);
   1218     } else {
   1219       int function_start_pos = shared->start_position();
   1220       int line = script->GetLineNumber(function_start_pos) + 1;
   1221       accumulator->Add(":~%d", line);
   1222     }
   1223 
   1224     accumulator->Add("] [pc=%p] ", pc);
   1225   }
   1226 
   1227   accumulator->Add("(this=%o", receiver);
   1228 
   1229   // Print the parameters.
   1230   int parameters_count = ComputeParametersCount();
   1231   for (int i = 0; i < parameters_count; i++) {
   1232     accumulator->Add(",");
   1233     // If we have a name for the parameter we print it. Nameless
   1234     // parameters are either because we have more actual parameters
   1235     // than formal parameters or because we have no scope information.
   1236     if (i < scope_info->ParameterCount()) {
   1237       accumulator->PrintName(scope_info->ParameterName(i));
   1238       accumulator->Add("=");
   1239     }
   1240     accumulator->Add("%o", GetParameter(i));
   1241   }
   1242 
   1243   accumulator->Add(")");
   1244   if (mode == OVERVIEW) {
   1245     accumulator->Add("\n");
   1246     return;
   1247   }
   1248   if (is_optimized()) {
   1249     accumulator->Add(" {\n// optimized frame\n");
   1250     PrintFunctionSource(accumulator, shared, code);
   1251     accumulator->Add("}\n");
   1252     return;
   1253   }
   1254   accumulator->Add(" {\n");
   1255 
   1256   // Compute the number of locals and expression stack elements.
   1257   int stack_locals_count = scope_info->StackLocalCount();
   1258   int heap_locals_count = scope_info->ContextLocalCount();
   1259   int expressions_count = ComputeExpressionsCount();
   1260 
   1261   // Print stack-allocated local variables.
   1262   if (stack_locals_count > 0) {
   1263     accumulator->Add("  // stack-allocated locals\n");
   1264   }
   1265   for (int i = 0; i < stack_locals_count; i++) {
   1266     accumulator->Add("  var ");
   1267     accumulator->PrintName(scope_info->StackLocalName(i));
   1268     accumulator->Add(" = ");
   1269     if (i < expressions_count) {
   1270       accumulator->Add("%o", GetExpression(i));
   1271     } else {
   1272       accumulator->Add("// no expression found - inconsistent frame?");
   1273     }
   1274     accumulator->Add("\n");
   1275   }
   1276 
   1277   // Try to get hold of the context of this frame.
   1278   Context* context = NULL;
   1279   if (this->context() != NULL && this->context()->IsContext()) {
   1280     context = Context::cast(this->context());
   1281   }
   1282   while (context->IsWithContext()) {
   1283     context = context->previous();
   1284     DCHECK(context != NULL);
   1285   }
   1286 
   1287   // Print heap-allocated local variables.
   1288   if (heap_locals_count > 0) {
   1289     accumulator->Add("  // heap-allocated locals\n");
   1290   }
   1291   for (int i = 0; i < heap_locals_count; i++) {
   1292     accumulator->Add("  var ");
   1293     accumulator->PrintName(scope_info->ContextLocalName(i));
   1294     accumulator->Add(" = ");
   1295     if (context != NULL) {
   1296       int index = Context::MIN_CONTEXT_SLOTS + i;
   1297       if (index < context->length()) {
   1298         accumulator->Add("%o", context->get(index));
   1299       } else {
   1300         accumulator->Add(
   1301             "// warning: missing context slot - inconsistent frame?");
   1302       }
   1303     } else {
   1304       accumulator->Add("// warning: no context found - inconsistent frame?");
   1305     }
   1306     accumulator->Add("\n");
   1307   }
   1308 
   1309   // Print the expression stack.
   1310   int expressions_start = stack_locals_count;
   1311   if (expressions_start < expressions_count) {
   1312     accumulator->Add("  // expression stack (top to bottom)\n");
   1313   }
   1314   for (int i = expressions_count - 1; i >= expressions_start; i--) {
   1315     accumulator->Add("  [%02d] : %o\n", i, GetExpression(i));
   1316   }
   1317 
   1318   PrintFunctionSource(accumulator, shared, code);
   1319 
   1320   accumulator->Add("}\n\n");
   1321 }
   1322 
   1323 
   1324 void ArgumentsAdaptorFrame::Print(StringStream* accumulator,
   1325                                   PrintMode mode,
   1326                                   int index) const {
   1327   int actual = ComputeParametersCount();
   1328   int expected = -1;
   1329   JSFunction* function = this->function();
   1330   expected = function->shared()->internal_formal_parameter_count();
   1331 
   1332   PrintIndex(accumulator, mode, index);
   1333   accumulator->Add("arguments adaptor frame: %d->%d", actual, expected);
   1334   if (mode == OVERVIEW) {
   1335     accumulator->Add("\n");
   1336     return;
   1337   }
   1338   accumulator->Add(" {\n");
   1339 
   1340   // Print actual arguments.
   1341   if (actual > 0) accumulator->Add("  // actual arguments\n");
   1342   for (int i = 0; i < actual; i++) {
   1343     accumulator->Add("  [%02d] : %o", i, GetParameter(i));
   1344     if (expected != -1 && i >= expected) {
   1345       accumulator->Add("  // not passed to callee");
   1346     }
   1347     accumulator->Add("\n");
   1348   }
   1349 
   1350   accumulator->Add("}\n\n");
   1351 }
   1352 
   1353 
   1354 void EntryFrame::Iterate(ObjectVisitor* v) const {
   1355   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
   1356 }
   1357 
   1358 
   1359 void StandardFrame::IterateExpressions(ObjectVisitor* v) const {
   1360   const int offset = StandardFrameConstants::kLastObjectOffset;
   1361   Object** base = &Memory::Object_at(sp());
   1362   Object** limit = &Memory::Object_at(fp() + offset) + 1;
   1363   v->VisitPointers(base, limit);
   1364 }
   1365 
   1366 
   1367 void JavaScriptFrame::Iterate(ObjectVisitor* v) const {
   1368   IterateExpressions(v);
   1369   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
   1370 }
   1371 
   1372 
   1373 void InternalFrame::Iterate(ObjectVisitor* v) const {
   1374   // Internal frames only have object pointers on the expression stack
   1375   // as they never have any arguments.
   1376   IterateExpressions(v);
   1377   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
   1378 }
   1379 
   1380 
   1381 void StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const {
   1382   Object** base = &Memory::Object_at(sp());
   1383   Object** limit = &Memory::Object_at(fp() +
   1384                                       kFirstRegisterParameterFrameOffset);
   1385   v->VisitPointers(base, limit);
   1386   base = &Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset);
   1387   const int offset = StandardFrameConstants::kLastObjectOffset;
   1388   limit = &Memory::Object_at(fp() + offset) + 1;
   1389   v->VisitPointers(base, limit);
   1390   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
   1391 }
   1392 
   1393 
   1394 Address StubFailureTrampolineFrame::GetCallerStackPointer() const {
   1395   return fp() + StandardFrameConstants::kCallerSPOffset;
   1396 }
   1397 
   1398 
   1399 Code* StubFailureTrampolineFrame::unchecked_code() const {
   1400   Code* trampoline;
   1401   StubFailureTrampolineStub(isolate(), NOT_JS_FUNCTION_STUB_MODE).
   1402       FindCodeInCache(&trampoline);
   1403   if (trampoline->contains(pc())) {
   1404     return trampoline;
   1405   }
   1406 
   1407   StubFailureTrampolineStub(isolate(), JS_FUNCTION_STUB_MODE).
   1408       FindCodeInCache(&trampoline);
   1409   if (trampoline->contains(pc())) {
   1410     return trampoline;
   1411   }
   1412 
   1413   UNREACHABLE();
   1414   return NULL;
   1415 }
   1416 
   1417 
   1418 // -------------------------------------------------------------------------
   1419 
   1420 
   1421 JavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) {
   1422   DCHECK(n >= 0);
   1423   for (int i = 0; i <= n; i++) {
   1424     while (!iterator_.frame()->is_java_script()) iterator_.Advance();
   1425     if (i == n) return JavaScriptFrame::cast(iterator_.frame());
   1426     iterator_.Advance();
   1427   }
   1428   UNREACHABLE();
   1429   return NULL;
   1430 }
   1431 
   1432 
   1433 // -------------------------------------------------------------------------
   1434 
   1435 
   1436 static Map* GcSafeMapOfCodeSpaceObject(HeapObject* object) {
   1437   MapWord map_word = object->map_word();
   1438   return map_word.IsForwardingAddress() ?
   1439       map_word.ToForwardingAddress()->map() : map_word.ToMap();
   1440 }
   1441 
   1442 
   1443 static int GcSafeSizeOfCodeSpaceObject(HeapObject* object) {
   1444   return object->SizeFromMap(GcSafeMapOfCodeSpaceObject(object));
   1445 }
   1446 
   1447 
   1448 #ifdef DEBUG
   1449 static bool GcSafeCodeContains(HeapObject* code, Address addr) {
   1450   Map* map = GcSafeMapOfCodeSpaceObject(code);
   1451   DCHECK(map == code->GetHeap()->code_map());
   1452   Address start = code->address();
   1453   Address end = code->address() + code->SizeFromMap(map);
   1454   return start <= addr && addr < end;
   1455 }
   1456 #endif
   1457 
   1458 
   1459 Code* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object,
   1460                                                 Address inner_pointer) {
   1461   Code* code = reinterpret_cast<Code*>(object);
   1462   DCHECK(code != NULL && GcSafeCodeContains(code, inner_pointer));
   1463   return code;
   1464 }
   1465 
   1466 
   1467 Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer(
   1468     Address inner_pointer) {
   1469   Heap* heap = isolate_->heap();
   1470   if (!heap->code_space()->Contains(inner_pointer) &&
   1471       !heap->lo_space()->Contains(inner_pointer)) {
   1472     return nullptr;
   1473   }
   1474 
   1475   // Check if the inner pointer points into a large object chunk.
   1476   LargePage* large_page = heap->lo_space()->FindPage(inner_pointer);
   1477   if (large_page != NULL) {
   1478     return GcSafeCastToCode(large_page->GetObject(), inner_pointer);
   1479   }
   1480 
   1481   // Iterate through the page until we reach the end or find an object starting
   1482   // after the inner pointer.
   1483   Page* page = Page::FromAddress(inner_pointer);
   1484 
   1485   DCHECK_EQ(page->owner(), heap->code_space());
   1486   heap->mark_compact_collector()->SweepOrWaitUntilSweepingCompleted(page);
   1487 
   1488   Address addr = page->skip_list()->StartFor(inner_pointer);
   1489 
   1490   Address top = heap->code_space()->top();
   1491   Address limit = heap->code_space()->limit();
   1492 
   1493   while (true) {
   1494     if (addr == top && addr != limit) {
   1495       addr = limit;
   1496       continue;
   1497     }
   1498 
   1499     HeapObject* obj = HeapObject::FromAddress(addr);
   1500     int obj_size = GcSafeSizeOfCodeSpaceObject(obj);
   1501     Address next_addr = addr + obj_size;
   1502     if (next_addr > inner_pointer) return GcSafeCastToCode(obj, inner_pointer);
   1503     addr = next_addr;
   1504   }
   1505 }
   1506 
   1507 
   1508 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
   1509     InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
   1510   isolate_->counters()->pc_to_code()->Increment();
   1511   DCHECK(base::bits::IsPowerOfTwo32(kInnerPointerToCodeCacheSize));
   1512   uint32_t hash = ComputeIntegerHash(ObjectAddressForHashing(inner_pointer),
   1513                                      v8::internal::kZeroHashSeed);
   1514   uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
   1515   InnerPointerToCodeCacheEntry* entry = cache(index);
   1516   if (entry->inner_pointer == inner_pointer) {
   1517     isolate_->counters()->pc_to_code_cached()->Increment();
   1518     DCHECK(entry->code == GcSafeFindCodeForInnerPointer(inner_pointer));
   1519   } else {
   1520     // Because this code may be interrupted by a profiling signal that
   1521     // also queries the cache, we cannot update inner_pointer before the code
   1522     // has been set. Otherwise, we risk trying to use a cache entry before
   1523     // the code has been computed.
   1524     entry->code = GcSafeFindCodeForInnerPointer(inner_pointer);
   1525     entry->safepoint_entry.Reset();
   1526     entry->inner_pointer = inner_pointer;
   1527   }
   1528   return entry;
   1529 }
   1530 
   1531 
   1532 // -------------------------------------------------------------------------
   1533 
   1534 
   1535 int NumRegs(RegList reglist) { return base::bits::CountPopulation(reglist); }
   1536 
   1537 
   1538 struct JSCallerSavedCodeData {
   1539   int reg_code[kNumJSCallerSaved];
   1540 };
   1541 
   1542 JSCallerSavedCodeData caller_saved_code_data;
   1543 
   1544 void SetUpJSCallerSavedCodeData() {
   1545   int i = 0;
   1546   for (int r = 0; r < kNumRegs; r++)
   1547     if ((kJSCallerSaved & (1 << r)) != 0)
   1548       caller_saved_code_data.reg_code[i++] = r;
   1549 
   1550   DCHECK(i == kNumJSCallerSaved);
   1551 }
   1552 
   1553 
   1554 int JSCallerSavedCode(int n) {
   1555   DCHECK(0 <= n && n < kNumJSCallerSaved);
   1556   return caller_saved_code_data.reg_code[n];
   1557 }
   1558 
   1559 
   1560 #define DEFINE_WRAPPER(type, field)                              \
   1561 class field##_Wrapper : public ZoneObject {                      \
   1562  public:  /* NOLINT */                                           \
   1563   field##_Wrapper(const field& original) : frame_(original) {    \
   1564   }                                                              \
   1565   field frame_;                                                  \
   1566 };
   1567 STACK_FRAME_TYPE_LIST(DEFINE_WRAPPER)
   1568 #undef DEFINE_WRAPPER
   1569 
   1570 static StackFrame* AllocateFrameCopy(StackFrame* frame, Zone* zone) {
   1571 #define FRAME_TYPE_CASE(type, field) \
   1572   case StackFrame::type: { \
   1573     field##_Wrapper* wrapper = \
   1574         new(zone) field##_Wrapper(*(reinterpret_cast<field*>(frame))); \
   1575     return &wrapper->frame_; \
   1576   }
   1577 
   1578   switch (frame->type()) {
   1579     STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
   1580     default: UNREACHABLE();
   1581   }
   1582 #undef FRAME_TYPE_CASE
   1583   return NULL;
   1584 }
   1585 
   1586 
   1587 Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone) {
   1588   ZoneList<StackFrame*> list(10, zone);
   1589   for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
   1590     StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
   1591     list.Add(frame, zone);
   1592   }
   1593   return list.ToVector();
   1594 }
   1595 
   1596 
   1597 }  // namespace internal
   1598 }  // namespace v8
   1599