Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:05:27

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 };
0047 
0048 // The output structure filled up by GetStackSample API function.
0049 struct SampleInfo {
0050   size_t frames_count;              // Number of frames collected.
0051   void* external_callback_entry;    // External callback address if VM is
0052                                     // executing an external callback.
0053   void* context;                    // Incumbent native context address.
0054   void* embedder_context;           // Native context address for embedder state
0055   StateTag vm_state;                // Current VM state.
0056   EmbedderStateTag embedder_state;  // Current Embedder state
0057 };
0058 
0059 struct MemoryRange {
0060   const void* start = nullptr;
0061   size_t length_in_bytes = 0;
0062 };
0063 
0064 struct JSEntryStub {
0065   MemoryRange code;
0066 };
0067 
0068 struct JSEntryStubs {
0069   JSEntryStub js_entry_stub;
0070   JSEntryStub js_construct_entry_stub;
0071   JSEntryStub js_run_microtasks_entry_stub;
0072 };
0073 
0074 /**
0075  * Various helpers for skipping over V8 frames in a given stack.
0076  *
0077  * The unwinder API is only supported on the x64, ARM64 and ARM32 architectures.
0078  */
0079 class V8_EXPORT Unwinder {
0080  public:
0081   /**
0082    * Attempt to unwind the stack to the most recent C++ frame. This function is
0083    * signal-safe and does not access any V8 state and thus doesn't require an
0084    * Isolate.
0085    *
0086    * The unwinder needs to know the location of the JS Entry Stub (a piece of
0087    * code that is run when C++ code calls into generated JS code). This is used
0088    * for edge cases where the current frame is being constructed or torn down
0089    * when the stack sample occurs.
0090    *
0091    * The unwinder also needs the virtual memory range of all possible V8 code
0092    * objects. There are two ranges required - the heap code range and the range
0093    * for code embedded in the binary.
0094    *
0095    * Available on x64, ARM64 and ARM32.
0096    *
0097    * \param code_pages A list of all of the ranges in which V8 has allocated
0098    * executable code. The caller should obtain this list by calling
0099    * Isolate::CopyCodePages() during the same interrupt/thread suspension that
0100    * captures the stack.
0101    * \param register_state The current registers. This is an in-out param that
0102    * will be overwritten with the register values after unwinding, on success.
0103    * \param stack_base The resulting stack pointer and frame pointer values are
0104    * bounds-checked against the stack_base and the original stack pointer value
0105    * to ensure that they are valid locations in the given stack. If these values
0106    * or any intermediate frame pointer values used during unwinding are ever out
0107    * of these bounds, unwinding will fail.
0108    *
0109    * \return True on success.
0110    */
0111   static bool TryUnwindV8Frames(const JSEntryStubs& entry_stubs,
0112                                 size_t code_pages_length,
0113                                 const MemoryRange* code_pages,
0114                                 RegisterState* register_state,
0115                                 const void* stack_base);
0116 
0117   /**
0118    * Whether the PC is within the V8 code range represented by code_pages.
0119    *
0120    * If this returns false, then calling UnwindV8Frames() with the same PC
0121    * and unwind_state will always fail. If it returns true, then unwinding may
0122    * (but not necessarily) be successful.
0123    *
0124    * Available on x64, ARM64 and ARM32
0125    */
0126   static bool PCIsInV8(size_t code_pages_length, const MemoryRange* code_pages,
0127                        void* pc);
0128 };
0129 
0130 }  // namespace v8
0131 
0132 #endif  // INCLUDE_V8_UNWINDER_H_