8 #include "src/handles.h" 9 #include "src/objects.h" 10 #include "src/objects/code.h" 11 #include "src/safepoint-table.h" 22 class ExternalCallbackScope;
23 class InnerPointerToCodeCache;
27 class StackFrameIteratorBase;
31 class WasmInstanceObject;
32 class WasmModuleObject;
36 static const int kNextOffset = 0 * kPointerSize;
37 static const int kPaddingOffset = 1 * kPointerSize;
39 static const int kSize = kPaddingOffset + kPointerSize;
40 static const int kSlotCount = kSize >> kPointerSizeLog2;
58 #define STACK_FRAME_TYPE_LIST(V) \ 59 V(ENTRY, EntryFrame) \ 60 V(CONSTRUCT_ENTRY, ConstructEntryFrame) \ 62 V(OPTIMIZED, OptimizedFrame) \ 63 V(WASM_COMPILED, WasmCompiledFrame) \ 64 V(WASM_TO_JS, WasmToJsFrame) \ 65 V(JS_TO_WASM, JsToWasmFrame) \ 66 V(WASM_INTERPRETER_ENTRY, WasmInterpreterEntryFrame) \ 67 V(C_WASM_ENTRY, CWasmEntryFrame) \ 68 V(WASM_COMPILE_LAZY, WasmCompileLazyFrame) \ 69 V(INTERPRETED, InterpretedFrame) \ 71 V(BUILTIN_CONTINUATION, BuiltinContinuationFrame) \ 72 V(JAVA_SCRIPT_BUILTIN_CONTINUATION, JavaScriptBuiltinContinuationFrame) \ 73 V(JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH, \ 74 JavaScriptBuiltinContinuationWithCatchFrame) \ 75 V(INTERNAL, InternalFrame) \ 76 V(CONSTRUCT, ConstructFrame) \ 77 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame) \ 78 V(BUILTIN, BuiltinFrame) \ 79 V(BUILTIN_EXIT, BuiltinExitFrame) \ 80 V(NATIVE, NativeFrame) 85 #define DECLARE_TYPE(type, ignore) type, 88 STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
101 ID_MIN_VALUE = kMinInt,
102 ID_MAX_VALUE = kMaxInt,
111 INNER_JSENTRY_FRAME = (0 << kSmiTagSize) | kSmiTag,
112 OUTERMOST_JSENTRY_FRAME = (1 << kSmiTagSize) | kSmiTag
114 STATIC_ASSERT((INNER_JSENTRY_FRAME & kHeapObjectTagMask) != kHeapObjectTag);
115 STATIC_ASSERT((OUTERMOST_JSENTRY_FRAME & kHeapObjectTagMask) !=
122 Address* callee_pc_address =
nullptr;
123 Address* constant_pool_address =
nullptr;
136 static int32_t TypeToMarker(Type
type) {
138 return (
type << kSmiTagSize) | kSmiTag;
145 static Type MarkerToType(intptr_t marker) {
146 DCHECK(IsTypeMarker(marker));
147 return static_cast<Type>(marker >> kSmiTagSize);
155 static bool IsTypeMarker(intptr_t function_or_marker) {
156 return (function_or_marker & kSmiTagMask) == kSmiTag;
161 StackFrame(
const StackFrame& original) {
162 this->state_ = original.state_;
163 this->iterator_ =
nullptr;
164 this->isolate_ = original.isolate_;
168 bool is_entry()
const {
return type() == ENTRY; }
169 bool is_construct_entry()
const {
return type() == CONSTRUCT_ENTRY; }
170 bool is_exit()
const {
return type() == EXIT; }
171 bool is_optimized()
const {
return type() == OPTIMIZED; }
172 bool is_interpreted()
const {
return type() == INTERPRETED; }
173 bool is_wasm_compiled()
const {
return type() == WASM_COMPILED; }
174 bool is_wasm_compile_lazy()
const {
return type() == WASM_COMPILE_LAZY; }
175 bool is_wasm_to_js()
const {
return type() == WASM_TO_JS; }
176 bool is_js_to_wasm()
const {
return type() == JS_TO_WASM; }
177 bool is_wasm_interpreter_entry()
const {
178 return type() == WASM_INTERPRETER_ENTRY;
180 bool is_arguments_adaptor()
const {
return type() == ARGUMENTS_ADAPTOR; }
181 bool is_builtin()
const {
return type() == BUILTIN; }
182 bool is_internal()
const {
return type() == INTERNAL; }
183 bool is_builtin_continuation()
const {
184 return type() == BUILTIN_CONTINUATION;
186 bool is_java_script_builtin_continuation()
const {
187 return type() == JAVA_SCRIPT_BUILTIN_CONTINUATION;
189 bool is_java_script_builtin_with_catch_continuation()
const {
190 return type() == JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH;
192 bool is_construct()
const {
return type() == CONSTRUCT; }
193 bool is_builtin_exit()
const {
return type() == BUILTIN_EXIT; }
194 virtual bool is_standard()
const {
return false; }
196 bool is_java_script()
const {
197 Type type = this->type();
198 return (type == OPTIMIZED) || (type == INTERPRETED) || (type == BUILTIN) ||
199 (type == JAVA_SCRIPT_BUILTIN_CONTINUATION) ||
200 (type == JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH);
202 bool is_wasm()
const {
203 Type type = this->type();
204 return type == WASM_COMPILED || type == WASM_INTERPRETER_ENTRY;
208 Address sp()
const {
return state_.sp; }
209 Address fp()
const {
return state_.fp; }
210 Address callee_pc()
const {
211 return state_.callee_pc_address ? *state_.callee_pc_address : kNullAddress;
213 Address caller_sp()
const {
return GetCallerStackPointer(); }
218 Address UnpaddedFP()
const;
220 Address pc()
const {
return *pc_address(); }
221 void set_pc(Address pc) { *pc_address() = pc; }
223 Address constant_pool()
const {
return *constant_pool_address(); }
224 void set_constant_pool(Address constant_pool) {
225 *constant_pool_address() = constant_pool;
228 Address* pc_address()
const {
return state_.pc_address; }
230 Address* constant_pool_address()
const {
231 return state_.constant_pool_address;
235 Id id()
const {
return static_cast<Id
>(caller_sp()); }
238 inline StackHandler* top_handler()
const;
241 virtual Type type()
const = 0;
245 virtual Code unchecked_code()
const = 0;
248 Code LookupCode()
const;
250 virtual void Iterate(RootVisitor* v)
const = 0;
251 static void IteratePc(RootVisitor* v, Address* pc_address,
252 Address* constant_pool_address, Code holder);
257 static void SetReturnAddressLocationResolver(
258 ReturnAddressLocationResolver resolver);
261 static inline Address* ResolveReturnAddressLocation(Address* pc_address);
264 enum PrintMode { OVERVIEW, DETAILS };
265 virtual void Print(StringStream* accumulator, PrintMode mode,
268 Isolate* isolate()
const {
return isolate_; }
270 void operator=(
const StackFrame& original) =
delete;
273 inline explicit StackFrame(StackFrameIteratorBase* iterator);
274 virtual ~StackFrame() =
default;
277 virtual Address GetCallerStackPointer()
const = 0;
280 static Type ComputeType(
const StackFrameIteratorBase* iterator, State* state);
283 bool can_access_heap_objects()
const;
287 const StackFrameIteratorBase* iterator_;
291 static ReturnAddressLocationResolver return_address_location_resolver_;
294 virtual void ComputeCallerState(State* state)
const = 0;
297 virtual Type GetCallerState(State* state)
const;
299 static const intptr_t kIsolateTag = 1;
301 friend class StackFrameIterator;
302 friend class StackFrameIteratorBase;
303 friend class StackHandlerIterator;
304 friend class SafeStackFrameIterator;
309 Type
type()
const override {
return NATIVE; }
311 Code unchecked_code()
const override;
319 Address GetCallerStackPointer()
const override;
322 void ComputeCallerState(
State* state)
const override;
330 Type
type()
const override {
return ENTRY; }
332 Code unchecked_code()
const override;
338 DCHECK(frame->is_entry());
348 Address GetCallerStackPointer()
const override {
return 0; }
351 void ComputeCallerState(
State* state)
const override;
352 Type GetCallerState(
State* state)
const override;
359 Type
type()
const override {
return CONSTRUCT_ENTRY; }
361 Code unchecked_code()
const override;
364 DCHECK(frame->is_construct_entry());
379 Type
type()
const override {
return EXIT; }
381 Code unchecked_code()
const override;
383 Object*& code_slot()
const;
389 DCHECK(frame->is_exit());
396 static Type GetStateForFramePointer(
Address fp,
State* state);
398 static StackFrame::Type ComputeFrameType(
Address fp);
404 Address GetCallerStackPointer()
const override;
407 void ComputeCallerState(
State* state)
const override;
417 Type
type()
const override {
return BUILTIN_EXIT; }
420 DCHECK(frame->is_builtin_exit());
427 bool IsConstructor()
const;
430 int index)
const override;
436 Object* GetParameter(
int i)
const;
437 int ComputeParametersCount()
const;
439 inline Object* receiver_slot_object()
const;
440 inline Object* argc_slot_object()
const;
441 inline Object* target_slot_object()
const;
442 inline Object* new_target_slot_object()
const;
452 #define FRAME_SUMMARY_VARIANTS(F) \ 453 F(JAVA_SCRIPT, JavaScriptFrameSummary, java_script_summary_, JavaScript) \ 454 F(WASM_COMPILED, WasmCompiledFrameSummary, wasm_compiled_summary_, \ 456 F(WASM_INTERPRETED, WasmInterpretedFrameSummary, wasm_interpreted_summary_, \ 459 #define FRAME_SUMMARY_KIND(kind, type, field, desc) kind, 460 enum Kind { FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_KIND) };
461 #undef FRAME_SUMMARY_KIND 466 : isolate_(isolate), kind_(kind) {}
467 Isolate* isolate()
const {
return isolate_; }
468 Kind kind()
const {
return kind_; }
479 int code_offset,
bool is_constructor);
484 int code_offset()
const {
return code_offset_; }
485 bool is_constructor()
const {
return is_constructor_; }
486 bool is_subject_to_debugging()
const;
488 int SourceStatementPosition()
const;
498 bool is_constructor_;
504 bool at_to_number_conversion);
509 int byte_offset()
const;
510 bool is_constructor()
const {
return false; }
511 bool is_subject_to_debugging()
const {
return true; }
518 bool at_to_number_conversion()
const {
return at_to_number_conversion_; }
522 bool at_to_number_conversion_;
529 bool at_to_number_conversion);
532 int code_offset()
const {
return code_offset_; }
533 int byte_offset()
const;
534 static int GetWasmSourcePosition(
const wasm::WasmCode* code,
int offset);
544 uint32_t function_index,
int byte_offset);
545 uint32_t function_index()
const {
return function_index_; }
546 int code_offset()
const {
return byte_offset_; }
547 int byte_offset()
const {
return byte_offset_; }
554 #undef FRAME_SUMMARY_FIELD 555 #define FRAME_SUMMARY_CONS(kind, type, field, desc) \ 556 FrameSummary(type summ) : field(summ) {} // NOLINT 557 FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CONS)
558 #undef FRAME_SUMMARY_CONS 569 int code_offset()
const;
570 bool is_constructor()
const;
571 bool is_subject_to_debugging()
const;
574 int SourceStatementPosition()
const;
578 #define FRAME_SUMMARY_CAST(kind_, type, field, desc) \ 579 bool Is##desc() const { return base_.kind() == kind_; } \ 580 const type& As##desc() const { \ 581 DCHECK_EQ(base_.kind(), kind_); \ 584 FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CAST)
585 #undef FRAME_SUMMARY_CAST 587 bool IsWasm()
const {
return IsWasmCompiled() || IsWasmInterpreted(); }
588 const WasmFrameSummary& AsWasm()
const {
589 if (IsWasmCompiled())
return AsWasmCompiled();
590 return AsWasmInterpreted();
594 #define FRAME_SUMMARY_FIELD(kind, type, field, desc) type field; 596 FrameSummaryBase base_;
597 FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_FIELD)
604 bool is_standard()
const override {
return true; }
607 virtual Object* receiver()
const;
608 virtual Script* script()
const;
609 virtual Object* context()
const;
610 virtual int position()
const;
613 inline Object* GetExpression(
int index)
const;
614 inline void SetExpression(
int index,
Object* value);
615 int ComputeExpressionsCount()
const;
618 virtual Object* GetParameter(
int index)
const;
619 virtual int ComputeParametersCount()
const;
622 virtual bool IsConstructor()
const;
627 virtual void Summarize(std::vector<FrameSummary>* frames)
const;
630 DCHECK(frame->is_standard());
637 void ComputeCallerState(
State* state)
const override;
640 inline Address caller_fp()
const;
641 inline Address caller_pc()
const;
656 virtual Address GetExpressionAddress(
int n)
const;
660 static inline bool IsArgumentsAdaptorFrame(
Address fp);
664 static inline bool IsConstructFrame(
Address fp);
676 Type
type()
const override = 0;
678 void Summarize(std::vector<FrameSummary>* frames)
const override;
682 Object* unchecked_function()
const;
683 Object* receiver()
const override;
684 Object* context()
const override;
685 Script* script()
const override;
687 inline void set_receiver(
Object* value);
690 inline Address GetParameterSlot(
int index)
const;
691 Object* GetParameter(
int index)
const override;
692 int ComputeParametersCount()
const override;
695 void SetParameterValue(
int index,
Object* value)
const;
698 bool IsConstructor()
const override;
702 bool HasInlinedFrames()
const;
707 inline bool has_adapted_arguments()
const;
714 int index)
const override;
717 Code unchecked_code()
const override;
720 virtual void GetFunctions(std::vector<SharedFunctionInfo*>* functions)
const;
728 virtual int LookupExceptionHandlerInTable(
729 int* data, HandlerTable::CatchPrediction* prediction);
734 static Register constant_pool_pointer_register();
737 DCHECK(frame->is_java_script());
742 int code_offset, FILE* file,
743 bool print_line_number);
745 static void PrintTop(
Isolate* isolate, FILE* file,
bool print_args,
746 bool print_line_number);
748 static void CollectFunctionAndOffsetForICStats(
JSFunction*
function,
751 static void CollectTopFrameForICStats(
Isolate* isolate);
756 Address GetCallerStackPointer()
const override;
758 virtual int GetNumberOfIncomingArguments()
const;
760 virtual void PrintFrameKind(
StringStream* accumulator)
const {}
763 inline Object* function_slot_object()
const;
771 Type
type()
const override {
return STUB; }
777 Code unchecked_code()
const override;
783 int LookupExceptionHandlerInTable(
int* data);
788 Address GetCallerStackPointer()
const override;
790 virtual int GetNumberOfIncomingArguments()
const;
798 Type
type()
const override {
return OPTIMIZED; }
806 void GetFunctions(std::vector<SharedFunctionInfo*>* functions)
const override;
808 void Summarize(std::vector<FrameSummary>* frames)
const override;
811 int LookupExceptionHandlerInTable(
812 int* data, HandlerTable::CatchPrediction* prediction)
override;
816 Object* receiver()
const override;
818 static int StackSlotOffsetRelativeToFp(
int slot_index);
823 int GetNumberOfIncomingArguments()
const override;
828 Object* StackSlotAt(
int index)
const;
834 Type
type()
const override {
return INTERPRETED; }
837 int position()
const override;
840 int LookupExceptionHandlerInTable(
841 int* data, HandlerTable::CatchPrediction* prediction)
override;
844 int GetBytecodeOffset()
const;
848 void PatchBytecodeOffset(
int new_offset);
858 Object* ReadInterpreterRegister(
int register_index)
const;
859 void WriteInterpreterRegister(
int register_index,
Object* value);
862 void Summarize(std::vector<FrameSummary>* frames)
const override;
864 static int GetBytecodeOffset(
Address fp);
867 DCHECK(frame->is_interpreted());
874 Address GetExpressionAddress(
int n)
const override;
886 Type
type()
const override {
return ARGUMENTS_ADAPTOR; }
889 Code unchecked_code()
const override;
892 DCHECK(frame->is_arguments_adaptor());
898 int index)
const override;
903 int GetNumberOfIncomingArguments()
const override;
913 Type
type()
const final {
return BUILTIN; }
916 DCHECK(frame->is_builtin());
923 int GetNumberOfIncomingArguments()
const final;
924 void PrintFrameKind(
StringStream* accumulator)
const override;
932 Type
type()
const override {
return WASM_COMPILED; }
939 int index)
const override;
943 int LookupExceptionHandlerInTable(
int* data);
946 Code unchecked_code()
const override;
952 Script* script()
const override;
953 int position()
const override;
954 bool at_to_number_conversion()
const;
956 void Summarize(std::vector<FrameSummary>* frames)
const override;
959 DCHECK(frame->is_wasm_compiled());
966 Address GetCallerStackPointer()
const override;
975 Type
type()
const override {
return WASM_INTERPRETER_ENTRY; }
982 int index)
const override;
984 void Summarize(std::vector<FrameSummary>* frames)
const override;
987 Code unchecked_code()
const override;
993 Script* script()
const override;
994 int position()
const override;
995 Object* context()
const override;
998 DCHECK(frame->is_wasm_interpreter_entry());
1005 Address GetCallerStackPointer()
const override;
1014 Type
type()
const override {
return WASM_TO_JS; }
1025 Type
type()
const override {
return JS_TO_WASM; }
1036 Type
type()
const override {
return C_WASM_ENTRY; }
1047 Type
type()
const override {
return WASM_COMPILE_LAZY; }
1049 Code unchecked_code()
const override;
1057 DCHECK(frame->is_wasm_compile_lazy());
1064 Address GetCallerStackPointer()
const override;
1072 Type
type()
const override {
return INTERNAL; }
1078 Code unchecked_code()
const override;
1081 DCHECK(frame->is_internal());
1088 Address GetCallerStackPointer()
const override;
1099 Type
type()
const override {
return CONSTRUCT; }
1102 DCHECK(frame->is_construct());
1115 Type
type()
const override {
return BUILTIN_CONTINUATION; }
1118 DCHECK(frame->is_builtin_continuation());
1131 Type
type()
const override {
return JAVA_SCRIPT_BUILTIN_CONTINUATION; }
1134 DCHECK(frame->is_java_script_builtin_continuation());
1138 int ComputeParametersCount()
const override;
1139 intptr_t GetSPToFPDelta()
const;
1141 Object* context()
const override;
1154 Type
type()
const override {
1155 return JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH;
1159 DCHECK(frame->is_java_script_builtin_with_catch_continuation());
1165 void SetException(
Object* exception);
1177 Isolate* isolate()
const {
return isolate_; }
1179 bool done()
const {
return frame_ ==
nullptr; }
1186 #define DECLARE_SINGLETON(ignore, type) type type##_; 1187 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
1188 #undef DECLARE_SINGLETON 1191 const bool can_access_heap_objects_;
1237 bool done()
const {
return iterator_.done(); }
1239 void AdvanceOneFrame() { iterator_.Advance(); }
1253 bool done()
const {
return iterator_.done(); }
1255 void AdvanceOneFrame() { iterator_.Advance(); }
1259 inline bool is_javascript()
const;
1260 inline bool is_wasm()
const;
1278 StackFrame::Type top_frame_type()
const {
return top_frame_type_; }
1281 void AdvanceOneFrame();
1283 bool IsValidStackAddress(
Address addr)
const {
1284 return low_bound_ <= addr && addr <= high_bound_;
1288 bool IsValidExitFrame(
Address fp)
const;
1293 StackFrame::Type top_frame_type_;
1299 #endif // V8_FRAMES_H_