1 /* 2 * Copyright 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_COMPILER_JIT_JIT_LOGGER_H_ 18 #define ART_COMPILER_JIT_JIT_LOGGER_H_ 19 20 #include "base/mutex.h" 21 #include "compiled_method.h" 22 #include "driver/compiler_driver.h" 23 #include "driver/compiler_options.h" 24 25 namespace art { 26 27 class ArtMethod; 28 29 namespace jit { 30 31 // 32 // JitLogger supports two approaches of perf profiling. 33 // 34 // (1) perf-map: 35 // The perf-map mechanism generates perf-PID.map file, 36 // which provides simple "address, size, method_name" information to perf, 37 // and allows perf to map samples in jit-code-cache to jitted method symbols. 38 // 39 // Command line Example: 40 // $ perf record dalvikvm -Xcompiler-option --generate-debug-info -cp <classpath> Test 41 // $ perf report 42 // NOTE: 43 // - Make sure that the perf-PID.map file is available for 'perf report' tool to access, 44 // so that jitted method can be displayed. 45 // 46 // 47 // (2) perf-inject: 48 // The perf-inject mechansim generates jit-PID.dump file, 49 // which provides rich informations about a jitted method. 50 // It allows perf or other profiling tools to do advanced analysis on jitted code, 51 // for example instruction level profiling. 52 // 53 // Command line Example: 54 // $ perf record -k mono dalvikvm -Xcompiler-option --generate-debug-info -cp <classpath> Test 55 // $ perf inject -i perf.data -o perf.data.jitted 56 // $ perf report -i perf.data.jitted 57 // $ perf annotate -i perf.data.jitted 58 // NOTE: 59 // REQUIREMENTS 60 // - The 'perf record -k mono' option requires 4.1 (or higher) Linux kernel. 61 // - The 'perf inject' (generating jit ELF files feature) requires perf 4.6 (or higher). 62 // PERF RECORD 63 // - The '-k mono' option tells 'perf record' to use CLOCK_MONOTONIC clock during sampling; 64 // which is required by 'perf inject', to make sure that both perf.data and jit-PID.dump 65 // have unified clock source for timestamps. 66 // PERF INJECT 67 // - The 'perf inject' tool injects information from jit-PID.dump into perf.data file, 68 // and generates small ELF files (jitted-TID-CODEID.so) for each jitted method. 69 // - On Android devices, the jit-PID.dump file is generated in /data/misc/trace/ folder, and 70 // such location is recorded in perf.data file. 71 // The 'perf inject' tool is going to look for jit-PID.dump and generates small ELF files in 72 // this /data/misc/trace/ folder. 73 // Make sure that you have the read/write access to /data/misc/trace/ folder. 74 // - On non-Android devices, the jit-PID.dump file is generated in /tmp/ folder, and 75 // 'perf inject' tool operates on this folder. 76 // Make sure that you have the read/write access to /tmp/ folder. 77 // - If you are executing 'perf inject' on non-Android devices (host), but perf.data and 78 // jit-PID.dump files are adb-pulled from Android devices, make sure that there is a 79 // /data/misc/trace/ folder on host, and jit-PID.dump file is copied to this folder. 80 // - Currently 'perf inject' doesn't provide option to change the path for jit-PID.dump and 81 // generated ELF files. 82 // PERF ANNOTATE 83 // - The 'perf annotate' tool displays assembly level profiling report. 84 // Source code can also be displayed if the ELF file has debug symbols. 85 // - Make sure above small ELF files are available for 'perf annotate' tool to access, 86 // so that jitted code can be displayed in assembly view. 87 // 88 class JitLogger { 89 public: JitLogger()90 JitLogger() : code_index_(0), marker_address_(nullptr) {} 91 OpenLog()92 void OpenLog() { 93 OpenPerfMapLog(); 94 OpenJitDumpLog(); 95 } 96 WriteLog(const void * ptr,size_t code_size,ArtMethod * method)97 void WriteLog(const void* ptr, size_t code_size, ArtMethod* method) 98 REQUIRES_SHARED(Locks::mutator_lock_) { 99 WritePerfMapLog(ptr, code_size, method); 100 WriteJitDumpLog(ptr, code_size, method); 101 } 102 CloseLog()103 void CloseLog() { 104 ClosePerfMapLog(); 105 CloseJitDumpLog(); 106 } 107 108 private: 109 // For perf-map profiling 110 void OpenPerfMapLog(); 111 void WritePerfMapLog(const void* ptr, size_t code_size, ArtMethod* method) 112 REQUIRES_SHARED(Locks::mutator_lock_); 113 void ClosePerfMapLog(); 114 115 // For perf-inject profiling 116 void OpenJitDumpLog(); 117 void WriteJitDumpLog(const void* ptr, size_t code_size, ArtMethod* method) 118 REQUIRES_SHARED(Locks::mutator_lock_); 119 void CloseJitDumpLog(); 120 121 void OpenMarkerFile(); 122 void CloseMarkerFile(); 123 void WriteJitDumpHeader(); 124 void WriteJitDumpDebugInfo(); 125 126 std::unique_ptr<File> perf_file_; 127 std::unique_ptr<File> jit_dump_file_; 128 uint64_t code_index_; 129 void* marker_address_; 130 131 DISALLOW_COPY_AND_ASSIGN(JitLogger); 132 }; 133 134 } // namespace jit 135 } // namespace art 136 137 #endif // ART_COMPILER_JIT_JIT_LOGGER_H_ 138