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