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