Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/node/v8-unwinder.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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