v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
frames.h
Go to the documentation of this file.
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.
4
5#ifndef V8_EXECUTION_FRAMES_H_
6#define V8_EXECUTION_FRAMES_H_
7
9#include "src/base/bounds.h"
13#include "src/common/globals.h"
14#include "src/objects/code.h"
16#include "src/objects/objects.h"
17
18#if V8_ENABLE_WEBASSEMBLY
19#include "src/wasm/stacks.h"
21#endif // V8_ENABLE_WEBASSEMBLY
22
23//
24// Frame inheritance hierarchy (please keep in sync with frame-constants.h):
25// - CommonFrame
26// - CommonFrameWithJSLinkage
27// - JavaScriptFrame (aka StandardFrame)
28// - UnoptimizedJSFrame
29// - InterpretedFrame
30// - BaselineFrame
31// - OptimizedJSFrame
32// - MaglevFrame
33// - TurbofanJSFrame
34// - TypedFrameWithJSLinkage
35// - BuiltinFrame
36// - JavaScriptBuiltinContinuationFrame
37// - JavaScriptBuiltinContinuationWithCatchFrame
38// - TurbofanStubWithContextFrame
39// - TypedFrame
40// - NativeFrame
41// - EntryFrame
42// - ConstructEntryFrame
43// - ExitFrame
44// - BuiltinExitFrame
45// - StubFrame
46// - JsToWasmFrame
47// - CWasmEntryFrame
48// - Internal
49// - ConstructFrame
50// - FastConstructFrame
51// - BuiltinContinuationFrame
52// - WasmFrame
53// - WasmExitFrame
54// - WasmToJsFrame
55// - WasmInterpreterEntryFrame (#if V8_ENABLE_DRUMBRAKE)
56// - WasmDebugBreakFrame
57// - WasmLiftoffSetupFrame
58// - IrregexpFrame
59
60namespace v8 {
61namespace internal {
62namespace wasm {
63class WasmCode;
64struct JumpBuffer;
65class StackMemory;
66} // namespace wasm
67
68class AbstractCode;
69class Debug;
70class ExternalCallbackScope;
71class InnerPointerToCodeCache;
72class Isolate;
73class ObjectVisitor;
74class Register;
75class RootVisitor;
76class StackFrameInfo;
77class StackFrameIteratorBase;
78class StringStream;
79class ThreadLocalTop;
80class WasmInstanceObject;
81class WasmModuleObject;
82
83#if V8_ENABLE_DRUMBRAKE
84class Tuple2;
85#endif // V8_ENABLE_DRUMBRAKE
86
88 public:
89 static const int kNextOffset = 0 * kSystemPointerSize;
90 static const int kPaddingOffset = 1 * kSystemPointerSize;
91
94};
95
97 public:
98 // Get the address of this stack handler.
99 inline Address address() const;
100
101 // Get the next stack handler in the chain.
102 inline StackHandler* next() const;
103
104 // Get the next stack handler, as an Address. This is safe to use even
105 // when the next handler is null.
106 inline Address next_address() const;
107
108 // Conversion support.
109 static inline StackHandler* FromAddress(Address address);
110
111 private:
113};
114
115#define STACK_FRAME_TYPE_LIST(V) \
116 V(ENTRY, EntryFrame) \
117 V(CONSTRUCT_ENTRY, ConstructEntryFrame) \
118 V(EXIT, ExitFrame) \
119 IF_WASM(V, WASM, WasmFrame) \
120 IF_WASM(V, WASM_TO_JS, WasmToJsFrame) \
121 IF_WASM(V, WASM_TO_JS_FUNCTION, WasmToJsFunctionFrame) \
122 IF_WASM(V, JS_TO_WASM, JsToWasmFrame) \
123 IF_WASM(V, STACK_SWITCH, StackSwitchFrame) \
124 IF_WASM_DRUMBRAKE(V, WASM_INTERPRETER_ENTRY, WasmInterpreterEntryFrame) \
125 IF_WASM(V, WASM_DEBUG_BREAK, WasmDebugBreakFrame) \
126 IF_WASM(V, C_WASM_ENTRY, CWasmEntryFrame) \
127 IF_WASM(V, WASM_EXIT, WasmExitFrame) \
128 IF_WASM(V, WASM_LIFTOFF_SETUP, WasmLiftoffSetupFrame) \
129 IF_WASM(V, WASM_SEGMENT_START, WasmSegmentStartFrame) \
130 V(INTERPRETED, InterpretedFrame) \
131 V(BASELINE, BaselineFrame) \
132 V(MAGLEV, MaglevFrame) \
133 V(TURBOFAN_JS, TurbofanJSFrame) \
134 V(STUB, StubFrame) \
135 V(TURBOFAN_STUB_WITH_CONTEXT, TurbofanStubWithContextFrame) \
136 V(BUILTIN_CONTINUATION, BuiltinContinuationFrame) \
137 V(JAVASCRIPT_BUILTIN_CONTINUATION, JavaScriptBuiltinContinuationFrame) \
138 V(JAVASCRIPT_BUILTIN_CONTINUATION_WITH_CATCH, \
139 JavaScriptBuiltinContinuationWithCatchFrame) \
140 V(INTERNAL, InternalFrame) \
141 V(CONSTRUCT, ConstructFrame) \
142 V(FAST_CONSTRUCT, FastConstructFrame) \
143 V(BUILTIN, BuiltinFrame) \
144 V(BUILTIN_EXIT, BuiltinExitFrame) \
145 V(API_CALLBACK_EXIT, ApiCallbackExitFrame) \
146 V(API_ACCESSOR_EXIT, ApiAccessorExitFrame) \
147 V(NATIVE, NativeFrame) \
148 V(IRREGEXP, IrregexpFrame)
149
150// Abstract base class for all stack frames.
152 public:
153#define DECLARE_TYPE(type, ignore) type,
154 enum Type {
157 // Used by FrameScope to indicate that the stack frame is constructed
158 // manually and the FrameScope does not need to emit code.
159 MANUAL
160 };
161#undef DECLARE_TYPE
162
163 // Used to mark the outermost JS entry frame.
164 //
165 // The mark is an opaque value that should be pushed onto the stack directly,
166 // carefully crafted to not be interpreted as a tagged pointer.
174
185
186 // Convert a stack frame type to a marker that can be stored on the stack.
187 //
188 // The marker is an opaque value, not intended to be interpreted in any way
189 // except being checked by IsTypeMarker or converted by MarkerToType.
190 // It has the same tagging as Smis, so any marker value that does not pass
191 // IsTypeMarker can instead be interpreted as a tagged pointer.
192 //
193 // Note that the marker is not a Smi: Smis on 64-bit architectures are stored
194 // in the top 32 bits of a 64-bit value, which in turn makes them expensive
195 // (in terms of code/instruction size) to push as immediates onto the stack.
196 static constexpr int32_t TypeToMarker(Type type) {
197 DCHECK_GE(type, 0);
198 return (type << kSmiTagSize) | kSmiTag;
199 }
200
201 // Convert a marker back to a stack frame type.
202 //
203 // Unlike the return value of TypeToMarker, this takes an intptr_t, as that is
204 // the type of the value on the stack.
205 static constexpr Type MarkerToType(intptr_t marker) {
206 DCHECK(IsTypeMarker(marker));
207 return static_cast<Type>(marker >> kSmiTagSize);
208 }
209
210 // Check if a marker is a stack frame type marker.
211 //
212 // Returns true if the given marker is tagged as a stack frame type marker,
213 // and should be converted back to a stack frame type using MarkerToType.
214 static constexpr bool IsTypeMarker(uintptr_t function_or_marker) {
215 static_assert(kSmiTag == 0);
216 static_assert((std::numeric_limits<uintptr_t>::max() >> kSmiTagSize) >
217 Type::NUMBER_OF_TYPES);
218 return (function_or_marker & kSmiTagMask) == kSmiTag &&
219 function_or_marker < (Type::NUMBER_OF_TYPES << kSmiTagSize);
220 }
221
222 // Copy constructor; it breaks the connection to host iterator
223 // (as an iterator usually lives on stack).
225 : iterator_(nullptr),
226 isolate_(original.isolate_),
227 state_(original.state_) {}
228
229 // Type testers.
230 bool is_entry() const { return type() == ENTRY; }
231 bool is_construct_entry() const { return type() == CONSTRUCT_ENTRY; }
232 bool is_exit() const { return type() == EXIT; }
233 bool is_optimized_js() const {
234 static_assert(TURBOFAN_JS == MAGLEV + 1);
235 return base::IsInRange(type(), MAGLEV, TURBOFAN_JS);
236 }
237 bool is_unoptimized_js() const {
238 static_assert(BASELINE == INTERPRETED + 1);
239 return base::IsInRange(type(), INTERPRETED, BASELINE);
240 }
241 bool is_interpreted() const { return type() == INTERPRETED; }
242 bool is_baseline() const { return type() == BASELINE; }
243 bool is_maglev() const { return type() == MAGLEV; }
244 bool is_turbofan_js() const { return type() == TURBOFAN_JS; }
245#if V8_ENABLE_WEBASSEMBLY
246 bool is_wasm() const {
247 return this->type() == WASM || this->type() == WASM_SEGMENT_START
248#ifdef V8_ENABLE_DRUMBRAKE
249 || this->type() == WASM_INTERPRETER_ENTRY
250#endif // V8_ENABLE_DRUMBRAKE
251 ;
252 }
253 bool is_c_wasm_entry() const { return type() == C_WASM_ENTRY; }
254 bool is_wasm_liftoff_setup() const { return type() == WASM_LIFTOFF_SETUP; }
255#if V8_ENABLE_DRUMBRAKE
256 bool is_wasm_interpreter_entry() const {
257 return type() == WASM_INTERPRETER_ENTRY;
258 }
259#endif // V8_ENABLE_DRUMBRAKE
260 bool is_wasm_debug_break() const { return type() == WASM_DEBUG_BREAK; }
261 bool is_wasm_to_js() const {
262 return type() == WASM_TO_JS || type() == WASM_TO_JS_FUNCTION;
263 }
264 bool is_js_to_wasm() const { return type() == JS_TO_WASM; }
265#endif // V8_ENABLE_WEBASSEMBLY
266 bool is_builtin() const { return type() == BUILTIN; }
267 bool is_internal() const { return type() == INTERNAL; }
269 return type() == BUILTIN_CONTINUATION;
270 }
272 return type() == JAVASCRIPT_BUILTIN_CONTINUATION;
273 }
275 return type() == JAVASCRIPT_BUILTIN_CONTINUATION_WITH_CATCH;
276 }
277 bool is_construct() const { return type() == CONSTRUCT; }
278 bool is_fast_construct() const { return type() == FAST_CONSTRUCT; }
279 bool is_builtin_exit() const { return type() == BUILTIN_EXIT; }
280 bool is_api_accessor_exit() const { return type() == API_ACCESSOR_EXIT; }
281 bool is_api_callback_exit() const { return type() == API_CALLBACK_EXIT; }
282 bool is_irregexp() const { return type() == IRREGEXP; }
283
284 static bool IsJavaScript(Type t) {
285 static_assert(INTERPRETED + 1 == BASELINE);
286 static_assert(BASELINE + 1 == MAGLEV);
287 static_assert(MAGLEV + 1 == TURBOFAN_JS);
288 return t >= INTERPRETED && t <= TURBOFAN_JS;
289 }
290 bool is_javascript() const { return IsJavaScript(type()); }
291
292 // Accessors.
293 Address sp() const {
295 return state_.sp;
296 }
297 Address fp() const { return state_.fp; }
298 Address callee_fp() const { return state_.callee_fp; }
299 Address callee_pc() const { return state_.callee_pc; }
301 inline Address pc() const;
306
307 // Skip authentication of the PC, when using CFI. Used in the profiler, where
308 // in certain corner-cases we do not use an address on the stack, which would
309 // be signed, as the PC of the frame.
310 inline Address unauthenticated_pc() const;
312
313 // Conditionally calls either pc() or unauthenticated_pc() based on whether
314 // this is fast C call stack frame.
315 inline Address maybe_unauthenticated_pc() const;
317
318 // If the stack pointer is missing, this is a fast C call frame. For such
319 // frames we cannot compute a stack pointer because of the missing ExitFrame.
320 bool InFastCCall() const { return state_.sp == kNullAddress; }
321
326
327 Address* pc_address() const { return state_.pc_address; }
328
332
333 // Get the id of this stack frame.
334 StackFrameId id() const { return static_cast<StackFrameId>(caller_sp()); }
335
336 // Get the top handler from the current stack iterator.
337 inline StackHandler* top_handler() const;
338
339 // Get the type of this frame.
340 virtual Type type() const = 0;
341
342 // Get the code associated with this frame. The result might be a Code object
343 // or an empty value.
344 // This method is used by Isolate::PushStackTraceAndDie() for collecting a
345 // stack trace on fatal error and thus it might be called in the middle of GC
346 // and should be as safe as possible.
348
349 // Search for the code associated with this frame.
351 V8_EXPORT_PRIVATE std::pair<Tagged<Code>, int> LookupCodeAndOffset() const;
353 V8_EXPORT_PRIVATE std::pair<Tagged<GcSafeCode>, int>
355
356 virtual void Iterate(RootVisitor* v) const = 0;
358 Tagged<GcSafeCode> holder) const;
359
360 // Sets a callback function for return-address rewriting profilers
361 // to resolve the location of a return address to the location of the
362 // profiler's stashed return address.
365
366 static inline Address ReadPC(Address* pc_address);
367
368 // Resolves pc_address through the resolution address function if one is set.
370
371 // Printing support.
373 virtual void Print(StringStream* accumulator, PrintMode mode,
374 int index) const;
375
376 Isolate* isolate() const { return isolate_; }
377
378 void operator=(const StackFrame& original) = delete;
379
380 protected:
381 inline explicit StackFrame(StackFrameIteratorBase* iterator);
382
383 // Compute the stack pointer for the calling frame.
384 virtual Address GetCallerStackPointer() const = 0;
385
387
388 private:
391
393
394 // Fill in the state of the calling frame.
395 virtual void ComputeCallerState(State* state) const = 0;
396
397 // Get the type and the state of the calling frame.
398 virtual Type GetCallerState(State* state) const;
399
400 static const intptr_t kIsolateTag = 1;
401
402 friend class StackFrameIterator;
406};
407
408class CommonFrame;
409
411 public:
412// Subclasses for the different summary kinds:
413#define FRAME_SUMMARY_VARIANTS(F) \
414 F(JAVASCRIPT, JavaScriptFrameSummary, javascript_summary_, JavaScript) \
415 IF_WASM(F, BUILTIN, BuiltinFrameSummary, builtin_summary_, Builtin) \
416 IF_WASM(F, WASM, WasmFrameSummary, wasm_summary_, Wasm) \
417 IF_WASM_DRUMBRAKE(F, WASM_INTERPRETED, WasmInterpretedFrameSummary, \
418 wasm_interpreted_summary_, WasmInterpreted) \
419 IF_WASM(F, WASM_INLINED, WasmInlinedFrameSummary, wasm_inlined_summary_, \
420 WasmInlined)
421
422#define FRAME_SUMMARY_KIND(kind, type, field, desc) kind,
424#undef FRAME_SUMMARY_KIND
425
427 public:
429 : isolate_(isolate), kind_(kind) {}
430 Isolate* isolate() const { return isolate_; }
431 Kind kind() const { return kind_; }
432
433 private:
436 };
437
439 public:
441 Tagged<JSFunction> function,
442 Tagged<AbstractCode> abstract_code, int code_offset,
443 bool is_constructor, Tagged<FixedArray> parameters);
444
445 void EnsureSourcePositionsAvailable();
446 bool AreSourcePositionsAvailable() const;
447
450 Handle<AbstractCode> abstract_code() const { return abstract_code_; }
451 int code_offset() const { return code_offset_; }
452 bool is_constructor() const { return is_constructor_; }
454 bool is_subject_to_debugging() const;
455 int SourcePosition() const;
456 int SourceStatementPosition() const;
457 Handle<Object> script() const;
459 DirectHandle<StackFrameInfo> CreateStackFrameInfo() const;
460
461 private:
468 };
469
470#if V8_ENABLE_WEBASSEMBLY
471 class WasmFrameSummary : public FrameSummaryBase {
472 public:
473 WasmFrameSummary(Isolate* isolate,
475 wasm::WasmCode* code, int byte_offset, int function_index,
476 bool at_to_number_conversion);
477
478 Handle<Object> receiver() const;
479 uint32_t function_index() const;
480 wasm::WasmCode* code() const { return code_; }
481 // Returns the wire bytes offset relative to the function entry.
482 int code_offset() const { return byte_offset_; }
483 bool is_constructor() const { return false; }
484 bool is_subject_to_debugging() const { return true; }
485 int SourcePosition() const;
486 int SourceStatementPosition() const { return SourcePosition(); }
487 Handle<Script> script() const;
488 DirectHandle<WasmInstanceObject> wasm_instance() const;
489 DirectHandle<WasmTrustedInstanceData> wasm_trusted_instance_data() const {
490 return instance_data_;
491 }
492 DirectHandle<Context> native_context() const;
493 bool at_to_number_conversion() const { return at_to_number_conversion_; }
494 DirectHandle<StackFrameInfo> CreateStackFrameInfo() const;
495
496 private:
497 Handle<WasmTrustedInstanceData> instance_data_;
498 bool at_to_number_conversion_;
499 wasm::WasmCode* code_;
500 int byte_offset_;
501 int function_index_;
502 };
503
504 // Summary of a wasm frame inlined into JavaScript. (Wasm frames inlined into
505 // wasm are expressed by a WasmFrameSummary.)
506 class WasmInlinedFrameSummary : public FrameSummaryBase {
507 public:
508 WasmInlinedFrameSummary(Isolate* isolate,
509 Handle<WasmTrustedInstanceData> instance_data,
510 int function_index, int op_wire_bytes_offset);
511
512 DirectHandle<WasmInstanceObject> wasm_instance() const;
513 DirectHandle<WasmTrustedInstanceData> wasm_trusted_instance_data() const {
514 return instance_data_;
515 }
516 Handle<Object> receiver() const;
517 uint32_t function_index() const;
518 int code_offset() const { return op_wire_bytes_offset_; }
519 bool is_constructor() const { return false; }
520 bool is_subject_to_debugging() const { return true; }
521 Handle<Script> script() const;
522 int SourcePosition() const;
523 int SourceStatementPosition() const { return SourcePosition(); }
524 DirectHandle<Context> native_context() const;
525 DirectHandle<StackFrameInfo> CreateStackFrameInfo() const;
526
527 private:
528 Handle<WasmTrustedInstanceData> instance_data_;
529 int function_index_;
530 int op_wire_bytes_offset_; // relative to function offset.
531 };
532
533 class BuiltinFrameSummary : public FrameSummaryBase {
534 public:
535 BuiltinFrameSummary(Isolate*, Builtin);
536
537 Builtin builtin() const { return builtin_; }
538
539 Handle<Object> receiver() const;
540 int code_offset() const { return 0; }
541 bool is_constructor() const { return false; }
542 bool is_subject_to_debugging() const { return false; }
543 Handle<Object> script() const;
544 int SourcePosition() const { return kNoSourcePosition; }
545 int SourceStatementPosition() const { return 0; }
546 DirectHandle<Context> native_context() const;
547 DirectHandle<StackFrameInfo> CreateStackFrameInfo() const;
548
549 private:
550 Builtin builtin_;
551 };
552
553#if V8_ENABLE_DRUMBRAKE
554 class WasmInterpretedFrameSummary : public FrameSummaryBase {
555 public:
556 WasmInterpretedFrameSummary(Isolate*, Handle<WasmInstanceObject>,
557 uint32_t function_index, int byte_offset);
558 Handle<WasmInstanceObject> wasm_instance() const { return wasm_instance_; }
559 Handle<WasmTrustedInstanceData> instance_data() const;
560 uint32_t function_index() const { return function_index_; }
561 int byte_offset() const { return byte_offset_; }
562
563 Handle<Object> receiver() const;
564 int code_offset() const { return byte_offset_; }
565 bool is_constructor() const { return false; }
566 bool is_subject_to_debugging() const { return true; }
567 int SourcePosition() const;
568 int SourceStatementPosition() const { return SourcePosition(); }
569 Handle<Script> script() const;
570 DirectHandle<Context> native_context() const;
571 DirectHandle<StackFrameInfo> CreateStackFrameInfo() const;
572
573 private:
574 Handle<WasmInstanceObject> wasm_instance_;
575 uint32_t function_index_;
576 int byte_offset_;
577 };
578#endif // V8_ENABLE_DRUMBRAKE
579#endif // V8_ENABLE_WEBASSEMBLY
580
581#define FRAME_SUMMARY_CONS(kind, type, field, desc) \
582 FrameSummary(type summ) : field(summ) {} // NOLINT
584#undef FRAME_SUMMARY_CONS
585
586 ~FrameSummary();
587
588 static FrameSummary GetTop(const CommonFrame* frame);
589 static FrameSummary GetBottom(const CommonFrame* frame);
590 static FrameSummary GetSingle(const CommonFrame* frame);
591 static FrameSummary Get(const CommonFrame* frame, int index);
592
593 void EnsureSourcePositionsAvailable();
594 bool AreSourcePositionsAvailable() const;
595
596 // Dispatched accessors.
598 int code_offset() const;
599 bool is_constructor() const;
602 int SourcePosition() const;
606
607#define FRAME_SUMMARY_CAST(kind_, type, field, desc) \
608 bool Is##desc() const { return base_.kind() == kind_; } \
609 const type& As##desc() const { \
610 DCHECK_EQ(base_.kind(), kind_); \
611 return field; \
612 }
614#undef FRAME_SUMMARY_CAST
615
616 private:
617#define FRAME_SUMMARY_FIELD(kind, type, field, desc) type field;
618 union {
621 };
622#undef FRAME_SUMMARY_FIELD
623};
624
625// FrameSummaries represents a collection of summarized frames
626// within a standard frame. In unoptimized code, there is only one frame,
627// while in optimized code, multiple frames may exist due to inlining.
628// The functions are ordered bottom-to-top (i.e. summaries.last() is the
629// top-most activation; caller comes before callee).
631 std::vector<FrameSummary> frames;
633
634 FrameSummaries() = default;
635
636 explicit FrameSummaries(FrameSummary summary) : frames() {
637 frames.push_back(summary);
638 }
639
640 int size() const { return static_cast<int>(frames.size()); }
641};
642
643class CommonFrame : public StackFrame {
644 public:
645 // Accessors.
646 virtual Tagged<Object> context()
647 const; // TODO(victorgomes): CommonFrames don't have context.
648 virtual int position() const;
649
650 // Access the expressions in the stack frame including locals.
651 inline Tagged<Object> GetExpression(int index) const;
652 inline void SetExpression(int index, Tagged<Object> value);
653 int ComputeExpressionsCount() const;
654
655 Address GetCallerStackPointer() const override;
656
657 // Build a list with summaries for this frame including all inlined frames.
658 // The functions are ordered bottom-to-top (i.e. summaries.last() is the
659 // top-most activation; caller comes before callee).
660 virtual FrameSummaries Summarize() const;
661
662 static CommonFrame* cast(StackFrame* frame) {
663 // It is always safe to cast to common.
664 return static_cast<CommonFrame*>(frame);
665 }
666
667 protected:
668 inline explicit CommonFrame(StackFrameIteratorBase* iterator);
669
670 bool HasTaggedOutgoingParams(Tagged<GcSafeCode> code_lookup) const;
671
672 void ComputeCallerState(State* state) const override;
673
674 // Accessors.
675 inline Address caller_fp() const;
676 inline Address caller_pc() const;
677
678 // Iterate over expression stack including stack handlers, locals,
679 // and parts of the fixed part including context and code fields.
680 void IterateExpressions(RootVisitor* v) const;
681
683
684 // Returns the address of the n'th expression stack element.
685 virtual Address GetExpressionAddress(int n) const;
686};
687
688// This frame is used for TF-optimized code without JS linkage, but
689// contains the context instead of a type marker.
691 public:
692 Type type() const override { return TURBOFAN_STUB_WITH_CONTEXT; }
693
694 Tagged<HeapObject> unchecked_code() const override;
695 void Iterate(RootVisitor* v) const override;
696
697 protected:
698 inline explicit TurbofanStubWithContextFrame(
699 StackFrameIteratorBase* iterator);
700
701 private:
703};
704
705class TypedFrame : public CommonFrame {
706 public:
707 Tagged<HeapObject> unchecked_code() const override { return {}; }
708 void Iterate(RootVisitor* v) const override;
709
712
713 protected:
714 inline explicit TypedFrame(StackFrameIteratorBase* iterator);
715};
716
718 public:
719 // Accessors.
720 virtual Tagged<JSFunction> function() const = 0;
721
722 // Access the parameters.
723 virtual Tagged<Object> receiver() const;
724 virtual Tagged<Object> GetParameter(int index) const;
725 virtual int ComputeParametersCount() const;
727 virtual int GetActualArgumentCount() const;
728
729 Tagged<HeapObject> unchecked_code() const override;
730
731 // Lookup exception handler for current {pc}, returns -1 if none found. Also
732 // returns data associated with the handler site specific to the frame type:
733 // - OptimizedJSFrame : Data is not used and will not return a value.
734 // - UnoptimizedJSFrame: Data is the register index holding the context.
736 int* data, HandlerTable::CatchPrediction* prediction);
737
738 // Check if this frame is a constructor frame invoked through 'new'.
739 virtual bool IsConstructor() const;
740
741 // Summarize Frame
742 FrameSummaries Summarize() const override;
743
744 protected:
745 inline explicit CommonFrameWithJSLinkage(StackFrameIteratorBase* iterator);
746
747 // Determines if the standard frame for the given frame pointer is a
748 // construct frame.
749 static inline bool IsConstructFrame(Address fp);
750 inline Address GetParameterSlot(int index) const;
751};
752
754 public:
755 void Iterate(RootVisitor* v) const override;
756
757 protected:
758 inline explicit TypedFrameWithJSLinkage(StackFrameIteratorBase* iterator);
759};
760
762 public:
763 Type type() const override = 0;
764
765 // Accessors.
766 Tagged<JSFunction> function() const override;
768 Tagged<Script> script() const;
769 Tagged<Object> context() const override;
770 int GetActualArgumentCount() const override;
771
772 inline void set_receiver(Tagged<Object> value);
773
774 // Debugger access.
775 void SetParameterValue(int index, Tagged<Object> value) const;
776
777 // Check if this frame is a constructor frame invoked through 'new'.
778 bool IsConstructor() const override;
779
780 // Garbage collection support.
781 void Iterate(RootVisitor* v) const override;
782
783 // Printing support.
784 void Print(StringStream* accumulator, PrintMode mode,
785 int index) const override;
786
787 // Return a list with {SharedFunctionInfo} objects of this frame.
788 virtual void GetFunctions(
789 std::vector<Tagged<SharedFunctionInfo>>* functions) const;
790
791 void GetFunctions(std::vector<Handle<SharedFunctionInfo>>* functions) const;
792
793 // Returns {AbstractCode, code offset} pair for this frame's PC value.
794 std::tuple<Tagged<AbstractCode>, int> GetActiveCodeAndOffset() const;
795
796 // Architecture-specific register description.
797 static Register fp_register();
798 static Register context_register();
800
801 bool is_unoptimized() const { return is_unoptimized_js(); }
802 bool is_optimized() const { return is_optimized_js(); }
803 bool is_turbofan() const { return is_turbofan_js(); }
804
806 DCHECK(frame->is_javascript());
807 return static_cast<JavaScriptFrame*>(frame);
808 }
809
810 static void PrintFunctionAndOffset(Isolate* isolate,
811 Tagged<JSFunction> function,
812 Tagged<AbstractCode> code, int code_offset,
813 FILE* file, bool print_line_number);
814
815 static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
816 bool print_line_number);
817
818 static void CollectFunctionAndOffsetForICStats(Isolate* isolate,
819 Tagged<JSFunction> function,
821 int code_offset);
822
823 protected:
824 inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
825
826 Address GetCallerStackPointer() const override;
827
828 virtual void PrintFrameKind(StringStream* accumulator) const {}
829
830 private:
832
834};
835
836class NativeFrame : public TypedFrame {
837 public:
838 Type type() const override { return NATIVE; }
839
840 // Garbage collection support.
841 void Iterate(RootVisitor* v) const override {}
842
843 protected:
844 inline explicit NativeFrame(StackFrameIteratorBase* iterator);
845
846 private:
847 void ComputeCallerState(State* state) const override;
848
850};
851
852// Entry frames are used to enter JavaScript execution from C.
853class EntryFrame : public TypedFrame {
854 public:
855 Type type() const override { return ENTRY; }
856
857 Tagged<HeapObject> unchecked_code() const override;
858
859 // Garbage collection support.
860 void Iterate(RootVisitor* v) const override;
861
862 static EntryFrame* cast(StackFrame* frame) {
863 DCHECK(frame->is_entry());
864 return static_cast<EntryFrame*>(frame);
865 }
866
867 protected:
868 inline explicit EntryFrame(StackFrameIteratorBase* iterator);
869
870 // The caller stack pointer for entry frames is always zero. The
871 // real information about the caller frame is available through the
872 // link to the top exit frame.
873 Address GetCallerStackPointer() const override { return 0; }
874
875 private:
876 void ComputeCallerState(State* state) const override;
877 Type GetCallerState(State* state) const override;
878
880};
881
883 public:
884 Type type() const override { return CONSTRUCT_ENTRY; }
885
886 Tagged<HeapObject> unchecked_code() const override;
887
889 DCHECK(frame->is_construct_entry());
890 return static_cast<ConstructEntryFrame*>(frame);
891 }
892
893 protected:
894 inline explicit ConstructEntryFrame(StackFrameIteratorBase* iterator);
895
896 private:
898};
899
900// Exit frames are used to exit JavaScript execution and go to C, or to switch
901// out of the current stack for wasm stack-switching.
902class ExitFrame : public TypedFrame {
903 public:
904 Type type() const override { return EXIT; }
905
906 // Garbage collection support.
907 void Iterate(RootVisitor* v) const override;
908
909 static ExitFrame* cast(StackFrame* frame) {
910 DCHECK(frame->is_exit());
911 return static_cast<ExitFrame*>(frame);
912 }
913
914 // Compute the state and type of an exit frame given a frame
915 // pointer. Used when constructing the first stack frame seen by an
916 // iterator and the frames following entry frames.
920 static void FillState(Address fp, Address sp, State* state);
921
922 protected:
923 inline explicit ExitFrame(StackFrameIteratorBase* iterator);
924
925 private:
926 void ComputeCallerState(State* state) const override;
927
929};
930
931// Builtin exit frames are a special case of exit frames, which are used
932// whenever C++ builtins (e.g., Math.acos) are called. Their main purpose is
933// to allow such builtins to appear in stack traces.
935 public:
936 Type type() const override { return BUILTIN_EXIT; }
937
939
940 Tagged<Object> receiver() const;
941 Tagged<Object> GetParameter(int i) const;
942 int ComputeParametersCount() const;
944
945 // Check if this frame is a constructor frame invoked through 'new'.
946 bool IsConstructor() const;
947
948 void Print(StringStream* accumulator, PrintMode mode,
949 int index) const override;
950
951 // Summarize Frame
952 FrameSummaries Summarize() const override;
953
954 protected:
955 inline explicit BuiltinExitFrame(StackFrameIteratorBase* iterator);
956
957 private:
959 inline Tagged<Object> argc_slot_object() const;
960 inline Tagged<Object> target_slot_object() const;
962
964};
965
966// Api callback exit frames are a special case of exit frames, which are used
967// whenever an Api functions (such as v8::Function or v8::FunctionTemplate) are
968// called. Their main purpose is to support preprocessing of exceptions thrown
969// from Api functions and as a bonus it allows these functions to appear in
970// stack traces (see v8_flags.experimental_stack_trace_frames).
972 public:
973 Type type() const override { return API_CALLBACK_EXIT; }
974
975 // In case function slot contains FunctionTemplateInfo, instantiate the
976 // function, stores it in the function slot and returns JSFunction handle.
978
980
981 inline Tagged<Object> receiver() const;
982 inline Tagged<Object> GetParameter(int i) const;
983 inline int ComputeParametersCount() const;
985
986 inline Tagged<Object> context() const override;
987
988 // Check if this frame is a constructor frame invoked through 'new'.
989 inline bool IsConstructor() const;
990
991 void Print(StringStream* accumulator, PrintMode mode,
992 int index) const override;
993
994 // Summarize Frame
995 FrameSummaries Summarize() const override;
996
999 return static_cast<ApiCallbackExitFrame*>(frame);
1000 }
1001
1002 protected:
1003 inline explicit ApiCallbackExitFrame(StackFrameIteratorBase* iterator);
1004
1005 private:
1006 // ApiCallbackExitFrame might contain either FunctionTemplateInfo or
1007 // JSFunction in the function slot.
1008 inline Tagged<HeapObject> target() const;
1009
1010 inline void set_target(Tagged<HeapObject> function) const;
1011
1012 inline FullObjectSlot target_slot() const;
1013
1015};
1016
1017// Api accessor exit frames are a special case of exit frames, which are used
1018// whenever an Api property accessor callbacks (v8::AccessorGetterCallback or
1019// v8::AccessorSetterCallback) are called. Their main purpose is to support
1020// preprocessing of exceptions thrown from these callbacks.
1022 public:
1023 Type type() const override { return API_ACCESSOR_EXIT; }
1024
1025 inline Tagged<Name> property_name() const;
1026
1027 inline Tagged<Object> receiver() const;
1028 inline Tagged<Object> holder() const;
1029
1030 void Print(StringStream* accumulator, PrintMode mode,
1031 int index) const override;
1032
1033 // Summarize Frame
1034 FrameSummaries Summarize() const override;
1035
1037 DCHECK(frame->is_api_accessor_exit());
1038 return static_cast<ApiAccessorExitFrame*>(frame);
1039 }
1040
1041 protected:
1042 inline explicit ApiAccessorExitFrame(StackFrameIteratorBase* iterator);
1043
1044 private:
1045 inline FullObjectSlot property_name_slot() const;
1046 inline FullObjectSlot receiver_slot() const;
1047 inline FullObjectSlot holder_slot() const;
1048
1050};
1051
1052class StubFrame : public TypedFrame {
1053 public:
1054 Type type() const override { return STUB; }
1055
1056 Tagged<HeapObject> unchecked_code() const override;
1057
1058 // Lookup exception handler for current {pc}, returns -1 if none found. Only
1059 // TurboFan stub frames are supported.
1061
1062 FrameSummaries Summarize() const override;
1063
1064 protected:
1065 inline explicit StubFrame(StackFrameIteratorBase* iterator);
1066
1067 private:
1069};
1070
1072 public:
1073 // Return a list with {SharedFunctionInfo} objects of this frame.
1074 // The functions are ordered bottom-to-top (i.e. functions.last()
1075 // is the top-most activation)
1076 void GetFunctions(
1077 std::vector<Tagged<SharedFunctionInfo>>* functions) const override;
1078
1079 FrameSummaries Summarize() const override;
1080
1082 int* deopt_index) const;
1083
1084 static int StackSlotOffsetRelativeToFp(int slot_index);
1085
1086 // Lookup exception handler for current {pc}, returns -1 if none found.
1088 int* data, HandlerTable::CatchPrediction* prediction) override;
1089
1091 int trampoline_pc) const = 0;
1092
1093 protected:
1094 inline explicit OptimizedJSFrame(StackFrameIteratorBase* iterator);
1095};
1096
1097// An unoptimized frame is a JavaScript frame that is executing bytecode. It
1098// may be executing it using the interpreter, or via baseline code compiled from
1099// the bytecode.
1101 public:
1102 // Accessors.
1103 int position() const override;
1104
1105 // Lookup exception handler for current {pc}, returns -1 if none found.
1107 int* data, HandlerTable::CatchPrediction* prediction) override;
1108
1109 // Returns the current offset into the bytecode stream.
1110 virtual int GetBytecodeOffset() const = 0;
1111
1112 // Returns the frame's current bytecode array.
1114
1115 // Access to the interpreter register file for this frame.
1116 Tagged<Object> ReadInterpreterRegister(int register_index) const;
1117
1118 inline void SetFeedbackVector(Tagged<FeedbackVector> feedback_vector);
1119
1120 // Build a list with summaries for this frame including all inlined frames.
1121 FrameSummaries Summarize() const override;
1122
1124 DCHECK(frame->is_unoptimized_js());
1125 return static_cast<UnoptimizedJSFrame*>(frame);
1126 }
1127
1128 protected:
1129 inline explicit UnoptimizedJSFrame(StackFrameIteratorBase* iterator);
1130
1131 Address GetExpressionAddress(int n) const override;
1132
1133 private:
1135};
1136
1138 public:
1139 Type type() const override { return INTERPRETED; }
1140
1141 // Returns the current offset into the bytecode stream.
1142 int GetBytecodeOffset() const override;
1143
1144 // Updates the current offset into the bytecode stream, mainly used for stack
1145 // unwinding to continue execution at a different bytecode offset.
1146 void PatchBytecodeOffset(int new_offset);
1147
1148 // Updates the frame's BytecodeArray with |bytecode_array|. Used by the
1149 // debugger to swap execution onto a BytecodeArray patched with breakpoints.
1150 void PatchBytecodeArray(Tagged<BytecodeArray> bytecode_array);
1151
1153 DCHECK(frame->is_interpreted());
1154 return static_cast<InterpretedFrame*>(frame);
1155 }
1156 static const InterpretedFrame* cast(const StackFrame* frame) {
1157 DCHECK(frame->is_interpreted());
1158 return static_cast<const InterpretedFrame*>(frame);
1159 }
1160
1161 protected:
1162 inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
1163
1164 private:
1166};
1167
1169 public:
1170 Type type() const override { return BASELINE; }
1171
1172 // Returns the current offset into the bytecode stream.
1173 int GetBytecodeOffset() const override;
1174
1175 intptr_t GetPCForBytecodeOffset(int lookup_offset) const;
1176
1177 void PatchContext(Tagged<Context> value);
1178
1180 DCHECK(frame->is_baseline());
1181 return static_cast<BaselineFrame*>(frame);
1182 }
1183 static const BaselineFrame* cast(const StackFrame* frame) {
1184 DCHECK(frame->is_baseline());
1185 return static_cast<const BaselineFrame*>(frame);
1186 }
1187
1188 protected:
1189 inline explicit BaselineFrame(StackFrameIteratorBase* iterator);
1190
1191 private:
1193};
1194
1196 public:
1197 Type type() const override { return MAGLEV; }
1198
1199 static MaglevFrame* cast(StackFrame* frame) {
1200 DCHECK(frame->is_maglev());
1201 return static_cast<MaglevFrame*>(frame);
1202 }
1203
1204 void Iterate(RootVisitor* v) const override;
1205
1207 int trampoline_pc) const override;
1208
1211
1212 static intptr_t StackGuardFrameSize(int register_input_count);
1213
1214 protected:
1215 inline explicit MaglevFrame(StackFrameIteratorBase* iterator);
1216
1217 private:
1219};
1220
1222 public:
1223 Type type() const override { return TURBOFAN_JS; }
1224
1225 int ComputeParametersCount() const override;
1226
1227 void Iterate(RootVisitor* v) const override;
1228
1230 int trampoline_pc) const override;
1231
1232 protected:
1233 inline explicit TurbofanJSFrame(StackFrameIteratorBase* iterator);
1234
1235 private:
1237
1238 Tagged<Object> StackSlotAt(int index) const;
1239};
1240
1241// Builtin frames are built for builtins with JavaScript linkage, such as
1242// various standard library functions (i.e. Math.asin, Math.floor, etc.).
1244 public:
1245 Type type() const final { return BUILTIN; }
1246
1247 static BuiltinFrame* cast(StackFrame* frame) {
1248 DCHECK(frame->is_builtin());
1249 return static_cast<BuiltinFrame*>(frame);
1250 }
1251
1252 Tagged<JSFunction> function() const override;
1253 int ComputeParametersCount() const override;
1254
1255 protected:
1256 inline explicit BuiltinFrame(StackFrameIteratorBase* iterator);
1257
1258 private:
1260};
1261
1262#if V8_ENABLE_WEBASSEMBLY
1263class WasmFrame : public TypedFrame {
1264 public:
1265 Type type() const override { return WASM; }
1266
1267 // Printing support.
1268 void Print(StringStream* accumulator, PrintMode mode,
1269 int index) const override;
1270
1271 // Lookup exception handler for current {pc}, returns -1 if none found.
1272 int LookupExceptionHandlerInTable();
1273
1274 void Iterate(RootVisitor* v) const override;
1275
1276 // Accessors.
1277 virtual V8_EXPORT_PRIVATE Tagged<WasmInstanceObject> wasm_instance() const;
1278 virtual Tagged<WasmTrustedInstanceData> trusted_instance_data() const;
1279 V8_EXPORT_PRIVATE wasm::NativeModule* native_module() const;
1280
1281 virtual wasm::WasmCode* wasm_code() const;
1282 int function_index() const;
1283 Tagged<Script> script() const;
1284 // Byte position in the module, or asm.js source position.
1285 int position() const override;
1286 Tagged<Object> context() const override;
1287 bool at_to_number_conversion() const;
1288 // Generated code byte offset in the function.
1289 int generated_code_offset() const;
1290 bool is_inspectable() const;
1291
1292 FrameSummaries Summarize() const override;
1293
1294 static WasmFrame* cast(StackFrame* frame) {
1295 DCHECK(frame->is_wasm()
1296#ifdef V8_ENABLE_DRUMBRAKE
1297 && !frame->is_wasm_interpreter_entry()
1298#endif // V8_ENABLE_DRUMBRAKE
1299 );
1300 return static_cast<WasmFrame*>(frame);
1301 }
1302
1303 protected:
1304 inline explicit WasmFrame(StackFrameIteratorBase* iterator);
1305
1306 private:
1307 friend class StackFrameIteratorBase;
1308 Tagged<WasmModuleObject> module_object() const;
1309};
1310
1311// WasmSegmentStartFrame is a regular Wasm frame moved to the
1312// beginning of a new stack segment allocated for growable stack.
1313// It requires special handling on return. To indicate that, the WASM frame type
1314// is replaced by WASM_SEGMENT_START.
1315class WasmSegmentStartFrame : public WasmFrame {
1316 public:
1317 // type() intentionally returns WASM frame type because WasmSegmentStartFrame
1318 // behaves exactly like regular WasmFrame in all scenarios.
1319 Type type() const override { return WASM; }
1320
1321 protected:
1322 inline explicit WasmSegmentStartFrame(StackFrameIteratorBase* iterator);
1323
1324 private:
1325 friend class StackFrameIteratorBase;
1326};
1327
1328// Wasm to C-API exit frame.
1329class WasmExitFrame : public WasmFrame {
1330 public:
1331 Type type() const override { return WASM_EXIT; }
1332 static Address ComputeStackPointer(Address fp);
1333
1334 protected:
1335 inline explicit WasmExitFrame(StackFrameIteratorBase* iterator);
1336
1337 private:
1338 friend class StackFrameIteratorBase;
1339};
1340
1341#if V8_ENABLE_DRUMBRAKE
1342class WasmInterpreterEntryFrame final : public WasmFrame {
1343 public:
1344 Type type() const override { return WASM_INTERPRETER_ENTRY; }
1345
1346 // GC support.
1347 void Iterate(RootVisitor* v) const override;
1348
1349 // Printing support.
1350 void Print(StringStream* accumulator, PrintMode mode,
1351 int index) const override;
1352
1353 FrameSummaries Summarize() const override;
1354
1355 // Determine the code for the frame.
1356 Tagged<HeapObject> unchecked_code() const override;
1357
1358 // Accessors.
1359 Tagged<Tuple2> interpreter_object() const;
1360 V8_EXPORT_PRIVATE Tagged<WasmInstanceObject> wasm_instance() const override;
1361 Tagged<WasmTrustedInstanceData> trusted_instance_data() const override;
1362
1363 wasm::WasmCode* wasm_code() const override { UNREACHABLE(); }
1364 int function_index(int inlined_function_index) const;
1365 int position() const override;
1366 Tagged<Object> context() const override;
1367
1368 static WasmInterpreterEntryFrame* cast(StackFrame* frame) {
1369 DCHECK(frame->is_wasm_interpreter_entry());
1370 return static_cast<WasmInterpreterEntryFrame*>(frame);
1371 }
1372
1373 protected:
1374 inline explicit WasmInterpreterEntryFrame(StackFrameIteratorBase* iterator);
1375
1376 Address GetCallerStackPointer() const override;
1377
1378 private:
1379 friend class StackFrameIteratorBase;
1380 Tagged<WasmModuleObject> module_object() const;
1381};
1382#endif // V8_ENABLE_DRUMBRAKE
1383
1384class WasmDebugBreakFrame final : public TypedFrame {
1385 public:
1386 Type type() const override { return WASM_DEBUG_BREAK; }
1387
1388 // GC support.
1389 void Iterate(RootVisitor* v) const override;
1390
1391 void Print(StringStream* accumulator, PrintMode mode,
1392 int index) const override;
1393
1394 static WasmDebugBreakFrame* cast(StackFrame* frame) {
1395 DCHECK(frame->is_wasm_debug_break());
1396 return static_cast<WasmDebugBreakFrame*>(frame);
1397 }
1398
1399 protected:
1400 inline explicit WasmDebugBreakFrame(StackFrameIteratorBase*);
1401
1402 private:
1403 friend class StackFrameIteratorBase;
1404};
1405
1406class WasmToJsFrame : public WasmFrame {
1407 public:
1408 Type type() const override { return WASM_TO_JS; }
1409
1410#if V8_ENABLE_DRUMBRAKE
1411 void Iterate(RootVisitor* v) const override;
1412#endif // V8_ENABLE_DRUMBRAKE
1413
1414 int position() const override { return 0; }
1415 Tagged<WasmInstanceObject> wasm_instance() const override;
1416 Tagged<WasmTrustedInstanceData> trusted_instance_data() const override;
1417
1418 protected:
1419 inline explicit WasmToJsFrame(StackFrameIteratorBase* iterator);
1420
1421 private:
1422 friend class StackFrameIteratorBase;
1423};
1424
1425class WasmToJsFunctionFrame : public TypedFrame {
1426 public:
1427 Type type() const override { return WASM_TO_JS_FUNCTION; }
1428
1429 protected:
1430 inline explicit WasmToJsFunctionFrame(StackFrameIteratorBase* iterator);
1431
1432 private:
1433 friend class StackFrameIteratorBase;
1434};
1435
1436class JsToWasmFrame : public StubFrame {
1437 public:
1438 Type type() const override { return JS_TO_WASM; }
1439
1440 void Iterate(RootVisitor* v) const override;
1441
1442 protected:
1443 inline explicit JsToWasmFrame(StackFrameIteratorBase* iterator);
1444
1445 private:
1446 friend class StackFrameIteratorBase;
1447};
1448
1449class StackSwitchFrame : public ExitFrame {
1450 public:
1451 Type type() const override { return STACK_SWITCH; }
1452 void Iterate(RootVisitor* v) const override;
1453 static void GetStateForJumpBuffer(wasm::JumpBuffer* jmpbuf, State* state);
1454
1455 protected:
1456 inline explicit StackSwitchFrame(StackFrameIteratorBase* iterator);
1457
1458 private:
1459 friend class StackFrameIteratorBase;
1460};
1461
1462class CWasmEntryFrame : public StubFrame {
1463 public:
1464 Type type() const override { return C_WASM_ENTRY; }
1465
1466#if V8_ENABLE_DRUMBRAKE
1467 void Iterate(RootVisitor* v) const override;
1468#endif // V8_ENABLE_DRUMBRAKE
1469
1470 protected:
1471 inline explicit CWasmEntryFrame(StackFrameIteratorBase* iterator);
1472
1473 private:
1474 friend class StackFrameIteratorBase;
1475 Type GetCallerState(State* state) const override;
1476};
1477
1478class WasmLiftoffSetupFrame : public TypedFrame {
1479 public:
1480 Type type() const override { return WASM_LIFTOFF_SETUP; }
1481
1482 FullObjectSlot wasm_instance_data_slot() const;
1483
1484 int GetDeclaredFunctionIndex() const;
1485
1486 wasm::NativeModule* GetNativeModule() const;
1487
1488 // Garbage collection support.
1489 void Iterate(RootVisitor* v) const override;
1490
1491 static WasmLiftoffSetupFrame* cast(StackFrame* frame) {
1492 DCHECK(frame->is_wasm_liftoff_setup());
1493 return static_cast<WasmLiftoffSetupFrame*>(frame);
1494 }
1495
1496 protected:
1497 inline explicit WasmLiftoffSetupFrame(StackFrameIteratorBase* iterator);
1498
1499 private:
1500 friend class StackFrameIteratorBase;
1501};
1502#endif // V8_ENABLE_WEBASSEMBLY
1503
1505 public:
1506 Type type() const override { return INTERNAL; }
1507
1508 // Garbage collection support.
1509 void Iterate(RootVisitor* v) const override;
1510
1512 DCHECK(frame->is_internal());
1513 return static_cast<InternalFrame*>(frame);
1514 }
1515
1516 protected:
1517 inline explicit InternalFrame(StackFrameIteratorBase* iterator);
1518
1519 private:
1521};
1522
1523// Construct frames are special trampoline frames introduced to handle
1524// function invocations through 'new'.
1526 public:
1527 Type type() const override { return CONSTRUCT; }
1528
1530 DCHECK(frame->is_construct());
1531 return static_cast<ConstructFrame*>(frame);
1532 }
1533
1534 void Iterate(RootVisitor* v) const override;
1535
1536 protected:
1537 inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
1538
1539 private:
1541};
1542
1543// Fast construct frames are special construct trampoline frames that avoid
1544// pushing arguments to the stack twice.
1546 public:
1547 Type type() const override { return FAST_CONSTRUCT; }
1548
1550 DCHECK(frame->is_fast_construct());
1551 return static_cast<FastConstructFrame*>(frame);
1552 }
1553
1554 protected:
1555 inline explicit FastConstructFrame(StackFrameIteratorBase* iterator);
1556
1557 private:
1559};
1560
1562 public:
1563 Type type() const override { return BUILTIN_CONTINUATION; }
1564
1567 return static_cast<BuiltinContinuationFrame*>(frame);
1568 }
1569
1570 protected:
1571 inline explicit BuiltinContinuationFrame(StackFrameIteratorBase* iterator);
1572
1573 private:
1575};
1576
1578 public:
1579 Type type() const override { return JAVASCRIPT_BUILTIN_CONTINUATION; }
1580
1585
1586 Tagged<JSFunction> function() const override;
1587 int ComputeParametersCount() const override;
1588 intptr_t GetSPToFPDelta() const;
1589
1590 Tagged<Object> context() const override;
1591
1592 protected:
1593 inline explicit JavaScriptBuiltinContinuationFrame(
1594 StackFrameIteratorBase* iterator);
1595
1596 private:
1598};
1599
1602 public:
1603 Type type() const override {
1604 return JAVASCRIPT_BUILTIN_CONTINUATION_WITH_CATCH;
1605 }
1606
1611
1612 // Patch in the exception object at the appropriate location into the stack
1613 // frame.
1614 void SetException(Tagged<Object> exception);
1615
1616 protected:
1618 StackFrameIteratorBase* iterator);
1619
1620 private:
1622};
1623
1625 public:
1626 Type type() const override { return IRREGEXP; }
1627
1628 void Iterate(RootVisitor* v) const override {
1629 // Irregexp frames should not be visited by GC because they are not visible
1630 // to any stack iterator except StackFrameIteratorForProfiler, which is not
1631 // used by GC.
1632 UNREACHABLE();
1633 }
1634
1636 DCHECK(frame->is_irregexp());
1637 return static_cast<IrregexpFrame*>(frame);
1638 }
1639
1640 protected:
1641 inline explicit IrregexpFrame(StackFrameIteratorBase* iterator);
1642
1643 private:
1645};
1646
1648 public:
1651
1652 Isolate* isolate() const { return isolate_; }
1653#if V8_ENABLE_WEBASSEMBLY
1654 wasm::StackMemory* wasm_stack() const { return wasm_stack_; }
1655#endif
1656
1657 bool done() const { return frame_ == nullptr; }
1658
1659#ifdef DEBUG
1660 // The StackFrameIteratorForProfiler is limited in functionality because it
1661 // may run at an arbitrary point in time where stack contents are not
1662 // guaranteed to be in a consistent state and heap accesses may be limited.
1663 virtual bool IsStackFrameIteratorForProfiler() const = 0;
1664#endif // DEBUG
1666 StackFrame::State* state) const = 0;
1667
1668 protected:
1669 // An iterator that iterates over a given thread's stack.
1670 explicit StackFrameIteratorBase(Isolate* isolate);
1671
1673 union {
1675#define DECLARE_SINGLETON(ignore, type) type type##_;
1677#undef DECLARE_SINGLETON
1678 };
1681#if V8_ENABLE_WEBASSEMBLY
1682 // Stop at the end of the topmost (wasm) stack.
1683 bool first_stack_only_ = false;
1684 // // Current wasm stack being iterated.
1685 wasm::StackMemory* wasm_stack_ = nullptr;
1686#endif
1687
1689 DCHECK(!done());
1690 return handler_;
1691 }
1692
1693 // Update the current frame to the given state.
1695 // A helper function, can set the frame to nullptr.
1696 void SetNewFrame(StackFrame::Type type);
1697
1698 private:
1699 friend class StackFrame;
1700};
1701
1703 public:
1704 // An iterator that iterates over the isolate's current thread's stack,
1705 V8_EXPORT_PRIVATE explicit StackFrameIterator(Isolate* isolate);
1706 // An iterator that iterates over a given thread's stack.
1708#if V8_ENABLE_WEBASSEMBLY
1709 // Depending on the use case, users of the StackFrameIterator should either:
1710 // - Use the default constructor, which iterates the active stack and its
1711 // ancestors, but not the suspended stacks.
1712 // - Or use the constructor below to iterate the topmost stack only, and
1713 // iterate the {Isolate::wasm_stacks()} list on the side to visit all
1714 // inactive stacks.
1715 struct FirstStackOnly {};
1717 FirstStackOnly);
1718 // An iterator that iterates over a given wasm stack segment.
1720 wasm::StackMemory* stack);
1721#endif
1722
1725
1727 DCHECK(!done());
1728 return frame_;
1729 }
1732
1733#if V8_ENABLE_WEBASSEMBLY
1734 // Go to the first frame of this stack.
1735 void Reset(ThreadLocalTop* top, wasm::StackMemory* stack);
1736#endif
1737
1738#ifdef DEBUG
1739 bool IsStackFrameIteratorForProfiler() const override { return false; }
1740#endif // DEBUG
1742 StackFrame::State* state) const override;
1743
1744 private:
1745 // Go back to the first frame.
1746 void Reset(ThreadLocalTop* top);
1747};
1748
1749// A wrapper around StackFrameIterator that skips over all non-JS frames.
1751 public:
1752 explicit JavaScriptStackFrameIterator(Isolate* isolate) : iterator_(isolate) {
1753 if (!done()) Advance();
1754 }
1756 : iterator_(isolate, top) {
1757 if (!done()) Advance();
1758 }
1759
1762 }
1766 bool done() const { return iterator_.done(); }
1767
1769
1770 private:
1772};
1773
1774// A wrapper around StackFrameIterator that skips over all non-debuggable
1775// frames (i.e. it iterates over Wasm and debuggable JS frames).
1777 public:
1778 explicit DebuggableStackFrameIterator(Isolate* isolate);
1779 // Skip frames until the frame with the given id is reached.
1781
1782 bool done() const { return iterator_.done(); }
1783 void Advance();
1784 int FrameFunctionCount() const;
1785
1786 inline CommonFrame* frame() const;
1787 inline CommonFrame* Reframe();
1788
1789 inline bool is_javascript() const;
1790#if V8_ENABLE_WEBASSEMBLY
1791 inline bool is_wasm() const;
1792#if V8_ENABLE_DRUMBRAKE
1793 inline bool is_wasm_interpreter_entry() const;
1794#endif // V8_ENABLE_DRUMBRAKE
1795#endif // V8_ENABLE_WEBASSEMBLY
1796 inline JavaScriptFrame* javascript_frame() const;
1797
1798 // Use this instead of FrameSummary::GetTop(javascript_frame) to keep
1799 // filtering behavior consistent with the rest of
1800 // DebuggableStackFrameIterator.
1801 FrameSummary GetTopValidFrame() const;
1802
1803 private:
1805 static bool IsValidFrame(StackFrame* frame);
1806};
1807
1808// Similar to StackFrameIterator, but can be created and used at any time and
1809// any stack state. Currently, the only user is the profiler; if this ever
1810// changes, find another name for this class.
1811// IMPORTANT: Do not mark this class as V8_EXPORT_PRIVATE. The profiler creates
1812// instances of this class from a signal handler. If we use V8_EXPORT_PRIVATE
1813// "ld" inserts a symbol stub for the constructor call that may crash with
1814// a stackoverflow when called from a signal handler.
1816 public:
1818 Address sp, Address lr, Address js_entry_sp);
1819
1820 inline StackFrame* frame() const;
1821 void Advance();
1822
1824
1825#ifdef DEBUG
1826 bool IsStackFrameIteratorForProfiler() const override { return true; }
1827#endif // DEBUG
1829 StackFrame::State* state) const override;
1830
1831 private:
1832 void AdvanceOneFrame();
1833
1834 bool IsValidStackAddress(Address addr) const {
1835 return low_bound_ <= addr && addr <= high_bound_;
1836 }
1837 bool IsValidState(const StackFrame::State& frame) const;
1838 bool HasValidExitIfEntryFrame(const StackFrame* frame) const;
1839 bool IsValidExitFrame(Address fp) const;
1840 bool IsValidTop(ThreadLocalTop* top) const;
1841 static bool IsValidFrameType(StackFrame::Type type);
1842
1844 StackFrame::State* state);
1845
1846 // Returns true if the pc points to a bytecode handler and the frame pointer
1847 // doesn't seem to be a bytecode handler's frame, which implies that the
1848 // bytecode handler has an elided frame. This is not precise and might give
1849 // false negatives since it relies on checks to the frame's type marker,
1850 // which might be uninitialized.
1852 Address fp) const;
1853
1859#if V8_ENABLE_WEBASSEMBLY
1860 std::vector<std::unique_ptr<wasm::StackMemory>>& wasm_stacks_;
1861#endif
1862};
1863
1864// We cannot export 'StackFrameIteratorForProfiler' for cctests since the
1865// linker inserted symbol stub may cause a stack overflow
1866// (https://crbug.com/1449195).
1867// We subclass it and export the subclass instead.
1870 public:
1872 Address fp, Address sp, Address lr,
1873 Address js_entry_sp);
1874 // Redeclare methods needed by the test. Otherwise we'd have to
1875 // export individual methods on the base class (which we don't want to risk).
1876 void Advance();
1877};
1878
1879// Frame layout helper classes. Used by the deoptimizer and instruction
1880// selector.
1881// -------------------------------------------------------------------------
1882
1883// How to calculate the frame layout information. Precise, when all information
1884// is available during deoptimization. Conservative, when an overapproximation
1885// is fine.
1886// TODO(jgruber): Investigate whether the conservative kind can be removed. It
1887// seems possible: 1. is_topmost should be known through the outer_state chain
1888// of FrameStateDescriptor; 2. the deopt_kind may be a property of the bailout
1889// id; 3. for continuation_mode, we only care whether it is a mode with catch,
1890// and that is likewise known at compile-time.
1891// There is nothing specific blocking this, the investigation just requires time
1892// and it is not that important to get the exact frame height at compile-time.
1893enum class FrameInfoKind {
1894 kPrecise,
1896};
1897
1898// Used by the deoptimizer. Corresponds to frame kinds:
1900 STUB, // BuiltinContinuationFrame
1901 JAVASCRIPT, // JavaScriptBuiltinContinuationFrame
1902 JAVASCRIPT_WITH_CATCH, // JavaScriptBuiltinContinuationWithCatchFrame
1903 JAVASCRIPT_HANDLE_EXCEPTION // JavaScriptBuiltinContinuationWithCatchFrame
1904};
1905
1907 public:
1908 static UnoptimizedFrameInfo Precise(int parameters_count_with_receiver,
1909 int translation_height, bool is_topmost,
1910 bool pad_arguments) {
1911 return {parameters_count_with_receiver, translation_height, is_topmost,
1912 pad_arguments, FrameInfoKind::kPrecise};
1913 }
1914
1915 static UnoptimizedFrameInfo Conservative(int parameters_count_with_receiver,
1916 int locals_count) {
1917 return {parameters_count_with_receiver, locals_count, false, true,
1919 }
1920
1921 static uint32_t GetStackSizeForAdditionalArguments(int parameters_count);
1922
1923 uint32_t register_stack_slot_count() const {
1925 }
1929 uint32_t frame_size_in_bytes() const { return frame_size_in_bytes_; }
1930
1931 private:
1932 UnoptimizedFrameInfo(int parameters_count_with_receiver,
1933 int translation_height, bool is_topmost,
1934 bool pad_arguments, FrameInfoKind frame_info_kind);
1935
1939};
1940
1942 public:
1943 static ConstructStubFrameInfo Precise(int translation_height,
1944 bool is_topmost) {
1945 return {translation_height, is_topmost, FrameInfoKind::kPrecise};
1946 }
1947
1948 static ConstructStubFrameInfo Conservative(int parameters_count) {
1949 return {parameters_count, false, FrameInfoKind::kConservative};
1950 }
1951
1955 uint32_t frame_size_in_bytes() const { return frame_size_in_bytes_; }
1956
1957 private:
1958 ConstructStubFrameInfo(int translation_height, bool is_topmost,
1959 FrameInfoKind frame_info_kind);
1960
1963};
1964
1966 public:
1967 static FastConstructStubFrameInfo Precise(bool is_topmost) {
1968 return FastConstructStubFrameInfo(is_topmost);
1969 }
1970
1972 // Assume it is the top most frame when conservative.
1973 return FastConstructStubFrameInfo(true);
1974 }
1975
1979 uint32_t frame_size_in_bytes() const { return frame_size_in_bytes_; }
1980
1981 private:
1982 explicit FastConstructStubFrameInfo(bool is_topmost);
1983
1986};
1987
1988// Used by BuiltinContinuationFrameInfo.
1991
1993 public:
1995 int translation_height,
1996 const CallInterfaceDescriptor& continuation_descriptor,
1997 const RegisterConfiguration* register_config, bool is_topmost,
1998 DeoptimizeKind deopt_kind, BuiltinContinuationMode continuation_mode) {
1999 return {translation_height,
2000 continuation_descriptor,
2001 register_config,
2002 is_topmost,
2003 deopt_kind,
2004 continuation_mode,
2006 }
2007
2009 int parameters_count,
2010 const CallInterfaceDescriptor& continuation_descriptor,
2011 const RegisterConfiguration* register_config) {
2012 // It doesn't matter what we pass as is_topmost, deopt_kind and
2013 // continuation_mode; these values are ignored in conservative mode.
2014 return {parameters_count,
2015 continuation_descriptor,
2016 register_config,
2017 false,
2021 }
2022
2030 uint32_t frame_size_in_bytes() const { return frame_size_in_bytes_; }
2033 }
2034
2035 private:
2037 int translation_height,
2038 const CallInterfaceDescriptor& continuation_descriptor,
2039 const RegisterConfiguration* register_config, bool is_topmost,
2040 DeoptimizeKind deopt_kind, BuiltinContinuationMode continuation_mode,
2041 FrameInfoKind frame_info_kind);
2042
2048};
2049
2050} // namespace internal
2051} // namespace v8
2052
2053#endif // V8_EXECUTION_FRAMES_H_
Isolate * isolate_
#define BUILTIN(name)
Builtins::Kind kind
Definition builtins.cc:40
#define ENTRY(Name,...)
static ApiAccessorExitFrame * cast(StackFrame *frame)
Definition frames.h:1036
FullObjectSlot receiver_slot() const
Definition frames-inl.h:221
FullObjectSlot property_name_slot() const
Definition frames-inl.h:216
FrameSummaries Summarize() const override
Definition frames.cc:1357
FullObjectSlot holder_slot() const
Definition frames-inl.h:225
Tagged< Object > receiver() const
Definition frames-inl.h:233
ApiAccessorExitFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:212
Type type() const override
Definition frames.h:1023
Tagged< Object > holder() const
Definition frames-inl.h:237
void Print(StringStream *accumulator, PrintMode mode, int index) const override
Definition frames.cc:1447
Tagged< Name > property_name() const
Definition frames-inl.h:229
void Print(StringStream *accumulator, PrintMode mode, int index) const override
Definition frames.cc:1424
FullObjectSlot target_slot() const
Definition frames-inl.h:172
DirectHandle< JSFunction > GetFunction() const
Definition frames.cc:1280
FrameSummaries Summarize() const override
Definition frames.cc:1328
void set_target(Tagged< HeapObject > function) const
Definition frames-inl.h:187
DirectHandle< FunctionTemplateInfo > GetFunctionTemplateInfo() const
Definition frames.cc:1304
Tagged< Object > context() const override
Definition frames-inl.h:167
Tagged< HeapObject > target() const
Definition frames-inl.h:181
static ApiCallbackExitFrame * cast(StackFrame *frame)
Definition frames.h:997
ApiCallbackExitFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:163
Tagged< Object > GetParameter(int i) const
Definition frames-inl.h:199
DirectHandle< FixedArray > GetParameters() const
Definition frames.cc:1316
Tagged< Object > receiver() const
Definition frames-inl.h:176
Type type() const override
Definition frames.h:973
int GetBytecodeOffset() const override
Definition frames.cc:3353
Type type() const override
Definition frames.h:1170
static const BaselineFrame * cast(const StackFrame *frame)
Definition frames.h:1183
void PatchContext(Tagged< Context > value)
Definition frames.cc:3364
BaselineFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:312
intptr_t GetPCForBytecodeOffset(int lookup_offset) const
Definition frames.cc:3358
static BaselineFrame * cast(StackFrame *frame)
Definition frames.h:1179
BuiltinContinuationFrameInfo(int translation_height, const CallInterfaceDescriptor &continuation_descriptor, const RegisterConfiguration *register_config, bool is_topmost, DeoptimizeKind deopt_kind, BuiltinContinuationMode continuation_mode, FrameInfoKind frame_info_kind)
Definition frames.cc:4287
uint32_t translated_stack_parameter_count() const
Definition frames.h:2026
static BuiltinContinuationFrameInfo Conservative(int parameters_count, const CallInterfaceDescriptor &continuation_descriptor, const RegisterConfiguration *register_config)
Definition frames.h:2008
static BuiltinContinuationFrameInfo Precise(int translation_height, const CallInterfaceDescriptor &continuation_descriptor, const RegisterConfiguration *register_config, bool is_topmost, DeoptimizeKind deopt_kind, BuiltinContinuationMode continuation_mode)
Definition frames.h:1994
BuiltinContinuationFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:375
static BuiltinContinuationFrame * cast(StackFrame *frame)
Definition frames.h:1565
Tagged< Object > argc_slot_object() const
Definition frames-inl.h:148
Tagged< Object > new_target_slot_object() const
Definition frames-inl.h:158
Type type() const override
Definition frames.h:936
Tagged< JSFunction > function() const
Definition frames.cc:1224
Tagged< Object > GetParameter(int i) const
Definition frames.cc:1232
void Print(StringStream *accumulator, PrintMode mode, int index) const override
Definition frames.cc:1395
DirectHandle< FixedArray > GetParameters() const
Definition frames.cc:1251
Tagged< Object > receiver_slot_object() const
Definition frames-inl.h:143
BuiltinExitFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:140
Tagged< Object > target_slot_object() const
Definition frames-inl.h:153
FrameSummaries Summarize() const override
Definition frames.cc:1212
Tagged< Object > receiver() const
Definition frames.cc:1228
static BuiltinFrame * cast(StackFrame *frame)
Definition frames.h:1247
int ComputeParametersCount() const override
Definition frames.cc:3374
BuiltinFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:321
Type type() const final
Definition frames.h:1245
Tagged< JSFunction > function() const override
Definition frames.cc:3369
virtual int ComputeParametersCount() const
Definition frames.cc:2624
Address GetParameterSlot(int index) const
Definition frames-inl.h:269
CommonFrameWithJSLinkage(StackFrameIteratorBase *iterator)
Definition frames-inl.h:119
FrameSummaries Summarize() const override
Definition frames.cc:2479
virtual int GetActualArgumentCount() const
Definition frames-inl.h:277
Tagged< HeapObject > unchecked_code() const override
Definition frames.cc:2418
virtual bool IsConstructor() const
Definition frames.cc:2475
virtual int LookupExceptionHandlerInTable(int *data, HandlerTable::CatchPrediction *prediction)
Definition frames.cc:2521
DirectHandle< FixedArray > GetParameters() const
Definition frames.cc:2638
static bool IsConstructFrame(Address fp)
Definition frames-inl.h:259
virtual Tagged< JSFunction > function() const =0
virtual Tagged< Object > GetParameter(int index) const
Definition frames.cc:2620
virtual Tagged< Object > receiver() const
Definition frames.cc:2505
Address GetCallerStackPointer() const override
Definition frames.cc:1065
CommonFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:239
int ComputeExpressionsCount() const
Definition frames.cc:1481
virtual Tagged< Object > context() const
Definition frames.cc:1470
void ComputeCallerState(State *state) const override
Definition frames.cc:1489
bool HasTaggedOutgoingParams(Tagged< GcSafeCode > code_lookup) const
Definition frames.cc:2240
Address caller_fp() const
Definition frames-inl.h:250
void SetExpression(int index, Tagged< Object > value)
Definition frames-inl.h:246
void IterateTurbofanJSOptimizedFrame(RootVisitor *v) const
Definition frames.cc:2272
virtual int position() const
Definition frames.cc:1474
Address caller_pc() const
Definition frames-inl.h:254
Tagged< Object > GetExpression(int index) const
Definition frames-inl.h:242
void IterateExpressions(RootVisitor *v) const
Definition frames.cc:4091
virtual FrameSummaries Summarize() const
Definition frames.cc:1508
static CommonFrame * cast(StackFrame *frame)
Definition frames.h:662
virtual Address GetExpressionAddress(int n) const
Definition frames.cc:1460
Type type() const override
Definition frames.h:884
static ConstructEntryFrame * cast(StackFrame *frame)
Definition frames.h:888
Tagged< HeapObject > unchecked_code() const override
Definition frames.cc:1118
ConstructEntryFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:133
Type type() const override
Definition frames.h:1527
static ConstructFrame * cast(StackFrame *frame)
Definition frames.h:1529
ConstructFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:369
void Iterate(RootVisitor *v) const override
Definition frames.cc:326
uint32_t frame_size_in_bytes() const
Definition frames.h:1955
static ConstructStubFrameInfo Conservative(int parameters_count)
Definition frames.h:1948
static ConstructStubFrameInfo Precise(int translation_height, bool is_topmost)
Definition frames.h:1943
uint32_t frame_size_in_bytes_without_fixed() const
Definition frames.h:1952
ConstructStubFrameInfo(int translation_height, bool is_topmost, FrameInfoKind frame_info_kind)
Definition frames.cc:4243
Type type() const override
Definition frames.h:855
Tagged< HeapObject > unchecked_code() const override
Definition frames.cc:1078
Type GetCallerState(State *state) const override
Definition frames.cc:1086
EntryFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:130
Address GetCallerStackPointer() const override
Definition frames.h:873
static EntryFrame * cast(StackFrame *frame)
Definition frames.h:862
void Iterate(RootVisitor *v) const override
Definition frames.cc:4087
void ComputeCallerState(State *state) const override
Definition frames.cc:1082
ExitFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:137
void ComputeCallerState(State *state) const override
Definition frames.cc:1122
static StackFrame::Type ComputeFrameType(Address fp)
Definition frames.cc:1155
static void FillState(Address fp, Address sp, State *state)
Definition frames.cc:1199
Type type() const override
Definition frames.h:904
void Iterate(RootVisitor *v) const override
Definition frames.cc:1135
static Address ComputeStackPointer(Address fp)
Definition frames.cc:1182
static ExitFrame * cast(StackFrame *frame)
Definition frames.h:909
static Type GetStateForFramePointer(Address fp, State *state)
Definition frames.cc:1141
FastConstructFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:372
Type type() const override
Definition frames.h:1547
static FastConstructFrame * cast(StackFrame *frame)
Definition frames.h:1549
uint32_t frame_size_in_bytes_without_fixed() const
Definition frames.h:1976
static FastConstructStubFrameInfo Conservative()
Definition frames.h:1971
static FastConstructStubFrameInfo Precise(bool is_topmost)
Definition frames.h:1967
FrameSummaryBase(Isolate *isolate, Kind kind)
Definition frames.h:428
Handle< JSFunction > function() const
Definition frames.h:449
Handle< AbstractCode > abstract_code() const
Definition frames.h:450
DirectHandle< FixedArray > parameters() const
Definition frames.h:453
bool is_subject_to_debugging() const
DirectHandle< Context > native_context() const
int SourceStatementPosition() const
FrameSummaryBase base_
Definition frames.h:619
Handle< Object > script() const
DirectHandle< StackFrameInfo > CreateStackFrameInfo() const
Handle< Object > receiver() const
static InternalFrame * cast(StackFrame *frame)
Definition frames.h:1511
Type type() const override
Definition frames.h:1506
InternalFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:366
void Iterate(RootVisitor *v) const override
Definition frames.cc:4114
static InterpretedFrame * cast(StackFrame *frame)
Definition frames.h:1152
void PatchBytecodeOffset(int new_offset)
Definition frames.cc:3335
Type type() const override
Definition frames.h:1139
void PatchBytecodeArray(Tagged< BytecodeArray > bytecode_array)
Definition frames.cc:3344
InterpretedFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:309
static const InterpretedFrame * cast(const StackFrame *frame)
Definition frames.h:1156
int GetBytecodeOffset() const override
Definition frames.cc:3326
IrregexpFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:388
static IrregexpFrame * cast(StackFrame *frame)
Definition frames.h:1635
void Iterate(RootVisitor *v) const override
Definition frames.h:1628
Type type() const override
Definition frames.h:1626
Tagged< JSFunction > function() const override
Definition frames.cc:2652
Tagged< Object > context() const override
Definition frames.cc:2674
JavaScriptBuiltinContinuationFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:379
static JavaScriptBuiltinContinuationFrame * cast(StackFrame *frame)
Definition frames.h:1581
JavaScriptBuiltinContinuationWithCatchFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:384
static JavaScriptBuiltinContinuationWithCatchFrame * cast(StackFrame *frame)
Definition frames.h:1607
bool IsConstructor() const override
Definition frames.cc:2414
Type type() const override=0
Address GetCallerStackPointer() const override
Definition frames.cc:2432
Tagged< JSFunction > function() const override
Definition frames.cc:2492
void Print(StringStream *accumulator, PrintMode mode, int index) const override
Definition frames.cc:3974
Tagged< Object > function_slot_object() const
Definition frames-inl.h:291
void SetParameterValue(int index, Tagged< Object > value) const
Definition frames.cc:2410
void Iterate(RootVisitor *v) const override
Definition frames.cc:4101
static void CollectFunctionAndOffsetForICStats(Isolate *isolate, Tagged< JSFunction > function, Tagged< AbstractCode > code, int code_offset)
Definition frames.cc:2597
virtual void GetFunctions(std::vector< Tagged< SharedFunctionInfo > > *functions) const
Definition frames.cc:2436
static void PrintTop(Isolate *isolate, FILE *file, bool print_args, bool print_line_number)
Definition frames.cc:2562
int GetActualArgumentCount() const override
Definition frames.cc:2632
JavaScriptFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:266
virtual void PrintFrameKind(StringStream *accumulator) const
Definition frames.h:828
void set_receiver(Tagged< Object > value)
Definition frames-inl.h:281
bool is_unoptimized() const
Definition frames.h:801
Tagged< Script > script() const
Definition frames.cc:2517
static Register constant_pool_pointer_register()
std::tuple< Tagged< AbstractCode >, int > GetActiveCodeAndOffset() const
Definition frames.cc:2453
static void PrintFunctionAndOffset(Isolate *isolate, Tagged< JSFunction > function, Tagged< AbstractCode > code, int code_offset, FILE *file, bool print_line_number)
Definition frames.cc:2532
Tagged< Object > unchecked_function() const
Definition frames.cc:2496
Tagged< Object > context() const override
Definition frames.cc:2510
static JavaScriptFrame * cast(StackFrame *frame)
Definition frames.h:805
JavaScriptStackFrameIterator(Isolate *isolate)
Definition frames.h:1752
JavaScriptFrame * frame() const
Definition frames.h:1760
V8_EXPORT_PRIVATE void Advance()
Definition frames.cc:341
JavaScriptStackFrameIterator(Isolate *isolate, ThreadLocalTop *top)
Definition frames.h:1755
BytecodeOffset GetBytecodeOffsetForOSR() const
Definition frames.cc:2208
Type type() const override
Definition frames.h:1197
DirectHandle< JSFunction > GetInnermostFunction() const
Definition frames.cc:2204
static MaglevFrame * cast(StackFrame *frame)
Definition frames.h:1199
int FindReturnPCForTrampoline(Tagged< Code > code, int trampoline_pc) const override
Definition frames.cc:3192
void Iterate(RootVisitor *v) const override
Definition frames.cc:2097
MaglevFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:315
static intptr_t StackGuardFrameSize(int register_input_count)
Type type() const override
Definition frames.h:838
void Iterate(RootVisitor *v) const override
Definition frames.h:841
void ComputeCallerState(State *state) const override
Definition frames.cc:1069
NativeFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:127
FrameSummaries Summarize() const override
Definition frames.cc:3033
void GetFunctions(std::vector< Tagged< SharedFunctionInfo > > *functions) const override
Definition frames.cc:3235
OptimizedJSFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:303
virtual int FindReturnPCForTrampoline(Tagged< Code > code, int trampoline_pc) const =0
int LookupExceptionHandlerInTable(int *data, HandlerTable::CatchPrediction *prediction) override
Definition frames.cc:3156
static int StackSlotOffsetRelativeToFp(int slot_index)
Definition frames.cc:3275
Tagged< DeoptimizationData > GetDeoptimizationData(Tagged< Code > code, int *deopt_index) const
Definition frames.cc:3208
StackFrameIteratorBase(const StackFrameIteratorBase &)=delete
void SetNewFrame(StackFrame::Type type, StackFrame::State *state)
Definition frames.cc:290
StackFrameIteratorBase & operator=(const StackFrameIteratorBase &)=delete
StackHandler * handler() const
Definition frames.h:1688
virtual StackFrame::Type ComputeStackFrameType(StackFrame::State *state) const =0
bool IsValidStackAddress(Address addr) const
Definition frames.h:1834
StackFrame::Type GetCallerIfValid(StackFrame *frame, StackFrame::State *state)
bool IsValidTop(ThreadLocalTop *top) const
Definition frames.cc:613
bool IsValidState(const StackFrame::State &frame) const
Definition frames.cc:652
StackFrameIteratorForProfiler(Isolate *isolate, Address pc, Address fp, Address sp, Address lr, Address js_entry_sp)
Definition frames.cc:472
bool HasValidExitIfEntryFrame(const StackFrame *frame) const
Definition frames.cc:657
bool IsValidExitFrame(Address fp) const
Definition frames.cc:674
bool IsNoFrameBytecodeHandlerPc(Isolate *isolate, Address pc, Address fp) const
Definition frames.cc:447
StackFrame::Type ComputeStackFrameType(StackFrame::State *state) const override
Definition frames.cc:1007
ExternalCallbackScope * external_callback_scope_
Definition frames.h:1857
StackFrame::Type top_frame_type() const
Definition frames.h:1823
static bool IsValidFrameType(StackFrame::Type type)
Definition frames-inl.h:428
V8_EXPORT_PRIVATE void Advance()
Definition frames.cc:161
StackFrameIterator(const StackFrameIterator &)=delete
StackFrame * frame() const
Definition frames.h:1726
void Reset(ThreadLocalTop *top)
Definition frames.cc:255
StackFrameIterator & operator=(const StackFrameIterator &)=delete
V8_EXPORT_PRIVATE StackFrameIterator(Isolate *isolate)
Definition frames.cc:137
StackFrame::Type ComputeStackFrameType(StackFrame::State *state) const override
Definition frames.cc:903
static constexpr int32_t TypeToMarker(Type type)
Definition frames.h:196
V8_EXPORT_PRIVATE Tagged< GcSafeCode > GcSafeLookupCode() const
Definition frames.cc:745
Address unauthenticated_pc() const
Definition frames-inl.h:80
bool is_stack_exit_frame() const
Definition frames.h:305
static const intptr_t kIsolateTag
Definition frames.h:400
bool is_baseline() const
Definition frames.h:242
bool is_builtin_exit() const
Definition frames.h:279
V8_EXPORT_PRIVATE Tagged< Code > LookupCode() const
Definition frames.cc:757
static ReturnAddressLocationResolver return_address_location_resolver_
Definition frames.h:392
bool is_builtin_continuation() const
Definition frames.h:268
V8_EXPORT_PRIVATE std::pair< Tagged< Code >, int > LookupCodeAndOffset() const
Definition frames.cc:762
Address caller_sp() const
Definition frames.h:300
bool is_profiler_entry_frame() const
Definition frames.h:302
static constexpr bool IsTypeMarker(uintptr_t function_or_marker)
Definition frames.h:214
static Address maybe_unauthenticated_pc(Address *pc_address)
Address callee_fp() const
Definition frames.h:298
Address sp() const
Definition frames.h:293
static bool IsJavaScript(Type t)
Definition frames.h:284
static constexpr Type MarkerToType(intptr_t marker)
Definition frames.h:205
Address constant_pool() const
Definition frames.h:322
virtual Type type() const =0
bool InFastCCall() const
Definition frames.h:320
bool is_javascript() const
Definition frames.h:290
bool is_construct() const
Definition frames.h:277
bool is_builtin() const
Definition frames.h:266
virtual Address GetCallerStackPointer() const =0
Isolate *const isolate_
Definition frames.h:389
bool is_maglev() const
Definition frames.h:243
virtual void ComputeCallerState(State *state) const =0
Address * pc_address() const
Definition frames.h:327
Isolate * isolate() const
Definition frames.h:376
bool is_entry() const
Definition frames.h:230
bool is_internal() const
Definition frames.h:267
static Address * ResolveReturnAddressLocation(Address *pc_address)
Definition frames-inl.h:107
StackHandler * top_handler() const
Definition frames-inl.h:74
bool is_api_callback_exit() const
Definition frames.h:281
bool is_exit() const
Definition frames.h:232
void set_constant_pool(Address constant_pool)
Definition frames.h:323
virtual void Iterate(RootVisitor *v) const =0
bool is_unoptimized_js() const
Definition frames.h:237
Address callee_pc() const
Definition frames.h:299
const StackFrameIteratorBase *const iterator_
Definition frames.h:386
virtual Type GetCallerState(State *state) const
Definition frames.cc:1060
bool is_javascript_builtin_with_catch_continuation() const
Definition frames.h:274
StackFrameId id() const
Definition frames.h:334
Address pc() const
Definition frames-inl.h:78
Address * constant_pool_address() const
Definition frames.h:329
bool is_construct_entry() const
Definition frames.h:231
Address fp() const
Definition frames.h:297
V8_EXPORT_PRIVATE std::pair< Tagged< GcSafeCode >, int > GcSafeLookupCodeAndOffset() const
Definition frames.cc:749
bool is_javascript_builtin_continuation() const
Definition frames.h:271
static void SetReturnAddressLocationResolver(ReturnAddressLocationResolver resolver)
Definition frames.cc:813
bool is_interpreted() const
Definition frames.h:241
virtual void Print(StringStream *accumulator, PrintMode mode, int index) const
Definition frames.cc:1386
bool is_turbofan_js() const
Definition frames.h:244
virtual Tagged< HeapObject > unchecked_code() const =0
StackFrame(const StackFrame &original) V8_NOEXCEPT
Definition frames.h:224
bool is_irregexp() const
Definition frames.h:282
bool is_optimized_js() const
Definition frames.h:233
Address maybe_unauthenticated_pc() const
Definition frames-inl.h:89
bool is_fast_construct() const
Definition frames.h:278
bool is_api_accessor_exit() const
Definition frames.h:280
void operator=(const StackFrame &original)=delete
void IteratePc(RootVisitor *v, Address *constant_pool_address, Tagged< GcSafeCode > holder) const
Definition frames.cc:768
static Address ReadPC(Address *pc_address)
Definition frames-inl.h:103
static const int kPaddingOffset
Definition frames.h:90
static StackHandler * FromAddress(Address address)
Definition frames-inl.h:67
Address address() const
Definition frames-inl.h:54
DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler)
StackHandler * next() const
Definition frames-inl.h:58
Address next_address() const
Definition frames-inl.h:63
Tagged< HeapObject > unchecked_code() const override
Definition frames.cc:2364
FrameSummaries Summarize() const override
Definition frames.cc:2381
int LookupExceptionHandlerInTable()
Definition frames.cc:2371
Type type() const override
Definition frames.h:1054
StubFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:300
int FindReturnPCForTrampoline(Tagged< Code > code, int trampoline_pc) const override
Definition frames.cc:3200
TurbofanJSFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:318
void Iterate(RootVisitor *v) const override
Definition frames.cc:2360
Tagged< Object > StackSlotAt(int index) const
Type type() const override
Definition frames.h:1223
int ComputeParametersCount() const override
Definition frames.cc:2422
Tagged< HeapObject > unchecked_code() const override
Definition frames.cc:2265
void Iterate(RootVisitor *v) const override
Definition frames.cc:2356
TurbofanStubWithContextFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:296
void Iterate(RootVisitor *v) const override
Definition frames.cc:319
TypedFrameWithJSLinkage(StackFrameIteratorBase *iterator)
Definition frames-inl.h:123
void IterateParamsOfGenericWasmToJSWrapper(RootVisitor *v) const
Tagged< HeapObject > unchecked_code() const override
Definition frames.h:707
TypedFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:116
void Iterate(RootVisitor *v) const override
Definition frames.cc:1971
void IterateParamsOfOptimizedWasmToJSWrapper(RootVisitor *v) const
uint32_t register_stack_slot_count() const
Definition frames.h:1923
static uint32_t GetStackSizeForAdditionalArguments(int parameters_count)
Definition frames.cc:4237
static UnoptimizedFrameInfo Precise(int parameters_count_with_receiver, int translation_height, bool is_topmost, bool pad_arguments)
Definition frames.h:1908
UnoptimizedFrameInfo(int parameters_count_with_receiver, int translation_height, bool is_topmost, bool pad_arguments, FrameInfoKind frame_info_kind)
Definition frames.cc:4205
uint32_t frame_size_in_bytes() const
Definition frames.h:1929
static UnoptimizedFrameInfo Conservative(int parameters_count_with_receiver, int locals_count)
Definition frames.h:1915
uint32_t frame_size_in_bytes_without_fixed() const
Definition frames.h:1926
UnoptimizedJSFrame(StackFrameIteratorBase *iterator)
Definition frames-inl.h:306
Address GetExpressionAddress(int n) const override
Definition frames.cc:1465
void SetFeedbackVector(Tagged< FeedbackVector > feedback_vector)
Definition frames-inl.h:285
static UnoptimizedJSFrame * cast(StackFrame *frame)
Definition frames.h:1123
Tagged< BytecodeArray > GetBytecodeArray() const
Definition frames.cc:3299
Tagged< Object > ReadInterpreterRegister(int register_index) const
Definition frames.cc:3307
int LookupExceptionHandlerInTable(int *data, HandlerTable::CatchPrediction *prediction) override
Definition frames.cc:3286
FrameSummaries Summarize() const override
Definition frames.cc:3316
int position() const override
Definition frames.cc:3280
virtual int GetBytecodeOffset() const =0
Handle< Code > code
const JSFunctionRef function_
const PropertyKind kind_
#define DECLARE_TYPE(type, value)
#define CONSTRUCT_ENTRY(NAME, LOWER_NAME)
ZoneList< RegExpInstruction > code_
#define FRAME_SUMMARY_VARIANTS(F)
Definition frames.h:413
#define DECLARE_SINGLETON(ignore, type)
Definition frames.h:1675
#define FRAME_SUMMARY_CONS(kind, type, field, desc)
Definition frames.h:581
#define FRAME_SUMMARY_FIELD(kind, type, field, desc)
Definition frames.h:617
#define FRAME_SUMMARY_CAST(kind_, type, field, desc)
Definition frames.h:607
#define FRAME_SUMMARY_KIND(kind, type, field, desc)
Definition frames.h:422
#define STACK_FRAME_TYPE_LIST(V)
Definition frames.h:115
TNode< Context > context
Node * receiver_
TNode< Object > receiver
Builtin builtin
int position
Definition liveedit.cc:290
constexpr bool IsInRange(T value, U lower_limit, U higher_limit)
Definition bounds.h:20
uintptr_t Address
Definition memory.h:13
const intptr_t kHeapObjectTagMask
Definition v8-internal.h:75
constexpr int kNoSourcePosition
Definition globals.h:850
const int kSmiTagSize
Definition v8-internal.h:87
kWasmInternalFunctionIndirectPointerTag instance_data
BuiltinContinuationMode
Definition frames.h:1899
constexpr int kSystemPointerSizeLog2
Definition globals.h:494
constexpr int kSystemPointerSize
Definition globals.h:410
const int kHeapObjectTag
Definition v8-internal.h:72
const intptr_t kSmiTagMask
Definition v8-internal.h:88
const int kSmiTag
Definition v8-internal.h:86
static constexpr Address kNullAddress
Definition v8-internal.h:53
!IsContextMap !IsContextMap native_context
Definition map-inl.h:877
uintptr_t(*)(uintptr_t return_addr_location) ReturnAddressLocationResolver
Definition c-api.cc:87
uint32_t cast
#define V8_NOEXCEPT
#define UNREACHABLE()
Definition logging.h:67
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define DCHECK(condition)
Definition logging.h:482
#define V8_EXPORT_PRIVATE
Definition macros.h:460
std::vector< FrameSummary > frames
Definition frames.h:631
FrameSummaries(FrameSummary summary)
Definition frames.h:636
Node ** parameters_
wasm::ValueType type