Line data Source code
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_FRAMES_H_
6 : #define V8_FRAMES_H_
7 :
8 : #include "src/handles.h"
9 : #include "src/objects.h"
10 : #include "src/objects/code.h"
11 : #include "src/safepoint-table.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 : namespace wasm {
16 : class WasmCode;
17 : }
18 :
19 : // Forward declarations.
20 : class AbstractCode;
21 : class Debug;
22 : class ExternalCallbackScope;
23 : class InnerPointerToCodeCache;
24 : class Isolate;
25 : class ObjectVisitor;
26 : class RootVisitor;
27 : class StackFrameIteratorBase;
28 : class StringStream;
29 : class ThreadLocalTop;
30 : class WasmDebugInfo;
31 : class WasmInstanceObject;
32 : class WasmModuleObject;
33 :
34 : class StackHandlerConstants : public AllStatic {
35 : public:
36 : static const int kNextOffset = 0 * kSystemPointerSize;
37 : static const int kPaddingOffset = 1 * kSystemPointerSize;
38 :
39 : static const int kSize = kPaddingOffset + kSystemPointerSize;
40 : static const int kSlotCount = kSize >> kSystemPointerSizeLog2;
41 : };
42 :
43 : class StackHandler {
44 : public:
45 : // Get the address of this stack handler.
46 : inline Address address() const;
47 :
48 : // Get the next stack handler in the chain.
49 : inline StackHandler* next() const;
50 :
51 : // Get the next stack handler, as an Address. This is safe to use even
52 : // when the next handler is null.
53 : inline Address next_address() const;
54 :
55 : // Conversion support.
56 : static inline StackHandler* FromAddress(Address address);
57 :
58 : private:
59 : DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
60 : };
61 :
62 : #define STACK_FRAME_TYPE_LIST(V) \
63 : V(ENTRY, EntryFrame) \
64 : V(CONSTRUCT_ENTRY, ConstructEntryFrame) \
65 : V(EXIT, ExitFrame) \
66 : V(OPTIMIZED, OptimizedFrame) \
67 : V(WASM_COMPILED, WasmCompiledFrame) \
68 : V(WASM_TO_JS, WasmToJsFrame) \
69 : V(JS_TO_WASM, JsToWasmFrame) \
70 : V(WASM_INTERPRETER_ENTRY, WasmInterpreterEntryFrame) \
71 : V(C_WASM_ENTRY, CWasmEntryFrame) \
72 : V(WASM_COMPILE_LAZY, WasmCompileLazyFrame) \
73 : V(INTERPRETED, InterpretedFrame) \
74 : V(STUB, StubFrame) \
75 : V(BUILTIN_CONTINUATION, BuiltinContinuationFrame) \
76 : V(JAVA_SCRIPT_BUILTIN_CONTINUATION, JavaScriptBuiltinContinuationFrame) \
77 : V(JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH, \
78 : JavaScriptBuiltinContinuationWithCatchFrame) \
79 : V(INTERNAL, InternalFrame) \
80 : V(CONSTRUCT, ConstructFrame) \
81 : V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame) \
82 : V(BUILTIN, BuiltinFrame) \
83 : V(BUILTIN_EXIT, BuiltinExitFrame) \
84 : V(NATIVE, NativeFrame)
85 :
86 : // Abstract base class for all stack frames.
87 : class StackFrame {
88 : public:
89 : #define DECLARE_TYPE(type, ignore) type,
90 : enum Type {
91 : NONE = 0,
92 : STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
93 : NUMBER_OF_TYPES,
94 : // Used by FrameScope to indicate that the stack frame is constructed
95 : // manually and the FrameScope does not need to emit code.
96 : MANUAL
97 : };
98 : #undef DECLARE_TYPE
99 :
100 : // Opaque data type for identifying stack frames. Used extensively
101 : // by the debugger.
102 : // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
103 : // has correct value range (see Issue 830 for more details).
104 : enum Id {
105 : ID_MIN_VALUE = kMinInt,
106 : ID_MAX_VALUE = kMaxInt,
107 : NO_ID = 0
108 : };
109 :
110 : // Used to mark the outermost JS entry frame.
111 : //
112 : // The mark is an opaque value that should be pushed onto the stack directly,
113 : // carefully crafted to not be interpreted as a tagged pointer.
114 : enum JsFrameMarker {
115 : INNER_JSENTRY_FRAME = (0 << kSmiTagSize) | kSmiTag,
116 : OUTERMOST_JSENTRY_FRAME = (1 << kSmiTagSize) | kSmiTag
117 : };
118 : STATIC_ASSERT((INNER_JSENTRY_FRAME & kHeapObjectTagMask) != kHeapObjectTag);
119 : STATIC_ASSERT((OUTERMOST_JSENTRY_FRAME & kHeapObjectTagMask) !=
120 : kHeapObjectTag);
121 :
122 193855809 : struct State {
123 : Address sp = kNullAddress;
124 : Address fp = kNullAddress;
125 : Address* pc_address = nullptr;
126 : Address* callee_pc_address = nullptr;
127 : Address* constant_pool_address = nullptr;
128 : };
129 :
130 : // Convert a stack frame type to a marker that can be stored on the stack.
131 : //
132 : // The marker is an opaque value, not intended to be interpreted in any way
133 : // except being checked by IsTypeMarker or converted by MarkerToType.
134 : // It has the same tagging as Smis, so any marker value that does not pass
135 : // IsTypeMarker can instead be interpreted as a tagged pointer.
136 : //
137 : // Note that the marker is not a Smi: Smis on 64-bit architectures are stored
138 : // in the top 32 bits of a 64-bit value, which in turn makes them expensive
139 : // (in terms of code/instruction size) to push as immediates onto the stack.
140 : static int32_t TypeToMarker(Type type) {
141 : DCHECK_GE(type, 0);
142 1576079 : return (type << kSmiTagSize) | kSmiTag;
143 : }
144 :
145 : // Convert a marker back to a stack frame type.
146 : //
147 : // Unlike the return value of TypeToMarker, this takes an intptr_t, as that is
148 : // the type of the value on the stack.
149 : static Type MarkerToType(intptr_t marker) {
150 : DCHECK(IsTypeMarker(marker));
151 13227336 : return static_cast<Type>(marker >> kSmiTagSize);
152 : }
153 :
154 : // Check if a marker is a stack frame type marker or a tagged pointer.
155 : //
156 : // Returns true if the given marker is tagged as a stack frame type marker,
157 : // and should be converted back to a stack frame type using MarkerToType.
158 : // Otherwise, the value is a tagged function pointer.
159 : static bool IsTypeMarker(intptr_t function_or_marker) {
160 37585645 : return (function_or_marker & kSmiTagMask) == kSmiTag;
161 : }
162 :
163 : // Copy constructor; it breaks the connection to host iterator
164 : // (as an iterator usually lives on stack).
165 : StackFrame(const StackFrame& original) V8_NOEXCEPT {
166 : this->state_ = original.state_;
167 : this->iterator_ = nullptr;
168 : this->isolate_ = original.isolate_;
169 : }
170 :
171 : // Type testers.
172 349673 : bool is_entry() const { return type() == ENTRY; }
173 289240 : bool is_construct_entry() const { return type() == CONSTRUCT_ENTRY; }
174 141092 : bool is_exit() const { return type() == EXIT; }
175 23726062 : bool is_optimized() const { return type() == OPTIMIZED; }
176 1698602 : bool is_interpreted() const { return type() == INTERPRETED; }
177 364 : bool is_wasm_compiled() const { return type() == WASM_COMPILED; }
178 : bool is_wasm_compile_lazy() const { return type() == WASM_COMPILE_LAZY; }
179 : bool is_wasm_to_js() const { return type() == WASM_TO_JS; }
180 : bool is_js_to_wasm() const { return type() == JS_TO_WASM; }
181 : bool is_wasm_interpreter_entry() const {
182 384297 : return type() == WASM_INTERPRETER_ENTRY;
183 : }
184 715613 : bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
185 : bool is_builtin() const { return type() == BUILTIN; }
186 0 : bool is_internal() const { return type() == INTERNAL; }
187 : bool is_builtin_continuation() const {
188 : return type() == BUILTIN_CONTINUATION;
189 : }
190 : bool is_java_script_builtin_continuation() const {
191 : return type() == JAVA_SCRIPT_BUILTIN_CONTINUATION;
192 : }
193 : bool is_java_script_builtin_with_catch_continuation() const {
194 : return type() == JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH;
195 : }
196 10 : bool is_construct() const { return type() == CONSTRUCT; }
197 140820 : bool is_builtin_exit() const { return type() == BUILTIN_EXIT; }
198 0 : virtual bool is_standard() const { return false; }
199 :
200 12431678 : bool is_java_script() const {
201 12431678 : Type type = this->type();
202 24559408 : return (type == OPTIMIZED) || (type == INTERPRETED) || (type == BUILTIN) ||
203 24559177 : (type == JAVA_SCRIPT_BUILTIN_CONTINUATION) ||
204 12431678 : (type == JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH);
205 : }
206 : bool is_wasm() const {
207 4947617 : Type type = this->type();
208 4947617 : return type == WASM_COMPILED || type == WASM_INTERPRETER_ENTRY;
209 : }
210 :
211 : // Accessors.
212 : Address sp() const { return state_.sp; }
213 : Address fp() const { return state_.fp; }
214 : Address callee_pc() const {
215 308388 : return state_.callee_pc_address ? *state_.callee_pc_address : kNullAddress;
216 : }
217 61024045 : Address caller_sp() const { return GetCallerStackPointer(); }
218 :
219 : // If this frame is optimized and was dynamically aligned return its old
220 : // unaligned frame pointer. When the frame is deoptimized its FP will shift
221 : // up one word and become unaligned.
222 : Address UnpaddedFP() const;
223 :
224 25408686 : Address pc() const { return *pc_address(); }
225 33854 : void set_pc(Address pc) { *pc_address() = pc; }
226 :
227 : Address constant_pool() const { return *constant_pool_address(); }
228 : void set_constant_pool(Address constant_pool) {
229 : *constant_pool_address() = constant_pool;
230 : }
231 :
232 : Address* pc_address() const { return state_.pc_address; }
233 :
234 : Address* constant_pool_address() const {
235 : return state_.constant_pool_address;
236 : }
237 :
238 : // Get the id of this stack frame.
239 1987300 : Id id() const { return static_cast<Id>(caller_sp()); }
240 :
241 : // Get the top handler from the current stack iterator.
242 : inline StackHandler* top_handler() const;
243 :
244 : // Get the type of this frame.
245 : virtual Type type() const = 0;
246 :
247 : // Get the code associated with this frame.
248 : // This method could be called during marking phase of GC.
249 : virtual Code unchecked_code() const = 0;
250 :
251 : // Search for the code associated with this frame.
252 : V8_EXPORT_PRIVATE Code LookupCode() const;
253 :
254 : virtual void Iterate(RootVisitor* v) const = 0;
255 : static void IteratePc(RootVisitor* v, Address* pc_address,
256 : Address* constant_pool_address, Code holder);
257 :
258 : // Sets a callback function for return-address rewriting profilers
259 : // to resolve the location of a return address to the location of the
260 : // profiler's stashed return address.
261 : static void SetReturnAddressLocationResolver(
262 : ReturnAddressLocationResolver resolver);
263 :
264 : // Resolves pc_address through the resolution address function if one is set.
265 : static inline Address* ResolveReturnAddressLocation(Address* pc_address);
266 :
267 : // Printing support.
268 : enum PrintMode { OVERVIEW, DETAILS };
269 : virtual void Print(StringStream* accumulator, PrintMode mode,
270 : int index) const;
271 :
272 : Isolate* isolate() const { return isolate_; }
273 :
274 : void operator=(const StackFrame& original) = delete;
275 :
276 : protected:
277 : inline explicit StackFrame(StackFrameIteratorBase* iterator);
278 193858308 : virtual ~StackFrame() = default;
279 :
280 : // Compute the stack pointer for the calling frame.
281 : virtual Address GetCallerStackPointer() const = 0;
282 :
283 : // Compute the stack frame type for the given state.
284 : static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
285 :
286 : #ifdef DEBUG
287 : bool can_access_heap_objects() const;
288 : #endif
289 :
290 : private:
291 : const StackFrameIteratorBase* iterator_;
292 : Isolate* isolate_;
293 : State state_;
294 :
295 : static ReturnAddressLocationResolver return_address_location_resolver_;
296 :
297 : // Fill in the state of the calling frame.
298 : virtual void ComputeCallerState(State* state) const = 0;
299 :
300 : // Get the type and the state of the calling frame.
301 : virtual Type GetCallerState(State* state) const;
302 :
303 : static const intptr_t kIsolateTag = 1;
304 :
305 : friend class StackFrameIterator;
306 : friend class StackFrameIteratorBase;
307 : friend class StackHandlerIterator;
308 : friend class SafeStackFrameIterator;
309 : };
310 :
311 18462696 : class NativeFrame : public StackFrame {
312 : public:
313 0 : Type type() const override { return NATIVE; }
314 :
315 : Code unchecked_code() const override;
316 :
317 : // Garbage collection support.
318 0 : void Iterate(RootVisitor* v) const override {}
319 :
320 : protected:
321 : inline explicit NativeFrame(StackFrameIteratorBase* iterator);
322 :
323 : Address GetCallerStackPointer() const override;
324 :
325 : private:
326 : void ComputeCallerState(State* state) const override;
327 :
328 : friend class StackFrameIteratorBase;
329 : };
330 :
331 : // Entry frames are used to enter JavaScript execution from C.
332 36925392 : class EntryFrame: public StackFrame {
333 : public:
334 2230300 : Type type() const override { return ENTRY; }
335 :
336 : Code unchecked_code() const override;
337 :
338 : // Garbage collection support.
339 : void Iterate(RootVisitor* v) const override;
340 :
341 : static EntryFrame* cast(StackFrame* frame) {
342 : DCHECK(frame->is_entry());
343 : return static_cast<EntryFrame*>(frame);
344 : }
345 :
346 : protected:
347 : inline explicit EntryFrame(StackFrameIteratorBase* iterator);
348 :
349 : // The caller stack pointer for entry frames is always zero. The
350 : // real information about the caller frame is available through the
351 : // link to the top exit frame.
352 479 : Address GetCallerStackPointer() const override { return 0; }
353 :
354 : private:
355 : void ComputeCallerState(State* state) const override;
356 : Type GetCallerState(State* state) const override;
357 :
358 : friend class StackFrameIteratorBase;
359 : };
360 :
361 18462696 : class ConstructEntryFrame : public EntryFrame {
362 : public:
363 42 : Type type() const override { return CONSTRUCT_ENTRY; }
364 :
365 : Code unchecked_code() const override;
366 :
367 : static ConstructEntryFrame* cast(StackFrame* frame) {
368 : DCHECK(frame->is_construct_entry());
369 : return static_cast<ConstructEntryFrame*>(frame);
370 : }
371 :
372 : protected:
373 : inline explicit ConstructEntryFrame(StackFrameIteratorBase* iterator);
374 :
375 : private:
376 : friend class StackFrameIteratorBase;
377 : };
378 :
379 :
380 : // Exit frames are used to exit JavaScript execution and go to C.
381 36925392 : class ExitFrame: public StackFrame {
382 : public:
383 7760633 : Type type() const override { return EXIT; }
384 :
385 : Code unchecked_code() const override;
386 :
387 : // Garbage collection support.
388 : void Iterate(RootVisitor* v) const override;
389 :
390 : static ExitFrame* cast(StackFrame* frame) {
391 : DCHECK(frame->is_exit());
392 : return static_cast<ExitFrame*>(frame);
393 : }
394 :
395 : // Compute the state and type of an exit frame given a frame
396 : // pointer. Used when constructing the first stack frame seen by an
397 : // iterator and the frames following entry frames.
398 : static Type GetStateForFramePointer(Address fp, State* state);
399 : static Address ComputeStackPointer(Address fp);
400 : static StackFrame::Type ComputeFrameType(Address fp);
401 : static void FillState(Address fp, Address sp, State* state);
402 :
403 : protected:
404 : inline explicit ExitFrame(StackFrameIteratorBase* iterator);
405 :
406 : Address GetCallerStackPointer() const override;
407 :
408 : private:
409 : void ComputeCallerState(State* state) const override;
410 :
411 : friend class StackFrameIteratorBase;
412 : };
413 :
414 : // Builtin exit frames are a special case of exit frames, which are used
415 : // whenever C++ builtins (e.g., Math.acos) are called. Their main purpose is
416 : // to allow such builtins to appear in stack traces.
417 18462696 : class BuiltinExitFrame : public ExitFrame {
418 : public:
419 1135523 : Type type() const override { return BUILTIN_EXIT; }
420 :
421 : static BuiltinExitFrame* cast(StackFrame* frame) {
422 : DCHECK(frame->is_builtin_exit());
423 : return static_cast<BuiltinExitFrame*>(frame);
424 : }
425 :
426 : JSFunction function() const;
427 : Object receiver() const;
428 :
429 : bool IsConstructor() const;
430 :
431 : void Print(StringStream* accumulator, PrintMode mode,
432 : int index) const override;
433 :
434 : protected:
435 : inline explicit BuiltinExitFrame(StackFrameIteratorBase* iterator);
436 :
437 : private:
438 : Object GetParameter(int i) const;
439 : int ComputeParametersCount() const;
440 :
441 : inline Object receiver_slot_object() const;
442 : inline Object argc_slot_object() const;
443 : inline Object target_slot_object() const;
444 : inline Object new_target_slot_object() const;
445 :
446 : friend class StackFrameIteratorBase;
447 : friend class FrameArrayBuilder;
448 : };
449 :
450 : class StandardFrame;
451 :
452 : class V8_EXPORT_PRIVATE FrameSummary {
453 : public:
454 : // Subclasses for the different summary kinds:
455 : #define FRAME_SUMMARY_VARIANTS(F) \
456 : F(JAVA_SCRIPT, JavaScriptFrameSummary, java_script_summary_, JavaScript) \
457 : F(WASM_COMPILED, WasmCompiledFrameSummary, wasm_compiled_summary_, \
458 : WasmCompiled) \
459 : F(WASM_INTERPRETED, WasmInterpretedFrameSummary, wasm_interpreted_summary_, \
460 : WasmInterpreted)
461 :
462 : #define FRAME_SUMMARY_KIND(kind, type, field, desc) kind,
463 : enum Kind { FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_KIND) };
464 : #undef FRAME_SUMMARY_KIND
465 :
466 : class FrameSummaryBase {
467 : public:
468 : FrameSummaryBase(Isolate* isolate, Kind kind)
469 7745085 : : isolate_(isolate), kind_(kind) {}
470 : Isolate* isolate() const { return isolate_; }
471 : Kind kind() const { return kind_; }
472 :
473 : private:
474 : Isolate* isolate_;
475 : Kind kind_;
476 : };
477 :
478 : class JavaScriptFrameSummary : public FrameSummaryBase {
479 : public:
480 : JavaScriptFrameSummary(Isolate* isolate, Object receiver,
481 : JSFunction function, AbstractCode abstract_code,
482 : int code_offset, bool is_constructor,
483 : FixedArray parameters);
484 :
485 : void EnsureSourcePositionsAvailable();
486 :
487 : Handle<Object> receiver() const { return receiver_; }
488 : Handle<JSFunction> function() const { return function_; }
489 : Handle<AbstractCode> abstract_code() const { return abstract_code_; }
490 : int code_offset() const { return code_offset_; }
491 : bool is_constructor() const { return is_constructor_; }
492 : Handle<FixedArray> parameters() const { return parameters_; }
493 : bool is_subject_to_debugging() const;
494 : int SourcePosition() const;
495 : int SourceStatementPosition() const;
496 : Handle<Object> script() const;
497 : Handle<String> FunctionName() const;
498 : Handle<Context> native_context() const;
499 :
500 : private:
501 : Handle<Object> receiver_;
502 : Handle<JSFunction> function_;
503 : Handle<AbstractCode> abstract_code_;
504 : int code_offset_;
505 : bool is_constructor_;
506 : Handle<FixedArray> parameters_;
507 : };
508 :
509 : class WasmFrameSummary : public FrameSummaryBase {
510 : protected:
511 : WasmFrameSummary(Isolate*, Kind, Handle<WasmInstanceObject>,
512 : bool at_to_number_conversion);
513 :
514 : public:
515 : Handle<Object> receiver() const;
516 : uint32_t function_index() const;
517 : int byte_offset() const;
518 : bool is_constructor() const { return false; }
519 : bool is_subject_to_debugging() const { return true; }
520 : int SourcePosition() const;
521 0 : int SourceStatementPosition() const { return SourcePosition(); }
522 : Handle<Script> script() const;
523 : Handle<WasmInstanceObject> wasm_instance() const { return wasm_instance_; }
524 : Handle<String> FunctionName() const;
525 : Handle<Context> native_context() const;
526 : bool at_to_number_conversion() const { return at_to_number_conversion_; }
527 :
528 : private:
529 : Handle<WasmInstanceObject> wasm_instance_;
530 : bool at_to_number_conversion_;
531 : };
532 :
533 : class WasmCompiledFrameSummary : public WasmFrameSummary {
534 : public:
535 : WasmCompiledFrameSummary(Isolate*, Handle<WasmInstanceObject>,
536 : wasm::WasmCode*, int code_offset,
537 : bool at_to_number_conversion);
538 : uint32_t function_index() const;
539 : wasm::WasmCode* code() const { return code_; }
540 : int code_offset() const { return code_offset_; }
541 : int byte_offset() const;
542 : static int GetWasmSourcePosition(const wasm::WasmCode* code, int offset);
543 :
544 : private:
545 : wasm::WasmCode* const code_;
546 : int code_offset_;
547 : };
548 :
549 : class WasmInterpretedFrameSummary : public WasmFrameSummary {
550 : public:
551 : WasmInterpretedFrameSummary(Isolate*, Handle<WasmInstanceObject>,
552 : uint32_t function_index, int byte_offset);
553 : uint32_t function_index() const { return function_index_; }
554 : int code_offset() const { return byte_offset_; }
555 : int byte_offset() const { return byte_offset_; }
556 :
557 : private:
558 : uint32_t function_index_;
559 : int byte_offset_;
560 : };
561 :
562 : #define FRAME_SUMMARY_CONS(kind, type, field, desc) \
563 : FrameSummary(type summ) : field(summ) {} // NOLINT
564 8726386 : FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CONS)
565 : #undef FRAME_SUMMARY_CONS
566 :
567 : ~FrameSummary();
568 :
569 : static FrameSummary GetTop(const StandardFrame* frame);
570 : static FrameSummary GetBottom(const StandardFrame* frame);
571 : static FrameSummary GetSingle(const StandardFrame* frame);
572 : static FrameSummary Get(const StandardFrame* frame, int index);
573 :
574 : void EnsureSourcePositionsAvailable();
575 :
576 : // Dispatched accessors.
577 : Handle<Object> receiver() const;
578 : int code_offset() const;
579 : bool is_constructor() const;
580 : bool is_subject_to_debugging() const;
581 : Handle<Object> script() const;
582 : int SourcePosition() const;
583 : int SourceStatementPosition() const;
584 : Handle<String> FunctionName() const;
585 : Handle<Context> native_context() const;
586 :
587 : #define FRAME_SUMMARY_CAST(kind_, type, field, desc) \
588 : bool Is##desc() const { return base_.kind() == kind_; } \
589 : const type& As##desc() const { \
590 : DCHECK_EQ(base_.kind(), kind_); \
591 : return field; \
592 : }
593 5141055 : FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CAST)
594 : #undef FRAME_SUMMARY_CAST
595 :
596 : bool IsWasm() const { return IsWasmCompiled() || IsWasmInterpreted(); }
597 : const WasmFrameSummary& AsWasm() const {
598 : if (IsWasmCompiled()) return AsWasmCompiled();
599 : return AsWasmInterpreted();
600 : }
601 :
602 : private:
603 : #define FRAME_SUMMARY_FIELD(kind, type, field, desc) type field;
604 : union {
605 : FrameSummaryBase base_;
606 : FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_FIELD)
607 : };
608 : #undef FRAME_SUMMARY_FIELD
609 : };
610 :
611 295403136 : class StandardFrame : public StackFrame {
612 : public:
613 : // Testers.
614 0 : bool is_standard() const override { return true; }
615 :
616 : // Accessors.
617 : virtual Object receiver() const;
618 : virtual Script script() const;
619 : virtual Object context() const;
620 : virtual int position() const;
621 :
622 : // Access the expressions in the stack frame including locals.
623 : inline Object GetExpression(int index) const;
624 : inline void SetExpression(int index, Object value);
625 : int ComputeExpressionsCount() const;
626 :
627 : // Access the parameters.
628 : virtual Object GetParameter(int index) const;
629 : virtual int ComputeParametersCount() const;
630 :
631 : // Check if this frame is a constructor frame invoked through 'new'.
632 : virtual bool IsConstructor() const;
633 :
634 : // Build a list with summaries for this frame including all inlined frames.
635 : // The functions are ordered bottom-to-top (i.e. summaries.last() is the
636 : // top-most activation; caller comes before callee).
637 : virtual void Summarize(std::vector<FrameSummary>* frames) const;
638 :
639 : static StandardFrame* cast(StackFrame* frame) {
640 : DCHECK(frame->is_standard());
641 : return static_cast<StandardFrame*>(frame);
642 : }
643 :
644 : protected:
645 : inline explicit StandardFrame(StackFrameIteratorBase* iterator);
646 :
647 : void ComputeCallerState(State* state) const override;
648 :
649 : // Accessors.
650 : inline Address caller_fp() const;
651 : inline Address caller_pc() const;
652 :
653 : // Computes the address of the PC field in the standard frame given
654 : // by the provided frame pointer.
655 : static inline Address ComputePCAddress(Address fp);
656 :
657 : // Computes the address of the constant pool field in the standard
658 : // frame given by the provided frame pointer.
659 : static inline Address ComputeConstantPoolAddress(Address fp);
660 :
661 : // Iterate over expression stack including stack handlers, locals,
662 : // and parts of the fixed part including context and code fields.
663 : void IterateExpressions(RootVisitor* v) const;
664 :
665 : // Returns the address of the n'th expression stack element.
666 : virtual Address GetExpressionAddress(int n) const;
667 :
668 : // Determines if the standard frame for the given frame pointer is
669 : // an arguments adaptor frame.
670 : static inline bool IsArgumentsAdaptorFrame(Address fp);
671 :
672 : // Determines if the standard frame for the given frame pointer is a
673 : // construct frame.
674 : static inline bool IsConstructFrame(Address fp);
675 :
676 : // Used by OptimizedFrames and StubFrames.
677 : void IterateCompiledFrame(RootVisitor* v) const;
678 :
679 : private:
680 : friend class StackFrame;
681 : friend class SafeStackFrameIterator;
682 : };
683 :
684 110776176 : class JavaScriptFrame : public StandardFrame {
685 : public:
686 : Type type() const override = 0;
687 :
688 : void Summarize(std::vector<FrameSummary>* frames) const override;
689 :
690 : // Accessors.
691 : virtual JSFunction function() const;
692 : Object unchecked_function() const;
693 : Object receiver() const override;
694 : Object context() const override;
695 : Script script() const override;
696 :
697 : inline void set_receiver(Object value);
698 :
699 : // Access the parameters.
700 : inline Address GetParameterSlot(int index) const;
701 : Object GetParameter(int index) const override;
702 : int ComputeParametersCount() const override;
703 : Handle<FixedArray> GetParameters() const;
704 :
705 : // Debugger access.
706 : void SetParameterValue(int index, Object value) const;
707 :
708 : // Check if this frame is a constructor frame invoked through 'new'.
709 : bool IsConstructor() const override;
710 :
711 : // Determines whether this frame includes inlined activations. To get details
712 : // about the inlined frames use {GetFunctions} and {Summarize}.
713 : bool HasInlinedFrames() const;
714 :
715 : // Check if this frame has "adapted" arguments in the sense that the
716 : // actual passed arguments are available in an arguments adaptor
717 : // frame below it on the stack.
718 : inline bool has_adapted_arguments() const;
719 :
720 : // Garbage collection support.
721 : void Iterate(RootVisitor* v) const override;
722 :
723 : // Printing support.
724 : void Print(StringStream* accumulator, PrintMode mode,
725 : int index) const override;
726 :
727 : // Determine the code for the frame.
728 : Code unchecked_code() const override;
729 :
730 : // Return a list with {SharedFunctionInfo} objects of this frame.
731 : virtual void GetFunctions(std::vector<SharedFunctionInfo>* functions) const;
732 :
733 : void GetFunctions(std::vector<Handle<SharedFunctionInfo>>* functions) const;
734 :
735 : // Lookup exception handler for current {pc}, returns -1 if none found. Also
736 : // returns data associated with the handler site specific to the frame type:
737 : // - OptimizedFrame : Data is the stack slot count of the entire frame.
738 : // - InterpretedFrame: Data is the register index holding the context.
739 : virtual int LookupExceptionHandlerInTable(
740 : int* data, HandlerTable::CatchPrediction* prediction);
741 :
742 : // Architecture-specific register description.
743 : static Register fp_register();
744 : static Register context_register();
745 : static Register constant_pool_pointer_register();
746 :
747 : static JavaScriptFrame* cast(StackFrame* frame) {
748 : DCHECK(frame->is_java_script());
749 : return static_cast<JavaScriptFrame*>(frame);
750 : }
751 :
752 : static void PrintFunctionAndOffset(JSFunction function, AbstractCode code,
753 : int code_offset, FILE* file,
754 : bool print_line_number);
755 :
756 : static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
757 : bool print_line_number);
758 :
759 : static void CollectFunctionAndOffsetForICStats(JSFunction function,
760 : AbstractCode code,
761 : int code_offset);
762 :
763 : protected:
764 : inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
765 :
766 : Address GetCallerStackPointer() const override;
767 :
768 57 : virtual void PrintFrameKind(StringStream* accumulator) const {}
769 :
770 : private:
771 : inline Object function_slot_object() const;
772 :
773 : friend class StackFrameIteratorBase;
774 : };
775 :
776 :
777 73850784 : class StubFrame : public StandardFrame {
778 : public:
779 7127157 : Type type() const override { return STUB; }
780 :
781 : // GC support.
782 : void Iterate(RootVisitor* v) const override;
783 :
784 : // Determine the code for the frame.
785 : Code unchecked_code() const override;
786 :
787 : // Lookup exception handler for current {pc}, returns -1 if none found. Only
788 : // TurboFan stub frames are supported. Also returns data associated with the
789 : // handler site:
790 : // - TurboFan stub: Data is the stack slot count of the entire frame.
791 : int LookupExceptionHandlerInTable(int* data);
792 :
793 : protected:
794 : inline explicit StubFrame(StackFrameIteratorBase* iterator);
795 :
796 : Address GetCallerStackPointer() const override;
797 :
798 : friend class StackFrameIteratorBase;
799 : };
800 :
801 :
802 18462696 : class OptimizedFrame : public JavaScriptFrame {
803 : public:
804 9279213 : Type type() const override { return OPTIMIZED; }
805 :
806 : // GC support.
807 : void Iterate(RootVisitor* v) const override;
808 :
809 : // Return a list with {SharedFunctionInfo} objects of this frame.
810 : // The functions are ordered bottom-to-top (i.e. functions.last()
811 : // is the top-most activation)
812 : void GetFunctions(std::vector<SharedFunctionInfo>* functions) const override;
813 :
814 : void Summarize(std::vector<FrameSummary>* frames) const override;
815 :
816 : // Lookup exception handler for current {pc}, returns -1 if none found.
817 : int LookupExceptionHandlerInTable(
818 : int* data, HandlerTable::CatchPrediction* prediction) override;
819 :
820 : DeoptimizationData GetDeoptimizationData(int* deopt_index) const;
821 :
822 : Object receiver() const override;
823 : int ComputeParametersCount() const override;
824 :
825 : static int StackSlotOffsetRelativeToFp(int slot_index);
826 :
827 : protected:
828 : inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
829 :
830 :
831 : private:
832 : friend class StackFrameIteratorBase;
833 :
834 : Object StackSlotAt(int index) const;
835 : };
836 :
837 :
838 18462696 : class InterpretedFrame : public JavaScriptFrame {
839 : public:
840 38605045 : Type type() const override { return INTERPRETED; }
841 :
842 : // Accessors.
843 : int position() const override;
844 :
845 : // Lookup exception handler for current {pc}, returns -1 if none found.
846 : int LookupExceptionHandlerInTable(
847 : int* data, HandlerTable::CatchPrediction* prediction) override;
848 :
849 : // Returns the current offset into the bytecode stream.
850 : int GetBytecodeOffset() const;
851 :
852 : // Updates the current offset into the bytecode stream, mainly used for stack
853 : // unwinding to continue execution at a different bytecode offset.
854 : void PatchBytecodeOffset(int new_offset);
855 :
856 : // Returns the frame's current bytecode array.
857 : BytecodeArray GetBytecodeArray() const;
858 :
859 : // Updates the frame's BytecodeArray with |bytecode_array|. Used by the
860 : // debugger to swap execution onto a BytecodeArray patched with breakpoints.
861 : void PatchBytecodeArray(BytecodeArray bytecode_array);
862 :
863 : // Access to the interpreter register file for this frame.
864 : Object ReadInterpreterRegister(int register_index) const;
865 : void WriteInterpreterRegister(int register_index, Object value);
866 :
867 : // Build a list with summaries for this frame including all inlined frames.
868 : void Summarize(std::vector<FrameSummary>* frames) const override;
869 :
870 : static int GetBytecodeOffset(Address fp);
871 :
872 : static InterpretedFrame* cast(StackFrame* frame) {
873 : DCHECK(frame->is_interpreted());
874 : return static_cast<InterpretedFrame*>(frame);
875 : }
876 :
877 : protected:
878 : inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
879 :
880 : Address GetExpressionAddress(int n) const override;
881 :
882 : private:
883 : friend class StackFrameIteratorBase;
884 : };
885 :
886 :
887 : // Arguments adaptor frames are automatically inserted below
888 : // JavaScript frames when the actual number of parameters does not
889 : // match the formal number of parameters.
890 18462696 : class ArgumentsAdaptorFrame: public JavaScriptFrame {
891 : public:
892 2116199 : Type type() const override { return ARGUMENTS_ADAPTOR; }
893 :
894 : // Determine the code for the frame.
895 : Code unchecked_code() const override;
896 :
897 : static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
898 : DCHECK(frame->is_arguments_adaptor());
899 : return static_cast<ArgumentsAdaptorFrame*>(frame);
900 : }
901 :
902 : int ComputeParametersCount() const override;
903 :
904 : // Printing support.
905 : void Print(StringStream* accumulator, PrintMode mode,
906 : int index) const override;
907 :
908 : protected:
909 : inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
910 :
911 :
912 : private:
913 : friend class StackFrameIteratorBase;
914 : };
915 :
916 : // Builtin frames are built for builtins with JavaScript linkage, such as
917 : // various standard library functions (i.e. Math.asin, Math.floor, etc.).
918 18462696 : class BuiltinFrame final : public JavaScriptFrame {
919 : public:
920 0 : Type type() const final { return BUILTIN; }
921 :
922 : static BuiltinFrame* cast(StackFrame* frame) {
923 : DCHECK(frame->is_builtin());
924 : return static_cast<BuiltinFrame*>(frame);
925 : }
926 : int ComputeParametersCount() const final;
927 :
928 : protected:
929 : inline explicit BuiltinFrame(StackFrameIteratorBase* iterator);
930 :
931 : void PrintFrameKind(StringStream* accumulator) const override;
932 :
933 : private:
934 : friend class StackFrameIteratorBase;
935 : };
936 :
937 18462696 : class WasmCompiledFrame final : public StandardFrame {
938 : public:
939 5686408 : Type type() const override { return WASM_COMPILED; }
940 :
941 : // GC support.
942 : void Iterate(RootVisitor* v) const override;
943 :
944 : // Printing support.
945 : void Print(StringStream* accumulator, PrintMode mode,
946 : int index) const override;
947 :
948 : // Lookup exception handler for current {pc}, returns -1 if none found. Also
949 : // returns the stack slot count of the entire frame.
950 : int LookupExceptionHandlerInTable(int* data);
951 :
952 : // Determine the code for the frame.
953 : Code unchecked_code() const override;
954 :
955 : // Accessors.
956 : WasmInstanceObject wasm_instance() const;
957 : wasm::WasmCode* wasm_code() const;
958 : uint32_t function_index() const;
959 : Script script() const override;
960 : int position() const override;
961 : bool at_to_number_conversion() const;
962 :
963 : void Summarize(std::vector<FrameSummary>* frames) const override;
964 :
965 : static WasmCompiledFrame* cast(StackFrame* frame) {
966 : DCHECK(frame->is_wasm_compiled());
967 : return static_cast<WasmCompiledFrame*>(frame);
968 : }
969 :
970 : protected:
971 : inline explicit WasmCompiledFrame(StackFrameIteratorBase* iterator);
972 :
973 : Address GetCallerStackPointer() const override;
974 :
975 : private:
976 : friend class StackFrameIteratorBase;
977 : WasmModuleObject module_object() const;
978 : };
979 :
980 18462696 : class WasmInterpreterEntryFrame final : public StandardFrame {
981 : public:
982 21925 : Type type() const override { return WASM_INTERPRETER_ENTRY; }
983 :
984 : // GC support.
985 : void Iterate(RootVisitor* v) const override;
986 :
987 : // Printing support.
988 : void Print(StringStream* accumulator, PrintMode mode,
989 : int index) const override;
990 :
991 : void Summarize(std::vector<FrameSummary>* frames) const override;
992 :
993 : // Determine the code for the frame.
994 : Code unchecked_code() const override;
995 :
996 : // Accessors.
997 : WasmDebugInfo debug_info() const;
998 : WasmInstanceObject wasm_instance() const;
999 :
1000 : Script script() const override;
1001 : int position() const override;
1002 : Object context() const override;
1003 :
1004 : static WasmInterpreterEntryFrame* cast(StackFrame* frame) {
1005 : DCHECK(frame->is_wasm_interpreter_entry());
1006 : return static_cast<WasmInterpreterEntryFrame*>(frame);
1007 : }
1008 :
1009 : protected:
1010 : inline explicit WasmInterpreterEntryFrame(StackFrameIteratorBase* iterator);
1011 :
1012 : Address GetCallerStackPointer() const override;
1013 :
1014 : private:
1015 : friend class StackFrameIteratorBase;
1016 : WasmModuleObject module_object() const;
1017 : };
1018 :
1019 18462696 : class WasmToJsFrame : public StubFrame {
1020 : public:
1021 7388 : Type type() const override { return WASM_TO_JS; }
1022 :
1023 : protected:
1024 : inline explicit WasmToJsFrame(StackFrameIteratorBase* iterator);
1025 :
1026 : private:
1027 : friend class StackFrameIteratorBase;
1028 : };
1029 :
1030 18462696 : class JsToWasmFrame : public StubFrame {
1031 : public:
1032 462240 : Type type() const override { return JS_TO_WASM; }
1033 :
1034 : protected:
1035 : inline explicit JsToWasmFrame(StackFrameIteratorBase* iterator);
1036 :
1037 : private:
1038 : friend class StackFrameIteratorBase;
1039 : };
1040 :
1041 18462696 : class CWasmEntryFrame : public StubFrame {
1042 : public:
1043 5124 : Type type() const override { return C_WASM_ENTRY; }
1044 :
1045 : protected:
1046 : inline explicit CWasmEntryFrame(StackFrameIteratorBase* iterator);
1047 :
1048 : private:
1049 : friend class StackFrameIteratorBase;
1050 : };
1051 :
1052 18462696 : class WasmCompileLazyFrame : public StandardFrame {
1053 : public:
1054 88 : Type type() const override { return WASM_COMPILE_LAZY; }
1055 :
1056 : Code unchecked_code() const override;
1057 : WasmInstanceObject wasm_instance() const;
1058 : FullObjectSlot wasm_instance_slot() const;
1059 :
1060 : // Garbage collection support.
1061 : void Iterate(RootVisitor* v) const override;
1062 :
1063 : static WasmCompileLazyFrame* cast(StackFrame* frame) {
1064 : DCHECK(frame->is_wasm_compile_lazy());
1065 : return static_cast<WasmCompileLazyFrame*>(frame);
1066 : }
1067 :
1068 : protected:
1069 : inline explicit WasmCompileLazyFrame(StackFrameIteratorBase* iterator);
1070 :
1071 : Address GetCallerStackPointer() const override;
1072 :
1073 : private:
1074 : friend class StackFrameIteratorBase;
1075 : };
1076 :
1077 55388088 : class InternalFrame: public StandardFrame {
1078 : public:
1079 2831795 : Type type() const override { return INTERNAL; }
1080 :
1081 : // Garbage collection support.
1082 : void Iterate(RootVisitor* v) const override;
1083 :
1084 : // Determine the code for the frame.
1085 : Code unchecked_code() const override;
1086 :
1087 : static InternalFrame* cast(StackFrame* frame) {
1088 : DCHECK(frame->is_internal());
1089 : return static_cast<InternalFrame*>(frame);
1090 : }
1091 :
1092 : protected:
1093 : inline explicit InternalFrame(StackFrameIteratorBase* iterator);
1094 :
1095 : Address GetCallerStackPointer() const override;
1096 :
1097 : private:
1098 : friend class StackFrameIteratorBase;
1099 : };
1100 :
1101 :
1102 : // Construct frames are special trampoline frames introduced to handle
1103 : // function invocations through 'new'.
1104 18462696 : class ConstructFrame: public InternalFrame {
1105 : public:
1106 461168 : Type type() const override { return CONSTRUCT; }
1107 :
1108 : static ConstructFrame* cast(StackFrame* frame) {
1109 : DCHECK(frame->is_construct());
1110 : return static_cast<ConstructFrame*>(frame);
1111 : }
1112 :
1113 : protected:
1114 : inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
1115 :
1116 : private:
1117 : friend class StackFrameIteratorBase;
1118 : };
1119 :
1120 18462696 : class BuiltinContinuationFrame : public InternalFrame {
1121 : public:
1122 8 : Type type() const override { return BUILTIN_CONTINUATION; }
1123 :
1124 : static BuiltinContinuationFrame* cast(StackFrame* frame) {
1125 : DCHECK(frame->is_builtin_continuation());
1126 : return static_cast<BuiltinContinuationFrame*>(frame);
1127 : }
1128 :
1129 : protected:
1130 : inline explicit BuiltinContinuationFrame(StackFrameIteratorBase* iterator);
1131 :
1132 : private:
1133 : friend class StackFrameIteratorBase;
1134 : };
1135 :
1136 36925392 : class JavaScriptBuiltinContinuationFrame : public JavaScriptFrame {
1137 : public:
1138 707 : Type type() const override { return JAVA_SCRIPT_BUILTIN_CONTINUATION; }
1139 :
1140 : static JavaScriptBuiltinContinuationFrame* cast(StackFrame* frame) {
1141 : DCHECK(frame->is_java_script_builtin_continuation());
1142 : return static_cast<JavaScriptBuiltinContinuationFrame*>(frame);
1143 : }
1144 :
1145 : int ComputeParametersCount() const override;
1146 : intptr_t GetSPToFPDelta() const;
1147 :
1148 : Object context() const override;
1149 :
1150 : protected:
1151 : inline explicit JavaScriptBuiltinContinuationFrame(
1152 : StackFrameIteratorBase* iterator);
1153 :
1154 : private:
1155 : friend class StackFrameIteratorBase;
1156 : };
1157 :
1158 18462696 : class JavaScriptBuiltinContinuationWithCatchFrame
1159 : : public JavaScriptBuiltinContinuationFrame {
1160 : public:
1161 24 : Type type() const override {
1162 24 : return JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH;
1163 : }
1164 :
1165 : static JavaScriptBuiltinContinuationWithCatchFrame* cast(StackFrame* frame) {
1166 : DCHECK(frame->is_java_script_builtin_with_catch_continuation());
1167 : return static_cast<JavaScriptBuiltinContinuationWithCatchFrame*>(frame);
1168 : }
1169 :
1170 : // Patch in the exception object at the appropriate location into the stack
1171 : // frame.
1172 : void SetException(Object exception);
1173 :
1174 : protected:
1175 : inline explicit JavaScriptBuiltinContinuationWithCatchFrame(
1176 : StackFrameIteratorBase* iterator);
1177 :
1178 : private:
1179 : friend class StackFrameIteratorBase;
1180 : };
1181 :
1182 18462696 : class StackFrameIteratorBase {
1183 : public:
1184 : Isolate* isolate() const { return isolate_; }
1185 :
1186 258871 : bool done() const { return frame_ == nullptr; }
1187 :
1188 : protected:
1189 : // An iterator that iterates over a given thread's stack.
1190 : StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
1191 :
1192 : Isolate* isolate_;
1193 : #define DECLARE_SINGLETON(ignore, type) type type##_;
1194 : STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
1195 : #undef DECLARE_SINGLETON
1196 : StackFrame* frame_;
1197 : StackHandler* handler_;
1198 : const bool can_access_heap_objects_;
1199 :
1200 : StackHandler* handler() const {
1201 : DCHECK(!done());
1202 : return handler_;
1203 : }
1204 :
1205 : // Get the type-specific frame singleton in a given state.
1206 : StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
1207 : // A helper function, can return a nullptr pointer.
1208 : StackFrame* SingletonFor(StackFrame::Type type);
1209 :
1210 : private:
1211 : friend class StackFrame;
1212 : DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
1213 : };
1214 :
1215 :
1216 9130037 : class StackFrameIterator: public StackFrameIteratorBase {
1217 : public:
1218 : // An iterator that iterates over the isolate's current thread's stack,
1219 : V8_EXPORT_PRIVATE explicit StackFrameIterator(Isolate* isolate);
1220 : // An iterator that iterates over a given thread's stack.
1221 : V8_EXPORT_PRIVATE StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
1222 :
1223 : StackFrame* frame() const {
1224 : DCHECK(!done());
1225 : return frame_;
1226 : }
1227 : V8_EXPORT_PRIVATE void Advance();
1228 :
1229 : private:
1230 : // Go back to the first frame.
1231 : void Reset(ThreadLocalTop* top);
1232 :
1233 : DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
1234 : };
1235 :
1236 : // Iterator that supports iterating through all JavaScript frames.
1237 774181 : class JavaScriptFrameIterator {
1238 : public:
1239 : inline explicit JavaScriptFrameIterator(Isolate* isolate);
1240 : inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
1241 :
1242 : inline JavaScriptFrame* frame() const;
1243 :
1244 : bool done() const { return iterator_.done(); }
1245 : V8_EXPORT_PRIVATE void Advance();
1246 4105 : void AdvanceOneFrame() { iterator_.Advance(); }
1247 :
1248 : private:
1249 : StackFrameIterator iterator_;
1250 : };
1251 :
1252 : // NOTE: The stack trace frame iterator is an iterator that only traverse proper
1253 : // JavaScript frames that have proper JavaScript functions and WebAssembly
1254 : // frames.
1255 1962061 : class V8_EXPORT_PRIVATE StackTraceFrameIterator {
1256 : public:
1257 : explicit StackTraceFrameIterator(Isolate* isolate);
1258 : // Skip frames until the frame with the given id is reached.
1259 : StackTraceFrameIterator(Isolate* isolate, StackFrame::Id id);
1260 : bool done() const { return iterator_.done(); }
1261 : void Advance();
1262 : void AdvanceOneFrame() { iterator_.Advance(); }
1263 :
1264 : inline StandardFrame* frame() const;
1265 :
1266 : inline bool is_javascript() const;
1267 : inline bool is_wasm() const;
1268 : inline JavaScriptFrame* javascript_frame() const;
1269 :
1270 : private:
1271 : StackFrameIterator iterator_;
1272 : bool IsValidFrame(StackFrame* frame) const;
1273 : };
1274 :
1275 60357 : class SafeStackFrameIterator: public StackFrameIteratorBase {
1276 : public:
1277 : SafeStackFrameIterator(Isolate* isolate,
1278 : Address fp, Address sp,
1279 : Address js_entry_sp);
1280 :
1281 : inline StackFrame* frame() const;
1282 : void Advance();
1283 :
1284 : StackFrame::Type top_frame_type() const { return top_frame_type_; }
1285 :
1286 : private:
1287 : void AdvanceOneFrame();
1288 :
1289 : bool IsValidStackAddress(Address addr) const {
1290 1537185 : return low_bound_ <= addr && addr <= high_bound_;
1291 : }
1292 : bool IsValidFrame(StackFrame* frame) const;
1293 : bool IsValidCaller(StackFrame* frame);
1294 : bool IsValidExitFrame(Address fp) const;
1295 : bool IsValidTop(ThreadLocalTop* top) const;
1296 :
1297 : const Address low_bound_;
1298 : const Address high_bound_;
1299 : StackFrame::Type top_frame_type_;
1300 : ExternalCallbackScope* external_callback_scope_;
1301 : };
1302 : } // namespace internal
1303 : } // namespace v8
1304 :
1305 : #endif // V8_FRAMES_H_
|