5 #include "src/frames.h" 10 #include "src/base/bits.h" 11 #include "src/deoptimizer.h" 12 #include "src/frames-inl.h" 13 #include "src/ic/ic-stats.h" 14 #include "src/objects/code.h" 15 #include "src/objects/slots.h" 16 #include "src/objects/smi.h" 17 #include "src/register-configuration.h" 18 #include "src/safepoint-table.h" 19 #include "src/snapshot/snapshot.h" 20 #include "src/string-stream.h" 21 #include "src/visitors.h" 22 #include "src/vm-state-inl.h" 23 #include "src/wasm/wasm-code-manager.h" 24 #include "src/wasm/wasm-engine.h" 25 #include "src/wasm/wasm-objects-inl.h" 26 #include "src/zone/zone-containers.h" 31 ReturnAddressLocationResolver StackFrame::return_address_location_resolver_ =
39 : limit_(frame->fp()), handler_(handler) {
41 DCHECK(frame->sp() <= handler->address());
46 bool done() {
return handler_ ==
nullptr || handler_->address() > limit_; }
49 handler_ = handler_->next();
61 #define INITIALIZE_SINGLETON(type, field) field##_(this), 62 StackFrameIteratorBase::StackFrameIteratorBase(
Isolate* isolate,
63 bool can_access_heap_objects)
65 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) frame_(nullptr),
67 can_access_heap_objects_(can_access_heap_objects) {}
68 #undef INITIALIZE_SINGLETON 70 StackFrameIterator::StackFrameIterator(Isolate* isolate)
71 : StackFrameIterator(isolate, isolate->thread_local_top()) {}
73 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
74 : StackFrameIteratorBase(isolate, true) {
78 void StackFrameIterator::Advance() {
84 StackFrame::State state;
85 StackFrame::Type type = frame_->GetCallerState(&state);
88 StackHandlerIterator it(frame_, handler_);
89 while (!it.done()) it.Advance();
90 handler_ = it.handler();
93 frame_ = SingletonFor(type, &state);
97 DCHECK(!done() || handler_ ==
nullptr);
101 void StackFrameIterator::Reset(ThreadLocalTop* top) {
102 StackFrame::State state;
103 StackFrame::Type type = ExitFrame::GetStateForFramePointer(
104 Isolate::c_entry_fp(top), &state);
105 handler_ = StackHandler::FromAddress(Isolate::handler(top));
106 frame_ = SingletonFor(type, &state);
110 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type,
111 StackFrame::State* state) {
112 StackFrame* result = SingletonFor(type);
113 DCHECK((!result) == (type == StackFrame::NONE));
114 if (result) result->state_ = *state;
119 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type) {
120 #define FRAME_TYPE_CASE(type, field) \ 121 case StackFrame::type: \ 125 case StackFrame::NONE:
127 STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
132 #undef FRAME_TYPE_CASE 137 void JavaScriptFrameIterator::Advance() {
140 }
while (!iterator_.done() && !iterator_.frame()->is_java_script());
145 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
146 : iterator_(isolate) {
147 if (!done() && !IsValidFrame(iterator_.frame())) Advance();
150 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate,
152 : StackTraceFrameIterator(isolate) {
153 while (!done() && frame()->
id() !=
id) Advance();
156 void StackTraceFrameIterator::Advance() {
159 }
while (!done() && !IsValidFrame(iterator_.frame()));
162 bool StackTraceFrameIterator::IsValidFrame(StackFrame* frame)
const {
163 if (frame->is_java_script()) {
164 JavaScriptFrame* jsFrame =
static_cast<JavaScriptFrame*
>(frame);
165 if (!jsFrame->function()->IsJSFunction())
return false;
166 return jsFrame->function()->shared()->IsSubjectToDebugging();
169 return frame->is_wasm();
176 bool IsInterpreterFramePc(Isolate* isolate, Address pc,
177 StackFrame::State* state) {
178 Code interpreter_entry_trampoline =
179 isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline);
180 Code interpreter_bytecode_advance =
181 isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeAdvance);
182 Code interpreter_bytecode_dispatch =
183 isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
185 if (interpreter_entry_trampoline->contains(pc) ||
186 interpreter_bytecode_advance->contains(pc) ||
187 interpreter_bytecode_dispatch->contains(pc)) {
189 }
else if (FLAG_interpreted_frames_native_stack) {
190 intptr_t marker = Memory<intptr_t>(
191 state->fp + CommonFrameConstants::kContextOrFrameTypeOffset);
192 MSAN_MEMORY_IS_INITIALIZED(
193 state->fp + StandardFrameConstants::kFunctionOffset, kPointerSize);
194 Object* maybe_function =
195 Memory<Object*>(state->fp + StandardFrameConstants::kFunctionOffset);
198 if (StackFrame::IsTypeMarker(marker) || maybe_function->IsSmi()) {
200 }
else if (!isolate->heap()->code_space()->ContainsSlow(pc)) {
203 interpreter_entry_trampoline =
204 isolate->heap()->GcSafeFindCodeForInnerPointer(pc);
205 return interpreter_entry_trampoline->is_interpreter_trampoline_builtin();
211 DISABLE_ASAN Address ReadMemoryAt(Address address) {
212 return Memory<Address>(address);
217 SafeStackFrameIterator::SafeStackFrameIterator(
219 Address fp, Address sp, Address js_entry_sp)
220 : StackFrameIteratorBase(isolate, false),
222 high_bound_(js_entry_sp),
223 top_frame_type_(StackFrame::NONE),
224 external_callback_scope_(isolate->external_callback_scope()) {
225 StackFrame::State state;
226 StackFrame::Type type;
227 ThreadLocalTop* top = isolate->thread_local_top();
228 bool advance_frame =
true;
229 if (IsValidTop(top)) {
230 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
231 top_frame_type_ = type;
232 }
else if (IsValidStackAddress(fp)) {
233 DCHECK_NE(fp, kNullAddress);
236 state.pc_address = StackFrame::ResolveReturnAddressLocation(
237 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
242 if (IsValidStackAddress(sp)) {
243 MSAN_MEMORY_IS_INITIALIZED(sp, kPointerSize);
244 Address tos = ReadMemoryAt(sp);
245 if (IsInterpreterFramePc(isolate, tos, &state)) {
246 state.pc_address =
reinterpret_cast<Address*
>(sp);
247 advance_frame =
false;
255 STATIC_ASSERT(StandardFrameConstants::kFunctionOffset <
256 StandardFrameConstants::kContextOffset);
257 Address frame_marker = fp + StandardFrameConstants::kFunctionOffset;
258 if (IsValidStackAddress(frame_marker)) {
259 type = StackFrame::ComputeType(
this, &state);
260 top_frame_type_ = type;
262 if (type != StackFrame::INTERPRETED) {
263 advance_frame =
true;
273 type = StackFrame::OPTIMIZED;
275 top_frame_type_ = StackFrame::NONE;
280 frame_ = SingletonFor(type, &state);
281 if (advance_frame && frame_) Advance();
285 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top)
const {
286 Address c_entry_fp = Isolate::c_entry_fp(top);
287 if (!IsValidExitFrame(c_entry_fp))
return false;
289 Address handler = Isolate::handler(top);
290 if (handler == kNullAddress)
return false;
292 return c_entry_fp < handler;
296 void SafeStackFrameIterator::AdvanceOneFrame() {
298 StackFrame* last_frame = frame_;
299 Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
301 if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) {
307 StackFrame::State state;
308 StackFrame::Type type = frame_->GetCallerState(&state);
309 frame_ = SingletonFor(type, &state);
313 if (frame_->sp() <= last_sp || frame_->fp() <= last_fp) {
319 bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame)
const {
320 return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
324 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
325 StackFrame::State state;
326 if (frame->is_entry() || frame->is_construct_entry()) {
331 Memory<Address>(frame->fp() + EntryFrameConstants::kCallerFPOffset);
332 if (!IsValidExitFrame(caller_fp))
return false;
333 }
else if (frame->is_arguments_adaptor()) {
337 Object* number_of_args =
reinterpret_cast<ArgumentsAdaptorFrame*
>(frame)->
339 if (!number_of_args->IsSmi()) {
343 frame->ComputeCallerState(&state);
344 return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) &&
345 SingletonFor(frame->GetCallerState(&state)) !=
nullptr;
349 bool SafeStackFrameIterator::IsValidExitFrame(Address fp)
const {
350 if (!IsValidStackAddress(fp))
return false;
351 Address sp = ExitFrame::ComputeStackPointer(fp);
352 if (!IsValidStackAddress(sp))
return false;
353 StackFrame::State state;
354 ExitFrame::FillState(fp, sp, &state);
355 MSAN_MEMORY_IS_INITIALIZED(state.pc_address,
sizeof(state.pc_address));
356 return *state.pc_address != kNullAddress;
360 void SafeStackFrameIterator::Advance() {
364 ExternalCallbackScope* last_callback_scope =
nullptr;
365 while (external_callback_scope_ !=
nullptr &&
366 external_callback_scope_->scope_address() < frame_->fp()) {
372 last_callback_scope = external_callback_scope_;
373 external_callback_scope_ = external_callback_scope_->previous();
375 if (frame_->is_java_script() || frame_->is_wasm())
break;
376 if (frame_->is_exit() || frame_->is_builtin_exit()) {
382 if (last_callback_scope) {
383 frame_->state_.pc_address =
384 last_callback_scope->callback_entrypoint_address();
395 Code GetContainingCode(Isolate* isolate, Address pc) {
396 return isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code;
400 Code StackFrame::LookupCode()
const {
401 Code result = GetContainingCode(isolate(), pc());
402 DCHECK_GE(pc(), result->InstructionStart());
403 DCHECK_LT(pc(), result->InstructionEnd());
407 void StackFrame::IteratePc(RootVisitor* v, Address* pc_address,
408 Address* constant_pool_address, Code holder) {
409 Address pc = *pc_address;
410 DCHECK(holder->GetHeap()->GcSafeCodeContains(holder, pc));
411 unsigned pc_offset =
static_cast<unsigned>(pc - holder->InstructionStart());
412 ObjectPtr code = holder;
413 v->VisitRootPointer(Root::kTop,
nullptr, ObjectSlot(&code));
414 if (code == holder)
return;
415 holder = Code::unchecked_cast(code);
416 pc = holder->InstructionStart() + pc_offset;
418 if (FLAG_enable_embedded_constant_pool && constant_pool_address) {
419 *constant_pool_address = holder->constant_pool();
424 void StackFrame::SetReturnAddressLocationResolver(
425 ReturnAddressLocationResolver resolver) {
426 DCHECK_NULL(return_address_location_resolver_);
427 return_address_location_resolver_ = resolver;
430 StackFrame::Type StackFrame::ComputeType(
const StackFrameIteratorBase* iterator,
432 DCHECK_NE(state->fp, kNullAddress);
434 MSAN_MEMORY_IS_INITIALIZED(
435 state->fp + CommonFrameConstants::kContextOrFrameTypeOffset,
437 intptr_t marker = Memory<intptr_t>(
438 state->fp + CommonFrameConstants::kContextOrFrameTypeOffset);
439 if (!iterator->can_access_heap_objects_) {
445 MSAN_MEMORY_IS_INITIALIZED(
446 state->fp + StandardFrameConstants::kFunctionOffset, kPointerSize);
447 Object* maybe_function =
448 Memory<Object*>(state->fp + StandardFrameConstants::kFunctionOffset);
449 if (!StackFrame::IsTypeMarker(marker)) {
450 if (maybe_function->IsSmi()) {
452 }
else if (IsInterpreterFramePc(iterator->isolate(), *(state->pc_address),
460 Address pc = *(state->pc_address);
463 wasm::WasmCode* wasm_code =
464 iterator->isolate()->wasm_engine()->code_manager()->LookupCode(pc);
465 if (wasm_code !=
nullptr) {
466 switch (wasm_code->kind()) {
467 case wasm::WasmCode::kFunction:
468 return WASM_COMPILED;
469 case wasm::WasmCode::kWasmToJsWrapper:
471 case wasm::WasmCode::kLazyStub:
472 return WASM_COMPILE_LAZY;
473 case wasm::WasmCode::kRuntimeStub:
475 case wasm::WasmCode::kInterpreterEntry:
476 return WASM_INTERPRETER_ENTRY;
482 Code code_obj = GetContainingCode(iterator->isolate(), pc);
483 if (!code_obj.is_null()) {
484 switch (code_obj->kind()) {
486 if (StackFrame::IsTypeMarker(marker))
break;
487 if (code_obj->is_interpreter_trampoline_builtin()) {
490 if (code_obj->is_turbofanned()) {
498 case Code::OPTIMIZED_FUNCTION:
500 case Code::WASM_FUNCTION:
501 return WASM_COMPILED;
502 case Code::WASM_TO_JS_FUNCTION:
504 case Code::JS_TO_WASM_FUNCTION:
506 case Code::WASM_INTERPRETER_ENTRY:
507 return WASM_INTERPRETER_ENTRY;
508 case Code::C_WASM_ENTRY:
519 DCHECK(StackFrame::IsTypeMarker(marker));
520 StackFrame::Type candidate = StackFrame::MarkerToType(marker);
523 case CONSTRUCT_ENTRY:
525 case BUILTIN_CONTINUATION:
526 case JAVA_SCRIPT_BUILTIN_CONTINUATION:
527 case JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH:
532 case ARGUMENTS_ADAPTOR:
550 bool StackFrame::can_access_heap_objects()
const {
551 return iterator_->can_access_heap_objects_;
556 StackFrame::Type StackFrame::GetCallerState(State* state)
const {
557 ComputeCallerState(state);
558 return ComputeType(iterator_, state);
562 Address StackFrame::UnpaddedFP()
const {
566 Code NativeFrame::unchecked_code()
const {
return Code(); }
568 void NativeFrame::ComputeCallerState(State* state)
const {
569 state->sp = caller_sp();
570 state->fp = Memory<Address>(fp() + CommonFrameConstants::kCallerFPOffset);
571 state->pc_address = ResolveReturnAddressLocation(
572 reinterpret_cast<Address*>(fp() + CommonFrameConstants::kCallerPCOffset));
573 state->callee_pc_address =
nullptr;
574 state->constant_pool_address =
nullptr;
577 Code EntryFrame::unchecked_code()
const {
578 return isolate()->heap()->js_entry_code();
582 void EntryFrame::ComputeCallerState(State* state)
const {
583 GetCallerState(state);
587 StackFrame::Type EntryFrame::GetCallerState(State* state)
const {
588 const int offset = EntryFrameConstants::kCallerFPOffset;
589 Address fp = Memory<Address>(this->fp() + offset);
590 return ExitFrame::GetStateForFramePointer(fp, state);
593 Code ConstructEntryFrame::unchecked_code()
const {
594 return isolate()->heap()->js_construct_entry_code();
598 Object*& ExitFrame::code_slot()
const {
599 const int offset = ExitFrameConstants::kCodeOffset;
600 return Memory<Object*>(fp() + offset);
603 Code ExitFrame::unchecked_code()
const {
604 return Code::unchecked_cast(code_slot());
607 void ExitFrame::ComputeCallerState(State* state)
const {
609 state->sp = caller_sp();
610 state->fp = Memory<Address>(fp() + ExitFrameConstants::kCallerFPOffset);
611 state->pc_address = ResolveReturnAddressLocation(
612 reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
613 state->callee_pc_address =
nullptr;
614 if (FLAG_enable_embedded_constant_pool) {
615 state->constant_pool_address =
reinterpret_cast<Address*
>(
616 fp() + ExitFrameConstants::kConstantPoolOffset);
621 void ExitFrame::Iterate(RootVisitor* v)
const {
624 IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
625 v->VisitRootPointer(Root::kTop,
nullptr, ObjectSlot(&code_slot()));
629 Address ExitFrame::GetCallerStackPointer()
const {
630 return fp() + ExitFrameConstants::kCallerSPOffset;
634 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
635 if (fp == 0)
return NONE;
636 Address sp = ComputeStackPointer(fp);
637 FillState(fp, sp, state);
638 DCHECK_NE(*state->pc_address, kNullAddress);
640 return ComputeFrameType(fp);
643 StackFrame::Type ExitFrame::ComputeFrameType(Address fp) {
646 const int offset = ExitFrameConstants::kFrameTypeOffset;
647 Object* marker = Memory<Object*>(fp + offset);
649 if (!marker->IsSmi()) {
653 intptr_t marker_int = bit_cast<intptr_t>(marker);
655 StackFrame::Type frame_type =
static_cast<StackFrame::Type
>(marker_int >> 1);
656 if (frame_type == EXIT || frame_type == BUILTIN_EXIT) {
663 Address ExitFrame::ComputeStackPointer(Address fp) {
664 MSAN_MEMORY_IS_INITIALIZED(fp + ExitFrameConstants::kSPOffset, kPointerSize);
665 return Memory<Address>(fp + ExitFrameConstants::kSPOffset);
668 void ExitFrame::FillState(Address fp, Address sp, State* state) {
671 state->pc_address = ResolveReturnAddressLocation(
672 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize));
673 state->callee_pc_address =
nullptr;
678 state->constant_pool_address =
nullptr;
681 JSFunction* BuiltinExitFrame::function()
const {
682 return JSFunction::cast(target_slot_object());
685 Object* BuiltinExitFrame::receiver()
const {
return receiver_slot_object(); }
687 bool BuiltinExitFrame::IsConstructor()
const {
688 return !new_target_slot_object()->IsUndefined(isolate());
691 Object* BuiltinExitFrame::GetParameter(
int i)
const {
692 DCHECK(
i >= 0 &&
i < ComputeParametersCount());
694 BuiltinExitFrameConstants::kFirstArgumentOffset +
i * kPointerSize;
695 return Memory<Object*>(fp() + offset);
698 int BuiltinExitFrame::ComputeParametersCount()
const {
699 Object* argc_slot = argc_slot_object();
700 DCHECK(argc_slot->IsSmi());
703 int argc = Smi::ToInt(argc_slot) - 4;
709 void PrintIndex(StringStream* accumulator, StackFrame::PrintMode mode,
711 accumulator->Add((mode == StackFrame::OVERVIEW) ?
"%5d: " :
"[%d]: ", index);
714 const char* StringForStackFrameType(StackFrame::Type type) {
716 #define CASE(value, name) \ 717 case StackFrame::value: \ 719 STACK_FRAME_TYPE_LIST(CASE)
727 void StackFrame::Print(StringStream* accumulator, PrintMode mode,
729 DisallowHeapAllocation no_gc;
730 PrintIndex(accumulator, mode, index);
731 accumulator->Add(StringForStackFrameType(type()));
732 accumulator->Add(
" [pc: %p]\n", reinterpret_cast<void*>(pc()));
735 void BuiltinExitFrame::Print(StringStream* accumulator, PrintMode mode,
737 DisallowHeapAllocation no_gc;
738 Object* receiver = this->receiver();
739 JSFunction*
function = this->
function();
741 accumulator->PrintSecurityTokenIfChanged(
function);
742 PrintIndex(accumulator, mode, index);
743 accumulator->Add(
"builtin exit frame: ");
745 if (IsConstructor()) accumulator->Add(
"new ");
746 accumulator->PrintFunction(
function, receiver, &code);
748 accumulator->Add(
"(this=%o", receiver);
751 int parameters_count = ComputeParametersCount();
752 for (
int i = 0;
i < parameters_count;
i++) {
753 accumulator->Add(
",%o", GetParameter(
i));
756 accumulator->Add(
")\n\n");
759 Address StandardFrame::GetExpressionAddress(
int n)
const {
760 const int offset = StandardFrameConstants::kExpressionsOffset;
761 return fp() + offset - n * kPointerSize;
764 Address InterpretedFrame::GetExpressionAddress(
int n)
const {
765 const int offset = InterpreterFrameConstants::kExpressionsOffset;
766 return fp() + offset - n * kPointerSize;
769 Script* StandardFrame::script()
const {
775 Object* StandardFrame::receiver()
const {
776 return ReadOnlyRoots(isolate()).undefined_value();
779 Object* StandardFrame::context()
const {
780 return ReadOnlyRoots(isolate()).undefined_value();
783 int StandardFrame::position()
const {
784 AbstractCode code = AbstractCode::cast(LookupCode());
785 int code_offset =
static_cast<int>(pc() - code->InstructionStart());
786 return code->SourcePosition(code_offset);
789 int StandardFrame::ComputeExpressionsCount()
const {
790 Address base = GetExpressionAddress(0);
791 Address limit = sp() - kPointerSize;
792 DCHECK(base >= limit);
794 return static_cast<int>((base - limit) / kPointerSize);
797 Object* StandardFrame::GetParameter(
int index)
const {
802 int StandardFrame::ComputeParametersCount()
const {
return 0; }
804 void StandardFrame::ComputeCallerState(State* state)
const {
805 state->sp = caller_sp();
806 state->fp = caller_fp();
807 state->pc_address = ResolveReturnAddressLocation(
808 reinterpret_cast<Address*>(ComputePCAddress(fp())));
809 state->callee_pc_address = pc_address();
810 state->constant_pool_address =
811 reinterpret_cast<Address*
>(ComputeConstantPoolAddress(fp()));
815 bool StandardFrame::IsConstructor()
const {
return false; }
817 void StandardFrame::Summarize(std::vector<FrameSummary>* functions)
const {
822 void StandardFrame::IterateCompiledFrame(RootVisitor* v)
const {
825 DCHECK(can_access_heap_objects());
828 Address inner_pointer = pc();
829 const wasm::WasmCode* wasm_code =
830 isolate()->wasm_engine()->code_manager()->LookupCode(inner_pointer);
831 SafepointEntry safepoint_entry;
834 bool has_tagged_params =
false;
835 if (wasm_code !=
nullptr) {
836 SafepointTable table(wasm_code->instruction_start(),
837 wasm_code->safepoint_table_offset(),
838 wasm_code->stack_slots());
839 safepoint_entry = table.FindEntry(inner_pointer);
840 stack_slots = wasm_code->stack_slots();
841 has_tagged_params = wasm_code->kind() != wasm::WasmCode::kFunction;
843 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry =
844 isolate()->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer);
845 if (!entry->safepoint_entry.is_valid()) {
846 entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer);
847 DCHECK(entry->safepoint_entry.is_valid());
849 DCHECK(entry->safepoint_entry.Equals(
850 entry->code->GetSafepointEntry(inner_pointer)));
854 safepoint_entry = entry->safepoint_entry;
855 stack_slots = code->stack_slots();
856 has_tagged_params = code->has_tagged_params();
858 uint32_t slot_space = stack_slots * kPointerSize;
861 int frame_header_size = StandardFrameConstants::kFixedFrameSizeFromFp;
863 Memory<intptr_t>(fp() + CommonFrameConstants::kContextOrFrameTypeOffset);
864 if (StackFrame::IsTypeMarker(marker)) {
865 StackFrame::Type candidate = StackFrame::MarkerToType(marker);
868 case CONSTRUCT_ENTRY:
870 case BUILTIN_CONTINUATION:
871 case JAVA_SCRIPT_BUILTIN_CONTINUATION:
872 case JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH:
874 case ARGUMENTS_ADAPTOR:
880 frame_header_size = TypedFrameConstants::kFixedFrameSizeFromFp;
884 case WASM_INTERPRETER_ENTRY:
885 case WASM_COMPILE_LAZY:
886 frame_header_size = WasmCompiledFrameConstants::kFixedFrameSizeFromFp;
897 case NUMBER_OF_TYPES:
904 (frame_header_size + StandardFrameConstants::kFixedFrameSizeAboveFp);
906 ObjectSlot frame_header_base(&Memory<Object*>(fp() - frame_header_size));
907 ObjectSlot frame_header_limit(
908 &Memory<Object*>(fp() - StandardFrameConstants::kCPSlotSize));
909 ObjectSlot parameters_base(&Memory<Object*>(sp()));
910 ObjectSlot parameters_limit(frame_header_base.address() - slot_space);
913 if (safepoint_entry.argument_count() > 0) {
914 v->VisitRootPointers(Root::kTop,
nullptr, parameters_base,
915 parameters_base + safepoint_entry.argument_count());
916 parameters_base += safepoint_entry.argument_count();
920 if (safepoint_entry.has_doubles()) {
922 DCHECK(!isolate()->serializer_enabled());
924 RegisterConfiguration::Default()->num_allocatable_double_registers() *
925 kDoubleSize / kPointerSize;
929 if (safepoint_entry.HasRegisters()) {
930 for (
int i = kNumSafepointRegisters - 1;
i >=0;
i--) {
931 if (safepoint_entry.HasRegisterAt(
i)) {
932 int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(
i);
933 v->VisitRootPointer(Root::kTop,
nullptr,
934 parameters_base + reg_stack_index);
938 parameters_base += kNumSafepointRegisters;
942 uint8_t* safepoint_bits = safepoint_entry.bits();
943 safepoint_bits += kNumSafepointRegisters >> kBitsPerByteLog2;
946 if (has_tagged_params) {
947 v->VisitRootPointers(Root::kTop,
nullptr, parameters_base,
952 for (
unsigned index = 0; index < stack_slots; index++) {
953 int byte_index = index >> kBitsPerByteLog2;
954 int bit_index = index & (kBitsPerByte - 1);
955 if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) {
956 v->VisitRootPointer(Root::kTop,
nullptr, parameters_limit + index);
961 if (!code.is_null()) {
963 IteratePc(v, pc_address(), constant_pool_address(), code);
969 v->VisitRootPointers(Root::kTop,
nullptr, frame_header_base,
973 void StubFrame::Iterate(RootVisitor* v)
const { IterateCompiledFrame(v); }
975 Code StubFrame::unchecked_code()
const {
976 return isolate()->FindCodeObject(pc());
980 Address StubFrame::GetCallerStackPointer()
const {
981 return fp() + ExitFrameConstants::kCallerSPOffset;
985 int StubFrame::GetNumberOfIncomingArguments()
const {
989 int StubFrame::LookupExceptionHandlerInTable(
int* stack_slots) {
990 Code code = LookupCode();
991 DCHECK(code->is_turbofanned());
992 DCHECK_EQ(code->kind(), Code::BUILTIN);
993 HandlerTable table(code);
994 int pc_offset =
static_cast<int>(pc() - code->InstructionStart());
995 *stack_slots = code->stack_slots();
996 return table.LookupReturn(pc_offset);
999 void OptimizedFrame::Iterate(RootVisitor* v)
const { IterateCompiledFrame(v); }
1001 void JavaScriptFrame::SetParameterValue(
int index, Object* value)
const {
1002 Memory<Object*>(GetParameterSlot(index)) = value;
1006 bool JavaScriptFrame::IsConstructor()
const {
1007 Address fp = caller_fp();
1008 if (has_adapted_arguments()) {
1010 fp = Memory<Address>(fp + StandardFrameConstants::kCallerFPOffset);
1012 return IsConstructFrame(fp);
1016 bool JavaScriptFrame::HasInlinedFrames()
const {
1017 std::vector<SharedFunctionInfo*> functions;
1018 GetFunctions(&functions);
1019 return functions.size() > 1;
1022 Code JavaScriptFrame::unchecked_code()
const {
return function()->code(); }
1024 int JavaScriptFrame::GetNumberOfIncomingArguments()
const {
1025 DCHECK(can_access_heap_objects() &&
1026 isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
1027 return function()->shared()->internal_formal_parameter_count();
1030 int OptimizedFrame::GetNumberOfIncomingArguments()
const {
1031 Code code = LookupCode();
1032 if (code->kind() == Code::BUILTIN) {
1033 return static_cast<int>(
1034 Memory<intptr_t>(fp() + OptimizedBuiltinFrameConstants::kArgCOffset));
1036 return JavaScriptFrame::GetNumberOfIncomingArguments();
1040 Address JavaScriptFrame::GetCallerStackPointer()
const {
1041 return fp() + StandardFrameConstants::kCallerSPOffset;
1044 void JavaScriptFrame::GetFunctions(
1045 std::vector<SharedFunctionInfo*>* functions)
const {
1046 DCHECK(functions->empty());
1047 functions->push_back(
function()->shared());
1050 void JavaScriptFrame::GetFunctions(
1051 std::vector<Handle<SharedFunctionInfo>>* functions)
const {
1052 DCHECK(functions->empty());
1053 std::vector<SharedFunctionInfo*> raw_functions;
1054 GetFunctions(&raw_functions);
1055 for (
const auto& raw_function : raw_functions) {
1056 functions->push_back(
1057 Handle<SharedFunctionInfo>(raw_function,
function()->GetIsolate()));
1061 void JavaScriptFrame::Summarize(std::vector<FrameSummary>* functions)
const {
1062 DCHECK(functions->empty());
1063 Code code = LookupCode();
1064 int offset =
static_cast<int>(pc() - code->InstructionStart());
1065 AbstractCode abstract_code = AbstractCode::cast(code);
1066 FrameSummary::JavaScriptFrameSummary summary(isolate(), receiver(),
1067 function(), abstract_code,
1068 offset, IsConstructor());
1069 functions->push_back(summary);
1072 JSFunction* JavaScriptFrame::function()
const {
1073 return JSFunction::cast(function_slot_object());
1076 Object* JavaScriptFrame::unchecked_function()
const {
1080 DCHECK(function_slot_object()->IsJSFunction() ||
1081 ReadOnlyRoots(isolate()).arguments_marker() == function_slot_object());
1082 return function_slot_object();
1085 Object* JavaScriptFrame::receiver()
const {
return GetParameter(-1); }
1087 Object* JavaScriptFrame::context()
const {
1088 const int offset = StandardFrameConstants::kContextOffset;
1089 Object* maybe_result = Memory<Object*>(fp() + offset);
1090 DCHECK(!maybe_result->IsSmi());
1091 return maybe_result;
1094 Script* JavaScriptFrame::script()
const {
1095 return Script::cast(
function()->shared()->script());
1098 int JavaScriptFrame::LookupExceptionHandlerInTable(
1099 int* stack_depth, HandlerTable::CatchPrediction* prediction) {
1100 DCHECK_EQ(0, LookupCode()->handler_table_offset());
1101 DCHECK(!LookupCode()->is_optimized_code());
1105 void JavaScriptFrame::PrintFunctionAndOffset(JSFunction*
function,
1106 AbstractCode code,
int code_offset,
1108 bool print_line_number) {
1109 PrintF(file,
"%s", function->IsOptimized() ?
"*" :
"~");
1110 function->PrintName(file);
1111 PrintF(file,
"+%d", code_offset);
1112 if (print_line_number) {
1113 SharedFunctionInfo* shared =
function->shared();
1114 int source_pos = code->SourcePosition(code_offset);
1115 Object* maybe_script = shared->script();
1116 if (maybe_script->IsScript()) {
1117 Script* script = Script::cast(maybe_script);
1118 int line = script->GetLineNumber(source_pos) + 1;
1119 Object* script_name_raw = script->name();
1120 if (script_name_raw->IsString()) {
1121 String script_name = String::cast(script->name());
1122 std::unique_ptr<char[]> c_script_name =
1123 script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1124 PrintF(file,
" at %s:%d", c_script_name.get(), line);
1126 PrintF(file,
" at <unknown>:%d", line);
1129 PrintF(file,
" at <unknown>:<unknown>");
1134 void JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file,
bool print_args,
1135 bool print_line_number) {
1137 DisallowHeapAllocation no_allocation;
1138 JavaScriptFrameIterator it(isolate);
1139 while (!it.done()) {
1140 if (it.frame()->is_java_script()) {
1141 JavaScriptFrame* frame = it.frame();
1142 if (frame->IsConstructor()) PrintF(file,
"new ");
1143 JSFunction*
function = frame->function();
1144 int code_offset = 0;
1145 if (frame->is_interpreted()) {
1146 InterpretedFrame* iframe =
reinterpret_cast<InterpretedFrame*
>(frame);
1147 code_offset = iframe->GetBytecodeOffset();
1149 Code code = frame->unchecked_code();
1150 code_offset =
static_cast<int>(frame->pc() - code->InstructionStart());
1152 PrintFunctionAndOffset(
function, function->abstract_code(), code_offset,
1153 file, print_line_number);
1158 PrintF(file,
"(this=");
1159 frame->receiver()->ShortPrint(file);
1160 const int length = frame->ComputeParametersCount();
1161 for (
int i = 0;
i < length;
i++) {
1163 frame->GetParameter(
i)->ShortPrint(file);
1173 void JavaScriptFrame::CollectFunctionAndOffsetForICStats(JSFunction*
function,
1176 auto ic_stats = ICStats::instance();
1177 ICInfo& ic_info = ic_stats->Current();
1178 SharedFunctionInfo* shared =
function->shared();
1180 ic_info.function_name = ic_stats->GetOrCacheFunctionName(
function);
1181 ic_info.script_offset = code_offset;
1183 int source_pos = code->SourcePosition(code_offset);
1184 Object* maybe_script = shared->script();
1185 if (maybe_script->IsScript()) {
1186 Script* script = Script::cast(maybe_script);
1187 ic_info.line_num = script->GetLineNumber(source_pos) + 1;
1188 ic_info.script_name = ic_stats->GetOrCacheScriptName(script);
1192 void JavaScriptFrame::CollectTopFrameForICStats(Isolate* isolate) {
1194 DisallowHeapAllocation no_allocation;
1195 JavaScriptFrameIterator it(isolate);
1196 ICInfo& ic_info = ICStats::instance()->Current();
1197 while (!it.done()) {
1198 if (it.frame()->is_java_script()) {
1199 JavaScriptFrame* frame = it.frame();
1200 if (frame->IsConstructor()) ic_info.is_constructor =
true;
1201 JSFunction*
function = frame->function();
1202 int code_offset = 0;
1203 if (frame->is_interpreted()) {
1204 InterpretedFrame* iframe =
reinterpret_cast<InterpretedFrame*
>(frame);
1205 code_offset = iframe->GetBytecodeOffset();
1207 Code code = frame->unchecked_code();
1208 code_offset =
static_cast<int>(frame->pc() - code->InstructionStart());
1210 CollectFunctionAndOffsetForICStats(
function, function->abstract_code(),
1218 Object* JavaScriptFrame::GetParameter(
int index)
const {
1219 return Memory<Object*>(GetParameterSlot(index));
1222 int JavaScriptFrame::ComputeParametersCount()
const {
1223 return GetNumberOfIncomingArguments();
1226 int JavaScriptBuiltinContinuationFrame::ComputeParametersCount()
const {
1229 DCHECK_EQ(RegisterConfiguration::Default()->GetAllocatableGeneralCode(0),
1230 kJavaScriptCallArgCountRegister.code());
1231 Object* argc_object =
1232 Memory<Object*>(fp() + BuiltinContinuationFrameConstants::kArgCOffset);
1233 return Smi::ToInt(argc_object);
1236 intptr_t JavaScriptBuiltinContinuationFrame::GetSPToFPDelta()
const {
1237 Address height_slot =
1238 fp() + BuiltinContinuationFrameConstants::kFrameSPtoFPDeltaAtDeoptimize;
1239 intptr_t height = Smi::ToInt(Smi(Memory<Address>(height_slot)));
1243 Object* JavaScriptBuiltinContinuationFrame::context()
const {
1244 return Memory<Object*>(
1245 fp() + BuiltinContinuationFrameConstants::kBuiltinContextOffset);
1248 void JavaScriptBuiltinContinuationWithCatchFrame::SetException(
1249 Object* exception) {
1250 Address exception_argument_slot =
1251 fp() + JavaScriptFrameConstants::kLastParameterOffset +
1255 CHECK_EQ(ReadOnlyRoots(isolate()).the_hole_value(),
1256 Memory<Object*>(exception_argument_slot));
1257 Memory<Object*>(exception_argument_slot) = exception;
1260 FrameSummary::JavaScriptFrameSummary::JavaScriptFrameSummary(
1261 Isolate* isolate, Object* receiver, JSFunction*
function,
1262 AbstractCode abstract_code,
int code_offset,
bool is_constructor)
1263 : FrameSummaryBase(isolate, FrameSummary::JAVA_SCRIPT),
1264 receiver_(receiver, isolate),
1265 function_(function, isolate),
1266 abstract_code_(abstract_code, isolate),
1267 code_offset_(code_offset),
1268 is_constructor_(is_constructor) {
1269 DCHECK(abstract_code->IsBytecodeArray() ||
1270 Code::cast(abstract_code)->kind() != Code::OPTIMIZED_FUNCTION);
1273 bool FrameSummary::JavaScriptFrameSummary::is_subject_to_debugging()
const {
1274 return function()->shared()->IsSubjectToDebugging();
1277 int FrameSummary::JavaScriptFrameSummary::SourcePosition()
const {
1278 return abstract_code()->SourcePosition(code_offset());
1281 int FrameSummary::JavaScriptFrameSummary::SourceStatementPosition()
const {
1282 return abstract_code()->SourceStatementPosition(code_offset());
1285 Handle<Object> FrameSummary::JavaScriptFrameSummary::script()
const {
1286 return handle(function_->shared()->script(), isolate());
1289 Handle<String> FrameSummary::JavaScriptFrameSummary::FunctionName()
const {
1290 return JSFunction::GetDebugName(function_);
1293 Handle<Context> FrameSummary::JavaScriptFrameSummary::native_context()
const {
1294 return handle(function_->context()->native_context(), isolate());
1297 FrameSummary::WasmFrameSummary::WasmFrameSummary(
1298 Isolate* isolate, FrameSummary::Kind kind,
1299 Handle<WasmInstanceObject> instance,
bool at_to_number_conversion)
1300 : FrameSummaryBase(isolate, kind),
1301 wasm_instance_(instance),
1302 at_to_number_conversion_(at_to_number_conversion) {}
1304 Handle<Object> FrameSummary::WasmFrameSummary::receiver()
const {
1305 return wasm_instance_->GetIsolate()->global_proxy();
1308 #define WASM_SUMMARY_DISPATCH(type, name) \ 1309 type FrameSummary::WasmFrameSummary::name() const { \ 1310 DCHECK(kind() == Kind::WASM_COMPILED || kind() == Kind::WASM_INTERPRETED); \ 1311 return kind() == Kind::WASM_COMPILED \ 1312 ? static_cast<const WasmCompiledFrameSummary*>(this)->name() \ 1313 : static_cast<const WasmInterpretedFrameSummary*>(this) \ 1317 WASM_SUMMARY_DISPATCH(
uint32_t, function_index)
1318 WASM_SUMMARY_DISPATCH(
int, byte_offset)
1320 #undef WASM_SUMMARY_DISPATCH 1322 int FrameSummary::WasmFrameSummary::SourcePosition()
const {
1323 Handle<WasmModuleObject> module_object(wasm_instance()->module_object(),
1325 return WasmModuleObject::GetSourcePosition(module_object, function_index(),
1327 at_to_number_conversion());
1330 Handle<Script> FrameSummary::WasmFrameSummary::script()
const {
1331 return handle(wasm_instance()->module_object()->script(),
1332 wasm_instance()->GetIsolate());
1335 Handle<String> FrameSummary::WasmFrameSummary::FunctionName()
const {
1336 Handle<WasmModuleObject> module_object(wasm_instance()->module_object(),
1338 return WasmModuleObject::GetFunctionName(isolate(), module_object,
1342 Handle<Context> FrameSummary::WasmFrameSummary::native_context()
const {
1343 return handle(wasm_instance()->native_context(), isolate());
1346 FrameSummary::WasmCompiledFrameSummary::WasmCompiledFrameSummary(
1347 Isolate* isolate, Handle<WasmInstanceObject> instance, wasm::WasmCode* code,
1348 int code_offset,
bool at_to_number_conversion)
1349 : WasmFrameSummary(isolate, WASM_COMPILED, instance,
1350 at_to_number_conversion),
1352 code_offset_(code_offset) {}
1354 uint32_t FrameSummary::WasmCompiledFrameSummary::function_index()
const {
1355 return code()->index();
1358 int FrameSummary::WasmCompiledFrameSummary::GetWasmSourcePosition(
1359 const wasm::WasmCode* code,
int offset) {
1363 for (SourcePositionTableIterator iterator(code->source_positions());
1364 !iterator.done() && iterator.code_offset() <= offset;
1365 iterator.Advance()) {
1366 position = iterator.source_position().ScriptOffset();
1371 int FrameSummary::WasmCompiledFrameSummary::byte_offset()
const {
1372 return GetWasmSourcePosition(code_, code_offset());
1375 FrameSummary::WasmInterpretedFrameSummary::WasmInterpretedFrameSummary(
1376 Isolate* isolate, Handle<WasmInstanceObject> instance,
1377 uint32_t function_index,
int byte_offset)
1378 : WasmFrameSummary(isolate, WASM_INTERPRETED, instance, false),
1379 function_index_(function_index),
1380 byte_offset_(byte_offset) {}
1382 FrameSummary::~FrameSummary() {
1383 #define FRAME_SUMMARY_DESTR(kind, type, field, desc) \ 1387 switch (base_.kind()) {
1388 FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_DESTR)
1392 #undef FRAME_SUMMARY_DESTR 1395 FrameSummary FrameSummary::GetTop(
const StandardFrame* frame) {
1396 std::vector<FrameSummary> frames;
1397 frame->Summarize(&frames);
1398 DCHECK_LT(0, frames.size());
1399 return frames.back();
1402 FrameSummary FrameSummary::GetBottom(
const StandardFrame* frame) {
1403 return Get(frame, 0);
1406 FrameSummary FrameSummary::GetSingle(
const StandardFrame* frame) {
1407 std::vector<FrameSummary> frames;
1408 frame->Summarize(&frames);
1409 DCHECK_EQ(1, frames.size());
1410 return frames.front();
1413 FrameSummary FrameSummary::Get(
const StandardFrame* frame,
int index) {
1414 DCHECK_LE(0, index);
1415 std::vector<FrameSummary> frames;
1416 frame->Summarize(&frames);
1417 DCHECK_GT(frames.size(), index);
1418 return frames[index];
1421 #define FRAME_SUMMARY_DISPATCH(ret, name) \ 1422 ret FrameSummary::name() const { \ 1423 switch (base_.kind()) { \ 1425 return java_script_summary_.name(); \ 1426 case WASM_COMPILED: \ 1427 return wasm_compiled_summary_.name(); \ 1428 case WASM_INTERPRETED: \ 1429 return wasm_interpreted_summary_.name(); \ 1436 FRAME_SUMMARY_DISPATCH(Handle<Object>, receiver)
1437 FRAME_SUMMARY_DISPATCH(
int, code_offset)
1438 FRAME_SUMMARY_DISPATCH(
bool, is_constructor)
1439 FRAME_SUMMARY_DISPATCH(
bool, is_subject_to_debugging)
1440 FRAME_SUMMARY_DISPATCH(Handle<Object>, script)
1441 FRAME_SUMMARY_DISPATCH(
int, SourcePosition)
1442 FRAME_SUMMARY_DISPATCH(
int, SourceStatementPosition)
1443 FRAME_SUMMARY_DISPATCH(Handle<String>, FunctionName)
1444 FRAME_SUMMARY_DISPATCH(Handle<Context>, native_context)
1446 #undef FRAME_SUMMARY_DISPATCH 1448 void OptimizedFrame::Summarize(std::vector<FrameSummary>* frames)
const {
1449 DCHECK(frames->empty());
1450 DCHECK(is_optimized());
1454 Code code = LookupCode();
1455 if (code->kind() == Code::BUILTIN) {
1456 return JavaScriptFrame::Summarize(frames);
1459 int deopt_index = Safepoint::kNoDeoptimizationIndex;
1460 DeoptimizationData
const data = GetDeoptimizationData(&deopt_index);
1461 if (deopt_index == Safepoint::kNoDeoptimizationIndex) {
1462 CHECK(data.is_null());
1463 FATAL(
"Missing deoptimization information for OptimizedFrame::Summarize.");
1469 TranslatedState translated(
this);
1470 translated.Prepare(fp());
1474 bool is_constructor = IsConstructor();
1475 for (
auto it = translated.begin(); it != translated.end(); it++) {
1476 if (it->kind() == TranslatedFrame::kInterpretedFunction ||
1477 it->kind() == TranslatedFrame::kJavaScriptBuiltinContinuation ||
1479 TranslatedFrame::kJavaScriptBuiltinContinuationWithCatch) {
1480 Handle<SharedFunctionInfo> shared_info = it->shared_info();
1484 TranslatedFrame::iterator translated_values = it->begin();
1487 Handle<JSFunction>
function =
1488 Handle<JSFunction>::cast(translated_values->GetValue());
1489 translated_values++;
1492 Handle<Object> receiver = translated_values->GetValue();
1493 translated_values++;
1497 Handle<AbstractCode> abstract_code;
1498 unsigned code_offset;
1499 if (it->kind() == TranslatedFrame::kJavaScriptBuiltinContinuation ||
1501 TranslatedFrame::kJavaScriptBuiltinContinuationWithCatch) {
1504 handle(AbstractCode::cast(isolate()->builtins()->builtin(
1505 Builtins::GetBuiltinFromBailoutId(it->node_id()))),
1508 DCHECK_EQ(it->kind(), TranslatedFrame::kInterpretedFunction);
1509 code_offset = it->node_id().ToInt();
1510 abstract_code = handle(shared_info->abstract_code(), isolate());
1514 FrameSummary::JavaScriptFrameSummary summary(isolate(), *receiver,
1515 *
function, *abstract_code,
1516 code_offset, is_constructor);
1517 frames->push_back(summary);
1518 is_constructor =
false;
1519 }
else if (it->kind() == TranslatedFrame::kConstructStub) {
1521 DCHECK(!is_constructor);
1522 is_constructor =
true;
1528 int OptimizedFrame::LookupExceptionHandlerInTable(
1529 int* stack_slots, HandlerTable::CatchPrediction* prediction) {
1533 DCHECK_NULL(prediction);
1534 Code code = LookupCode();
1535 HandlerTable table(code);
1536 int pc_offset =
static_cast<int>(pc() - code->InstructionStart());
1537 if (stack_slots) *stack_slots = code->stack_slots();
1542 if (code->kind() == Code::OPTIMIZED_FUNCTION &&
1543 code->marked_for_deoptimization()) {
1544 SafepointTable safepoints(code);
1545 pc_offset = safepoints.find_return_pc(pc_offset);
1547 return table.LookupReturn(pc_offset);
1550 DeoptimizationData OptimizedFrame::GetDeoptimizationData(
1551 int* deopt_index)
const {
1552 DCHECK(is_optimized());
1554 JSFunction* opt_function =
function();
1555 Code code = opt_function->code();
1560 if (!code->contains(pc())) {
1561 code = isolate()->heap()->GcSafeFindCodeForInnerPointer(pc());
1563 DCHECK(!code.is_null());
1564 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
1566 SafepointEntry safepoint_entry = code->GetSafepointEntry(pc());
1567 *deopt_index = safepoint_entry.deoptimization_index();
1568 if (*deopt_index != Safepoint::kNoDeoptimizationIndex) {
1569 return DeoptimizationData::cast(code->deoptimization_data());
1571 return DeoptimizationData();
1574 Object* OptimizedFrame::receiver()
const {
1575 Code code = LookupCode();
1576 if (code->kind() == Code::BUILTIN) {
1577 Address argc_ptr = fp() + OptimizedBuiltinFrameConstants::kArgCOffset;
1578 intptr_t argc = *
reinterpret_cast<intptr_t*
>(argc_ptr);
1579 intptr_t args_size =
1580 (StandardFrameConstants::kFixedSlotCountAboveFp + argc) * kPointerSize;
1581 Address receiver_ptr = fp() + args_size;
1582 return *ObjectSlot(receiver_ptr);
1584 return JavaScriptFrame::receiver();
1588 void OptimizedFrame::GetFunctions(
1589 std::vector<SharedFunctionInfo*>* functions)
const {
1590 DCHECK(functions->empty());
1591 DCHECK(is_optimized());
1595 Code code = LookupCode();
1596 if (code->kind() == Code::BUILTIN) {
1597 return JavaScriptFrame::GetFunctions(functions);
1600 DisallowHeapAllocation no_gc;
1601 int deopt_index = Safepoint::kNoDeoptimizationIndex;
1602 DeoptimizationData
const data = GetDeoptimizationData(&deopt_index);
1603 DCHECK(!data.is_null());
1604 DCHECK_NE(Safepoint::kNoDeoptimizationIndex, deopt_index);
1605 FixedArray
const literal_array = data->LiteralArray();
1607 TranslationIterator it(data->TranslationByteArray(),
1608 data->TranslationIndex(deopt_index)->value());
1609 Translation::Opcode opcode =
static_cast<Translation::Opcode
>(it.Next());
1610 DCHECK_EQ(Translation::BEGIN, opcode);
1612 int jsframe_count = it.Next();
1617 while (jsframe_count != 0) {
1618 opcode =
static_cast<Translation::Opcode
>(it.Next());
1619 if (opcode == Translation::INTERPRETED_FRAME ||
1620 opcode == Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME ||
1622 Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME) {
1627 Object* shared = literal_array->get(it.Next());
1628 functions->push_back(SharedFunctionInfo::cast(shared));
1631 it.Skip(Translation::NumberOfOperandsFor(opcode) - 2);
1634 it.Skip(Translation::NumberOfOperandsFor(opcode));
1640 int OptimizedFrame::StackSlotOffsetRelativeToFp(
int slot_index) {
1641 return StandardFrameConstants::kCallerSPOffset -
1642 ((slot_index + 1) * kPointerSize);
1646 Object* OptimizedFrame::StackSlotAt(
int index)
const {
1647 return Memory<Object*>(fp() + StackSlotOffsetRelativeToFp(index));
1650 int InterpretedFrame::position()
const {
1651 AbstractCode code = AbstractCode::cast(GetBytecodeArray());
1652 int code_offset = GetBytecodeOffset();
1653 return code->SourcePosition(code_offset);
1656 int InterpretedFrame::LookupExceptionHandlerInTable(
1657 int* context_register, HandlerTable::CatchPrediction* prediction) {
1658 HandlerTable table(GetBytecodeArray());
1659 return table.LookupRange(GetBytecodeOffset(), context_register, prediction);
1662 int InterpretedFrame::GetBytecodeOffset()
const {
1663 const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
1665 InterpreterFrameConstants::kBytecodeOffsetFromFp,
1666 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1667 int raw_offset = Smi::ToInt(GetExpression(index));
1668 return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
1671 int InterpretedFrame::GetBytecodeOffset(Address fp) {
1672 const int offset = InterpreterFrameConstants::kExpressionsOffset;
1673 const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
1675 InterpreterFrameConstants::kBytecodeOffsetFromFp,
1676 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1677 Address expression_offset = fp + offset - index * kPointerSize;
1678 int raw_offset = Smi::ToInt(Memory<Object*>(expression_offset));
1679 return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
1682 void InterpretedFrame::PatchBytecodeOffset(
int new_offset) {
1683 const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
1685 InterpreterFrameConstants::kBytecodeOffsetFromFp,
1686 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1687 int raw_offset = new_offset + BytecodeArray::kHeaderSize - kHeapObjectTag;
1688 SetExpression(index, Smi::FromInt(raw_offset));
1691 BytecodeArray InterpretedFrame::GetBytecodeArray()
const {
1692 const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
1694 InterpreterFrameConstants::kBytecodeArrayFromFp,
1695 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1696 return BytecodeArray::cast(GetExpression(index));
1699 void InterpretedFrame::PatchBytecodeArray(BytecodeArray bytecode_array) {
1700 const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
1702 InterpreterFrameConstants::kBytecodeArrayFromFp,
1703 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1704 SetExpression(index, bytecode_array);
1707 Object* InterpretedFrame::ReadInterpreterRegister(
int register_index)
const {
1708 const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
1710 InterpreterFrameConstants::kRegisterFileFromFp,
1711 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1712 return GetExpression(index + register_index);
1715 void InterpretedFrame::WriteInterpreterRegister(
int register_index,
1717 const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
1719 InterpreterFrameConstants::kRegisterFileFromFp,
1720 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize);
1721 return SetExpression(index + register_index, value);
1724 void InterpretedFrame::Summarize(std::vector<FrameSummary>* functions)
const {
1725 DCHECK(functions->empty());
1726 AbstractCode abstract_code = AbstractCode::cast(GetBytecodeArray());
1727 FrameSummary::JavaScriptFrameSummary summary(
1728 isolate(), receiver(),
function(), abstract_code, GetBytecodeOffset(),
1730 functions->push_back(summary);
1733 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments()
const {
1734 return Smi::ToInt(GetExpression(0));
1737 Code ArgumentsAdaptorFrame::unchecked_code()
const {
1738 return isolate()->builtins()->builtin(
1739 Builtins::kArgumentsAdaptorTrampoline);
1742 int BuiltinFrame::GetNumberOfIncomingArguments()
const {
1743 return Smi::ToInt(GetExpression(0));
1746 void BuiltinFrame::PrintFrameKind(StringStream* accumulator)
const {
1747 accumulator->Add(
"builtin frame: ");
1750 Address InternalFrame::GetCallerStackPointer()
const {
1753 return fp() + StandardFrameConstants::kCallerSPOffset;
1756 Code InternalFrame::unchecked_code()
const { UNREACHABLE(); }
1758 void WasmCompiledFrame::Print(StringStream* accumulator, PrintMode mode,
1760 PrintIndex(accumulator, mode, index);
1761 accumulator->Add(
"WASM [");
1762 accumulator->PrintName(script()->name());
1763 Address instruction_start = isolate()
1767 ->instruction_start();
1768 Vector<const uint8_t> raw_func_name =
1769 module_object()->GetRawFunctionName(function_index());
1770 const int kMaxPrintedFunctionName = 64;
1771 char func_name[kMaxPrintedFunctionName + 1];
1772 int func_name_len = std::min(kMaxPrintedFunctionName, raw_func_name.length());
1773 memcpy(func_name, raw_func_name.start(), func_name_len);
1774 func_name[func_name_len] =
'\0';
1775 int pos = position();
1776 const wasm::WasmModule* module = wasm_instance()->module_object()->module();
1777 int func_index = function_index();
1778 int func_code_offset = module->functions[func_index].code.offset();
1779 accumulator->Add(
"], function #%u ('%s'), pc=%p (+0x%x), pos=%d (+%d)\n",
1780 func_index, func_name, reinterpret_cast<void*>(pc()),
1781 static_cast<int>(pc() - instruction_start), pos,
1782 pos - func_code_offset);
1783 if (mode != OVERVIEW) accumulator->Add(
"\n");
1786 Code WasmCompiledFrame::unchecked_code()
const {
1787 return isolate()->FindCodeObject(pc());
1790 void WasmCompiledFrame::Iterate(RootVisitor* v)
const {
1791 IterateCompiledFrame(v);
1794 Address WasmCompiledFrame::GetCallerStackPointer()
const {
1795 return fp() + ExitFrameConstants::kCallerSPOffset;
1798 wasm::WasmCode* WasmCompiledFrame::wasm_code()
const {
1799 return isolate()->wasm_engine()->code_manager()->LookupCode(pc());
1802 WasmInstanceObject* WasmCompiledFrame::wasm_instance()
const {
1803 const int offset = WasmCompiledFrameConstants::kWasmInstanceOffset;
1804 Object* instance = Memory<Object*>(fp() + offset);
1805 return WasmInstanceObject::cast(instance);
1808 WasmModuleObject* WasmCompiledFrame::module_object()
const {
1809 return wasm_instance()->module_object();
1812 uint32_t WasmCompiledFrame::function_index()
const {
1813 return FrameSummary::GetSingle(
this).AsWasmCompiled().function_index();
1816 Script* WasmCompiledFrame::script()
const {
return module_object()->script(); }
1818 int WasmCompiledFrame::position()
const {
1819 return FrameSummary::GetSingle(
this).SourcePosition();
1822 void WasmCompiledFrame::Summarize(std::vector<FrameSummary>* functions)
const {
1823 DCHECK(functions->empty());
1824 wasm::WasmCode* code = wasm_code();
1825 int offset =
static_cast<int>(pc() - code->instruction_start());
1826 Handle<WasmInstanceObject> instance(wasm_instance(), isolate());
1827 FrameSummary::WasmCompiledFrameSummary summary(
1828 isolate(), instance, code, offset, at_to_number_conversion());
1829 functions->push_back(summary);
1832 bool WasmCompiledFrame::at_to_number_conversion()
const {
1835 wasm::WasmCode* code =
1836 callee_pc() != kNullAddress
1837 ? isolate()->wasm_engine()->code_manager()->LookupCode(callee_pc())
1839 if (!code || code->kind() != wasm::WasmCode::kWasmToJsWrapper)
return false;
1840 int offset =
static_cast<int>(callee_pc() - code->instruction_start());
1841 int pos = FrameSummary::WasmCompiledFrameSummary::GetWasmSourcePosition(
1843 DCHECK(pos == 0 || pos == 1);
1848 int WasmCompiledFrame::LookupExceptionHandlerInTable(
int* stack_slots) {
1849 DCHECK_NOT_NULL(stack_slots);
1850 wasm::WasmCode* code =
1851 isolate()->wasm_engine()->code_manager()->LookupCode(pc());
1852 if (!code->IsAnonymous() && code->handler_table_offset() > 0) {
1853 HandlerTable table(code->instruction_start(), code->handler_table_offset());
1854 int pc_offset =
static_cast<int>(pc() - code->instruction_start());
1855 *stack_slots =
static_cast<int>(code->stack_slots());
1856 return table.LookupReturn(pc_offset);
1861 void WasmInterpreterEntryFrame::Iterate(RootVisitor* v)
const {
1862 IterateCompiledFrame(v);
1865 void WasmInterpreterEntryFrame::Print(StringStream* accumulator, PrintMode mode,
1867 PrintIndex(accumulator, mode, index);
1868 accumulator->Add(
"WASM INTERPRETER ENTRY [");
1869 Script* script = this->script();
1870 accumulator->PrintName(script->name());
1871 accumulator->Add(
"]");
1872 if (mode != OVERVIEW) accumulator->Add(
"\n");
1875 void WasmInterpreterEntryFrame::Summarize(
1876 std::vector<FrameSummary>* functions)
const {
1877 Handle<WasmInstanceObject> instance(wasm_instance(), isolate());
1878 std::vector<std::pair<uint32_t, int>> interpreted_stack =
1879 instance->debug_info()->GetInterpretedStack(fp());
1881 for (
auto& e : interpreted_stack) {
1882 FrameSummary::WasmInterpretedFrameSummary summary(isolate(), instance,
1884 functions->push_back(summary);
1888 Code WasmInterpreterEntryFrame::unchecked_code()
const { UNREACHABLE(); }
1890 WasmInstanceObject* WasmInterpreterEntryFrame::wasm_instance()
const {
1891 const int offset = WasmCompiledFrameConstants::kWasmInstanceOffset;
1892 Object* instance = Memory<Object*>(fp() + offset);
1893 return WasmInstanceObject::cast(instance);
1896 WasmDebugInfo* WasmInterpreterEntryFrame::debug_info()
const {
1897 return wasm_instance()->debug_info();
1900 WasmModuleObject* WasmInterpreterEntryFrame::module_object()
const {
1901 return wasm_instance()->module_object();
1904 Script* WasmInterpreterEntryFrame::script()
const {
1905 return module_object()->script();
1908 int WasmInterpreterEntryFrame::position()
const {
1909 return FrameSummary::GetBottom(
this).AsWasmInterpreted().SourcePosition();
1912 Object* WasmInterpreterEntryFrame::context()
const {
1913 return wasm_instance()->native_context();
1916 Address WasmInterpreterEntryFrame::GetCallerStackPointer()
const {
1917 return fp() + ExitFrameConstants::kCallerSPOffset;
1920 Code WasmCompileLazyFrame::unchecked_code()
const {
return Code(); }
1922 WasmInstanceObject* WasmCompileLazyFrame::wasm_instance()
const {
1923 return WasmInstanceObject::cast(*wasm_instance_slot());
1926 ObjectSlot WasmCompileLazyFrame::wasm_instance_slot()
const {
1927 const int offset = WasmCompileLazyFrameConstants::kWasmInstanceOffset;
1928 return ObjectSlot(&Memory<Object*>(fp() + offset));
1931 void WasmCompileLazyFrame::Iterate(RootVisitor* v)
const {
1932 const int header_size = WasmCompileLazyFrameConstants::kFixedFrameSizeFromFp;
1933 ObjectSlot base(&Memory<Object*>(sp()));
1934 ObjectSlot limit(&Memory<Object*>(fp() - header_size));
1935 v->VisitRootPointers(Root::kTop,
nullptr, base, limit);
1936 v->VisitRootPointer(Root::kTop,
nullptr, wasm_instance_slot());
1939 Address WasmCompileLazyFrame::GetCallerStackPointer()
const {
1940 return fp() + WasmCompileLazyFrameConstants::kCallerSPOffset;
1945 void PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo* shared,
1947 if (FLAG_max_stack_trace_source_length != 0 && !code.is_null()) {
1948 std::ostringstream os;
1949 os <<
"--------- s o u r c e c o d e ---------\n" 1950 << SourceCodeOf(shared, FLAG_max_stack_trace_source_length)
1951 <<
"\n-----------------------------------------\n";
1952 accumulator->Add(os.str().c_str());
1960 void JavaScriptFrame::Print(StringStream* accumulator,
1963 DisallowHeapAllocation no_gc;
1964 Object* receiver = this->receiver();
1965 JSFunction*
function = this->
function();
1967 accumulator->PrintSecurityTokenIfChanged(
function);
1968 PrintIndex(accumulator, mode, index);
1969 PrintFrameKind(accumulator);
1971 if (IsConstructor()) accumulator->Add(
"new ");
1972 accumulator->PrintFunction(
function, receiver, &code);
1973 accumulator->Add(
" [%p]",
function);
1979 SharedFunctionInfo* shared =
function->shared();
1980 ScopeInfo scope_info = shared->scope_info();
1981 Object* script_obj = shared->script();
1982 if (script_obj->IsScript()) {
1983 Script* script = Script::cast(script_obj);
1984 accumulator->Add(
" [");
1985 accumulator->PrintName(script->name());
1987 if (is_interpreted()) {
1988 const InterpretedFrame* iframe =
1989 reinterpret_cast<const InterpretedFrame*
>(
this);
1990 BytecodeArray bytecodes = iframe->GetBytecodeArray();
1991 int offset = iframe->GetBytecodeOffset();
1992 int source_pos = AbstractCode::cast(bytecodes)->SourcePosition(offset);
1993 int line = script->GetLineNumber(source_pos) + 1;
1994 accumulator->Add(
":%d] [bytecode=%p offset=%d]", line,
1995 reinterpret_cast<void*>(bytecodes.ptr()), offset);
1997 int function_start_pos = shared->StartPosition();
1998 int line = script->GetLineNumber(function_start_pos) + 1;
1999 accumulator->Add(
":~%d] [pc=%p]", line, reinterpret_cast<void*>(pc()));
2003 accumulator->Add(
"(this=%o", receiver);
2006 int parameters_count = ComputeParametersCount();
2007 for (
int i = 0;
i < parameters_count;
i++) {
2008 accumulator->Add(
",");
2009 accumulator->Add(
"%o", GetParameter(
i));
2012 accumulator->Add(
")");
2013 if (mode == OVERVIEW) {
2014 accumulator->Add(
"\n");
2017 if (is_optimized()) {
2018 accumulator->Add(
" {\n// optimized frame\n");
2019 PrintFunctionSource(accumulator, shared, code);
2020 accumulator->Add(
"}\n");
2023 accumulator->Add(
" {\n");
2026 int heap_locals_count = scope_info->ContextLocalCount();
2027 int expressions_count = ComputeExpressionsCount();
2031 if (this->context() !=
nullptr && this->context()->IsContext()) {
2032 context = Context::cast(this->context());
2033 while (context->IsWithContext()) {
2034 context = context->previous();
2035 DCHECK(!context.is_null());
2040 if (heap_locals_count > 0) {
2041 accumulator->Add(
" // heap-allocated locals\n");
2043 for (
int i = 0;
i < heap_locals_count;
i++) {
2044 accumulator->Add(
" var ");
2045 accumulator->PrintName(scope_info->ContextLocalName(
i));
2046 accumulator->Add(
" = ");
2047 if (!context.is_null()) {
2048 int index = Context::MIN_CONTEXT_SLOTS +
i;
2049 if (index < context->length()) {
2050 accumulator->Add(
"%o", context->get(index));
2053 "// warning: missing context slot - inconsistent frame?");
2056 accumulator->Add(
"// warning: no context found - inconsistent frame?");
2058 accumulator->Add(
"\n");
2062 if (0 < expressions_count) {
2063 accumulator->Add(
" // expression stack (top to bottom)\n");
2065 for (
int i = expressions_count - 1;
i >= 0;
i--) {
2066 accumulator->Add(
" [%02d] : %o\n",
i, GetExpression(
i));
2069 PrintFunctionSource(accumulator, shared, code);
2071 accumulator->Add(
"}\n\n");
2075 void ArgumentsAdaptorFrame::Print(StringStream* accumulator,
2078 int actual = ComputeParametersCount();
2080 JSFunction*
function = this->
function();
2081 expected =
function->shared()->internal_formal_parameter_count();
2083 PrintIndex(accumulator, mode, index);
2084 accumulator->Add(
"arguments adaptor frame: %d->%d", actual, expected);
2085 if (mode == OVERVIEW) {
2086 accumulator->Add(
"\n");
2089 accumulator->Add(
" {\n");
2092 if (actual > 0) accumulator->Add(
" // actual arguments\n");
2093 for (
int i = 0;
i < actual;
i++) {
2094 accumulator->Add(
" [%02d] : %o",
i, GetParameter(
i));
2095 if (expected != -1 &&
i >= expected) {
2096 accumulator->Add(
" // not passed to callee");
2098 accumulator->Add(
"\n");
2101 accumulator->Add(
"}\n\n");
2104 void EntryFrame::Iterate(RootVisitor* v)
const {
2105 IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
2108 void StandardFrame::IterateExpressions(RootVisitor* v)
const {
2109 const int offset = StandardFrameConstants::kLastObjectOffset;
2110 ObjectSlot base(&Memory<Object*>(sp()));
2111 ObjectSlot limit(&Memory<Object*>(fp() + offset) + 1);
2112 v->VisitRootPointers(Root::kTop,
nullptr, base, limit);
2115 void JavaScriptFrame::Iterate(RootVisitor* v)
const {
2116 IterateExpressions(v);
2117 IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
2120 void InternalFrame::Iterate(RootVisitor* v)
const {
2121 Code code = LookupCode();
2122 IteratePc(v, pc_address(), constant_pool_address(), code);
2129 if (code->has_tagged_params()) IterateExpressions(v);
2136 uint32_t PcAddressForHashing(Isolate* isolate, Address address) {
2137 if (InstructionStream::PcIsOffHeap(isolate, address)) {
2139 return EmbeddedData::FromBlob(isolate).AddressForHashing(address);
2141 return ObjectAddressForHashing(reinterpret_cast<void*>(address));
2146 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
2147 InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
2148 isolate_->counters()->pc_to_code()->Increment();
2149 DCHECK(base::bits::IsPowerOfTwo(kInnerPointerToCodeCacheSize));
2151 ComputeUnseededHash(PcAddressForHashing(isolate_, inner_pointer));
2152 uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
2153 InnerPointerToCodeCacheEntry* entry = cache(index);
2154 if (entry->inner_pointer == inner_pointer) {
2155 isolate_->counters()->pc_to_code_cached()->Increment();
2156 DCHECK(entry->code ==
2157 isolate_->heap()->GcSafeFindCodeForInnerPointer(inner_pointer));
2164 isolate_->heap()->GcSafeFindCodeForInnerPointer(inner_pointer);
2165 entry->safepoint_entry.Reset();
2166 entry->inner_pointer = inner_pointer;