1 /* 2 * Copyright (C) 2008 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 /* 18 * Android's method call profiling goodies. 19 */ 20 #ifndef DALVIK_PROFILE_H_ 21 #define DALVIK_PROFILE_H_ 22 23 #ifndef NOT_VM /* for utilities that sneakily include this file */ 24 25 #include <stdio.h> 26 27 struct Thread; // extern 28 29 30 /* boot init */ 31 bool dvmProfilingStartup(void); 32 void dvmProfilingShutdown(void); 33 34 /* 35 * Method trace state. This is currently global. In theory we could make 36 * most of this per-thread. 37 */ 38 struct MethodTraceState { 39 /* active state */ 40 pthread_mutex_t startStopLock; 41 pthread_cond_t threadExitCond; 42 FILE* traceFile; 43 bool directToDdms; 44 int bufferSize; 45 int flags; 46 47 int traceEnabled; 48 u1* buf; 49 volatile int curOffset; 50 u8 startWhen; 51 int overflow; 52 53 int traceVersion; 54 size_t recordSize; 55 56 bool samplingEnabled; 57 pthread_t samplingThreadHandle; 58 }; 59 60 /* 61 * Memory allocation profiler state. This is used both globally and 62 * per-thread. 63 * 64 * If you add a field here, zero it out in dvmStartAllocCounting(). 65 */ 66 struct AllocProfState { 67 bool enabled; // is allocation tracking enabled? 68 69 int allocCount; // #of objects allocated 70 int allocSize; // cumulative size of objects 71 72 int failedAllocCount; // #of times an allocation failed 73 int failedAllocSize; // cumulative size of failed allocations 74 75 int freeCount; // #of objects freed 76 int freeSize; // cumulative size of freed objects 77 78 int gcCount; // #of times an allocation triggered a GC 79 80 int classInitCount; // #of initialized classes 81 u8 classInitTime; // cumulative time spent in class init (nsec) 82 }; 83 84 85 /* 86 * Start/stop method tracing. 87 */ 88 void dvmMethodTraceStart(const char* traceFileName, int traceFd, int bufferSize, 89 int flags, bool directToDdms, bool samplingEnabled, int intervalUs); 90 void dvmMethodTraceStop(void); 91 92 /* 93 * Returns current method tracing mode. 94 */ 95 enum TracingMode { 96 TRACING_INACTIVE, 97 METHOD_TRACING_ACTIVE, 98 SAMPLE_PROFILING_ACTIVE, 99 }; 100 TracingMode dvmGetMethodTracingMode(void); 101 102 /* 103 * Start/stop emulator tracing. 104 */ 105 void dvmEmulatorTraceStart(void); 106 void dvmEmulatorTraceStop(void); 107 108 /* 109 * Start/stop Dalvik instruction counting. 110 */ 111 void dvmStartInstructionCounting(); 112 void dvmStopInstructionCounting(); 113 114 /* 115 * Bit flags for dvmMethodTraceStart "flags" argument. These must match 116 * the values in android.os.Debug. 117 */ 118 enum { 119 TRACE_ALLOC_COUNTS = 0x01, 120 }; 121 122 /* 123 * Call these when a method enters or exits. 124 */ 125 #define TRACE_METHOD_ENTER(_self, _method) \ 126 do { \ 127 if (_self->interpBreak.ctl.subMode & kSubModeMethodTrace) { \ 128 u4 cpuClockDiff = 0; \ 129 u4 wallClockDiff = 0; \ 130 dvmMethodTraceReadClocks(_self, &cpuClockDiff, &wallClockDiff); \ 131 dvmMethodTraceAdd(_self, _method, METHOD_TRACE_ENTER, \ 132 cpuClockDiff, wallClockDiff); \ 133 } \ 134 if (_self->interpBreak.ctl.subMode & kSubModeEmulatorTrace) \ 135 dvmEmitEmulatorTrace(_method, METHOD_TRACE_ENTER); \ 136 } while(0); 137 #define TRACE_METHOD_EXIT(_self, _method) \ 138 do { \ 139 if (_self->interpBreak.ctl.subMode & kSubModeMethodTrace) { \ 140 u4 cpuClockDiff = 0; \ 141 u4 wallClockDiff = 0; \ 142 dvmMethodTraceReadClocks(_self, &cpuClockDiff, &wallClockDiff); \ 143 dvmMethodTraceAdd(_self, _method, METHOD_TRACE_EXIT, \ 144 cpuClockDiff, wallClockDiff); \ 145 } \ 146 if (_self->interpBreak.ctl.subMode & kSubModeEmulatorTrace) \ 147 dvmEmitEmulatorTrace(_method, METHOD_TRACE_EXIT); \ 148 } while(0); 149 #define TRACE_METHOD_UNROLL(_self, _method) \ 150 do { \ 151 if (_self->interpBreak.ctl.subMode & kSubModeMethodTrace) { \ 152 u4 cpuClockDiff = 0; \ 153 u4 wallClockDiff = 0; \ 154 dvmMethodTraceReadClocks(_self, &cpuClockDiff, &wallClockDiff); \ 155 dvmMethodTraceAdd(_self, _method, METHOD_TRACE_UNROLL, \ 156 cpuClockDiff, wallClockDiff); \ 157 } \ 158 if (_self->interpBreak.ctl.subMode & kSubModeEmulatorTrace) \ 159 dvmEmitEmulatorTrace(_method, METHOD_TRACE_UNROLL); \ 160 } while(0); 161 162 void dvmMethodTraceReadClocks(Thread* self, u4* cpuClockDiff, 163 u4* wallClockDiff); 164 void dvmMethodTraceAdd(struct Thread* self, const Method* method, int action, 165 u4 cpuClockDiff, u4 wallClockDiff); 166 void dvmEmitEmulatorTrace(const Method* method, int action); 167 168 void dvmMethodTraceGCBegin(void); 169 void dvmMethodTraceGCEnd(void); 170 void dvmMethodTraceClassPrepBegin(void); 171 void dvmMethodTraceClassPrepEnd(void); 172 173 extern "C" void dvmFastMethodTraceEnter(const Method* method, struct Thread* self); 174 extern "C" void dvmFastMethodTraceExit(struct Thread* self); 175 extern "C" void dvmFastNativeMethodTraceExit(const Method* method, struct Thread* self); 176 177 /* 178 * Start/stop alloc counting. 179 */ 180 void dvmStartAllocCounting(void); 181 void dvmStopAllocCounting(void); 182 183 #endif 184 185 186 /* 187 * Enumeration for the two "action" bits. 188 */ 189 enum { 190 METHOD_TRACE_ENTER = 0x00, // method entry 191 METHOD_TRACE_EXIT = 0x01, // method exit 192 METHOD_TRACE_UNROLL = 0x02, // method exited by exception unrolling 193 // 0x03 currently unused 194 }; 195 196 #define TOKEN_CHAR '*' 197 198 /* 199 * Common definitions, shared with the dump tool. 200 */ 201 #define METHOD_ACTION_MASK 0x03 /* two bits */ 202 #define METHOD_ID(_method) ((_method) & (~METHOD_ACTION_MASK)) 203 #define METHOD_ACTION(_method) (((unsigned int)(_method)) & METHOD_ACTION_MASK) 204 #define METHOD_COMBINE(_method, _action) ((_method) | (_action)) 205 206 #endif // DALVIK_PROFILE_H_ 207