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_PERF_JIT_H_ 29 #define V8_PERF_JIT_H_ 30 31 #include "src/log.h" 32 33 namespace v8 { 34 namespace internal { 35 36 #if V8_OS_LINUX 37 38 // Linux perf tool logging support 39 class PerfJitLogger : public CodeEventLogger { 40 public: 41 explicit PerfJitLogger(Isolate* isolate); 42 virtual ~PerfJitLogger(); 43 44 void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override; CodeDisableOptEvent(AbstractCode * code,SharedFunctionInfo * shared)45 void CodeDisableOptEvent(AbstractCode* code, 46 SharedFunctionInfo* shared) override {} 47 48 private: 49 void OpenJitDumpFile(); 50 void CloseJitDumpFile(); 51 void* OpenMarkerFile(int fd); 52 void CloseMarkerFile(void* marker_address); 53 54 uint64_t GetTimestamp(); 55 void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo* shared, 56 const char* name, int length) override; 57 void LogRecordedBuffer(const wasm::WasmCode* code, const char* name, 58 int length) override; 59 60 // Extension added to V8 log file name to get the low-level log name. 61 static const char kFilenameFormatString[]; 62 static const int kFilenameBufferPadding; 63 64 // File buffer size of the low-level log. We don't use the default to 65 // minimize the associated overhead. 66 static const int kLogBufferSize = 2 * MB; 67 68 void WriteJitCodeLoadEntry(const uint8_t* code_pointer, uint32_t code_size, 69 const char* name, int name_length); 70 71 void LogWriteBytes(const char* bytes, int size); 72 void LogWriteHeader(); 73 void LogWriteDebugInfo(Code* code, SharedFunctionInfo* shared); 74 void LogWriteUnwindingInfo(Code* code); 75 76 static const uint32_t kElfMachIA32 = 3; 77 static const uint32_t kElfMachX64 = 62; 78 static const uint32_t kElfMachARM = 40; 79 static const uint32_t kElfMachMIPS = 10; 80 static const uint32_t kElfMachARM64 = 183; 81 GetElfMach()82 uint32_t GetElfMach() { 83 #if V8_TARGET_ARCH_IA32 84 return kElfMachIA32; 85 #elif V8_TARGET_ARCH_X64 86 return kElfMachX64; 87 #elif V8_TARGET_ARCH_ARM 88 return kElfMachARM; 89 #elif V8_TARGET_ARCH_MIPS 90 return kElfMachMIPS; 91 #elif V8_TARGET_ARCH_ARM64 92 return kElfMachARM64; 93 #else 94 UNIMPLEMENTED(); 95 return 0; 96 #endif 97 } 98 99 #if V8_TARGET_ARCH_32_BIT 100 static const int kElfHeaderSize = 0x34; 101 #elif V8_TARGET_ARCH_64_BIT 102 static const int kElfHeaderSize = 0x40; 103 #else 104 #error Unknown target architecture pointer size 105 #endif 106 107 // Per-process singleton file. We assume that there is one main isolate; 108 // to determine when it goes away, we keep reference count. 109 static base::LazyRecursiveMutex file_mutex_; 110 static FILE* perf_output_handle_; 111 static uint64_t reference_count_; 112 static void* marker_address_; 113 static uint64_t code_index_; 114 }; 115 116 #else 117 118 // PerfJitLogger is only implemented on Linux 119 class PerfJitLogger : public CodeEventLogger { 120 public: 121 explicit PerfJitLogger(Isolate* isolate) : CodeEventLogger(isolate) {} 122 123 void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override { 124 UNIMPLEMENTED(); 125 } 126 127 void CodeDisableOptEvent(AbstractCode* code, 128 SharedFunctionInfo* shared) override { 129 UNIMPLEMENTED(); 130 } 131 132 void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo* shared, 133 const char* name, int length) override { 134 UNIMPLEMENTED(); 135 } 136 137 void LogRecordedBuffer(const wasm::WasmCode* code, const char* name, 138 int length) override { 139 UNIMPLEMENTED(); 140 } 141 }; 142 143 #endif // V8_OS_LINUX 144 } // namespace internal 145 } // namespace v8 146 147 #endif // V8_PERF_JIT_H_ 148