1 // Copyright 2016 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_DIAGNOSTICS_PERF_JIT_H_ 29 #define V8_DIAGNOSTICS_PERF_JIT_H_ 30 31 #include "include/v8config.h" 32 33 // {PerfJitLogger} is only implemented on Linux. 34 #if V8_OS_LINUX 35 36 #include "src/logging/log.h" 37 38 namespace v8 { 39 namespace internal { 40 41 // Linux perf tool logging support. 42 class PerfJitLogger : public CodeEventLogger { 43 public: 44 explicit PerfJitLogger(Isolate* isolate); 45 ~PerfJitLogger() override; 46 47 void CodeMoveEvent(AbstractCode from, AbstractCode to) override; CodeDisableOptEvent(Handle<AbstractCode> code,Handle<SharedFunctionInfo> shared)48 void CodeDisableOptEvent(Handle<AbstractCode> code, 49 Handle<SharedFunctionInfo> shared) override {} 50 51 private: 52 void OpenJitDumpFile(); 53 void CloseJitDumpFile(); 54 void* OpenMarkerFile(int fd); 55 void CloseMarkerFile(void* marker_address); 56 57 uint64_t GetTimestamp(); 58 void LogRecordedBuffer(Handle<AbstractCode> code, 59 MaybeHandle<SharedFunctionInfo> maybe_shared, 60 const char* name, int length) override; 61 #if V8_ENABLE_WEBASSEMBLY 62 void LogRecordedBuffer(const wasm::WasmCode* code, const char* name, 63 int length) override; 64 #endif // V8_ENABLE_WEBASSEMBLY 65 66 // Extension added to V8 log file name to get the low-level log name. 67 static const char kFilenameFormatString[]; 68 static const int kFilenameBufferPadding; 69 70 // File buffer size of the low-level log. We don't use the default to 71 // minimize the associated overhead. 72 static const int kLogBufferSize = 2 * MB; 73 74 void WriteJitCodeLoadEntry(const uint8_t* code_pointer, uint32_t code_size, 75 const char* name, int name_length); 76 77 void LogWriteBytes(const char* bytes, int size); 78 void LogWriteHeader(); 79 void LogWriteDebugInfo(Handle<Code> code, Handle<SharedFunctionInfo> shared); 80 #if V8_ENABLE_WEBASSEMBLY 81 void LogWriteDebugInfo(const wasm::WasmCode* code); 82 #endif // V8_ENABLE_WEBASSEMBLY 83 void LogWriteUnwindingInfo(Code code); 84 85 static const uint32_t kElfMachIA32 = 3; 86 static const uint32_t kElfMachX64 = 62; 87 static const uint32_t kElfMachARM = 40; 88 static const uint32_t kElfMachMIPS = 8; 89 static const uint32_t kElfMachMIPS64 = 8; 90 static const uint32_t kElfMachLOONG64 = 258; 91 static const uint32_t kElfMachARM64 = 183; 92 static const uint32_t kElfMachS390x = 22; 93 static const uint32_t kElfMachPPC64 = 21; 94 static const uint32_t kElfMachRISCV = 243; 95 GetElfMach()96 uint32_t GetElfMach() { 97 #if V8_TARGET_ARCH_IA32 98 return kElfMachIA32; 99 #elif V8_TARGET_ARCH_X64 100 return kElfMachX64; 101 #elif V8_TARGET_ARCH_ARM 102 return kElfMachARM; 103 #elif V8_TARGET_ARCH_MIPS 104 return kElfMachMIPS; 105 #elif V8_TARGET_ARCH_MIPS64 106 return kElfMachMIPS64; 107 #elif V8_TARGET_ARCH_LOONG64 108 return kElfMachLOONG64; 109 #elif V8_TARGET_ARCH_ARM64 110 return kElfMachARM64; 111 #elif V8_TARGET_ARCH_S390X 112 return kElfMachS390x; 113 #elif V8_TARGET_ARCH_PPC64 114 return kElfMachPPC64; 115 #elif V8_TARGET_ARCH_RISCV64 116 return kElfMachRISCV; 117 #else 118 UNIMPLEMENTED(); 119 return 0; 120 #endif 121 } 122 123 #if V8_TARGET_ARCH_32_BIT 124 static const int kElfHeaderSize = 0x34; 125 #elif V8_TARGET_ARCH_64_BIT 126 static const int kElfHeaderSize = 0x40; 127 #else 128 #error Unknown target architecture pointer size 129 #endif 130 131 // Per-process singleton file. We assume that there is one main isolate; 132 // to determine when it goes away, we keep reference count. 133 static base::LazyRecursiveMutex file_mutex_; 134 static FILE* perf_output_handle_; 135 static uint64_t reference_count_; 136 static void* marker_address_; 137 static uint64_t code_index_; 138 static int process_id_; 139 }; 140 141 } // namespace internal 142 } // namespace v8 143 144 #endif // V8_OS_LINUX 145 146 #endif // V8_DIAGNOSTICS_PERF_JIT_H_ 147