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 : 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 1892998 : 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 12930091 : 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 35919177 : 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 125511 : bool is_entry() const { return type() == ENTRY; }
173 100103 : bool is_construct_entry() const { return type() == CONSTRUCT_ENTRY; }
174 59753 : bool is_exit() const { return type() == EXIT; }
175 22070063 : bool is_optimized() const { return type() == OPTIMIZED; }
176 507731 : bool is_interpreted() const { return type() == INTERPRETED; }
177 455 : 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 383462 : return type() == WASM_INTERPRETER_ENTRY;
183 : }
184 525461 : 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 59457 : bool is_builtin_exit() const { return type() == BUILTIN_EXIT; }
198 0 : virtual bool is_standard() const { return false; }
199 :
200 12936598 : bool is_java_script() const {
201 12936598 : Type type = this->type();
202 25944372 : return (type == OPTIMIZED) || (type == INTERPRETED) || (type == BUILTIN) ||
203 25944131 : (type == JAVA_SCRIPT_BUILTIN_CONTINUATION) ||
204 12936598 : (type == JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH);
205 : }
206 : bool is_wasm() const {
207 5255599 : Type type = this->type();
208 5255599 : return type == WASM_COMPILED || type == WASM_INTERPRETER_ENTRY;
209 : }
210 :
211 : // Accessors.
212 : Address sp() const { return state_.sp; }
213 39266 : Address fp() const { return state_.fp; }
214 : Address callee_pc() const {
215 349877 : return state_.callee_pc_address ? *state_.callee_pc_address : kNullAddress;
216 : }
217 58716792 : 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 24917832 : Address pc() const { return *pc_address(); }
225 263959 : 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 1981204 : 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 : 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 178833354 : 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 8515874 : 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 17031748 : class EntryFrame: public StackFrame {
333 : public:
334 2090454 : 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 8515874 : 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 17031748 : class ExitFrame: public StackFrame {
382 : public:
383 7112223 : Type type() const override { return EXIT; }
384 :
385 : Code unchecked_code() const override;
386 :
387 : Address& code_slot() const;
388 :
389 : // Garbage collection support.
390 : void Iterate(RootVisitor* v) const override;
391 :
392 : static ExitFrame* cast(StackFrame* frame) {
393 : DCHECK(frame->is_exit());
394 : return static_cast<ExitFrame*>(frame);
395 : }
396 :
397 : // Compute the state and type of an exit frame given a frame
398 : // pointer. Used when constructing the first stack frame seen by an
399 : // iterator and the frames following entry frames.
400 : static Type GetStateForFramePointer(Address fp, State* state);
401 : static Address ComputeStackPointer(Address fp);
402 : static StackFrame::Type ComputeFrameType(Address fp);
403 : static void FillState(Address fp, Address sp, State* state);
404 :
405 : protected:
406 : inline explicit ExitFrame(StackFrameIteratorBase* iterator);
407 :
408 : Address GetCallerStackPointer() const override;
409 :
410 : private:
411 : void ComputeCallerState(State* state) const override;
412 :
413 : friend class StackFrameIteratorBase;
414 : };
415 :
416 : // Builtin exit frames are a special case of exit frames, which are used
417 : // whenever C++ builtins (e.g., Math.acos) are called. Their main purpose is
418 : // to allow such builtins to appear in stack traces.
419 8515874 : class BuiltinExitFrame : public ExitFrame {
420 : public:
421 1166516 : Type type() const override { return BUILTIN_EXIT; }
422 :
423 : static BuiltinExitFrame* cast(StackFrame* frame) {
424 : DCHECK(frame->is_builtin_exit());
425 : return static_cast<BuiltinExitFrame*>(frame);
426 : }
427 :
428 : JSFunction function() const;
429 : Object receiver() const;
430 :
431 : bool IsConstructor() const;
432 :
433 : void Print(StringStream* accumulator, PrintMode mode,
434 : int index) const override;
435 :
436 : protected:
437 : inline explicit BuiltinExitFrame(StackFrameIteratorBase* iterator);
438 :
439 : private:
440 : Object GetParameter(int i) const;
441 : int ComputeParametersCount() const;
442 :
443 : inline Object receiver_slot_object() const;
444 : inline Object argc_slot_object() const;
445 : inline Object target_slot_object() const;
446 : inline Object new_target_slot_object() const;
447 :
448 : friend class StackFrameIteratorBase;
449 : };
450 :
451 : class StandardFrame;
452 :
453 : class FrameSummary {
454 : public:
455 : // Subclasses for the different summary kinds:
456 : #define FRAME_SUMMARY_VARIANTS(F) \
457 : F(JAVA_SCRIPT, JavaScriptFrameSummary, java_script_summary_, JavaScript) \
458 : F(WASM_COMPILED, WasmCompiledFrameSummary, wasm_compiled_summary_, \
459 : WasmCompiled) \
460 : F(WASM_INTERPRETED, WasmInterpretedFrameSummary, wasm_interpreted_summary_, \
461 : WasmInterpreted)
462 :
463 : #define FRAME_SUMMARY_KIND(kind, type, field, desc) kind,
464 : enum Kind { FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_KIND) };
465 : #undef FRAME_SUMMARY_KIND
466 :
467 : class FrameSummaryBase {
468 : public:
469 : FrameSummaryBase(Isolate* isolate, Kind kind)
470 7550946 : : isolate_(isolate), kind_(kind) {}
471 : Isolate* isolate() const { return isolate_; }
472 : Kind kind() const { return kind_; }
473 :
474 : private:
475 : Isolate* isolate_;
476 : Kind kind_;
477 : };
478 :
479 : class JavaScriptFrameSummary : public FrameSummaryBase {
480 : public:
481 : JavaScriptFrameSummary(Isolate* isolate, Object receiver,
482 : JSFunction function, AbstractCode abstract_code,
483 : int code_offset, bool is_constructor);
484 :
485 : Handle<Object> receiver() const { return receiver_; }
486 : Handle<JSFunction> function() const { return function_; }
487 : Handle<AbstractCode> abstract_code() const { return abstract_code_; }
488 : int code_offset() const { return code_offset_; }
489 : bool is_constructor() const { return is_constructor_; }
490 : bool is_subject_to_debugging() const;
491 : int SourcePosition() const;
492 : int SourceStatementPosition() const;
493 : Handle<Object> script() const;
494 : Handle<String> FunctionName() const;
495 : Handle<Context> native_context() const;
496 :
497 : private:
498 : Handle<Object> receiver_;
499 : Handle<JSFunction> function_;
500 : Handle<AbstractCode> abstract_code_;
501 : int code_offset_;
502 : bool is_constructor_;
503 : };
504 :
505 : class WasmFrameSummary : public FrameSummaryBase {
506 : protected:
507 : WasmFrameSummary(Isolate*, Kind, Handle<WasmInstanceObject>,
508 : bool at_to_number_conversion);
509 :
510 : public:
511 : Handle<Object> receiver() const;
512 : uint32_t function_index() const;
513 : int byte_offset() const;
514 : bool is_constructor() const { return false; }
515 : bool is_subject_to_debugging() const { return true; }
516 : int SourcePosition() const;
517 0 : int SourceStatementPosition() const { return SourcePosition(); }
518 : Handle<Script> script() const;
519 : Handle<WasmInstanceObject> wasm_instance() const { return wasm_instance_; }
520 : Handle<String> FunctionName() const;
521 : Handle<Context> native_context() const;
522 : bool at_to_number_conversion() const { return at_to_number_conversion_; }
523 :
524 : private:
525 : Handle<WasmInstanceObject> wasm_instance_;
526 : bool at_to_number_conversion_;
527 : };
528 :
529 : class WasmCompiledFrameSummary : public WasmFrameSummary {
530 : public:
531 : WasmCompiledFrameSummary(Isolate*, Handle<WasmInstanceObject>,
532 : wasm::WasmCode*, int code_offset,
533 : bool at_to_number_conversion);
534 : uint32_t function_index() const;
535 : wasm::WasmCode* code() const { return code_; }
536 : int code_offset() const { return code_offset_; }
537 : int byte_offset() const;
538 : static int GetWasmSourcePosition(const wasm::WasmCode* code, int offset);
539 :
540 : private:
541 : wasm::WasmCode* const code_;
542 : int code_offset_;
543 : };
544 :
545 : class WasmInterpretedFrameSummary : public WasmFrameSummary {
546 : public:
547 : WasmInterpretedFrameSummary(Isolate*, Handle<WasmInstanceObject>,
548 : uint32_t function_index, int byte_offset);
549 : uint32_t function_index() const { return function_index_; }
550 : int code_offset() const { return byte_offset_; }
551 : int byte_offset() const { return byte_offset_; }
552 :
553 : private:
554 : uint32_t function_index_;
555 : int byte_offset_;
556 : };
557 :
558 : #undef FRAME_SUMMARY_FIELD
559 : #define FRAME_SUMMARY_CONS(kind, type, field, desc) \
560 : FrameSummary(type summ) : field(summ) {} // NOLINT
561 8656077 : FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CONS)
562 : #undef FRAME_SUMMARY_CONS
563 :
564 : ~FrameSummary();
565 :
566 : static FrameSummary GetTop(const StandardFrame* frame);
567 : static FrameSummary GetBottom(const StandardFrame* frame);
568 : static FrameSummary GetSingle(const StandardFrame* frame);
569 : static FrameSummary Get(const StandardFrame* frame, int index);
570 :
571 : // Dispatched accessors.
572 : Handle<Object> receiver() const;
573 : int code_offset() const;
574 : bool is_constructor() const;
575 : bool is_subject_to_debugging() const;
576 : Handle<Object> script() const;
577 : int SourcePosition() const;
578 : int SourceStatementPosition() const;
579 : Handle<String> FunctionName() const;
580 : Handle<Context> native_context() const;
581 :
582 : #define FRAME_SUMMARY_CAST(kind_, type, field, desc) \
583 : bool Is##desc() const { return base_.kind() == kind_; } \
584 : const type& As##desc() const { \
585 : DCHECK_EQ(base_.kind(), kind_); \
586 : return field; \
587 : }
588 6219992 : FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CAST)
589 : #undef FRAME_SUMMARY_CAST
590 :
591 585 : bool IsWasm() const { return IsWasmCompiled() || IsWasmInterpreted(); }
592 : const WasmFrameSummary& AsWasm() const {
593 585 : if (IsWasmCompiled()) return AsWasmCompiled();
594 420 : return AsWasmInterpreted();
595 : }
596 :
597 : private:
598 : #define FRAME_SUMMARY_FIELD(kind, type, field, desc) type field;
599 : union {
600 : FrameSummaryBase base_;
601 : FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_FIELD)
602 : };
603 : };
604 :
605 136253984 : class StandardFrame : public StackFrame {
606 : public:
607 : // Testers.
608 0 : bool is_standard() const override { return true; }
609 :
610 : // Accessors.
611 : virtual Object receiver() const;
612 : virtual Script script() const;
613 : virtual Object context() const;
614 : virtual int position() const;
615 :
616 : // Access the expressions in the stack frame including locals.
617 : inline Object GetExpression(int index) const;
618 : inline void SetExpression(int index, Object value);
619 : int ComputeExpressionsCount() const;
620 :
621 : // Access the parameters.
622 : virtual Object GetParameter(int index) const;
623 : virtual int ComputeParametersCount() const;
624 :
625 : // Check if this frame is a constructor frame invoked through 'new'.
626 : virtual bool IsConstructor() const;
627 :
628 : // Build a list with summaries for this frame including all inlined frames.
629 : // The functions are ordered bottom-to-top (i.e. summaries.last() is the
630 : // top-most activation; caller comes before callee).
631 : virtual void Summarize(std::vector<FrameSummary>* frames) const;
632 :
633 : static StandardFrame* cast(StackFrame* frame) {
634 : DCHECK(frame->is_standard());
635 : return static_cast<StandardFrame*>(frame);
636 : }
637 :
638 : protected:
639 : inline explicit StandardFrame(StackFrameIteratorBase* iterator);
640 :
641 : void ComputeCallerState(State* state) const override;
642 :
643 : // Accessors.
644 : inline Address caller_fp() const;
645 : inline Address caller_pc() const;
646 :
647 : // Computes the address of the PC field in the standard frame given
648 : // by the provided frame pointer.
649 : static inline Address ComputePCAddress(Address fp);
650 :
651 : // Computes the address of the constant pool field in the standard
652 : // frame given by the provided frame pointer.
653 : static inline Address ComputeConstantPoolAddress(Address fp);
654 :
655 : // Iterate over expression stack including stack handlers, locals,
656 : // and parts of the fixed part including context and code fields.
657 : void IterateExpressions(RootVisitor* v) const;
658 :
659 : // Returns the address of the n'th expression stack element.
660 : virtual Address GetExpressionAddress(int n) const;
661 :
662 : // Determines if the standard frame for the given frame pointer is
663 : // an arguments adaptor frame.
664 : static inline bool IsArgumentsAdaptorFrame(Address fp);
665 :
666 : // Determines if the standard frame for the given frame pointer is a
667 : // construct frame.
668 : static inline bool IsConstructFrame(Address fp);
669 :
670 : // Used by OptimizedFrames and StubFrames.
671 : void IterateCompiledFrame(RootVisitor* v) const;
672 :
673 : private:
674 : friend class StackFrame;
675 : friend class SafeStackFrameIterator;
676 : };
677 :
678 51095244 : class JavaScriptFrame : public StandardFrame {
679 : public:
680 : Type type() const override = 0;
681 :
682 : void Summarize(std::vector<FrameSummary>* frames) const override;
683 :
684 : // Accessors.
685 : virtual JSFunction function() const;
686 : Object unchecked_function() const;
687 : Object receiver() const override;
688 : Object context() const override;
689 : Script script() const override;
690 :
691 : inline void set_receiver(Object value);
692 :
693 : // Access the parameters.
694 : inline Address GetParameterSlot(int index) const;
695 : Object GetParameter(int index) const override;
696 : int ComputeParametersCount() const override;
697 :
698 : // Debugger access.
699 : void SetParameterValue(int index, Object value) const;
700 :
701 : // Check if this frame is a constructor frame invoked through 'new'.
702 : bool IsConstructor() const override;
703 :
704 : // Determines whether this frame includes inlined activations. To get details
705 : // about the inlined frames use {GetFunctions} and {Summarize}.
706 : bool HasInlinedFrames() const;
707 :
708 : // Check if this frame has "adapted" arguments in the sense that the
709 : // actual passed arguments are available in an arguments adaptor
710 : // frame below it on the stack.
711 : inline bool has_adapted_arguments() const;
712 :
713 : // Garbage collection support.
714 : void Iterate(RootVisitor* v) const override;
715 :
716 : // Printing support.
717 : void Print(StringStream* accumulator, PrintMode mode,
718 : int index) const override;
719 :
720 : // Determine the code for the frame.
721 : Code unchecked_code() const override;
722 :
723 : // Return a list with {SharedFunctionInfo} objects of this frame.
724 : virtual void GetFunctions(std::vector<SharedFunctionInfo>* functions) const;
725 :
726 : void GetFunctions(std::vector<Handle<SharedFunctionInfo>>* functions) const;
727 :
728 : // Lookup exception handler for current {pc}, returns -1 if none found. Also
729 : // returns data associated with the handler site specific to the frame type:
730 : // - OptimizedFrame : Data is the stack slot count of the entire frame.
731 : // - InterpretedFrame: Data is the register index holding the context.
732 : virtual int LookupExceptionHandlerInTable(
733 : int* data, HandlerTable::CatchPrediction* prediction);
734 :
735 : // Architecture-specific register description.
736 : static Register fp_register();
737 : static Register context_register();
738 : static Register constant_pool_pointer_register();
739 :
740 9 : static JavaScriptFrame* cast(StackFrame* frame) {
741 : DCHECK(frame->is_java_script());
742 9 : return static_cast<JavaScriptFrame*>(frame);
743 : }
744 :
745 : static void PrintFunctionAndOffset(JSFunction function, AbstractCode code,
746 : int code_offset, FILE* file,
747 : bool print_line_number);
748 :
749 : static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
750 : bool print_line_number);
751 :
752 : static void CollectFunctionAndOffsetForICStats(JSFunction function,
753 : AbstractCode code,
754 : int code_offset);
755 : static void CollectTopFrameForICStats(Isolate* isolate);
756 :
757 : protected:
758 : inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
759 :
760 : Address GetCallerStackPointer() const override;
761 :
762 : virtual int GetNumberOfIncomingArguments() const;
763 :
764 63 : virtual void PrintFrameKind(StringStream* accumulator) const {}
765 :
766 : private:
767 : inline Object function_slot_object() const;
768 :
769 : friend class StackFrameIteratorBase;
770 : };
771 :
772 :
773 34063496 : class StubFrame : public StandardFrame {
774 : public:
775 6267124 : Type type() const override { return STUB; }
776 :
777 : // GC support.
778 : void Iterate(RootVisitor* v) const override;
779 :
780 : // Determine the code for the frame.
781 : Code unchecked_code() const override;
782 :
783 : // Lookup exception handler for current {pc}, returns -1 if none found. Only
784 : // TurboFan stub frames are supported. Also returns data associated with the
785 : // handler site:
786 : // - TurboFan stub: Data is the stack slot count of the entire frame.
787 : int LookupExceptionHandlerInTable(int* data);
788 :
789 : protected:
790 : inline explicit StubFrame(StackFrameIteratorBase* iterator);
791 :
792 : Address GetCallerStackPointer() const override;
793 :
794 : virtual int GetNumberOfIncomingArguments() const;
795 :
796 : friend class StackFrameIteratorBase;
797 : };
798 :
799 :
800 8515874 : class OptimizedFrame : public JavaScriptFrame {
801 : public:
802 9555955 : Type type() const override { return OPTIMIZED; }
803 :
804 : // GC support.
805 : void Iterate(RootVisitor* v) const override;
806 :
807 : // Return a list with {SharedFunctionInfo} objects of this frame.
808 : // The functions are ordered bottom-to-top (i.e. functions.last()
809 : // is the top-most activation)
810 : void GetFunctions(std::vector<SharedFunctionInfo>* functions) const override;
811 :
812 : void Summarize(std::vector<FrameSummary>* frames) const override;
813 :
814 : // Lookup exception handler for current {pc}, returns -1 if none found.
815 : int LookupExceptionHandlerInTable(
816 : int* data, HandlerTable::CatchPrediction* prediction) override;
817 :
818 : DeoptimizationData GetDeoptimizationData(int* deopt_index) const;
819 :
820 : Object receiver() const override;
821 :
822 : static int StackSlotOffsetRelativeToFp(int slot_index);
823 :
824 : protected:
825 : inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
826 :
827 : int GetNumberOfIncomingArguments() const override;
828 :
829 : private:
830 : friend class StackFrameIteratorBase;
831 :
832 : Object StackSlotAt(int index) const;
833 : };
834 :
835 :
836 8515874 : class InterpretedFrame : public JavaScriptFrame {
837 : public:
838 35564430 : Type type() const override { return INTERPRETED; }
839 :
840 : // Accessors.
841 : int position() const override;
842 :
843 : // Lookup exception handler for current {pc}, returns -1 if none found.
844 : int LookupExceptionHandlerInTable(
845 : int* data, HandlerTable::CatchPrediction* prediction) override;
846 :
847 : // Returns the current offset into the bytecode stream.
848 : int GetBytecodeOffset() const;
849 :
850 : // Updates the current offset into the bytecode stream, mainly used for stack
851 : // unwinding to continue execution at a different bytecode offset.
852 : void PatchBytecodeOffset(int new_offset);
853 :
854 : // Returns the frame's current bytecode array.
855 : BytecodeArray GetBytecodeArray() const;
856 :
857 : // Updates the frame's BytecodeArray with |bytecode_array|. Used by the
858 : // debugger to swap execution onto a BytecodeArray patched with breakpoints.
859 : void PatchBytecodeArray(BytecodeArray bytecode_array);
860 :
861 : // Access to the interpreter register file for this frame.
862 : Object ReadInterpreterRegister(int register_index) const;
863 : void WriteInterpreterRegister(int register_index, Object value);
864 :
865 : // Build a list with summaries for this frame including all inlined frames.
866 : void Summarize(std::vector<FrameSummary>* frames) const override;
867 :
868 : static int GetBytecodeOffset(Address fp);
869 :
870 6590 : static InterpretedFrame* cast(StackFrame* frame) {
871 : DCHECK(frame->is_interpreted());
872 6590 : return static_cast<InterpretedFrame*>(frame);
873 : }
874 :
875 : protected:
876 : inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
877 :
878 : Address GetExpressionAddress(int n) const override;
879 :
880 : private:
881 : friend class StackFrameIteratorBase;
882 : };
883 :
884 :
885 : // Arguments adaptor frames are automatically inserted below
886 : // JavaScript frames when the actual number of parameters does not
887 : // match the formal number of parameters.
888 8515874 : class ArgumentsAdaptorFrame: public JavaScriptFrame {
889 : public:
890 2971923 : Type type() const override { return ARGUMENTS_ADAPTOR; }
891 :
892 : // Determine the code for the frame.
893 : Code unchecked_code() const override;
894 :
895 9 : static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
896 : DCHECK(frame->is_arguments_adaptor());
897 9 : return static_cast<ArgumentsAdaptorFrame*>(frame);
898 : }
899 :
900 : // Printing support.
901 : void Print(StringStream* accumulator, PrintMode mode,
902 : int index) const override;
903 :
904 : protected:
905 : inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
906 :
907 : int GetNumberOfIncomingArguments() const override;
908 :
909 : private:
910 : friend class StackFrameIteratorBase;
911 : };
912 :
913 : // Builtin frames are built for builtins with JavaScript linkage, such as
914 : // various standard library functions (i.e. Math.asin, Math.floor, etc.).
915 8515874 : class BuiltinFrame final : public JavaScriptFrame {
916 : public:
917 0 : Type type() const final { return BUILTIN; }
918 :
919 : static BuiltinFrame* cast(StackFrame* frame) {
920 : DCHECK(frame->is_builtin());
921 : return static_cast<BuiltinFrame*>(frame);
922 : }
923 :
924 : protected:
925 : inline explicit BuiltinFrame(StackFrameIteratorBase* iterator);
926 :
927 : int GetNumberOfIncomingArguments() const final;
928 : void PrintFrameKind(StringStream* accumulator) const override;
929 :
930 : private:
931 : friend class StackFrameIteratorBase;
932 : };
933 :
934 8515874 : class WasmCompiledFrame final : public StandardFrame {
935 : public:
936 6165444 : Type type() const override { return WASM_COMPILED; }
937 :
938 : // GC support.
939 : void Iterate(RootVisitor* v) const override;
940 :
941 : // Printing support.
942 : void Print(StringStream* accumulator, PrintMode mode,
943 : int index) const override;
944 :
945 : // Lookup exception handler for current {pc}, returns -1 if none found. Also
946 : // returns the stack slot count of the entire frame.
947 : int LookupExceptionHandlerInTable(int* data);
948 :
949 : // Determine the code for the frame.
950 : Code unchecked_code() const override;
951 :
952 : // Accessors.
953 : WasmInstanceObject wasm_instance() const;
954 : wasm::WasmCode* wasm_code() const;
955 : uint32_t function_index() const;
956 : Script script() const override;
957 : int position() const override;
958 : bool at_to_number_conversion() const;
959 :
960 : void Summarize(std::vector<FrameSummary>* frames) const override;
961 :
962 90 : static WasmCompiledFrame* cast(StackFrame* frame) {
963 : DCHECK(frame->is_wasm_compiled());
964 90 : return static_cast<WasmCompiledFrame*>(frame);
965 : }
966 :
967 : protected:
968 : inline explicit WasmCompiledFrame(StackFrameIteratorBase* iterator);
969 :
970 : Address GetCallerStackPointer() const override;
971 :
972 : private:
973 : friend class StackFrameIteratorBase;
974 : WasmModuleObject module_object() const;
975 : };
976 :
977 8515874 : class WasmInterpreterEntryFrame final : public StandardFrame {
978 : public:
979 17805 : Type type() const override { return WASM_INTERPRETER_ENTRY; }
980 :
981 : // GC support.
982 : void Iterate(RootVisitor* v) const override;
983 :
984 : // Printing support.
985 : void Print(StringStream* accumulator, PrintMode mode,
986 : int index) const override;
987 :
988 : void Summarize(std::vector<FrameSummary>* frames) const override;
989 :
990 : // Determine the code for the frame.
991 : Code unchecked_code() const override;
992 :
993 : // Accessors.
994 : WasmDebugInfo debug_info() const;
995 : WasmInstanceObject wasm_instance() const;
996 :
997 : Script script() const override;
998 : int position() const override;
999 : Object context() const override;
1000 :
1001 39248 : static WasmInterpreterEntryFrame* cast(StackFrame* frame) {
1002 : DCHECK(frame->is_wasm_interpreter_entry());
1003 39248 : return static_cast<WasmInterpreterEntryFrame*>(frame);
1004 : }
1005 :
1006 : protected:
1007 : inline explicit WasmInterpreterEntryFrame(StackFrameIteratorBase* iterator);
1008 :
1009 : Address GetCallerStackPointer() const override;
1010 :
1011 : private:
1012 : friend class StackFrameIteratorBase;
1013 : WasmModuleObject module_object() const;
1014 : };
1015 :
1016 8515874 : class WasmToJsFrame : public StubFrame {
1017 : public:
1018 4758 : Type type() const override { return WASM_TO_JS; }
1019 :
1020 : protected:
1021 : inline explicit WasmToJsFrame(StackFrameIteratorBase* iterator);
1022 :
1023 : private:
1024 : friend class StackFrameIteratorBase;
1025 : };
1026 :
1027 8515874 : class JsToWasmFrame : public StubFrame {
1028 : public:
1029 515088 : Type type() const override { return JS_TO_WASM; }
1030 :
1031 : protected:
1032 : inline explicit JsToWasmFrame(StackFrameIteratorBase* iterator);
1033 :
1034 : private:
1035 : friend class StackFrameIteratorBase;
1036 : };
1037 :
1038 8515874 : class CWasmEntryFrame : public StubFrame {
1039 : public:
1040 2620 : Type type() const override { return C_WASM_ENTRY; }
1041 :
1042 : protected:
1043 : inline explicit CWasmEntryFrame(StackFrameIteratorBase* iterator);
1044 :
1045 : private:
1046 : friend class StackFrameIteratorBase;
1047 : };
1048 :
1049 8515874 : class WasmCompileLazyFrame : public StandardFrame {
1050 : public:
1051 0 : Type type() const override { return WASM_COMPILE_LAZY; }
1052 :
1053 : Code unchecked_code() const override;
1054 : WasmInstanceObject wasm_instance() const;
1055 : FullObjectSlot wasm_instance_slot() const;
1056 :
1057 : // Garbage collection support.
1058 : void Iterate(RootVisitor* v) const override;
1059 :
1060 : static WasmCompileLazyFrame* cast(StackFrame* frame) {
1061 : DCHECK(frame->is_wasm_compile_lazy());
1062 : return static_cast<WasmCompileLazyFrame*>(frame);
1063 : }
1064 :
1065 : protected:
1066 : inline explicit WasmCompileLazyFrame(StackFrameIteratorBase* iterator);
1067 :
1068 : Address GetCallerStackPointer() const override;
1069 :
1070 : private:
1071 : friend class StackFrameIteratorBase;
1072 : };
1073 :
1074 25547622 : class InternalFrame: public StandardFrame {
1075 : public:
1076 2694926 : Type type() const override { return INTERNAL; }
1077 :
1078 : // Garbage collection support.
1079 : void Iterate(RootVisitor* v) const override;
1080 :
1081 : // Determine the code for the frame.
1082 : Code unchecked_code() const override;
1083 :
1084 : static InternalFrame* cast(StackFrame* frame) {
1085 : DCHECK(frame->is_internal());
1086 : return static_cast<InternalFrame*>(frame);
1087 : }
1088 :
1089 : protected:
1090 : inline explicit InternalFrame(StackFrameIteratorBase* iterator);
1091 :
1092 : Address GetCallerStackPointer() const override;
1093 :
1094 : private:
1095 : friend class StackFrameIteratorBase;
1096 : };
1097 :
1098 :
1099 : // Construct frames are special trampoline frames introduced to handle
1100 : // function invocations through 'new'.
1101 8515874 : class ConstructFrame: public InternalFrame {
1102 : public:
1103 476355 : Type type() const override { return CONSTRUCT; }
1104 :
1105 : static ConstructFrame* cast(StackFrame* frame) {
1106 : DCHECK(frame->is_construct());
1107 : return static_cast<ConstructFrame*>(frame);
1108 : }
1109 :
1110 : protected:
1111 : inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
1112 :
1113 : private:
1114 : friend class StackFrameIteratorBase;
1115 : };
1116 :
1117 8515874 : class BuiltinContinuationFrame : public InternalFrame {
1118 : public:
1119 8 : Type type() const override { return BUILTIN_CONTINUATION; }
1120 :
1121 : static BuiltinContinuationFrame* cast(StackFrame* frame) {
1122 : DCHECK(frame->is_builtin_continuation());
1123 : return static_cast<BuiltinContinuationFrame*>(frame);
1124 : }
1125 :
1126 : protected:
1127 : inline explicit BuiltinContinuationFrame(StackFrameIteratorBase* iterator);
1128 :
1129 : private:
1130 : friend class StackFrameIteratorBase;
1131 : };
1132 :
1133 17031748 : class JavaScriptBuiltinContinuationFrame : public JavaScriptFrame {
1134 : public:
1135 756 : Type type() const override { return JAVA_SCRIPT_BUILTIN_CONTINUATION; }
1136 :
1137 : static JavaScriptBuiltinContinuationFrame* cast(StackFrame* frame) {
1138 : DCHECK(frame->is_java_script_builtin_continuation());
1139 : return static_cast<JavaScriptBuiltinContinuationFrame*>(frame);
1140 : }
1141 :
1142 : int ComputeParametersCount() const override;
1143 : intptr_t GetSPToFPDelta() const;
1144 :
1145 : Object context() const override;
1146 :
1147 : protected:
1148 : inline explicit JavaScriptBuiltinContinuationFrame(
1149 : StackFrameIteratorBase* iterator);
1150 :
1151 : private:
1152 : friend class StackFrameIteratorBase;
1153 : };
1154 :
1155 8515874 : class JavaScriptBuiltinContinuationWithCatchFrame
1156 : : public JavaScriptBuiltinContinuationFrame {
1157 : public:
1158 24 : Type type() const override {
1159 24 : return JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH;
1160 : }
1161 :
1162 : static JavaScriptBuiltinContinuationWithCatchFrame* cast(StackFrame* frame) {
1163 : DCHECK(frame->is_java_script_builtin_with_catch_continuation());
1164 : return static_cast<JavaScriptBuiltinContinuationWithCatchFrame*>(frame);
1165 : }
1166 :
1167 : // Patch in the exception object at the appropriate location into the stack
1168 : // frame.
1169 : void SetException(Object exception);
1170 :
1171 : protected:
1172 : inline explicit JavaScriptBuiltinContinuationWithCatchFrame(
1173 : StackFrameIteratorBase* iterator);
1174 :
1175 : private:
1176 : friend class StackFrameIteratorBase;
1177 : };
1178 :
1179 17031748 : class StackFrameIteratorBase {
1180 : public:
1181 : Isolate* isolate() const { return isolate_; }
1182 :
1183 329091 : bool done() const { return frame_ == nullptr; }
1184 :
1185 : protected:
1186 : // An iterator that iterates over a given thread's stack.
1187 : StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
1188 :
1189 : Isolate* isolate_;
1190 : #define DECLARE_SINGLETON(ignore, type) type type##_;
1191 : STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
1192 : #undef DECLARE_SINGLETON
1193 : StackFrame* frame_;
1194 : StackHandler* handler_;
1195 : const bool can_access_heap_objects_;
1196 :
1197 : StackHandler* handler() const {
1198 : DCHECK(!done());
1199 : return handler_;
1200 : }
1201 :
1202 : // Get the type-specific frame singleton in a given state.
1203 : StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
1204 : // A helper function, can return a nullptr pointer.
1205 : StackFrame* SingletonFor(StackFrame::Type type);
1206 :
1207 : private:
1208 : friend class StackFrame;
1209 : DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
1210 : };
1211 :
1212 :
1213 8372535 : class StackFrameIterator: public StackFrameIteratorBase {
1214 : public:
1215 : // An iterator that iterates over the isolate's current thread's stack,
1216 : explicit StackFrameIterator(Isolate* isolate);
1217 : // An iterator that iterates over a given thread's stack.
1218 : StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
1219 :
1220 78514 : StackFrame* frame() const {
1221 : DCHECK(!done());
1222 78514 : return frame_;
1223 : }
1224 : void Advance();
1225 :
1226 : private:
1227 : // Go back to the first frame.
1228 : void Reset(ThreadLocalTop* top);
1229 :
1230 : DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
1231 : };
1232 :
1233 : // Iterator that supports iterating through all JavaScript frames.
1234 510382 : class JavaScriptFrameIterator {
1235 : public:
1236 : inline explicit JavaScriptFrameIterator(Isolate* isolate);
1237 : inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
1238 :
1239 : inline JavaScriptFrame* frame() const;
1240 :
1241 1972132 : bool done() const { return iterator_.done(); }
1242 : void Advance();
1243 3518 : void AdvanceOneFrame() { iterator_.Advance(); }
1244 :
1245 : private:
1246 : StackFrameIterator iterator_;
1247 : };
1248 :
1249 : // NOTE: The stack trace frame iterator is an iterator that only traverse proper
1250 : // JavaScript frames that have proper JavaScript functions and WebAssembly
1251 : // frames.
1252 180 : class StackTraceFrameIterator {
1253 : public:
1254 : explicit StackTraceFrameIterator(Isolate* isolate);
1255 : // Skip frames until the frame with the given id is reached.
1256 : StackTraceFrameIterator(Isolate* isolate, StackFrame::Id id);
1257 13759023 : bool done() const { return iterator_.done(); }
1258 : void Advance();
1259 : void AdvanceOneFrame() { iterator_.Advance(); }
1260 :
1261 : inline StandardFrame* frame() const;
1262 :
1263 : inline bool is_javascript() const;
1264 : inline bool is_wasm() const;
1265 : inline JavaScriptFrame* javascript_frame() const;
1266 :
1267 : private:
1268 : StackFrameIterator iterator_;
1269 : bool IsValidFrame(StackFrame* frame) const;
1270 : };
1271 :
1272 :
1273 25308 : class SafeStackFrameIterator: public StackFrameIteratorBase {
1274 : public:
1275 : SafeStackFrameIterator(Isolate* isolate,
1276 : Address fp, Address sp,
1277 : Address js_entry_sp);
1278 :
1279 : inline StackFrame* frame() const;
1280 : void Advance();
1281 :
1282 : StackFrame::Type top_frame_type() const { return top_frame_type_; }
1283 :
1284 : private:
1285 : void AdvanceOneFrame();
1286 :
1287 : bool IsValidStackAddress(Address addr) const {
1288 552129 : return low_bound_ <= addr && addr <= high_bound_;
1289 : }
1290 : bool IsValidFrame(StackFrame* frame) const;
1291 : bool IsValidCaller(StackFrame* frame);
1292 : bool IsValidExitFrame(Address fp) const;
1293 : bool IsValidTop(ThreadLocalTop* top) const;
1294 :
1295 : const Address low_bound_;
1296 : const Address high_bound_;
1297 : StackFrame::Type top_frame_type_;
1298 : ExternalCallbackScope* external_callback_scope_;
1299 : };
1300 : } // namespace internal
1301 : } // namespace v8
1302 :
1303 : #endif // V8_FRAMES_H_
|