• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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