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