Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-01 08:24:15

0001 // Copyright 2021 the V8 project authors. All rights reserved.
0002 // Use of this source code is governed by a BSD-style license that can be
0003 // found in the LICENSE file.
0004 
0005 #ifndef INCLUDE_V8_UNWINDER_H_
0006 #define INCLUDE_V8_UNWINDER_H_
0007 
0008 #include <memory>
0009 
0010 #include "v8-embedder-state-scope.h"  // NOLINT(build/include_directory)
0011 #include "v8config.h"                 // NOLINT(build/include_directory)
0012 
0013 namespace v8 {
0014 // Holds the callee saved registers needed for the stack unwinder. It is the
0015 // empty struct if no registers are required. Implemented in
0016 // include/v8-unwinder-state.h.
0017 struct CalleeSavedRegisters;
0018 
0019 // A RegisterState represents the current state of registers used
0020 // by the sampling profiler API.
0021 struct V8_EXPORT RegisterState {
0022   RegisterState();
0023   ~RegisterState();
0024   RegisterState(const RegisterState& other);
0025   RegisterState& operator=(const RegisterState& other);
0026 
0027   void* pc;  // Instruction pointer.
0028   void* sp;  // Stack pointer.
0029   void* fp;  // Frame pointer.
0030   void* lr;  // Link register (or nullptr on platforms without a link register).
0031   // Callee saved registers (or null if no callee saved registers were stored)
0032   std::unique_ptr<CalleeSavedRegisters> callee_saved;
0033 };
0034 
0035 // A StateTag represents a possible state of the VM.
0036 enum StateTag : uint16_t {
0037   JS,
0038   GC,
0039   PARSER,
0040   BYTECODE_COMPILER,
0041   COMPILER,
0042   OTHER,
0043   EXTERNAL,
0044   ATOMICS_WAIT,
0045   IDLE,
0046   LOGGING,
0047 };
0048 
0049 // The output structure filled up by GetStackSample API function.
0050 struct SampleInfo {
0051   size_t frames_count;              // Number of frames collected.
0052   void* external_callback_entry;    // External callback address if VM is
0053                                     // executing an external callback.
0054   void* context;                    // Incumbent native context address.
0055   void* embedder_context;           // Native context address for embedder state
0056   StateTag vm_state;                // Current VM state.
0057   EmbedderStateTag embedder_state;  // Current Embedder state
0058 };
0059 
0060 struct MemoryRange {
0061   const void* start = nullptr;
0062   size_t length_in_bytes = 0;
0063 };
0064 
0065 struct JSEntryStub {
0066   MemoryRange code;
0067 };
0068 
0069 struct JSEntryStubs {
0070   JSEntryStub js_entry_stub;
0071   JSEntryStub js_construct_entry_stub;
0072   JSEntryStub js_run_microtasks_entry_stub;
0073 };
0074 
0075 /**
0076  * Various helpers for skipping over V8 frames in a given stack.
0077  *
0078  * The unwinder API is only supported on the x64, ARM64 and ARM32 architectures.
0079  */
0080 class V8_EXPORT Unwinder {
0081  public:
0082   /**
0083    * Attempt to unwind the stack to the most recent C++ frame. This function is
0084    * signal-safe and does not access any V8 state and thus doesn't require an
0085    * Isolate.
0086    *
0087    * The unwinder needs to know the location of the JS Entry Stub (a piece of
0088    * code that is run when C++ code calls into generated JS code). This is used
0089    * for edge cases where the current frame is being constructed or torn down
0090    * when the stack sample occurs.
0091    *
0092    * The unwinder also needs the virtual memory range of all possible V8 code
0093    * objects. There are two ranges required - the heap code range and the range
0094    * for code embedded in the binary.
0095    *
0096    * Available on x64, ARM64 and ARM32.
0097    *
0098    * \param code_pages A list of all of the ranges in which V8 has allocated
0099    * executable code. The caller should obtain this list by calling
0100    * Isolate::CopyCodePages() during the same interrupt/thread suspension that
0101    * captures the stack.
0102    * \param register_state The current registers. This is an in-out param that
0103    * will be overwritten with the register values after unwinding, on success.
0104    * \param stack_base The resulting stack pointer and frame pointer values are
0105    * bounds-checked against the stack_base and the original stack pointer value
0106    * to ensure that they are valid locations in the given stack. If these values
0107    * or any intermediate frame pointer values used during unwinding are ever out
0108    * of these bounds, unwinding will fail.
0109    *
0110    * \return True on success.
0111    */
0112   static bool TryUnwindV8Frames(const JSEntryStubs& entry_stubs,
0113                                 size_t code_pages_length,
0114                                 const MemoryRange* code_pages,
0115                                 RegisterState* register_state,
0116                                 const void* stack_base);
0117 
0118   /**
0119    * Whether the PC is within the V8 code range represented by code_pages.
0120    *
0121    * If this returns false, then calling UnwindV8Frames() with the same PC
0122    * and unwind_state will always fail. If it returns true, then unwinding may
0123    * (but not necessarily) be successful.
0124    *
0125    * Available on x64, ARM64 and ARM32
0126    */
0127   static bool PCIsInV8(size_t code_pages_length, const MemoryRange* code_pages,
0128                        void* pc);
0129 };
0130 
0131 }  // namespace v8
0132 
0133 #endif  // INCLUDE_V8_UNWINDER_H_