Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include "v8.h"
     29 
     30 #include "ast.h"
     31 #include "deoptimizer.h"
     32 #include "frames-inl.h"
     33 #include "full-codegen.h"
     34 #include "lazy-instance.h"
     35 #include "mark-compact.h"
     36 #include "safepoint-table.h"
     37 #include "scopeinfo.h"
     38 #include "string-stream.h"
     39 
     40 #include "allocation-inl.h"
     41 
     42 namespace v8 {
     43 namespace internal {
     44 
     45 
     46 static ReturnAddressLocationResolver return_address_location_resolver = NULL;
     47 
     48 
     49 // Resolves pc_address through the resolution address function if one is set.
     50 static inline Address* ResolveReturnAddressLocation(Address* pc_address) {
     51   if (return_address_location_resolver == NULL) {
     52     return pc_address;
     53   } else {
     54     return reinterpret_cast<Address*>(
     55         return_address_location_resolver(
     56             reinterpret_cast<uintptr_t>(pc_address)));
     57   }
     58 }
     59 
     60 
     61 // Iterator that supports traversing the stack handlers of a
     62 // particular frame. Needs to know the top of the handler chain.
     63 class StackHandlerIterator BASE_EMBEDDED {
     64  public:
     65   StackHandlerIterator(const StackFrame* frame, StackHandler* handler)
     66       : limit_(frame->fp()), handler_(handler) {
     67     // Make sure the handler has already been unwound to this frame.
     68     ASSERT(frame->sp() <= handler->address());
     69   }
     70 
     71   StackHandler* handler() const { return handler_; }
     72 
     73   bool done() {
     74     return handler_ == NULL || handler_->address() > limit_;
     75   }
     76   void Advance() {
     77     ASSERT(!done());
     78     handler_ = handler_->next();
     79   }
     80 
     81  private:
     82   const Address limit_;
     83   StackHandler* handler_;
     84 };
     85 
     86 
     87 // -------------------------------------------------------------------------
     88 
     89 
     90 #define INITIALIZE_SINGLETON(type, field) field##_(this),
     91 StackFrameIterator::StackFrameIterator()
     92     : isolate_(Isolate::Current()),
     93       STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
     94       frame_(NULL), handler_(NULL),
     95       thread_(isolate_->thread_local_top()),
     96       fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) {
     97   Reset();
     98 }
     99 StackFrameIterator::StackFrameIterator(Isolate* isolate)
    100     : isolate_(isolate),
    101       STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
    102       frame_(NULL), handler_(NULL),
    103       thread_(isolate_->thread_local_top()),
    104       fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) {
    105   Reset();
    106 }
    107 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
    108     : isolate_(isolate),
    109       STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
    110       frame_(NULL), handler_(NULL), thread_(t),
    111       fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) {
    112   Reset();
    113 }
    114 StackFrameIterator::StackFrameIterator(Isolate* isolate,
    115                                        bool use_top, Address fp, Address sp)
    116     : isolate_(isolate),
    117       STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
    118       frame_(NULL), handler_(NULL),
    119       thread_(use_top ? isolate_->thread_local_top() : NULL),
    120       fp_(use_top ? NULL : fp), sp_(sp),
    121       advance_(use_top ? &StackFrameIterator::AdvanceWithHandler :
    122                &StackFrameIterator::AdvanceWithoutHandler) {
    123   if (use_top || fp != NULL) {
    124     Reset();
    125   }
    126 }
    127 
    128 #undef INITIALIZE_SINGLETON
    129 
    130 
    131 void StackFrameIterator::AdvanceWithHandler() {
    132   ASSERT(!done());
    133   // Compute the state of the calling frame before restoring
    134   // callee-saved registers and unwinding handlers. This allows the
    135   // frame code that computes the caller state to access the top
    136   // handler and the value of any callee-saved register if needed.
    137   StackFrame::State state;
    138   StackFrame::Type type = frame_->GetCallerState(&state);
    139 
    140   // Unwind handlers corresponding to the current frame.
    141   StackHandlerIterator it(frame_, handler_);
    142   while (!it.done()) it.Advance();
    143   handler_ = it.handler();
    144 
    145   // Advance to the calling frame.
    146   frame_ = SingletonFor(type, &state);
    147 
    148   // When we're done iterating over the stack frames, the handler
    149   // chain must have been completely unwound.
    150   ASSERT(!done() || handler_ == NULL);
    151 }
    152 
    153 
    154 void StackFrameIterator::AdvanceWithoutHandler() {
    155   // A simpler version of Advance which doesn't care about handler.
    156   ASSERT(!done());
    157   StackFrame::State state;
    158   StackFrame::Type type = frame_->GetCallerState(&state);
    159   frame_ = SingletonFor(type, &state);
    160 }
    161 
    162 
    163 void StackFrameIterator::Reset() {
    164   StackFrame::State state;
    165   StackFrame::Type type;
    166   if (thread_ != NULL) {
    167     type = ExitFrame::GetStateForFramePointer(
    168         Isolate::c_entry_fp(thread_), &state);
    169     handler_ = StackHandler::FromAddress(
    170         Isolate::handler(thread_));
    171   } else {
    172     ASSERT(fp_ != NULL);
    173     state.fp = fp_;
    174     state.sp = sp_;
    175     state.pc_address = ResolveReturnAddressLocation(
    176         reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)));
    177     type = StackFrame::ComputeType(isolate(), &state);
    178   }
    179   if (SingletonFor(type) == NULL) return;
    180   frame_ = SingletonFor(type, &state);
    181 }
    182 
    183 
    184 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type,
    185                                              StackFrame::State* state) {
    186   if (type == StackFrame::NONE) return NULL;
    187   StackFrame* result = SingletonFor(type);
    188   ASSERT(result != NULL);
    189   result->state_ = *state;
    190   return result;
    191 }
    192 
    193 
    194 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type) {
    195 #define FRAME_TYPE_CASE(type, field) \
    196   case StackFrame::type: result = &field##_; break;
    197 
    198   StackFrame* result = NULL;
    199   switch (type) {
    200     case StackFrame::NONE: return NULL;
    201     STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
    202     default: break;
    203   }
    204   return result;
    205 
    206 #undef FRAME_TYPE_CASE
    207 }
    208 
    209 
    210 // -------------------------------------------------------------------------
    211 
    212 
    213 StackTraceFrameIterator::StackTraceFrameIterator() {
    214   if (!done() && !IsValidFrame()) Advance();
    215 }
    216 
    217 
    218 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
    219     : JavaScriptFrameIterator(isolate) {
    220   if (!done() && !IsValidFrame()) Advance();
    221 }
    222 
    223 
    224 void StackTraceFrameIterator::Advance() {
    225   while (true) {
    226     JavaScriptFrameIterator::Advance();
    227     if (done()) return;
    228     if (IsValidFrame()) return;
    229   }
    230 }
    231 
    232 bool StackTraceFrameIterator::IsValidFrame() {
    233     if (!frame()->function()->IsJSFunction()) return false;
    234     Object* script = JSFunction::cast(frame()->function())->shared()->script();
    235     // Don't show functions from native scripts to user.
    236     return (script->IsScript() &&
    237             Script::TYPE_NATIVE != Script::cast(script)->type()->value());
    238 }
    239 
    240 
    241 // -------------------------------------------------------------------------
    242 
    243 
    244 bool SafeStackFrameIterator::ExitFrameValidator::IsValidFP(Address fp) {
    245   if (!validator_.IsValid(fp)) return false;
    246   Address sp = ExitFrame::ComputeStackPointer(fp);
    247   if (!validator_.IsValid(sp)) return false;
    248   StackFrame::State state;
    249   ExitFrame::FillState(fp, sp, &state);
    250   if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) {
    251     return false;
    252   }
    253   return *state.pc_address != NULL;
    254 }
    255 
    256 
    257 SafeStackFrameIterator::ActiveCountMaintainer::ActiveCountMaintainer(
    258     Isolate* isolate)
    259     : isolate_(isolate) {
    260   isolate_->set_safe_stack_iterator_counter(
    261       isolate_->safe_stack_iterator_counter() + 1);
    262 }
    263 
    264 
    265 SafeStackFrameIterator::ActiveCountMaintainer::~ActiveCountMaintainer() {
    266   isolate_->set_safe_stack_iterator_counter(
    267       isolate_->safe_stack_iterator_counter() - 1);
    268 }
    269 
    270 
    271 SafeStackFrameIterator::SafeStackFrameIterator(
    272     Isolate* isolate,
    273     Address fp, Address sp, Address low_bound, Address high_bound) :
    274     maintainer_(isolate),
    275     stack_validator_(low_bound, high_bound),
    276     is_valid_top_(IsValidTop(isolate, low_bound, high_bound)),
    277     is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)),
    278     is_working_iterator_(is_valid_top_ || is_valid_fp_),
    279     iteration_done_(!is_working_iterator_),
    280     iterator_(isolate, is_valid_top_, is_valid_fp_ ? fp : NULL, sp) {
    281 }
    282 
    283 bool SafeStackFrameIterator::is_active(Isolate* isolate) {
    284   return isolate->safe_stack_iterator_counter() > 0;
    285 }
    286 
    287 
    288 bool SafeStackFrameIterator::IsValidTop(Isolate* isolate,
    289                                         Address low_bound, Address high_bound) {
    290   ThreadLocalTop* top = isolate->thread_local_top();
    291   Address fp = Isolate::c_entry_fp(top);
    292   ExitFrameValidator validator(low_bound, high_bound);
    293   if (!validator.IsValidFP(fp)) return false;
    294   return Isolate::handler(top) != NULL;
    295 }
    296 
    297 
    298 void SafeStackFrameIterator::Advance() {
    299   ASSERT(is_working_iterator_);
    300   ASSERT(!done());
    301   StackFrame* last_frame = iterator_.frame();
    302   Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
    303   // Before advancing to the next stack frame, perform pointer validity tests
    304   iteration_done_ = !IsValidFrame(last_frame) ||
    305       !CanIterateHandles(last_frame, iterator_.handler()) ||
    306       !IsValidCaller(last_frame);
    307   if (iteration_done_) return;
    308 
    309   iterator_.Advance();
    310   if (iterator_.done()) return;
    311   // Check that we have actually moved to the previous frame in the stack
    312   StackFrame* prev_frame = iterator_.frame();
    313   iteration_done_ = prev_frame->sp() < last_sp || prev_frame->fp() < last_fp;
    314 }
    315 
    316 
    317 bool SafeStackFrameIterator::CanIterateHandles(StackFrame* frame,
    318                                                StackHandler* handler) {
    319   // If StackIterator iterates over StackHandles, verify that
    320   // StackHandlerIterator can be instantiated (see StackHandlerIterator
    321   // constructor.)
    322   return !is_valid_top_ || (frame->sp() <= handler->address());
    323 }
    324 
    325 
    326 bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const {
    327   return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
    328 }
    329 
    330 
    331 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
    332   StackFrame::State state;
    333   if (frame->is_entry() || frame->is_entry_construct()) {
    334     // See EntryFrame::GetCallerState. It computes the caller FP address
    335     // and calls ExitFrame::GetStateForFramePointer on it. We need to be
    336     // sure that caller FP address is valid.
    337     Address caller_fp = Memory::Address_at(
    338         frame->fp() + EntryFrameConstants::kCallerFPOffset);
    339     ExitFrameValidator validator(stack_validator_);
    340     if (!validator.IsValidFP(caller_fp)) return false;
    341   } else if (frame->is_arguments_adaptor()) {
    342     // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that
    343     // the number of arguments is stored on stack as Smi. We need to check
    344     // that it really an Smi.
    345     Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)->
    346         GetExpression(0);
    347     if (!number_of_args->IsSmi()) {
    348       return false;
    349     }
    350   }
    351   frame->ComputeCallerState(&state);
    352   return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) &&
    353       iterator_.SingletonFor(frame->GetCallerState(&state)) != NULL;
    354 }
    355 
    356 
    357 void SafeStackFrameIterator::Reset() {
    358   if (is_working_iterator_) {
    359     iterator_.Reset();
    360     iteration_done_ = false;
    361   }
    362 }
    363 
    364 
    365 // -------------------------------------------------------------------------
    366 
    367 
    368 SafeStackTraceFrameIterator::SafeStackTraceFrameIterator(
    369     Isolate* isolate,
    370     Address fp, Address sp, Address low_bound, Address high_bound) :
    371     SafeJavaScriptFrameIterator(isolate, fp, sp, low_bound, high_bound) {
    372   if (!done() && !frame()->is_java_script()) Advance();
    373 }
    374 
    375 
    376 void SafeStackTraceFrameIterator::Advance() {
    377   while (true) {
    378     SafeJavaScriptFrameIterator::Advance();
    379     if (done()) return;
    380     if (frame()->is_java_script()) return;
    381   }
    382 }
    383 
    384 
    385 Code* StackFrame::GetSafepointData(Isolate* isolate,
    386                                    Address inner_pointer,
    387                                    SafepointEntry* safepoint_entry,
    388                                    unsigned* stack_slots) {
    389   InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry =
    390       isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer);
    391   if (!entry->safepoint_entry.is_valid()) {
    392     entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer);
    393     ASSERT(entry->safepoint_entry.is_valid());
    394   } else {
    395     ASSERT(entry->safepoint_entry.Equals(
    396         entry->code->GetSafepointEntry(inner_pointer)));
    397   }
    398 
    399   // Fill in the results and return the code.
    400   Code* code = entry->code;
    401   *safepoint_entry = entry->safepoint_entry;
    402   *stack_slots = code->stack_slots();
    403   return code;
    404 }
    405 
    406 
    407 bool StackFrame::HasHandler() const {
    408   StackHandlerIterator it(this, top_handler());
    409   return !it.done();
    410 }
    411 
    412 
    413 #ifdef DEBUG
    414 static bool GcSafeCodeContains(HeapObject* object, Address addr);
    415 #endif
    416 
    417 
    418 void StackFrame::IteratePc(ObjectVisitor* v,
    419                            Address* pc_address,
    420                            Code* holder) {
    421   Address pc = *pc_address;
    422   ASSERT(GcSafeCodeContains(holder, pc));
    423   unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start());
    424   Object* code = holder;
    425   v->VisitPointer(&code);
    426   if (code != holder) {
    427     holder = reinterpret_cast<Code*>(code);
    428     pc = holder->instruction_start() + pc_offset;
    429     *pc_address = pc;
    430   }
    431 }
    432 
    433 
    434 void StackFrame::SetReturnAddressLocationResolver(
    435     ReturnAddressLocationResolver resolver) {
    436   ASSERT(return_address_location_resolver == NULL);
    437   return_address_location_resolver = resolver;
    438 }
    439 
    440 
    441 StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) {
    442   ASSERT(state->fp != NULL);
    443   if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
    444     return ARGUMENTS_ADAPTOR;
    445   }
    446   // The marker and function offsets overlap. If the marker isn't a
    447   // smi then the frame is a JavaScript frame -- and the marker is
    448   // really the function.
    449   const int offset = StandardFrameConstants::kMarkerOffset;
    450   Object* marker = Memory::Object_at(state->fp + offset);
    451   if (!marker->IsSmi()) {
    452     // If we're using a "safe" stack iterator, we treat optimized
    453     // frames as normal JavaScript frames to avoid having to look
    454     // into the heap to determine the state. This is safe as long
    455     // as nobody tries to GC...
    456     if (SafeStackFrameIterator::is_active(isolate)) return JAVA_SCRIPT;
    457     Code::Kind kind = GetContainingCode(isolate, *(state->pc_address))->kind();
    458     ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION);
    459     return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT;
    460   }
    461   return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
    462 }
    463 
    464 
    465 
    466 StackFrame::Type StackFrame::GetCallerState(State* state) const {
    467   ComputeCallerState(state);
    468   return ComputeType(isolate(), state);
    469 }
    470 
    471 
    472 Code* EntryFrame::unchecked_code() const {
    473   return HEAP->raw_unchecked_js_entry_code();
    474 }
    475 
    476 
    477 void EntryFrame::ComputeCallerState(State* state) const {
    478   GetCallerState(state);
    479 }
    480 
    481 
    482 void EntryFrame::SetCallerFp(Address caller_fp) {
    483   const int offset = EntryFrameConstants::kCallerFPOffset;
    484   Memory::Address_at(this->fp() + offset) = caller_fp;
    485 }
    486 
    487 
    488 StackFrame::Type EntryFrame::GetCallerState(State* state) const {
    489   const int offset = EntryFrameConstants::kCallerFPOffset;
    490   Address fp = Memory::Address_at(this->fp() + offset);
    491   return ExitFrame::GetStateForFramePointer(fp, state);
    492 }
    493 
    494 
    495 Code* EntryConstructFrame::unchecked_code() const {
    496   return HEAP->raw_unchecked_js_construct_entry_code();
    497 }
    498 
    499 
    500 Object*& ExitFrame::code_slot() const {
    501   const int offset = ExitFrameConstants::kCodeOffset;
    502   return Memory::Object_at(fp() + offset);
    503 }
    504 
    505 
    506 Code* ExitFrame::unchecked_code() const {
    507   return reinterpret_cast<Code*>(code_slot());
    508 }
    509 
    510 
    511 void ExitFrame::ComputeCallerState(State* state) const {
    512   // Set up the caller state.
    513   state->sp = caller_sp();
    514   state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);
    515   state->pc_address = ResolveReturnAddressLocation(
    516       reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
    517 }
    518 
    519 
    520 void ExitFrame::SetCallerFp(Address caller_fp) {
    521   Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp;
    522 }
    523 
    524 
    525 void ExitFrame::Iterate(ObjectVisitor* v) const {
    526   // The arguments are traversed as part of the expression stack of
    527   // the calling frame.
    528   IteratePc(v, pc_address(), LookupCode());
    529   v->VisitPointer(&code_slot());
    530 }
    531 
    532 
    533 Address ExitFrame::GetCallerStackPointer() const {
    534   return fp() + ExitFrameConstants::kCallerSPDisplacement;
    535 }
    536 
    537 
    538 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
    539   if (fp == 0) return NONE;
    540   Address sp = ComputeStackPointer(fp);
    541   FillState(fp, sp, state);
    542   ASSERT(*state->pc_address != NULL);
    543   return EXIT;
    544 }
    545 
    546 
    547 void ExitFrame::FillState(Address fp, Address sp, State* state) {
    548   state->sp = sp;
    549   state->fp = fp;
    550   state->pc_address = ResolveReturnAddressLocation(
    551       reinterpret_cast<Address*>(sp - 1 * kPointerSize));
    552 }
    553 
    554 
    555 Address StandardFrame::GetExpressionAddress(int n) const {
    556   const int offset = StandardFrameConstants::kExpressionsOffset;
    557   return fp() + offset - n * kPointerSize;
    558 }
    559 
    560 
    561 Object* StandardFrame::GetExpression(Address fp, int index) {
    562   return Memory::Object_at(GetExpressionAddress(fp, index));
    563 }
    564 
    565 
    566 Address StandardFrame::GetExpressionAddress(Address fp, int n) {
    567   const int offset = StandardFrameConstants::kExpressionsOffset;
    568   return fp + offset - n * kPointerSize;
    569 }
    570 
    571 
    572 int StandardFrame::ComputeExpressionsCount() const {
    573   const int offset =
    574       StandardFrameConstants::kExpressionsOffset + kPointerSize;
    575   Address base = fp() + offset;
    576   Address limit = sp();
    577   ASSERT(base >= limit);  // stack grows downwards
    578   // Include register-allocated locals in number of expressions.
    579   return static_cast<int>((base - limit) / kPointerSize);
    580 }
    581 
    582 
    583 void StandardFrame::ComputeCallerState(State* state) const {
    584   state->sp = caller_sp();
    585   state->fp = caller_fp();
    586   state->pc_address = ResolveReturnAddressLocation(
    587       reinterpret_cast<Address*>(ComputePCAddress(fp())));
    588 }
    589 
    590 
    591 void StandardFrame::SetCallerFp(Address caller_fp) {
    592   Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) =
    593       caller_fp;
    594 }
    595 
    596 
    597 bool StandardFrame::IsExpressionInsideHandler(int n) const {
    598   Address address = GetExpressionAddress(n);
    599   for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
    600     if (it.handler()->includes(address)) return true;
    601   }
    602   return false;
    603 }
    604 
    605 
    606 void OptimizedFrame::Iterate(ObjectVisitor* v) const {
    607 #ifdef DEBUG
    608   // Make sure that optimized frames do not contain any stack handlers.
    609   StackHandlerIterator it(this, top_handler());
    610   ASSERT(it.done());
    611 #endif
    612 
    613   // Make sure that we're not doing "safe" stack frame iteration. We cannot
    614   // possibly find pointers in optimized frames in that state.
    615   ASSERT(!SafeStackFrameIterator::is_active(isolate()));
    616 
    617   // Compute the safepoint information.
    618   unsigned stack_slots = 0;
    619   SafepointEntry safepoint_entry;
    620   Code* code = StackFrame::GetSafepointData(
    621       isolate(), pc(), &safepoint_entry, &stack_slots);
    622   unsigned slot_space = stack_slots * kPointerSize;
    623 
    624   // Visit the outgoing parameters.
    625   Object** parameters_base = &Memory::Object_at(sp());
    626   Object** parameters_limit = &Memory::Object_at(
    627       fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space);
    628 
    629   // Visit the parameters that may be on top of the saved registers.
    630   if (safepoint_entry.argument_count() > 0) {
    631     v->VisitPointers(parameters_base,
    632                      parameters_base + safepoint_entry.argument_count());
    633     parameters_base += safepoint_entry.argument_count();
    634   }
    635 
    636   // Skip saved double registers.
    637   if (safepoint_entry.has_doubles()) {
    638     parameters_base += DoubleRegister::kNumAllocatableRegisters *
    639         kDoubleSize / kPointerSize;
    640   }
    641 
    642   // Visit the registers that contain pointers if any.
    643   if (safepoint_entry.HasRegisters()) {
    644     for (int i = kNumSafepointRegisters - 1; i >=0; i--) {
    645       if (safepoint_entry.HasRegisterAt(i)) {
    646         int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(i);
    647         v->VisitPointer(parameters_base + reg_stack_index);
    648       }
    649     }
    650     // Skip the words containing the register values.
    651     parameters_base += kNumSafepointRegisters;
    652   }
    653 
    654   // We're done dealing with the register bits.
    655   uint8_t* safepoint_bits = safepoint_entry.bits();
    656   safepoint_bits += kNumSafepointRegisters >> kBitsPerByteLog2;
    657 
    658   // Visit the rest of the parameters.
    659   v->VisitPointers(parameters_base, parameters_limit);
    660 
    661   // Visit pointer spill slots and locals.
    662   for (unsigned index = 0; index < stack_slots; index++) {
    663     int byte_index = index >> kBitsPerByteLog2;
    664     int bit_index = index & (kBitsPerByte - 1);
    665     if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) {
    666       v->VisitPointer(parameters_limit + index);
    667     }
    668   }
    669 
    670   // Visit the context and the function.
    671   Object** fixed_base = &Memory::Object_at(
    672       fp() + JavaScriptFrameConstants::kFunctionOffset);
    673   Object** fixed_limit = &Memory::Object_at(fp());
    674   v->VisitPointers(fixed_base, fixed_limit);
    675 
    676   // Visit the return address in the callee and incoming arguments.
    677   IteratePc(v, pc_address(), code);
    678 }
    679 
    680 
    681 bool JavaScriptFrame::IsConstructor() const {
    682   Address fp = caller_fp();
    683   if (has_adapted_arguments()) {
    684     // Skip the arguments adaptor frame and look at the real caller.
    685     fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset);
    686   }
    687   return IsConstructFrame(fp);
    688 }
    689 
    690 
    691 int JavaScriptFrame::GetArgumentsLength() const {
    692   // If there is an arguments adaptor frame get the arguments length from it.
    693   if (has_adapted_arguments()) {
    694     return Smi::cast(GetExpression(caller_fp(), 0))->value();
    695   } else {
    696     return GetNumberOfIncomingArguments();
    697   }
    698 }
    699 
    700 
    701 Code* JavaScriptFrame::unchecked_code() const {
    702   JSFunction* function = JSFunction::cast(this->function());
    703   return function->unchecked_code();
    704 }
    705 
    706 
    707 int JavaScriptFrame::GetNumberOfIncomingArguments() const {
    708   ASSERT(!SafeStackFrameIterator::is_active(isolate()) &&
    709          isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
    710 
    711   JSFunction* function = JSFunction::cast(this->function());
    712   return function->shared()->formal_parameter_count();
    713 }
    714 
    715 
    716 Address JavaScriptFrame::GetCallerStackPointer() const {
    717   return fp() + StandardFrameConstants::kCallerSPOffset;
    718 }
    719 
    720 
    721 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) {
    722   ASSERT(functions->length() == 0);
    723   functions->Add(JSFunction::cast(function()));
    724 }
    725 
    726 
    727 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) {
    728   ASSERT(functions->length() == 0);
    729   Code* code_pointer = LookupCode();
    730   int offset = static_cast<int>(pc() - code_pointer->address());
    731   FrameSummary summary(receiver(),
    732                        JSFunction::cast(function()),
    733                        code_pointer,
    734                        offset,
    735                        IsConstructor());
    736   functions->Add(summary);
    737 }
    738 
    739 
    740 void JavaScriptFrame::PrintTop(FILE* file,
    741                                bool print_args,
    742                                bool print_line_number) {
    743   // constructor calls
    744   HandleScope scope;
    745   AssertNoAllocation no_allocation;
    746   JavaScriptFrameIterator it;
    747   while (!it.done()) {
    748     if (it.frame()->is_java_script()) {
    749       JavaScriptFrame* frame = it.frame();
    750       if (frame->IsConstructor()) PrintF(file, "new ");
    751       // function name
    752       Object* maybe_fun = frame->function();
    753       if (maybe_fun->IsJSFunction()) {
    754         JSFunction* fun = JSFunction::cast(maybe_fun);
    755         fun->PrintName();
    756         Code* js_code = frame->unchecked_code();
    757         Address pc = frame->pc();
    758         int code_offset =
    759             static_cast<int>(pc - js_code->instruction_start());
    760         PrintF("+%d", code_offset);
    761         SharedFunctionInfo* shared = fun->shared();
    762         if (print_line_number) {
    763           Code* code = Code::cast(
    764               v8::internal::Isolate::Current()->heap()->FindCodeObject(pc));
    765           int source_pos = code->SourcePosition(pc);
    766           Object* maybe_script = shared->script();
    767           if (maybe_script->IsScript()) {
    768             Handle<Script> script(Script::cast(maybe_script));
    769             int line = GetScriptLineNumberSafe(script, source_pos) + 1;
    770             Object* script_name_raw = script->name();
    771             if (script_name_raw->IsString()) {
    772               String* script_name = String::cast(script->name());
    773               SmartArrayPointer<char> c_script_name =
    774                   script_name->ToCString(DISALLOW_NULLS,
    775                                          ROBUST_STRING_TRAVERSAL);
    776               PrintF(file, " at %s:%d", *c_script_name, line);
    777             } else {
    778               PrintF(file, "at <unknown>:%d", line);
    779             }
    780           } else {
    781             PrintF(file, " at <unknown>:<unknown>");
    782           }
    783         }
    784       } else {
    785         PrintF("<unknown>");
    786       }
    787 
    788       if (print_args) {
    789         // function arguments
    790         // (we are intentionally only printing the actually
    791         // supplied parameters, not all parameters required)
    792         PrintF(file, "(this=");
    793         frame->receiver()->ShortPrint(file);
    794         const int length = frame->ComputeParametersCount();
    795         for (int i = 0; i < length; i++) {
    796           PrintF(file, ", ");
    797           frame->GetParameter(i)->ShortPrint(file);
    798         }
    799         PrintF(file, ")");
    800       }
    801       break;
    802     }
    803     it.Advance();
    804   }
    805 }
    806 
    807 
    808 void FrameSummary::Print() {
    809   PrintF("receiver: ");
    810   receiver_->ShortPrint();
    811   PrintF("\nfunction: ");
    812   function_->shared()->DebugName()->ShortPrint();
    813   PrintF("\ncode: ");
    814   code_->ShortPrint();
    815   if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT");
    816   if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT");
    817   PrintF("\npc: %d\n", offset_);
    818 }
    819 
    820 
    821 void OptimizedFrame::Summarize(List<FrameSummary>* frames) {
    822   ASSERT(frames->length() == 0);
    823   ASSERT(is_optimized());
    824 
    825   int deopt_index = Safepoint::kNoDeoptimizationIndex;
    826   DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
    827 
    828   // BUG(3243555): Since we don't have a lazy-deopt registered at
    829   // throw-statements, we can't use the translation at the call-site of
    830   // throw. An entry with no deoptimization index indicates a call-site
    831   // without a lazy-deopt. As a consequence we are not allowed to inline
    832   // functions containing throw.
    833   if (deopt_index == Safepoint::kNoDeoptimizationIndex) {
    834     JavaScriptFrame::Summarize(frames);
    835     return;
    836   }
    837 
    838   TranslationIterator it(data->TranslationByteArray(),
    839                          data->TranslationIndex(deopt_index)->value());
    840   Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
    841   ASSERT(opcode == Translation::BEGIN);
    842   it.Next();  // Drop frame count.
    843   int jsframe_count = it.Next();
    844 
    845   // We create the summary in reverse order because the frames
    846   // in the deoptimization translation are ordered bottom-to-top.
    847   bool is_constructor = IsConstructor();
    848   int i = jsframe_count;
    849   while (i > 0) {
    850     opcode = static_cast<Translation::Opcode>(it.Next());
    851     if (opcode == Translation::JS_FRAME) {
    852       i--;
    853       int ast_id = it.Next();
    854       int function_id = it.Next();
    855       it.Next();  // Skip height.
    856       JSFunction* function =
    857           JSFunction::cast(data->LiteralArray()->get(function_id));
    858 
    859       // The translation commands are ordered and the receiver is always
    860       // at the first position. Since we are always at a call when we need
    861       // to construct a stack trace, the receiver is always in a stack slot.
    862       opcode = static_cast<Translation::Opcode>(it.Next());
    863       ASSERT(opcode == Translation::STACK_SLOT ||
    864              opcode == Translation::LITERAL);
    865       int index = it.Next();
    866 
    867       // Get the correct receiver in the optimized frame.
    868       Object* receiver = NULL;
    869       if (opcode == Translation::LITERAL) {
    870         receiver = data->LiteralArray()->get(index);
    871       } else {
    872         // Positive index means the value is spilled to the locals
    873         // area. Negative means it is stored in the incoming parameter
    874         // area.
    875         if (index >= 0) {
    876           receiver = GetExpression(index);
    877         } else {
    878           // Index -1 overlaps with last parameter, -n with the first parameter,
    879           // (-n - 1) with the receiver with n being the number of parameters
    880           // of the outermost, optimized frame.
    881           int parameter_count = ComputeParametersCount();
    882           int parameter_index = index + parameter_count;
    883           receiver = (parameter_index == -1)
    884               ? this->receiver()
    885               : this->GetParameter(parameter_index);
    886         }
    887       }
    888 
    889       Code* code = function->shared()->code();
    890       DeoptimizationOutputData* output_data =
    891           DeoptimizationOutputData::cast(code->deoptimization_data());
    892       unsigned entry = Deoptimizer::GetOutputInfo(output_data,
    893                                                   ast_id,
    894                                                   function->shared());
    895       unsigned pc_offset =
    896           FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize;
    897       ASSERT(pc_offset > 0);
    898 
    899       FrameSummary summary(receiver, function, code, pc_offset, is_constructor);
    900       frames->Add(summary);
    901       is_constructor = false;
    902     } else if (opcode == Translation::CONSTRUCT_STUB_FRAME) {
    903       // The next encountered JS_FRAME will be marked as a constructor call.
    904       it.Skip(Translation::NumberOfOperandsFor(opcode));
    905       ASSERT(!is_constructor);
    906       is_constructor = true;
    907     } else {
    908       // Skip over operands to advance to the next opcode.
    909       it.Skip(Translation::NumberOfOperandsFor(opcode));
    910     }
    911   }
    912   ASSERT(!is_constructor);
    913 }
    914 
    915 
    916 DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData(
    917     int* deopt_index) {
    918   ASSERT(is_optimized());
    919 
    920   JSFunction* opt_function = JSFunction::cast(function());
    921   Code* code = opt_function->code();
    922 
    923   // The code object may have been replaced by lazy deoptimization. Fall
    924   // back to a slow search in this case to find the original optimized
    925   // code object.
    926   if (!code->contains(pc())) {
    927     code = isolate()->inner_pointer_to_code_cache()->
    928         GcSafeFindCodeForInnerPointer(pc());
    929   }
    930   ASSERT(code != NULL);
    931   ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
    932 
    933   SafepointEntry safepoint_entry = code->GetSafepointEntry(pc());
    934   *deopt_index = safepoint_entry.deoptimization_index();
    935   ASSERT(*deopt_index != Safepoint::kNoDeoptimizationIndex);
    936 
    937   return DeoptimizationInputData::cast(code->deoptimization_data());
    938 }
    939 
    940 
    941 int OptimizedFrame::GetInlineCount() {
    942   ASSERT(is_optimized());
    943 
    944   int deopt_index = Safepoint::kNoDeoptimizationIndex;
    945   DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
    946 
    947   TranslationIterator it(data->TranslationByteArray(),
    948                          data->TranslationIndex(deopt_index)->value());
    949   Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
    950   ASSERT(opcode == Translation::BEGIN);
    951   USE(opcode);
    952   it.Next();  // Drop frame count.
    953   int jsframe_count = it.Next();
    954   return jsframe_count;
    955 }
    956 
    957 
    958 void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) {
    959   ASSERT(functions->length() == 0);
    960   ASSERT(is_optimized());
    961 
    962   int deopt_index = Safepoint::kNoDeoptimizationIndex;
    963   DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
    964 
    965   TranslationIterator it(data->TranslationByteArray(),
    966                          data->TranslationIndex(deopt_index)->value());
    967   Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
    968   ASSERT(opcode == Translation::BEGIN);
    969   it.Next();  // Drop frame count.
    970   int jsframe_count = it.Next();
    971 
    972   // We insert the frames in reverse order because the frames
    973   // in the deoptimization translation are ordered bottom-to-top.
    974   while (jsframe_count > 0) {
    975     opcode = static_cast<Translation::Opcode>(it.Next());
    976     if (opcode == Translation::JS_FRAME) {
    977       jsframe_count--;
    978       it.Next();  // Skip ast id.
    979       int function_id = it.Next();
    980       it.Next();  // Skip height.
    981       JSFunction* function =
    982           JSFunction::cast(data->LiteralArray()->get(function_id));
    983       functions->Add(function);
    984     } else {
    985       // Skip over operands to advance to the next opcode.
    986       it.Skip(Translation::NumberOfOperandsFor(opcode));
    987     }
    988   }
    989 }
    990 
    991 
    992 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const {
    993   return Smi::cast(GetExpression(0))->value();
    994 }
    995 
    996 
    997 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const {
    998   return fp() + StandardFrameConstants::kCallerSPOffset;
    999 }
   1000 
   1001 
   1002 Address InternalFrame::GetCallerStackPointer() const {
   1003   // Internal frames have no arguments. The stack pointer of the
   1004   // caller is at a fixed offset from the frame pointer.
   1005   return fp() + StandardFrameConstants::kCallerSPOffset;
   1006 }
   1007 
   1008 
   1009 Code* ArgumentsAdaptorFrame::unchecked_code() const {
   1010   return isolate()->builtins()->builtin(
   1011       Builtins::kArgumentsAdaptorTrampoline);
   1012 }
   1013 
   1014 
   1015 Code* InternalFrame::unchecked_code() const {
   1016   const int offset = InternalFrameConstants::kCodeOffset;
   1017   Object* code = Memory::Object_at(fp() + offset);
   1018   ASSERT(code != NULL);
   1019   return reinterpret_cast<Code*>(code);
   1020 }
   1021 
   1022 
   1023 void StackFrame::PrintIndex(StringStream* accumulator,
   1024                             PrintMode mode,
   1025                             int index) {
   1026   accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index);
   1027 }
   1028 
   1029 
   1030 void JavaScriptFrame::Print(StringStream* accumulator,
   1031                             PrintMode mode,
   1032                             int index) const {
   1033   HandleScope scope;
   1034   Object* receiver = this->receiver();
   1035   Object* function = this->function();
   1036 
   1037   accumulator->PrintSecurityTokenIfChanged(function);
   1038   PrintIndex(accumulator, mode, index);
   1039   Code* code = NULL;
   1040   if (IsConstructor()) accumulator->Add("new ");
   1041   accumulator->PrintFunction(function, receiver, &code);
   1042 
   1043   // Get scope information for nicer output, if possible. If code is NULL, or
   1044   // doesn't contain scope info, scope_info will return 0 for the number of
   1045   // parameters, stack local variables, context local variables, stack slots,
   1046   // or context slots.
   1047   Handle<ScopeInfo> scope_info(ScopeInfo::Empty());
   1048 
   1049   if (function->IsJSFunction()) {
   1050     Handle<SharedFunctionInfo> shared(JSFunction::cast(function)->shared());
   1051     scope_info = Handle<ScopeInfo>(shared->scope_info());
   1052     Object* script_obj = shared->script();
   1053     if (script_obj->IsScript()) {
   1054       Handle<Script> script(Script::cast(script_obj));
   1055       accumulator->Add(" [");
   1056       accumulator->PrintName(script->name());
   1057 
   1058       Address pc = this->pc();
   1059       if (code != NULL && code->kind() == Code::FUNCTION &&
   1060           pc >= code->instruction_start() && pc < code->instruction_end()) {
   1061         int source_pos = code->SourcePosition(pc);
   1062         int line = GetScriptLineNumberSafe(script, source_pos) + 1;
   1063         accumulator->Add(":%d", line);
   1064       } else {
   1065         int function_start_pos = shared->start_position();
   1066         int line = GetScriptLineNumberSafe(script, function_start_pos) + 1;
   1067         accumulator->Add(":~%d", line);
   1068       }
   1069 
   1070       accumulator->Add("] ");
   1071     }
   1072   }
   1073 
   1074   accumulator->Add("(this=%o", receiver);
   1075 
   1076   // Print the parameters.
   1077   int parameters_count = ComputeParametersCount();
   1078   for (int i = 0; i < parameters_count; i++) {
   1079     accumulator->Add(",");
   1080     // If we have a name for the parameter we print it. Nameless
   1081     // parameters are either because we have more actual parameters
   1082     // than formal parameters or because we have no scope information.
   1083     if (i < scope_info->ParameterCount()) {
   1084       accumulator->PrintName(scope_info->ParameterName(i));
   1085       accumulator->Add("=");
   1086     }
   1087     accumulator->Add("%o", GetParameter(i));
   1088   }
   1089 
   1090   accumulator->Add(")");
   1091   if (mode == OVERVIEW) {
   1092     accumulator->Add("\n");
   1093     return;
   1094   }
   1095   if (is_optimized()) {
   1096     accumulator->Add(" {\n// optimized frame\n}\n");
   1097     return;
   1098   }
   1099   accumulator->Add(" {\n");
   1100 
   1101   // Compute the number of locals and expression stack elements.
   1102   int stack_locals_count = scope_info->StackLocalCount();
   1103   int heap_locals_count = scope_info->ContextLocalCount();
   1104   int expressions_count = ComputeExpressionsCount();
   1105 
   1106   // Print stack-allocated local variables.
   1107   if (stack_locals_count > 0) {
   1108     accumulator->Add("  // stack-allocated locals\n");
   1109   }
   1110   for (int i = 0; i < stack_locals_count; i++) {
   1111     accumulator->Add("  var ");
   1112     accumulator->PrintName(scope_info->StackLocalName(i));
   1113     accumulator->Add(" = ");
   1114     if (i < expressions_count) {
   1115       accumulator->Add("%o", GetExpression(i));
   1116     } else {
   1117       accumulator->Add("// no expression found - inconsistent frame?");
   1118     }
   1119     accumulator->Add("\n");
   1120   }
   1121 
   1122   // Try to get hold of the context of this frame.
   1123   Context* context = NULL;
   1124   if (this->context() != NULL && this->context()->IsContext()) {
   1125     context = Context::cast(this->context());
   1126   }
   1127 
   1128   // Print heap-allocated local variables.
   1129   if (heap_locals_count > 0) {
   1130     accumulator->Add("  // heap-allocated locals\n");
   1131   }
   1132   for (int i = 0; i < heap_locals_count; i++) {
   1133     accumulator->Add("  var ");
   1134     accumulator->PrintName(scope_info->ContextLocalName(i));
   1135     accumulator->Add(" = ");
   1136     if (context != NULL) {
   1137       if (i < context->length()) {
   1138         accumulator->Add("%o", context->get(Context::MIN_CONTEXT_SLOTS + i));
   1139       } else {
   1140         accumulator->Add(
   1141             "// warning: missing context slot - inconsistent frame?");
   1142       }
   1143     } else {
   1144       accumulator->Add("// warning: no context found - inconsistent frame?");
   1145     }
   1146     accumulator->Add("\n");
   1147   }
   1148 
   1149   // Print the expression stack.
   1150   int expressions_start = stack_locals_count;
   1151   if (expressions_start < expressions_count) {
   1152     accumulator->Add("  // expression stack (top to bottom)\n");
   1153   }
   1154   for (int i = expressions_count - 1; i >= expressions_start; i--) {
   1155     if (IsExpressionInsideHandler(i)) continue;
   1156     accumulator->Add("  [%02d] : %o\n", i, GetExpression(i));
   1157   }
   1158 
   1159   // Print details about the function.
   1160   if (FLAG_max_stack_trace_source_length != 0 && code != NULL) {
   1161     SharedFunctionInfo* shared = JSFunction::cast(function)->shared();
   1162     accumulator->Add("--------- s o u r c e   c o d e ---------\n");
   1163     shared->SourceCodePrint(accumulator, FLAG_max_stack_trace_source_length);
   1164     accumulator->Add("\n-----------------------------------------\n");
   1165   }
   1166 
   1167   accumulator->Add("}\n\n");
   1168 }
   1169 
   1170 
   1171 void ArgumentsAdaptorFrame::Print(StringStream* accumulator,
   1172                                   PrintMode mode,
   1173                                   int index) const {
   1174   int actual = ComputeParametersCount();
   1175   int expected = -1;
   1176   Object* function = this->function();
   1177   if (function->IsJSFunction()) {
   1178     expected = JSFunction::cast(function)->shared()->formal_parameter_count();
   1179   }
   1180 
   1181   PrintIndex(accumulator, mode, index);
   1182   accumulator->Add("arguments adaptor frame: %d->%d", actual, expected);
   1183   if (mode == OVERVIEW) {
   1184     accumulator->Add("\n");
   1185     return;
   1186   }
   1187   accumulator->Add(" {\n");
   1188 
   1189   // Print actual arguments.
   1190   if (actual > 0) accumulator->Add("  // actual arguments\n");
   1191   for (int i = 0; i < actual; i++) {
   1192     accumulator->Add("  [%02d] : %o", i, GetParameter(i));
   1193     if (expected != -1 && i >= expected) {
   1194       accumulator->Add("  // not passed to callee");
   1195     }
   1196     accumulator->Add("\n");
   1197   }
   1198 
   1199   accumulator->Add("}\n\n");
   1200 }
   1201 
   1202 
   1203 void EntryFrame::Iterate(ObjectVisitor* v) const {
   1204   StackHandlerIterator it(this, top_handler());
   1205   ASSERT(!it.done());
   1206   StackHandler* handler = it.handler();
   1207   ASSERT(handler->is_js_entry());
   1208   handler->Iterate(v, LookupCode());
   1209 #ifdef DEBUG
   1210   // Make sure that the entry frame does not contain more than one
   1211   // stack handler.
   1212   it.Advance();
   1213   ASSERT(it.done());
   1214 #endif
   1215   IteratePc(v, pc_address(), LookupCode());
   1216 }
   1217 
   1218 
   1219 void StandardFrame::IterateExpressions(ObjectVisitor* v) const {
   1220   const int offset = StandardFrameConstants::kContextOffset;
   1221   Object** base = &Memory::Object_at(sp());
   1222   Object** limit = &Memory::Object_at(fp() + offset) + 1;
   1223   for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
   1224     StackHandler* handler = it.handler();
   1225     // Traverse pointers down to - but not including - the next
   1226     // handler in the handler chain. Update the base to skip the
   1227     // handler and allow the handler to traverse its own pointers.
   1228     const Address address = handler->address();
   1229     v->VisitPointers(base, reinterpret_cast<Object**>(address));
   1230     base = reinterpret_cast<Object**>(address + StackHandlerConstants::kSize);
   1231     // Traverse the pointers in the handler itself.
   1232     handler->Iterate(v, LookupCode());
   1233   }
   1234   v->VisitPointers(base, limit);
   1235 }
   1236 
   1237 
   1238 void JavaScriptFrame::Iterate(ObjectVisitor* v) const {
   1239   IterateExpressions(v);
   1240   IteratePc(v, pc_address(), LookupCode());
   1241 }
   1242 
   1243 
   1244 void InternalFrame::Iterate(ObjectVisitor* v) const {
   1245   // Internal frames only have object pointers on the expression stack
   1246   // as they never have any arguments.
   1247   IterateExpressions(v);
   1248   IteratePc(v, pc_address(), LookupCode());
   1249 }
   1250 
   1251 
   1252 // -------------------------------------------------------------------------
   1253 
   1254 
   1255 JavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) {
   1256   ASSERT(n >= 0);
   1257   for (int i = 0; i <= n; i++) {
   1258     while (!iterator_.frame()->is_java_script()) iterator_.Advance();
   1259     if (i == n) return JavaScriptFrame::cast(iterator_.frame());
   1260     iterator_.Advance();
   1261   }
   1262   UNREACHABLE();
   1263   return NULL;
   1264 }
   1265 
   1266 
   1267 // -------------------------------------------------------------------------
   1268 
   1269 
   1270 static Map* GcSafeMapOfCodeSpaceObject(HeapObject* object) {
   1271   MapWord map_word = object->map_word();
   1272   return map_word.IsForwardingAddress() ?
   1273       map_word.ToForwardingAddress()->map() : map_word.ToMap();
   1274 }
   1275 
   1276 
   1277 static int GcSafeSizeOfCodeSpaceObject(HeapObject* object) {
   1278   return object->SizeFromMap(GcSafeMapOfCodeSpaceObject(object));
   1279 }
   1280 
   1281 
   1282 #ifdef DEBUG
   1283 static bool GcSafeCodeContains(HeapObject* code, Address addr) {
   1284   Map* map = GcSafeMapOfCodeSpaceObject(code);
   1285   ASSERT(map == code->GetHeap()->code_map());
   1286   Address start = code->address();
   1287   Address end = code->address() + code->SizeFromMap(map);
   1288   return start <= addr && addr < end;
   1289 }
   1290 #endif
   1291 
   1292 
   1293 Code* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object,
   1294                                                 Address inner_pointer) {
   1295   Code* code = reinterpret_cast<Code*>(object);
   1296   ASSERT(code != NULL && GcSafeCodeContains(code, inner_pointer));
   1297   return code;
   1298 }
   1299 
   1300 
   1301 Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer(
   1302     Address inner_pointer) {
   1303   Heap* heap = isolate_->heap();
   1304   // Check if the inner pointer points into a large object chunk.
   1305   LargePage* large_page = heap->lo_space()->FindPage(inner_pointer);
   1306   if (large_page != NULL) {
   1307     return GcSafeCastToCode(large_page->GetObject(), inner_pointer);
   1308   }
   1309 
   1310   // Iterate through the page until we reach the end or find an object starting
   1311   // after the inner pointer.
   1312   Page* page = Page::FromAddress(inner_pointer);
   1313 
   1314   Address addr = page->skip_list()->StartFor(inner_pointer);
   1315 
   1316   Address top = heap->code_space()->top();
   1317   Address limit = heap->code_space()->limit();
   1318 
   1319   while (true) {
   1320     if (addr == top && addr != limit) {
   1321       addr = limit;
   1322       continue;
   1323     }
   1324 
   1325     HeapObject* obj = HeapObject::FromAddress(addr);
   1326     int obj_size = GcSafeSizeOfCodeSpaceObject(obj);
   1327     Address next_addr = addr + obj_size;
   1328     if (next_addr > inner_pointer) return GcSafeCastToCode(obj, inner_pointer);
   1329     addr = next_addr;
   1330   }
   1331 }
   1332 
   1333 
   1334 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
   1335     InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
   1336   isolate_->counters()->pc_to_code()->Increment();
   1337   ASSERT(IsPowerOf2(kInnerPointerToCodeCacheSize));
   1338   uint32_t hash = ComputeIntegerHash(
   1339       static_cast<uint32_t>(reinterpret_cast<uintptr_t>(inner_pointer)),
   1340       v8::internal::kZeroHashSeed);
   1341   uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
   1342   InnerPointerToCodeCacheEntry* entry = cache(index);
   1343   if (entry->inner_pointer == inner_pointer) {
   1344     isolate_->counters()->pc_to_code_cached()->Increment();
   1345     ASSERT(entry->code == GcSafeFindCodeForInnerPointer(inner_pointer));
   1346   } else {
   1347     // Because this code may be interrupted by a profiling signal that
   1348     // also queries the cache, we cannot update inner_pointer before the code
   1349     // has been set. Otherwise, we risk trying to use a cache entry before
   1350     // the code has been computed.
   1351     entry->code = GcSafeFindCodeForInnerPointer(inner_pointer);
   1352     entry->safepoint_entry.Reset();
   1353     entry->inner_pointer = inner_pointer;
   1354   }
   1355   return entry;
   1356 }
   1357 
   1358 
   1359 // -------------------------------------------------------------------------
   1360 
   1361 int NumRegs(RegList reglist) {
   1362   int n = 0;
   1363   while (reglist != 0) {
   1364     n++;
   1365     reglist &= reglist - 1;  // clear one bit
   1366   }
   1367   return n;
   1368 }
   1369 
   1370 
   1371 struct JSCallerSavedCodeData {
   1372   JSCallerSavedCodeData() {
   1373     int i = 0;
   1374     for (int r = 0; r < kNumRegs; r++)
   1375       if ((kJSCallerSaved & (1 << r)) != 0)
   1376         reg_code[i++] = r;
   1377 
   1378     ASSERT(i == kNumJSCallerSaved);
   1379   }
   1380   int reg_code[kNumJSCallerSaved];
   1381 };
   1382 
   1383 
   1384 static LazyInstance<JSCallerSavedCodeData>::type caller_saved_code_data =
   1385     LAZY_INSTANCE_INITIALIZER;
   1386 
   1387 int JSCallerSavedCode(int n) {
   1388   ASSERT(0 <= n && n < kNumJSCallerSaved);
   1389   return caller_saved_code_data.Get().reg_code[n];
   1390 }
   1391 
   1392 
   1393 #define DEFINE_WRAPPER(type, field)                              \
   1394 class field##_Wrapper : public ZoneObject {                      \
   1395  public:  /* NOLINT */                                           \
   1396   field##_Wrapper(const field& original) : frame_(original) {    \
   1397   }                                                              \
   1398   field frame_;                                                  \
   1399 };
   1400 STACK_FRAME_TYPE_LIST(DEFINE_WRAPPER)
   1401 #undef DEFINE_WRAPPER
   1402 
   1403 static StackFrame* AllocateFrameCopy(StackFrame* frame) {
   1404 #define FRAME_TYPE_CASE(type, field) \
   1405   case StackFrame::type: { \
   1406     field##_Wrapper* wrapper = \
   1407         new field##_Wrapper(*(reinterpret_cast<field*>(frame))); \
   1408     return &wrapper->frame_; \
   1409   }
   1410 
   1411   switch (frame->type()) {
   1412     STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
   1413     default: UNREACHABLE();
   1414   }
   1415 #undef FRAME_TYPE_CASE
   1416   return NULL;
   1417 }
   1418 
   1419 Vector<StackFrame*> CreateStackMap() {
   1420   ZoneList<StackFrame*> list(10);
   1421   for (StackFrameIterator it; !it.done(); it.Advance()) {
   1422     StackFrame* frame = AllocateFrameCopy(it.frame());
   1423     list.Add(frame);
   1424   }
   1425   return list.ToVector();
   1426 }
   1427 
   1428 
   1429 } }  // namespace v8::internal
   1430