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