blob: f762974ad66f63bb5715551764c9df578760495e [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
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 * Android's method call profiling goodies.
18 */
19#ifndef _DALVIK_PROFILE
20#define _DALVIK_PROFILE
21
22#ifndef NOT_VM /* for utilities that sneakily include this file */
23
24#include <stdio.h>
25
26/* External allocations are hackish enough that it's worthwhile
27 * separating them for possible removal later.
28 */
29#define PROFILE_EXTERNAL_ALLOCATIONS 1
30
31struct Thread; // extern
32
33
34/* boot init */
35bool dvmProfilingStartup(void);
36void dvmProfilingShutdown(void);
37
38/*
39 * Method trace state. This is currently global. In theory we could make
40 * most of this per-thread.
41 *
42 */
43typedef struct MethodTraceState {
44 /* these are set during VM init */
45 Method* gcMethod;
46 Method* classPrepMethod;
47
48 /* active state */
49 pthread_mutex_t startStopLock;
50 pthread_cond_t threadExitCond;
51 FILE* traceFile;
52 int bufferSize;
53 int flags;
54
55 bool traceEnabled;
56 u1* buf;
57 volatile int curOffset;
58 u8 startWhen;
59 int overflow;
60} MethodTraceState;
61
62/*
63 * Memory allocation profiler state. This is used both globally and
64 * per-thread.
65 *
66 * If you add a field here, zero it out in dvmStartAllocCounting().
67 */
68typedef struct AllocProfState {
69 bool enabled; // is allocation tracking enabled?
70
71 int allocCount; // #of objects allocated
72 int allocSize; // cumulative size of objects
73
74 int failedAllocCount; // #of times an allocation failed
75 int failedAllocSize; // cumulative size of failed allocations
76
77 int freeCount; // #of objects freed
78 int freeSize; // cumulative size of freed objects
79
80 int gcCount; // #of times an allocation triggered a GC
81
82#if PROFILE_EXTERNAL_ALLOCATIONS
83 int externalAllocCount; // #of calls to dvmTrackExternalAllocation()
84 int externalAllocSize; // #of bytes passed to ...ExternalAllocation()
85
86 int failedExternalAllocCount; // #of times an allocation failed
87 int failedExternalAllocSize; // cumulative size of failed allocations
88
89 int externalFreeCount; // #of calls to dvmTrackExternalFree()
90 int externalFreeSize; // #of bytes passed to ...ExternalFree()
91#endif // PROFILE_EXTERNAL_ALLOCATIONS
92} AllocProfState;
93
94
95/*
96 * Start/stop method tracing.
97 */
98void dvmMethodTraceStart(const char* traceFileName, int bufferSize, int flags);
99void dvmMethodTraceStop(void);
100
101/*
102 * Start/stop emulator tracing.
103 */
104void dvmEmulatorTraceStart(void);
105void dvmEmulatorTraceStop(void);
106
107/*
108 * Start/stop Dalvik instruction counting.
109 */
110void dvmStartInstructionCounting();
111void dvmStopInstructionCounting();
112
113/*
114 * Bit flags for dvmMethodTraceStart "flags" argument. These must match
115 * the values in android.os.Debug.
116 */
117enum {
118 TRACE_ALLOC_COUNTS = 0x01,
119};
120
121/*
122 * Call these when a method enters or exits.
123 */
124#ifdef WITH_PROFILER
125# define TRACE_METHOD_ENTER(_self, _method) \
126 do { \
127 if (gDvm.activeProfilers != 0) { \
128 if (gDvm.methodTrace.traceEnabled) \
129 dvmMethodTraceAdd(_self, _method, METHOD_TRACE_ENTER); \
130 if (gDvm.emulatorTraceEnableCount != 0) \
131 dvmEmitEmulatorTrace(_method, METHOD_TRACE_ENTER); \
132 } \
133 } while(0);
134# define TRACE_METHOD_EXIT(_self, _method) \
135 do { \
136 if (gDvm.activeProfilers != 0) { \
137 if (gDvm.methodTrace.traceEnabled) \
138 dvmMethodTraceAdd(_self, _method, METHOD_TRACE_EXIT); \
139 if (gDvm.emulatorTraceEnableCount != 0) \
140 dvmEmitEmulatorTrace(_method, METHOD_TRACE_EXIT); \
141 } \
142 } while(0);
143# define TRACE_METHOD_UNROLL(_self, _method) \
144 do { \
145 if (gDvm.activeProfilers != 0) { \
146 if (gDvm.methodTrace.traceEnabled) \
147 dvmMethodTraceAdd(_self, _method, METHOD_TRACE_UNROLL); \
148 if (gDvm.emulatorTraceEnableCount != 0) \
149 dvmEmitEmulatorTrace(_method, METHOD_TRACE_UNROLL); \
150 } \
151 } while(0);
152#else
153# define TRACE_METHOD_ENTER(_self, _method) ((void) 0)
154# define TRACE_METHOD_EXIT(_self, _method) ((void) 0)
155# define TRACE_METHOD_UNROLL(_self, _method) ((void) 0)
156#endif
157
158void dvmMethodTraceAdd(struct Thread* self, const Method* method, int action);
159void dvmEmitEmulatorTrace(const Method* method, int action);
160
161void dvmMethodTraceGCBegin(void);
162void dvmMethodTraceGCEnd(void);
163void dvmMethodTraceClassPrepBegin(void);
164void dvmMethodTraceClassPrepEnd(void);
165
166/*
167 * Start/stop alloc counting.
168 */
169void dvmStartAllocCounting(void);
170void dvmStopAllocCounting(void);
171
172#endif
173
174
175/*
176 * Enumeration for the two "action" bits.
177 */
178enum {
179 METHOD_TRACE_ENTER = 0x00, // method entry
180 METHOD_TRACE_EXIT = 0x01, // method exit
181 METHOD_TRACE_UNROLL = 0x02, // method exited by exception unrolling
182 // 0x03 currently unused
183};
184
185#define TOKEN_CHAR '*'
186#define TRACE_VERSION 1
187
188/*
189 * Common definitions, shared with the dump tool.
190 */
191#define METHOD_ACTION_MASK 0x03 /* two bits */
192#define METHOD_ID(_method) ((_method) & (~METHOD_ACTION_MASK))
193#define METHOD_ACTION(_method) (((unsigned int)(_method)) & METHOD_ACTION_MASK)
194#define METHOD_COMBINE(_method, _action) ((_method) | (_action))
195
196#endif /*_DALVIK_PROFILE*/