1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "src/deoptimizer.h"
9 #include "src/frames-inl.h"
10 #include "src/full-codegen.h"
11 #include "src/heap/mark-compact.h"
12 #include "src/safepoint-table.h"
13 #include "src/scopeinfo.h"
14 #include "src/string-stream.h"
15 #include "src/vm-state-inl.h"
21 ReturnAddressLocationResolver
22 StackFrame::return_address_location_resolver_ = NULL;
25 // Iterator that supports traversing the stack handlers of a
26 // particular frame. Needs to know the top of the handler chain.
27 class StackHandlerIterator BASE_EMBEDDED {
29 StackHandlerIterator(const StackFrame* frame, StackHandler* handler)
30 : limit_(frame->fp()), handler_(handler) {
31 // Make sure the handler has already been unwound to this frame.
32 DCHECK(frame->sp() <= handler->address());
35 StackHandler* handler() const { return handler_; }
38 return handler_ == NULL || handler_->address() > limit_;
42 handler_ = handler_->next();
47 StackHandler* handler_;
51 // -------------------------------------------------------------------------
54 #define INITIALIZE_SINGLETON(type, field) field##_(this),
55 StackFrameIteratorBase::StackFrameIteratorBase(Isolate* isolate,
56 bool can_access_heap_objects)
58 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
59 frame_(NULL), handler_(NULL),
60 can_access_heap_objects_(can_access_heap_objects) {
62 #undef INITIALIZE_SINGLETON
65 StackFrameIterator::StackFrameIterator(Isolate* isolate)
66 : StackFrameIteratorBase(isolate, true) {
67 Reset(isolate->thread_local_top());
71 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
72 : StackFrameIteratorBase(isolate, true) {
77 void StackFrameIterator::Advance() {
79 // Compute the state of the calling frame before restoring
80 // callee-saved registers and unwinding handlers. This allows the
81 // frame code that computes the caller state to access the top
82 // handler and the value of any callee-saved register if needed.
83 StackFrame::State state;
84 StackFrame::Type type = frame_->GetCallerState(&state);
86 // Unwind handlers corresponding to the current frame.
87 StackHandlerIterator it(frame_, handler_);
88 while (!it.done()) it.Advance();
89 handler_ = it.handler();
91 // Advance to the calling frame.
92 frame_ = SingletonFor(type, &state);
94 // When we're done iterating over the stack frames, the handler
95 // chain must have been completely unwound.
96 DCHECK(!done() || handler_ == NULL);
100 void StackFrameIterator::Reset(ThreadLocalTop* top) {
101 StackFrame::State state;
102 StackFrame::Type type = ExitFrame::GetStateForFramePointer(
103 Isolate::c_entry_fp(top), &state);
104 handler_ = StackHandler::FromAddress(Isolate::handler(top));
105 if (SingletonFor(type) == NULL) return;
106 frame_ = SingletonFor(type, &state);
110 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type,
111 StackFrame::State* state) {
112 if (type == StackFrame::NONE) return NULL;
113 StackFrame* result = SingletonFor(type);
114 DCHECK(result != NULL);
115 result->state_ = *state;
120 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type) {
121 #define FRAME_TYPE_CASE(type, field) \
122 case StackFrame::type: result = &field##_; break;
124 StackFrame* result = NULL;
126 case StackFrame::NONE: return NULL;
127 STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
132 #undef FRAME_TYPE_CASE
136 // -------------------------------------------------------------------------
139 JavaScriptFrameIterator::JavaScriptFrameIterator(
140 Isolate* isolate, StackFrame::Id id)
141 : iterator_(isolate) {
144 if (frame()->id() == id) return;
149 void JavaScriptFrameIterator::Advance() {
152 } while (!iterator_.done() && !iterator_.frame()->is_java_script());
156 void JavaScriptFrameIterator::AdvanceToArgumentsFrame() {
157 if (!frame()->has_adapted_arguments()) return;
159 DCHECK(iterator_.frame()->is_arguments_adaptor());
163 // -------------------------------------------------------------------------
166 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
167 : JavaScriptFrameIterator(isolate) {
168 if (!done() && !IsValidFrame()) Advance();
172 void StackTraceFrameIterator::Advance() {
174 JavaScriptFrameIterator::Advance();
176 if (IsValidFrame()) return;
181 bool StackTraceFrameIterator::IsValidFrame() {
182 if (!frame()->function()->IsJSFunction()) return false;
183 Object* script = frame()->function()->shared()->script();
184 // Don't show functions from native scripts to user.
185 return (script->IsScript() &&
186 Script::TYPE_NATIVE != Script::cast(script)->type()->value());
190 // -------------------------------------------------------------------------
193 SafeStackFrameIterator::SafeStackFrameIterator(
195 Address fp, Address sp, Address js_entry_sp)
196 : StackFrameIteratorBase(isolate, false),
198 high_bound_(js_entry_sp),
199 top_frame_type_(StackFrame::NONE),
200 external_callback_scope_(isolate->external_callback_scope()) {
201 StackFrame::State state;
202 StackFrame::Type type;
203 ThreadLocalTop* top = isolate->thread_local_top();
204 if (IsValidTop(top)) {
205 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
206 top_frame_type_ = type;
207 } else if (IsValidStackAddress(fp)) {
211 state.pc_address = StackFrame::ResolveReturnAddressLocation(
212 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
213 // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset,
214 // we check only that kMarkerOffset is within the stack bounds and do
215 // compile time check that kContextOffset slot is pushed on the stack before
217 STATIC_ASSERT(StandardFrameConstants::kMarkerOffset <
218 StandardFrameConstants::kContextOffset);
219 Address frame_marker = fp + StandardFrameConstants::kMarkerOffset;
220 if (IsValidStackAddress(frame_marker)) {
221 type = StackFrame::ComputeType(this, &state);
222 top_frame_type_ = type;
224 // Mark the frame as JAVA_SCRIPT if we cannot determine its type.
225 // The frame anyways will be skipped.
226 type = StackFrame::JAVA_SCRIPT;
227 // Top frame is incomplete so we cannot reliably determine its type.
228 top_frame_type_ = StackFrame::NONE;
233 if (SingletonFor(type) == NULL) return;
234 frame_ = SingletonFor(type, &state);
235 if (frame_ == NULL) return;
239 if (frame_ != NULL && !frame_->is_exit() &&
240 external_callback_scope_ != NULL &&
241 external_callback_scope_->scope_address() < frame_->fp()) {
242 // Skip top ExternalCallbackScope if we already advanced to a JS frame
243 // under it. Sampler will anyways take this top external callback.
244 external_callback_scope_ = external_callback_scope_->previous();
249 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const {
250 Address c_entry_fp = Isolate::c_entry_fp(top);
251 if (!IsValidExitFrame(c_entry_fp)) return false;
252 // There should be at least one JS_ENTRY stack handler.
253 Address handler = Isolate::handler(top);
254 if (handler == NULL) return false;
255 // Check that there are no js frames on top of the native frames.
256 return c_entry_fp < handler;
260 void SafeStackFrameIterator::AdvanceOneFrame() {
262 StackFrame* last_frame = frame_;
263 Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
264 // Before advancing to the next stack frame, perform pointer validity tests.
265 if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) {
270 // Advance to the previous frame.
271 StackFrame::State state;
272 StackFrame::Type type = frame_->GetCallerState(&state);
273 frame_ = SingletonFor(type, &state);
274 if (frame_ == NULL) return;
276 // Check that we have actually moved to the previous frame in the stack.
277 if (frame_->sp() < last_sp || frame_->fp() < last_fp) {
283 bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const {
284 return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
288 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
289 StackFrame::State state;
290 if (frame->is_entry() || frame->is_entry_construct()) {
291 // See EntryFrame::GetCallerState. It computes the caller FP address
292 // and calls ExitFrame::GetStateForFramePointer on it. We need to be
293 // sure that caller FP address is valid.
294 Address caller_fp = Memory::Address_at(
295 frame->fp() + EntryFrameConstants::kCallerFPOffset);
296 if (!IsValidExitFrame(caller_fp)) return false;
297 } else if (frame->is_arguments_adaptor()) {
298 // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that
299 // the number of arguments is stored on stack as Smi. We need to check
300 // that it really an Smi.
301 Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)->
303 if (!number_of_args->IsSmi()) {
307 frame->ComputeCallerState(&state);
308 return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) &&
309 SingletonFor(frame->GetCallerState(&state)) != NULL;
313 bool SafeStackFrameIterator::IsValidExitFrame(Address fp) const {
314 if (!IsValidStackAddress(fp)) return false;
315 Address sp = ExitFrame::ComputeStackPointer(fp);
316 if (!IsValidStackAddress(sp)) return false;
317 StackFrame::State state;
318 ExitFrame::FillState(fp, sp, &state);
319 if (!IsValidStackAddress(reinterpret_cast<Address>(state.pc_address))) {
322 return *state.pc_address != NULL;
326 void SafeStackFrameIterator::Advance() {
330 if (frame_->is_java_script()) return;
331 if (frame_->is_exit() && external_callback_scope_) {
332 // Some of the EXIT frames may have ExternalCallbackScope allocated on
333 // top of them. In that case the scope corresponds to the first EXIT
334 // frame beneath it. There may be other EXIT frames on top of the
335 // ExternalCallbackScope, just skip them as we cannot collect any useful
336 // information about them.
337 if (external_callback_scope_->scope_address() < frame_->fp()) {
338 Address* callback_address =
339 external_callback_scope_->callback_address();
340 if (*callback_address != NULL) {
341 frame_->state_.pc_address = callback_address;
343 external_callback_scope_ = external_callback_scope_->previous();
344 DCHECK(external_callback_scope_ == NULL ||
345 external_callback_scope_->scope_address() > frame_->fp());
353 // -------------------------------------------------------------------------
356 Code* StackFrame::GetSafepointData(Isolate* isolate,
357 Address inner_pointer,
358 SafepointEntry* safepoint_entry,
359 unsigned* stack_slots) {
360 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry =
361 isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer);
362 if (!entry->safepoint_entry.is_valid()) {
363 entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer);
364 DCHECK(entry->safepoint_entry.is_valid());
366 DCHECK(entry->safepoint_entry.Equals(
367 entry->code->GetSafepointEntry(inner_pointer)));
370 // Fill in the results and return the code.
371 Code* code = entry->code;
372 *safepoint_entry = entry->safepoint_entry;
373 *stack_slots = code->stack_slots();
378 bool StackFrame::HasHandler() const {
379 StackHandlerIterator it(this, top_handler());
385 static bool GcSafeCodeContains(HeapObject* object, Address addr);
389 void StackFrame::IteratePc(ObjectVisitor* v,
392 Address pc = *pc_address;
393 DCHECK(GcSafeCodeContains(holder, pc));
394 unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start());
395 Object* code = holder;
396 v->VisitPointer(&code);
397 if (code != holder) {
398 holder = reinterpret_cast<Code*>(code);
399 pc = holder->instruction_start() + pc_offset;
405 void StackFrame::SetReturnAddressLocationResolver(
406 ReturnAddressLocationResolver resolver) {
407 DCHECK(return_address_location_resolver_ == NULL);
408 return_address_location_resolver_ = resolver;
412 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
414 DCHECK(state->fp != NULL);
415 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
416 return ARGUMENTS_ADAPTOR;
418 // The marker and function offsets overlap. If the marker isn't a
419 // smi then the frame is a JavaScript frame -- and the marker is
420 // really the function.
421 const int offset = StandardFrameConstants::kMarkerOffset;
422 Object* marker = Memory::Object_at(state->fp + offset);
423 if (!marker->IsSmi()) {
424 // If we're using a "safe" stack iterator, we treat optimized
425 // frames as normal JavaScript frames to avoid having to look
426 // into the heap to determine the state. This is safe as long
427 // as nobody tries to GC...
428 if (!iterator->can_access_heap_objects_) return JAVA_SCRIPT;
429 Code::Kind kind = GetContainingCode(iterator->isolate(),
430 *(state->pc_address))->kind();
431 DCHECK(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION);
432 return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT;
434 return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
439 bool StackFrame::can_access_heap_objects() const {
440 return iterator_->can_access_heap_objects_;
445 StackFrame::Type StackFrame::GetCallerState(State* state) const {
446 ComputeCallerState(state);
447 return ComputeType(iterator_, state);
451 Address StackFrame::UnpaddedFP() const {
452 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
453 if (!is_optimized()) return fp();
454 int32_t alignment_state = Memory::int32_at(
455 fp() + JavaScriptFrameConstants::kDynamicAlignmentStateOffset);
457 return (alignment_state == kAlignmentPaddingPushed) ?
458 (fp() + kPointerSize) : fp();
465 Code* EntryFrame::unchecked_code() const {
466 return isolate()->heap()->js_entry_code();
470 void EntryFrame::ComputeCallerState(State* state) const {
471 GetCallerState(state);
475 void EntryFrame::SetCallerFp(Address caller_fp) {
476 const int offset = EntryFrameConstants::kCallerFPOffset;
477 Memory::Address_at(this->fp() + offset) = caller_fp;
481 StackFrame::Type EntryFrame::GetCallerState(State* state) const {
482 const int offset = EntryFrameConstants::kCallerFPOffset;
483 Address fp = Memory::Address_at(this->fp() + offset);
484 return ExitFrame::GetStateForFramePointer(fp, state);
488 Code* EntryConstructFrame::unchecked_code() const {
489 return isolate()->heap()->js_construct_entry_code();
493 Object*& ExitFrame::code_slot() const {
494 const int offset = ExitFrameConstants::kCodeOffset;
495 return Memory::Object_at(fp() + offset);
499 Code* ExitFrame::unchecked_code() const {
500 return reinterpret_cast<Code*>(code_slot());
504 void ExitFrame::ComputeCallerState(State* state) const {
505 // Set up the caller state.
506 state->sp = caller_sp();
507 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);
508 state->pc_address = ResolveReturnAddressLocation(
509 reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
510 if (FLAG_enable_ool_constant_pool) {
511 state->constant_pool_address = reinterpret_cast<Address*>(
512 fp() + ExitFrameConstants::kConstantPoolOffset);
517 void ExitFrame::SetCallerFp(Address caller_fp) {
518 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp;
522 void ExitFrame::Iterate(ObjectVisitor* v) const {
523 // The arguments are traversed as part of the expression stack of
524 // the calling frame.
525 IteratePc(v, pc_address(), LookupCode());
526 v->VisitPointer(&code_slot());
527 if (FLAG_enable_ool_constant_pool) {
528 v->VisitPointer(&constant_pool_slot());
533 Address ExitFrame::GetCallerStackPointer() const {
534 return fp() + ExitFrameConstants::kCallerSPDisplacement;
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 DCHECK(*state->pc_address != NULL);
547 Address ExitFrame::ComputeStackPointer(Address fp) {
548 return Memory::Address_at(fp + ExitFrameConstants::kSPOffset);
552 void ExitFrame::FillState(Address fp, Address sp, State* state) {
555 state->pc_address = ResolveReturnAddressLocation(
556 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize));
557 state->constant_pool_address =
558 reinterpret_cast<Address*>(fp + ExitFrameConstants::kConstantPoolOffset);
562 Address StandardFrame::GetExpressionAddress(int n) const {
563 const int offset = StandardFrameConstants::kExpressionsOffset;
564 return fp() + offset - n * kPointerSize;
568 Object* StandardFrame::GetExpression(Address fp, int index) {
569 return Memory::Object_at(GetExpressionAddress(fp, index));
573 Address StandardFrame::GetExpressionAddress(Address fp, int n) {
574 const int offset = StandardFrameConstants::kExpressionsOffset;
575 return fp + offset - n * kPointerSize;
579 int StandardFrame::ComputeExpressionsCount() const {
581 StandardFrameConstants::kExpressionsOffset + kPointerSize;
582 Address base = fp() + offset;
583 Address limit = sp();
584 DCHECK(base >= limit); // stack grows downwards
585 // Include register-allocated locals in number of expressions.
586 return static_cast<int>((base - limit) / kPointerSize);
590 void StandardFrame::ComputeCallerState(State* state) const {
591 state->sp = caller_sp();
592 state->fp = caller_fp();
593 state->pc_address = ResolveReturnAddressLocation(
594 reinterpret_cast<Address*>(ComputePCAddress(fp())));
595 state->constant_pool_address =
596 reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp()));
600 void StandardFrame::SetCallerFp(Address caller_fp) {
601 Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) =
606 bool StandardFrame::IsExpressionInsideHandler(int n) const {
607 Address address = GetExpressionAddress(n);
608 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
609 if (it.handler()->includes(address)) return true;
615 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
616 // Make sure that we're not doing "safe" stack frame iteration. We cannot
617 // possibly find pointers in optimized frames in that state.
618 DCHECK(can_access_heap_objects());
620 // Compute the safepoint information.
621 unsigned stack_slots = 0;
622 SafepointEntry safepoint_entry;
623 Code* code = StackFrame::GetSafepointData(
624 isolate(), pc(), &safepoint_entry, &stack_slots);
625 unsigned slot_space = stack_slots * kPointerSize;
627 // Visit the outgoing parameters.
628 Object** parameters_base = &Memory::Object_at(sp());
629 Object** parameters_limit = &Memory::Object_at(
630 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space);
632 // Visit the parameters that may be on top of the saved registers.
633 if (safepoint_entry.argument_count() > 0) {
634 v->VisitPointers(parameters_base,
635 parameters_base + safepoint_entry.argument_count());
636 parameters_base += safepoint_entry.argument_count();
639 // Skip saved double registers.
640 if (safepoint_entry.has_doubles()) {
641 // Number of doubles not known at snapshot time.
642 DCHECK(!isolate()->serializer_enabled());
643 parameters_base += DoubleRegister::NumAllocatableRegisters() *
644 kDoubleSize / kPointerSize;
647 // Visit the registers that contain pointers if any.
648 if (safepoint_entry.HasRegisters()) {
649 for (int i = kNumSafepointRegisters - 1; i >=0; i--) {
650 if (safepoint_entry.HasRegisterAt(i)) {
651 int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(i);
652 v->VisitPointer(parameters_base + reg_stack_index);
655 // Skip the words containing the register values.
656 parameters_base += kNumSafepointRegisters;
659 // We're done dealing with the register bits.
660 uint8_t* safepoint_bits = safepoint_entry.bits();
661 safepoint_bits += kNumSafepointRegisters >> kBitsPerByteLog2;
663 // Visit the rest of the parameters.
664 v->VisitPointers(parameters_base, parameters_limit);
666 // Visit pointer spill slots and locals.
667 for (unsigned index = 0; index < stack_slots; index++) {
668 int byte_index = index >> kBitsPerByteLog2;
669 int bit_index = index & (kBitsPerByte - 1);
670 if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) {
671 v->VisitPointer(parameters_limit + index);
675 // Visit the return address in the callee and incoming arguments.
676 IteratePc(v, pc_address(), code);
678 // Visit the context in stub frame and JavaScript frame.
679 // Visit the function in JavaScript frame.
680 Object** fixed_base = &Memory::Object_at(
681 fp() + StandardFrameConstants::kMarkerOffset);
682 Object** fixed_limit = &Memory::Object_at(fp());
683 v->VisitPointers(fixed_base, fixed_limit);
687 void StubFrame::Iterate(ObjectVisitor* v) const {
688 IterateCompiledFrame(v);
692 Code* StubFrame::unchecked_code() const {
693 return static_cast<Code*>(isolate()->FindCodeObject(pc()));
697 Address StubFrame::GetCallerStackPointer() const {
698 return fp() + ExitFrameConstants::kCallerSPDisplacement;
702 int StubFrame::GetNumberOfIncomingArguments() const {
707 void OptimizedFrame::Iterate(ObjectVisitor* v) const {
709 // Make sure that optimized frames do not contain any stack handlers.
710 StackHandlerIterator it(this, top_handler());
714 IterateCompiledFrame(v);
718 void JavaScriptFrame::SetParameterValue(int index, Object* value) const {
719 Memory::Object_at(GetParameterSlot(index)) = value;
723 bool JavaScriptFrame::IsConstructor() const {
724 Address fp = caller_fp();
725 if (has_adapted_arguments()) {
726 // Skip the arguments adaptor frame and look at the real caller.
727 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset);
729 return IsConstructFrame(fp);
733 int JavaScriptFrame::GetArgumentsLength() const {
734 // If there is an arguments adaptor frame get the arguments length from it.
735 if (has_adapted_arguments()) {
736 return Smi::cast(GetExpression(caller_fp(), 0))->value();
738 return GetNumberOfIncomingArguments();
743 Code* JavaScriptFrame::unchecked_code() const {
744 return function()->code();
748 int JavaScriptFrame::GetNumberOfIncomingArguments() const {
749 DCHECK(can_access_heap_objects() &&
750 isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
752 return function()->shared()->formal_parameter_count();
756 Address JavaScriptFrame::GetCallerStackPointer() const {
757 return fp() + StandardFrameConstants::kCallerSPOffset;
761 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) {
762 DCHECK(functions->length() == 0);
763 functions->Add(function());
767 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) {
768 DCHECK(functions->length() == 0);
769 Code* code_pointer = LookupCode();
770 int offset = static_cast<int>(pc() - code_pointer->address());
771 FrameSummary summary(receiver(),
776 functions->Add(summary);
780 void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function, Code* code,
781 Address pc, FILE* file,
782 bool print_line_number) {
783 PrintF(file, "%s", function->IsOptimized() ? "*" : "~");
784 function->PrintName(file);
785 int code_offset = static_cast<int>(pc - code->instruction_start());
786 PrintF(file, "+%d", code_offset);
787 if (print_line_number) {
788 SharedFunctionInfo* shared = function->shared();
789 int source_pos = code->SourcePosition(pc);
790 Object* maybe_script = shared->script();
791 if (maybe_script->IsScript()) {
792 Script* script = Script::cast(maybe_script);
793 int line = script->GetLineNumber(source_pos) + 1;
794 Object* script_name_raw = script->name();
795 if (script_name_raw->IsString()) {
796 String* script_name = String::cast(script->name());
797 SmartArrayPointer<char> c_script_name =
798 script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
799 PrintF(file, " at %s:%d", c_script_name.get(), line);
801 PrintF(file, " at <unknown>:%d", line);
804 PrintF(file, " at <unknown>:<unknown>");
810 void JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file, bool print_args,
811 bool print_line_number) {
813 DisallowHeapAllocation no_allocation;
814 JavaScriptFrameIterator it(isolate);
816 if (it.frame()->is_java_script()) {
817 JavaScriptFrame* frame = it.frame();
818 if (frame->IsConstructor()) PrintF(file, "new ");
819 PrintFunctionAndOffset(frame->function(), frame->unchecked_code(),
820 frame->pc(), file, print_line_number);
822 // function arguments
823 // (we are intentionally only printing the actually
824 // supplied parameters, not all parameters required)
825 PrintF(file, "(this=");
826 frame->receiver()->ShortPrint(file);
827 const int length = frame->ComputeParametersCount();
828 for (int i = 0; i < length; i++) {
830 frame->GetParameter(i)->ShortPrint(file);
841 void JavaScriptFrame::SaveOperandStack(FixedArray* store,
842 int* stack_handler_index) const {
843 int operands_count = store->length();
844 DCHECK_LE(operands_count, ComputeOperandsCount());
846 // Visit the stack in LIFO order, saving operands and stack handlers into the
847 // array. The saved stack handlers store a link to the next stack handler,
848 // which will allow RestoreOperandStack to rewind the handlers.
849 StackHandlerIterator it(this, top_handler());
850 int i = operands_count - 1;
851 *stack_handler_index = -1;
852 for (; !it.done(); it.Advance()) {
853 StackHandler* handler = it.handler();
854 // Save operands pushed after the handler was pushed.
855 for (; GetOperandSlot(i) < handler->address(); i--) {
856 store->set(i, GetOperand(i));
858 DCHECK_GE(i + 1, StackHandlerConstants::kSlotCount);
859 DCHECK_EQ(handler->address(), GetOperandSlot(i));
860 int next_stack_handler_index = i + 1 - StackHandlerConstants::kSlotCount;
861 handler->Unwind(isolate(), store, next_stack_handler_index,
862 *stack_handler_index);
863 *stack_handler_index = next_stack_handler_index;
864 i -= StackHandlerConstants::kSlotCount;
867 // Save any remaining operands.
868 for (; i >= 0; i--) {
869 store->set(i, GetOperand(i));
874 void JavaScriptFrame::RestoreOperandStack(FixedArray* store,
875 int stack_handler_index) {
876 int operands_count = store->length();
877 DCHECK_LE(operands_count, ComputeOperandsCount());
879 while (i <= stack_handler_index) {
880 if (i < stack_handler_index) {
882 DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
883 Memory::Object_at(GetOperandSlot(i)) = store->get(i);
887 DCHECK_EQ(i, stack_handler_index);
888 // The FixedArray store grows up. The stack grows down. So the operand
889 // slot for i actually points to the bottom of the top word in the
890 // handler. The base of the StackHandler* is the address of the bottom
891 // word, which will be the last slot that is in the handler.
892 int handler_slot_index = i + StackHandlerConstants::kSlotCount - 1;
893 StackHandler *handler =
894 StackHandler::FromAddress(GetOperandSlot(handler_slot_index));
895 stack_handler_index = handler->Rewind(isolate(), store, i, fp());
896 i += StackHandlerConstants::kSlotCount;
900 for (; i < operands_count; i++) {
901 DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
902 Memory::Object_at(GetOperandSlot(i)) = store->get(i);
907 void FrameSummary::Print() {
908 PrintF("receiver: ");
909 receiver_->ShortPrint();
910 PrintF("\nfunction: ");
911 function_->shared()->DebugName()->ShortPrint();
914 if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT");
915 if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT");
916 PrintF("\npc: %d\n", offset_);
920 JSFunction* OptimizedFrame::LiteralAt(FixedArray* literal_array,
922 if (literal_id == Translation::kSelfLiteralId) {
926 return JSFunction::cast(literal_array->get(literal_id));
930 void OptimizedFrame::Summarize(List<FrameSummary>* frames) {
931 DCHECK(frames->length() == 0);
932 DCHECK(is_optimized());
934 // Delegate to JS frame in absence of inlining.
935 // TODO(turbofan): Revisit once we support inlining.
936 if (LookupCode()->is_turbofanned()) {
937 return JavaScriptFrame::Summarize(frames);
940 int deopt_index = Safepoint::kNoDeoptimizationIndex;
941 DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
942 FixedArray* literal_array = data->LiteralArray();
944 // BUG(3243555): Since we don't have a lazy-deopt registered at
945 // throw-statements, we can't use the translation at the call-site of
946 // throw. An entry with no deoptimization index indicates a call-site
947 // without a lazy-deopt. As a consequence we are not allowed to inline
948 // functions containing throw.
949 DCHECK(deopt_index != Safepoint::kNoDeoptimizationIndex);
951 TranslationIterator it(data->TranslationByteArray(),
952 data->TranslationIndex(deopt_index)->value());
953 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
954 DCHECK(opcode == Translation::BEGIN);
955 it.Next(); // Drop frame count.
956 int jsframe_count = it.Next();
958 // We create the summary in reverse order because the frames
959 // in the deoptimization translation are ordered bottom-to-top.
960 bool is_constructor = IsConstructor();
961 int i = jsframe_count;
963 opcode = static_cast<Translation::Opcode>(it.Next());
964 if (opcode == Translation::JS_FRAME) {
966 BailoutId ast_id = BailoutId(it.Next());
967 JSFunction* function = LiteralAt(literal_array, it.Next());
968 it.Next(); // Skip height.
970 // The translation commands are ordered and the receiver is always
971 // at the first position.
972 // If we are at a call, the receiver is always in a stack slot.
973 // Otherwise we are not guaranteed to get the receiver value.
974 opcode = static_cast<Translation::Opcode>(it.Next());
975 int index = it.Next();
977 // Get the correct receiver in the optimized frame.
978 Object* receiver = NULL;
979 if (opcode == Translation::LITERAL) {
980 receiver = data->LiteralArray()->get(index);
981 } else if (opcode == Translation::STACK_SLOT) {
982 // Positive index means the value is spilled to the locals
983 // area. Negative means it is stored in the incoming parameter
986 receiver = GetExpression(index);
988 // Index -1 overlaps with last parameter, -n with the first parameter,
989 // (-n - 1) with the receiver with n being the number of parameters
990 // of the outermost, optimized frame.
991 int parameter_count = ComputeParametersCount();
992 int parameter_index = index + parameter_count;
993 receiver = (parameter_index == -1)
995 : this->GetParameter(parameter_index);
998 // The receiver is not in a stack slot nor in a literal. We give up.
999 // TODO(3029): Materializing a captured object (or duplicated
1000 // object) is hard, we return undefined for now. This breaks the
1001 // produced stack trace, as constructor frames aren't marked as
1003 receiver = isolate()->heap()->undefined_value();
1006 Code* code = function->shared()->code();
1007 DeoptimizationOutputData* output_data =
1008 DeoptimizationOutputData::cast(code->deoptimization_data());
1009 unsigned entry = Deoptimizer::GetOutputInfo(output_data,
1011 function->shared());
1012 unsigned pc_offset =
1013 FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize;
1014 DCHECK(pc_offset > 0);
1016 FrameSummary summary(receiver, function, code, pc_offset, is_constructor);
1017 frames->Add(summary);
1018 is_constructor = false;
1019 } else if (opcode == Translation::CONSTRUCT_STUB_FRAME) {
1020 // The next encountered JS_FRAME will be marked as a constructor call.
1021 it.Skip(Translation::NumberOfOperandsFor(opcode));
1022 DCHECK(!is_constructor);
1023 is_constructor = true;
1025 // Skip over operands to advance to the next opcode.
1026 it.Skip(Translation::NumberOfOperandsFor(opcode));
1029 DCHECK(!is_constructor);
1033 DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData(
1035 DCHECK(is_optimized());
1037 JSFunction* opt_function = function();
1038 Code* code = opt_function->code();
1040 // The code object may have been replaced by lazy deoptimization. Fall
1041 // back to a slow search in this case to find the original optimized
1043 if (!code->contains(pc())) {
1044 code = isolate()->inner_pointer_to_code_cache()->
1045 GcSafeFindCodeForInnerPointer(pc());
1047 DCHECK(code != NULL);
1048 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
1050 SafepointEntry safepoint_entry = code->GetSafepointEntry(pc());
1051 *deopt_index = safepoint_entry.deoptimization_index();
1052 DCHECK(*deopt_index != Safepoint::kNoDeoptimizationIndex);
1054 return DeoptimizationInputData::cast(code->deoptimization_data());
1058 int OptimizedFrame::GetInlineCount() {
1059 DCHECK(is_optimized());
1061 // Delegate to JS frame in absence of inlining.
1062 // TODO(turbofan): Revisit once we support inlining.
1063 if (LookupCode()->is_turbofanned()) {
1064 return JavaScriptFrame::GetInlineCount();
1067 int deopt_index = Safepoint::kNoDeoptimizationIndex;
1068 DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
1070 TranslationIterator it(data->TranslationByteArray(),
1071 data->TranslationIndex(deopt_index)->value());
1072 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
1073 DCHECK(opcode == Translation::BEGIN);
1075 it.Next(); // Drop frame count.
1076 int jsframe_count = it.Next();
1077 return jsframe_count;
1081 void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) {
1082 DCHECK(functions->length() == 0);
1083 DCHECK(is_optimized());
1085 // Delegate to JS frame in absence of inlining.
1086 // TODO(turbofan): Revisit once we support inlining.
1087 if (LookupCode()->is_turbofanned()) {
1088 return JavaScriptFrame::GetFunctions(functions);
1091 int deopt_index = Safepoint::kNoDeoptimizationIndex;
1092 DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
1093 FixedArray* literal_array = data->LiteralArray();
1095 TranslationIterator it(data->TranslationByteArray(),
1096 data->TranslationIndex(deopt_index)->value());
1097 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
1098 DCHECK(opcode == Translation::BEGIN);
1099 it.Next(); // Drop frame count.
1100 int jsframe_count = it.Next();
1102 // We insert the frames in reverse order because the frames
1103 // in the deoptimization translation are ordered bottom-to-top.
1104 while (jsframe_count > 0) {
1105 opcode = static_cast<Translation::Opcode>(it.Next());
1106 if (opcode == Translation::JS_FRAME) {
1108 it.Next(); // Skip ast id.
1109 JSFunction* function = LiteralAt(literal_array, it.Next());
1110 it.Next(); // Skip height.
1111 functions->Add(function);
1113 // Skip over operands to advance to the next opcode.
1114 it.Skip(Translation::NumberOfOperandsFor(opcode));
1120 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const {
1121 return Smi::cast(GetExpression(0))->value();
1125 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const {
1126 return fp() + StandardFrameConstants::kCallerSPOffset;
1130 Address InternalFrame::GetCallerStackPointer() const {
1131 // Internal frames have no arguments. The stack pointer of the
1132 // caller is at a fixed offset from the frame pointer.
1133 return fp() + StandardFrameConstants::kCallerSPOffset;
1137 Code* ArgumentsAdaptorFrame::unchecked_code() const {
1138 return isolate()->builtins()->builtin(
1139 Builtins::kArgumentsAdaptorTrampoline);
1143 Code* InternalFrame::unchecked_code() const {
1144 const int offset = InternalFrameConstants::kCodeOffset;
1145 Object* code = Memory::Object_at(fp() + offset);
1146 DCHECK(code != NULL);
1147 return reinterpret_cast<Code*>(code);
1151 void StackFrame::PrintIndex(StringStream* accumulator,
1154 accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index);
1158 void JavaScriptFrame::Print(StringStream* accumulator,
1161 DisallowHeapAllocation no_gc;
1162 Object* receiver = this->receiver();
1163 JSFunction* function = this->function();
1165 accumulator->PrintSecurityTokenIfChanged(function);
1166 PrintIndex(accumulator, mode, index);
1168 if (IsConstructor()) accumulator->Add("new ");
1169 accumulator->PrintFunction(function, receiver, &code);
1171 // Get scope information for nicer output, if possible. If code is NULL, or
1172 // doesn't contain scope info, scope_info will return 0 for the number of
1173 // parameters, stack local variables, context local variables, stack slots,
1174 // or context slots.
1175 SharedFunctionInfo* shared = function->shared();
1176 ScopeInfo* scope_info = shared->scope_info();
1177 Object* script_obj = shared->script();
1178 if (script_obj->IsScript()) {
1179 Script* script = Script::cast(script_obj);
1180 accumulator->Add(" [");
1181 accumulator->PrintName(script->name());
1183 Address pc = this->pc();
1184 if (code != NULL && code->kind() == Code::FUNCTION &&
1185 pc >= code->instruction_start() && pc < code->instruction_end()) {
1186 int source_pos = code->SourcePosition(pc);
1187 int line = script->GetLineNumber(source_pos) + 1;
1188 accumulator->Add(":%d", line);
1190 int function_start_pos = shared->start_position();
1191 int line = script->GetLineNumber(function_start_pos) + 1;
1192 accumulator->Add(":~%d", line);
1195 accumulator->Add("] ");
1198 accumulator->Add("(this=%o", receiver);
1200 // Print the parameters.
1201 int parameters_count = ComputeParametersCount();
1202 for (int i = 0; i < parameters_count; i++) {
1203 accumulator->Add(",");
1204 // If we have a name for the parameter we print it. Nameless
1205 // parameters are either because we have more actual parameters
1206 // than formal parameters or because we have no scope information.
1207 if (i < scope_info->ParameterCount()) {
1208 accumulator->PrintName(scope_info->ParameterName(i));
1209 accumulator->Add("=");
1211 accumulator->Add("%o", GetParameter(i));
1214 accumulator->Add(")");
1215 if (mode == OVERVIEW) {
1216 accumulator->Add("\n");
1219 if (is_optimized()) {
1220 accumulator->Add(" {\n// optimized frame\n}\n");
1223 accumulator->Add(" {\n");
1225 // Compute the number of locals and expression stack elements.
1226 int stack_locals_count = scope_info->StackLocalCount();
1227 int heap_locals_count = scope_info->ContextLocalCount();
1228 int expressions_count = ComputeExpressionsCount();
1230 // Print stack-allocated local variables.
1231 if (stack_locals_count > 0) {
1232 accumulator->Add(" // stack-allocated locals\n");
1234 for (int i = 0; i < stack_locals_count; i++) {
1235 accumulator->Add(" var ");
1236 accumulator->PrintName(scope_info->StackLocalName(i));
1237 accumulator->Add(" = ");
1238 if (i < expressions_count) {
1239 accumulator->Add("%o", GetExpression(i));
1241 accumulator->Add("// no expression found - inconsistent frame?");
1243 accumulator->Add("\n");
1246 // Try to get hold of the context of this frame.
1247 Context* context = NULL;
1248 if (this->context() != NULL && this->context()->IsContext()) {
1249 context = Context::cast(this->context());
1251 while (context->IsWithContext()) {
1252 context = context->previous();
1253 DCHECK(context != NULL);
1256 // Print heap-allocated local variables.
1257 if (heap_locals_count > 0) {
1258 accumulator->Add(" // heap-allocated locals\n");
1260 for (int i = 0; i < heap_locals_count; i++) {
1261 accumulator->Add(" var ");
1262 accumulator->PrintName(scope_info->ContextLocalName(i));
1263 accumulator->Add(" = ");
1264 if (context != NULL) {
1265 int index = Context::MIN_CONTEXT_SLOTS + i;
1266 if (index < context->length()) {
1267 accumulator->Add("%o", context->get(index));
1270 "// warning: missing context slot - inconsistent frame?");
1273 accumulator->Add("// warning: no context found - inconsistent frame?");
1275 accumulator->Add("\n");
1278 // Print the expression stack.
1279 int expressions_start = stack_locals_count;
1280 if (expressions_start < expressions_count) {
1281 accumulator->Add(" // expression stack (top to bottom)\n");
1283 for (int i = expressions_count - 1; i >= expressions_start; i--) {
1284 if (IsExpressionInsideHandler(i)) continue;
1285 accumulator->Add(" [%02d] : %o\n", i, GetExpression(i));
1288 // Print details about the function.
1289 if (FLAG_max_stack_trace_source_length != 0 && code != NULL) {
1291 SharedFunctionInfo* shared = function->shared();
1292 os << "--------- s o u r c e c o d e ---------\n"
1293 << SourceCodeOf(shared, FLAG_max_stack_trace_source_length)
1294 << "\n-----------------------------------------\n";
1295 accumulator->Add(os.c_str());
1298 accumulator->Add("}\n\n");
1302 void ArgumentsAdaptorFrame::Print(StringStream* accumulator,
1305 int actual = ComputeParametersCount();
1307 JSFunction* function = this->function();
1308 expected = function->shared()->formal_parameter_count();
1310 PrintIndex(accumulator, mode, index);
1311 accumulator->Add("arguments adaptor frame: %d->%d", actual, expected);
1312 if (mode == OVERVIEW) {
1313 accumulator->Add("\n");
1316 accumulator->Add(" {\n");
1318 // Print actual arguments.
1319 if (actual > 0) accumulator->Add(" // actual arguments\n");
1320 for (int i = 0; i < actual; i++) {
1321 accumulator->Add(" [%02d] : %o", i, GetParameter(i));
1322 if (expected != -1 && i >= expected) {
1323 accumulator->Add(" // not passed to callee");
1325 accumulator->Add("\n");
1328 accumulator->Add("}\n\n");
1332 void EntryFrame::Iterate(ObjectVisitor* v) const {
1333 StackHandlerIterator it(this, top_handler());
1335 StackHandler* handler = it.handler();
1336 DCHECK(handler->is_js_entry());
1337 handler->Iterate(v, LookupCode());
1339 // Make sure that the entry frame does not contain more than one
1344 IteratePc(v, pc_address(), LookupCode());
1348 void StandardFrame::IterateExpressions(ObjectVisitor* v) const {
1349 const int offset = StandardFrameConstants::kLastObjectOffset;
1350 Object** base = &Memory::Object_at(sp());
1351 Object** limit = &Memory::Object_at(fp() + offset) + 1;
1352 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
1353 StackHandler* handler = it.handler();
1354 // Traverse pointers down to - but not including - the next
1355 // handler in the handler chain. Update the base to skip the
1356 // handler and allow the handler to traverse its own pointers.
1357 const Address address = handler->address();
1358 v->VisitPointers(base, reinterpret_cast<Object**>(address));
1359 base = reinterpret_cast<Object**>(address + StackHandlerConstants::kSize);
1360 // Traverse the pointers in the handler itself.
1361 handler->Iterate(v, LookupCode());
1363 v->VisitPointers(base, limit);
1367 void JavaScriptFrame::Iterate(ObjectVisitor* v) const {
1368 IterateExpressions(v);
1369 IteratePc(v, pc_address(), LookupCode());
1373 void InternalFrame::Iterate(ObjectVisitor* v) const {
1374 // Internal frames only have object pointers on the expression stack
1375 // as they never have any arguments.
1376 IterateExpressions(v);
1377 IteratePc(v, pc_address(), LookupCode());
1381 void StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const {
1382 Object** base = &Memory::Object_at(sp());
1383 Object** limit = &Memory::Object_at(fp() +
1384 kFirstRegisterParameterFrameOffset);
1385 v->VisitPointers(base, limit);
1386 base = &Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset);
1387 const int offset = StandardFrameConstants::kLastObjectOffset;
1388 limit = &Memory::Object_at(fp() + offset) + 1;
1389 v->VisitPointers(base, limit);
1390 IteratePc(v, pc_address(), LookupCode());
1394 Address StubFailureTrampolineFrame::GetCallerStackPointer() const {
1395 return fp() + StandardFrameConstants::kCallerSPOffset;
1399 Code* StubFailureTrampolineFrame::unchecked_code() const {
1401 StubFailureTrampolineStub(isolate(), NOT_JS_FUNCTION_STUB_MODE).
1402 FindCodeInCache(&trampoline);
1403 if (trampoline->contains(pc())) {
1407 StubFailureTrampolineStub(isolate(), JS_FUNCTION_STUB_MODE).
1408 FindCodeInCache(&trampoline);
1409 if (trampoline->contains(pc())) {
1418 // -------------------------------------------------------------------------
1421 JavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) {
1423 for (int i = 0; i <= n; i++) {
1424 while (!iterator_.frame()->is_java_script()) iterator_.Advance();
1425 if (i == n) return JavaScriptFrame::cast(iterator_.frame());
1426 iterator_.Advance();
1433 // -------------------------------------------------------------------------
1436 static Map* GcSafeMapOfCodeSpaceObject(HeapObject* object) {
1437 MapWord map_word = object->map_word();
1438 return map_word.IsForwardingAddress() ?
1439 map_word.ToForwardingAddress()->map() : map_word.ToMap();
1443 static int GcSafeSizeOfCodeSpaceObject(HeapObject* object) {
1444 return object->SizeFromMap(GcSafeMapOfCodeSpaceObject(object));
1449 static bool GcSafeCodeContains(HeapObject* code, Address addr) {
1450 Map* map = GcSafeMapOfCodeSpaceObject(code);
1451 DCHECK(map == code->GetHeap()->code_map());
1452 Address start = code->address();
1453 Address end = code->address() + code->SizeFromMap(map);
1454 return start <= addr && addr < end;
1459 Code* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object,
1460 Address inner_pointer) {
1461 Code* code = reinterpret_cast<Code*>(object);
1462 DCHECK(code != NULL && GcSafeCodeContains(code, inner_pointer));
1467 Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer(
1468 Address inner_pointer) {
1469 Heap* heap = isolate_->heap();
1470 // Check if the inner pointer points into a large object chunk.
1471 LargePage* large_page = heap->lo_space()->FindPage(inner_pointer);
1472 if (large_page != NULL) {
1473 return GcSafeCastToCode(large_page->GetObject(), inner_pointer);
1476 // Iterate through the page until we reach the end or find an object starting
1477 // after the inner pointer.
1478 Page* page = Page::FromAddress(inner_pointer);
1480 Address addr = page->skip_list()->StartFor(inner_pointer);
1482 Address top = heap->code_space()->top();
1483 Address limit = heap->code_space()->limit();
1486 if (addr == top && addr != limit) {
1491 HeapObject* obj = HeapObject::FromAddress(addr);
1492 int obj_size = GcSafeSizeOfCodeSpaceObject(obj);
1493 Address next_addr = addr + obj_size;
1494 if (next_addr > inner_pointer) return GcSafeCastToCode(obj, inner_pointer);
1500 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
1501 InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
1502 isolate_->counters()->pc_to_code()->Increment();
1503 DCHECK(IsPowerOf2(kInnerPointerToCodeCacheSize));
1504 uint32_t hash = ComputeIntegerHash(
1505 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(inner_pointer)),
1506 v8::internal::kZeroHashSeed);
1507 uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
1508 InnerPointerToCodeCacheEntry* entry = cache(index);
1509 if (entry->inner_pointer == inner_pointer) {
1510 isolate_->counters()->pc_to_code_cached()->Increment();
1511 DCHECK(entry->code == GcSafeFindCodeForInnerPointer(inner_pointer));
1513 // Because this code may be interrupted by a profiling signal that
1514 // also queries the cache, we cannot update inner_pointer before the code
1515 // has been set. Otherwise, we risk trying to use a cache entry before
1516 // the code has been computed.
1517 entry->code = GcSafeFindCodeForInnerPointer(inner_pointer);
1518 entry->safepoint_entry.Reset();
1519 entry->inner_pointer = inner_pointer;
1525 // -------------------------------------------------------------------------
1528 void StackHandler::Unwind(Isolate* isolate,
1531 int previous_handler_offset) const {
1532 STATIC_ASSERT(StackHandlerConstants::kSlotCount >= 5);
1533 DCHECK_LE(0, offset);
1534 DCHECK_GE(array->length(), offset + StackHandlerConstants::kSlotCount);
1535 // Unwinding a stack handler into an array chains it in the opposite
1536 // direction, re-using the "next" slot as a "previous" link, so that stack
1537 // handlers can be later re-wound in the correct order. Decode the "state"
1538 // slot into "index" and "kind" and store them separately, using the fp slot.
1539 array->set(offset, Smi::FromInt(previous_handler_offset)); // next
1540 array->set(offset + 1, *code_address()); // code
1541 array->set(offset + 2, Smi::FromInt(static_cast<int>(index()))); // state
1542 array->set(offset + 3, *context_address()); // context
1543 array->set(offset + 4, Smi::FromInt(static_cast<int>(kind()))); // fp
1545 *isolate->handler_address() = next()->address();
1549 int StackHandler::Rewind(Isolate* isolate,
1553 STATIC_ASSERT(StackHandlerConstants::kSlotCount >= 5);
1554 DCHECK_LE(0, offset);
1555 DCHECK_GE(array->length(), offset + StackHandlerConstants::kSlotCount);
1556 Smi* prev_handler_offset = Smi::cast(array->get(offset));
1557 Code* code = Code::cast(array->get(offset + 1));
1558 Smi* smi_index = Smi::cast(array->get(offset + 2));
1559 Object* context = array->get(offset + 3);
1560 Smi* smi_kind = Smi::cast(array->get(offset + 4));
1562 unsigned state = KindField::encode(static_cast<Kind>(smi_kind->value())) |
1563 IndexField::encode(static_cast<unsigned>(smi_index->value()));
1565 Memory::Address_at(address() + StackHandlerConstants::kNextOffset) =
1566 *isolate->handler_address();
1567 Memory::Object_at(address() + StackHandlerConstants::kCodeOffset) = code;
1568 Memory::uintptr_at(address() + StackHandlerConstants::kStateOffset) = state;
1569 Memory::Object_at(address() + StackHandlerConstants::kContextOffset) =
1571 SetFp(address() + StackHandlerConstants::kFPOffset, fp);
1573 *isolate->handler_address() = address();
1575 return prev_handler_offset->value();
1579 // -------------------------------------------------------------------------
1581 int NumRegs(RegList reglist) {
1582 return CompilerIntrinsics::CountSetBits(reglist);
1586 struct JSCallerSavedCodeData {
1587 int reg_code[kNumJSCallerSaved];
1590 JSCallerSavedCodeData caller_saved_code_data;
1592 void SetUpJSCallerSavedCodeData() {
1594 for (int r = 0; r < kNumRegs; r++)
1595 if ((kJSCallerSaved & (1 << r)) != 0)
1596 caller_saved_code_data.reg_code[i++] = r;
1598 DCHECK(i == kNumJSCallerSaved);
1602 int JSCallerSavedCode(int n) {
1603 DCHECK(0 <= n && n < kNumJSCallerSaved);
1604 return caller_saved_code_data.reg_code[n];
1608 #define DEFINE_WRAPPER(type, field) \
1609 class field##_Wrapper : public ZoneObject { \
1610 public: /* NOLINT */ \
1611 field##_Wrapper(const field& original) : frame_(original) { \
1615 STACK_FRAME_TYPE_LIST(DEFINE_WRAPPER)
1616 #undef DEFINE_WRAPPER
1618 static StackFrame* AllocateFrameCopy(StackFrame* frame, Zone* zone) {
1619 #define FRAME_TYPE_CASE(type, field) \
1620 case StackFrame::type: { \
1621 field##_Wrapper* wrapper = \
1622 new(zone) field##_Wrapper(*(reinterpret_cast<field*>(frame))); \
1623 return &wrapper->frame_; \
1626 switch (frame->type()) {
1627 STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
1628 default: UNREACHABLE();
1630 #undef FRAME_TYPE_CASE
1635 Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone) {
1636 ZoneList<StackFrame*> list(10, zone);
1637 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
1638 StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
1639 list.Add(frame, zone);
1641 return list.ToVector();
1645 } } // namespace v8::internal