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