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:
StackHandlerIterator(const StackFrame * frame,StackHandler * handler)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 
handler() const37   StackHandler* handler() const { return handler_; }
38 
done()39   bool done() {
40     return handler_ == NULL || handler_->address() > limit_;
41   }
Advance()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),
StackFrameIteratorBase(Isolate * isolate,bool can_access_heap_objects)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 
StackFrameIterator(Isolate * isolate)67 StackFrameIterator::StackFrameIterator(Isolate* isolate)
68     : StackFrameIteratorBase(isolate, true) {
69   Reset(isolate->thread_local_top());
70 }
71 
72 
StackFrameIterator(Isolate * isolate,ThreadLocalTop * t)73 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
74     : StackFrameIteratorBase(isolate, true) {
75   Reset(t);
76 }
77 
78 
Advance()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 
Reset(ThreadLocalTop * top)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 
SingletonFor(StackFrame::Type type,StackFrame::State * state)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 
SingletonFor(StackFrame::Type type)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 
JavaScriptFrameIterator(Isolate * isolate,StackFrame::Id id)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 
Advance()151 void JavaScriptFrameIterator::Advance() {
152   do {
153     iterator_.Advance();
154   } while (!iterator_.done() && !iterator_.frame()->is_java_script());
155 }
156 
157 
AdvanceToArgumentsFrame()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 
StackTraceFrameIterator(Isolate * isolate)168 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
169     : JavaScriptFrameIterator(isolate) {
170   if (!done() && !IsValidFrame()) Advance();
171 }
172 
173 
Advance()174 void StackTraceFrameIterator::Advance() {
175   while (true) {
176     JavaScriptFrameIterator::Advance();
177     if (done()) return;
178     if (IsValidFrame()) return;
179   }
180 }
181 
182 
IsValidFrame()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 
SafeStackFrameIterator(Isolate * isolate,Address fp,Address sp,Address js_entry_sp)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 
IsValidTop(ThreadLocalTop * top) const251 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 
AdvanceOneFrame()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 
IsValidFrame(StackFrame * frame) const285 bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const {
286   return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
287 }
288 
289 
IsValidCaller(StackFrame * frame)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 
IsValidExitFrame(Address fp) const315 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 
Advance()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 
GetSafepointData(Isolate * isolate,Address inner_pointer,SafepointEntry * safepoint_entry,unsigned * stack_slots)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 
IteratePc(ObjectVisitor * v,Address * pc_address,Address * constant_pool_address,Code * holder)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 
SetReturnAddressLocationResolver(ReturnAddressLocationResolver resolver)397 void StackFrame::SetReturnAddressLocationResolver(
398     ReturnAddressLocationResolver resolver) {
399   DCHECK(return_address_location_resolver_ == NULL);
400   return_address_location_resolver_ = resolver;
401 }
402 
403 
ComputeType(const StackFrameIteratorBase * iterator,State * state)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
can_access_heap_objects() const473 bool StackFrame::can_access_heap_objects() const {
474   return iterator_->can_access_heap_objects_;
475 }
476 #endif
477 
478 
GetCallerState(State * state) const479 StackFrame::Type StackFrame::GetCallerState(State* state) const {
480   ComputeCallerState(state);
481   return ComputeType(iterator_, state);
482 }
483 
484 
UnpaddedFP() const485 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 
unchecked_code() const499 Code* EntryFrame::unchecked_code() const {
500   return isolate()->heap()->js_entry_code();
501 }
502 
503 
ComputeCallerState(State * state) const504 void EntryFrame::ComputeCallerState(State* state) const {
505   GetCallerState(state);
506 }
507 
508 
SetCallerFp(Address caller_fp)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 
GetCallerState(State * state) const515 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 
unchecked_code() const522 Code* EntryConstructFrame::unchecked_code() const {
523   return isolate()->heap()->js_construct_entry_code();
524 }
525 
526 
code_slot() const527 Object*& ExitFrame::code_slot() const {
528   const int offset = ExitFrameConstants::kCodeOffset;
529   return Memory::Object_at(fp() + offset);
530 }
531 
532 
unchecked_code() const533 Code* ExitFrame::unchecked_code() const {
534   return reinterpret_cast<Code*>(code_slot());
535 }
536 
537 
ComputeCallerState(State * state) const538 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 
SetCallerFp(Address caller_fp)551 void ExitFrame::SetCallerFp(Address caller_fp) {
552   Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp;
553 }
554 
555 
Iterate(ObjectVisitor * v) const556 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 
GetCallerStackPointer() const564 Address ExitFrame::GetCallerStackPointer() const {
565   return fp() + ExitFrameConstants::kCallerSPDisplacement;
566 }
567 
568 
GetStateForFramePointer(Address fp,State * state)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 
ComputeStackPointer(Address fp)578 Address ExitFrame::ComputeStackPointer(Address fp) {
579   return Memory::Address_at(fp + ExitFrameConstants::kSPOffset);
580 }
581 
582 
FillState(Address fp,Address sp,State * state)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 
GetExpressionAddress(int n) const596 Address StandardFrame::GetExpressionAddress(int n) const {
597   const int offset = StandardFrameConstants::kExpressionsOffset;
598   return fp() + offset - n * kPointerSize;
599 }
600 
601 
GetExpression(Address fp,int index)602 Object* StandardFrame::GetExpression(Address fp, int index) {
603   return Memory::Object_at(GetExpressionAddress(fp, index));
604 }
605 
606 
GetExpressionAddress(Address fp,int n)607 Address StandardFrame::GetExpressionAddress(Address fp, int n) {
608   const int offset = StandardFrameConstants::kExpressionsOffset;
609   return fp + offset - n * kPointerSize;
610 }
611 
612 
ComputeExpressionsCount() const613 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 
ComputeCallerState(State * state) const624 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 
SetCallerFp(Address caller_fp)634 void StandardFrame::SetCallerFp(Address caller_fp) {
635   Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) =
636       caller_fp;
637 }
638 
639 
IterateCompiledFrame(ObjectVisitor * v) const640 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 
Iterate(ObjectVisitor * v) const714 void StubFrame::Iterate(ObjectVisitor* v) const {
715   IterateCompiledFrame(v);
716 }
717 
718 
unchecked_code() const719 Code* StubFrame::unchecked_code() const {
720   return static_cast<Code*>(isolate()->FindCodeObject(pc()));
721 }
722 
723 
GetCallerStackPointer() const724 Address StubFrame::GetCallerStackPointer() const {
725   return fp() + ExitFrameConstants::kCallerSPDisplacement;
726 }
727 
728 
GetNumberOfIncomingArguments() const729 int StubFrame::GetNumberOfIncomingArguments() const {
730   return 0;
731 }
732 
733 
Iterate(ObjectVisitor * v) const734 void OptimizedFrame::Iterate(ObjectVisitor* v) const {
735   IterateCompiledFrame(v);
736 }
737 
738 
SetParameterValue(int index,Object * value) const739 void JavaScriptFrame::SetParameterValue(int index, Object* value) const {
740   Memory::Object_at(GetParameterSlot(index)) = value;
741 }
742 
743 
IsConstructor() const744 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 
HasInlinedFrames() const754 bool JavaScriptFrame::HasInlinedFrames() const {
755   List<JSFunction*> functions(1);
756   GetFunctions(&functions);
757   return functions.length() > 1;
758 }
759 
760 
GetArgumentsLength() const761 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 
unchecked_code() const773 Code* JavaScriptFrame::unchecked_code() const {
774   return function()->code();
775 }
776 
777 
GetNumberOfIncomingArguments() const778 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 
GetCallerStackPointer() const786 Address JavaScriptFrame::GetCallerStackPointer() const {
787   return fp() + StandardFrameConstants::kCallerSPOffset;
788 }
789 
790 
GetFunctions(List<JSFunction * > * functions) const791 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const {
792   DCHECK(functions->length() == 0);
793   functions->Add(function());
794 }
795 
796 
Summarize(List<FrameSummary> * functions)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 
LookupExceptionHandlerInTable(int * stack_slots,HandlerTable::CatchPrediction * prediction)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 
PrintFunctionAndOffset(JSFunction * function,Code * code,Address pc,FILE * file,bool print_line_number)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 
PrintTop(Isolate * isolate,FILE * file,bool print_args,bool print_line_number)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 
SaveOperandStack(FixedArray * store) const881 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 
RestoreOperandStack(FixedArray * store)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 
FrameSummary(Object * receiver,JSFunction * function,Code * code,int offset,bool is_constructor)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 
Print()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 
Summarize(List<FrameSummary> * frames)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 
LookupExceptionHandlerInTable(int * stack_slots,HandlerTable::CatchPrediction * prediction)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 
GetDeoptimizationData(int * deopt_index) const1042 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 
GetFunctions(List<JSFunction * > * functions) const1067 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 
StackSlotOffsetRelativeToFp(int slot_index)1120 int OptimizedFrame::StackSlotOffsetRelativeToFp(int slot_index) {
1121   return StandardFrameConstants::kCallerSPOffset -
1122          ((slot_index + 1) * kPointerSize);
1123 }
1124 
1125 
StackSlotAt(int index) const1126 Object* OptimizedFrame::StackSlotAt(int index) const {
1127   return Memory::Object_at(fp() + StackSlotOffsetRelativeToFp(index));
1128 }
1129 
1130 
GetNumberOfIncomingArguments() const1131 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const {
1132   return Smi::cast(GetExpression(0))->value();
1133 }
1134 
1135 
GetCallerStackPointer() const1136 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const {
1137   return fp() + StandardFrameConstants::kCallerSPOffset;
1138 }
1139 
1140 
GetCallerStackPointer() const1141 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 
unchecked_code() const1148 Code* ArgumentsAdaptorFrame::unchecked_code() const {
1149   return isolate()->builtins()->builtin(
1150       Builtins::kArgumentsAdaptorTrampoline);
1151 }
1152 
1153 
unchecked_code() const1154 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 
PrintIndex(StringStream * accumulator,PrintMode mode,int index)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 
PrintFunctionSource(StringStream * accumulator,SharedFunctionInfo * shared,Code * code)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 
Print(StringStream * accumulator,PrintMode mode,int index) const1187 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 
Print(StringStream * accumulator,PrintMode mode,int index) const1324 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 
Iterate(ObjectVisitor * v) const1354 void EntryFrame::Iterate(ObjectVisitor* v) const {
1355   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
1356 }
1357 
1358 
IterateExpressions(ObjectVisitor * v) const1359 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 
Iterate(ObjectVisitor * v) const1367 void JavaScriptFrame::Iterate(ObjectVisitor* v) const {
1368   IterateExpressions(v);
1369   IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
1370 }
1371 
1372 
Iterate(ObjectVisitor * v) const1373 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 
Iterate(ObjectVisitor * v) const1381 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 
GetCallerStackPointer() const1394 Address StubFailureTrampolineFrame::GetCallerStackPointer() const {
1395   return fp() + StandardFrameConstants::kCallerSPOffset;
1396 }
1397 
1398 
unchecked_code() const1399 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 
FindJavaScriptFrame(int n)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 
GcSafeMapOfCodeSpaceObject(HeapObject * object)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 
GcSafeSizeOfCodeSpaceObject(HeapObject * object)1443 static int GcSafeSizeOfCodeSpaceObject(HeapObject* object) {
1444   return object->SizeFromMap(GcSafeMapOfCodeSpaceObject(object));
1445 }
1446 
1447 
1448 #ifdef DEBUG
GcSafeCodeContains(HeapObject * code,Address addr)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 
GcSafeCastToCode(HeapObject * object,Address inner_pointer)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 
GcSafeFindCodeForInnerPointer(Address inner_pointer)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*
GetCacheEntry(Address inner_pointer)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 
NumRegs(RegList reglist)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 
SetUpJSCallerSavedCodeData()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 
JSCallerSavedCode(int n)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 };
STACK_FRAME_TYPE_LIST(DEFINE_WRAPPER)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 
CreateStackMap(Isolate * isolate,Zone * zone)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