/*
* Android's method call profiling goodies.
*/
-#ifndef _DALVIK_PROFILE
-#define _DALVIK_PROFILE
+#ifndef DALVIK_PROFILE_H_
+#define DALVIK_PROFILE_H_
#ifndef NOT_VM /* for utilities that sneakily include this file */
#include <stdio.h>
-/* External allocations are hackish enough that it's worthwhile
- * separating them for possible removal later.
- */
-#define PROFILE_EXTERNAL_ALLOCATIONS 1
-
struct Thread; // extern
* Method trace state. This is currently global. In theory we could make
* most of this per-thread.
*/
-typedef struct MethodTraceState {
- /* these are set during VM init */
- Method* gcMethod;
- Method* classPrepMethod;
-
+struct MethodTraceState {
/* active state */
pthread_mutex_t startStopLock;
pthread_cond_t threadExitCond;
int traceVersion;
size_t recordSize;
-} MethodTraceState;
+
+ bool samplingEnabled;
+ pthread_t samplingThreadHandle;
+};
/*
* Memory allocation profiler state. This is used both globally and
*
* If you add a field here, zero it out in dvmStartAllocCounting().
*/
-typedef struct AllocProfState {
+struct AllocProfState {
bool enabled; // is allocation tracking enabled?
int allocCount; // #of objects allocated
int classInitCount; // #of initialized classes
u8 classInitTime; // cumulative time spent in class init (nsec)
-
-#if PROFILE_EXTERNAL_ALLOCATIONS
- int externalAllocCount; // #of calls to dvmTrackExternalAllocation()
- int externalAllocSize; // #of bytes passed to ...ExternalAllocation()
-
- int failedExternalAllocCount; // #of times an allocation failed
- int failedExternalAllocSize; // cumulative size of failed allocations
-
- int externalFreeCount; // #of calls to dvmTrackExternalFree()
- int externalFreeSize; // #of bytes passed to ...ExternalFree()
-#endif // PROFILE_EXTERNAL_ALLOCATIONS
-} AllocProfState;
+};
/*
* Start/stop method tracing.
*/
void dvmMethodTraceStart(const char* traceFileName, int traceFd, int bufferSize,
- int flags, bool directToDdms);
-bool dvmIsMethodTraceActive(void);
+ int flags, bool directToDdms, bool samplingEnabled, int intervalUs);
void dvmMethodTraceStop(void);
/*
+ * Returns current method tracing mode.
+ */
+enum TracingMode {
+ TRACING_INACTIVE,
+ METHOD_TRACING_ACTIVE,
+ SAMPLE_PROFILING_ACTIVE,
+};
+TracingMode dvmGetMethodTracingMode(void);
+
+/*
* Start/stop emulator tracing.
*/
void dvmEmulatorTraceStart(void);
/*
* Call these when a method enters or exits.
*/
-#define TRACE_METHOD_ENTER(_self, _method) \
+#define TRACE_METHOD_ENTER(_self, _method) \
do { \
- if (gDvm.activeProfilers != 0) { \
- if (gDvm.methodTrace.traceEnabled) \
- dvmMethodTraceAdd(_self, _method, METHOD_TRACE_ENTER); \
- if (gDvm.emulatorTraceEnableCount != 0) \
- dvmEmitEmulatorTrace(_method, METHOD_TRACE_ENTER); \
+ if (_self->interpBreak.ctl.subMode & kSubModeMethodTrace) { \
+ u4 cpuClockDiff = 0; \
+ u4 wallClockDiff = 0; \
+ dvmMethodTraceReadClocks(_self, &cpuClockDiff, &wallClockDiff); \
+ dvmMethodTraceAdd(_self, _method, METHOD_TRACE_ENTER, \
+ cpuClockDiff, wallClockDiff); \
} \
+ if (_self->interpBreak.ctl.subMode & kSubModeEmulatorTrace) \
+ dvmEmitEmulatorTrace(_method, METHOD_TRACE_ENTER); \
} while(0);
-#define TRACE_METHOD_EXIT(_self, _method) \
+#define TRACE_METHOD_EXIT(_self, _method) \
do { \
- if (gDvm.activeProfilers != 0) { \
- if (gDvm.methodTrace.traceEnabled) \
- dvmMethodTraceAdd(_self, _method, METHOD_TRACE_EXIT); \
- if (gDvm.emulatorTraceEnableCount != 0) \
- dvmEmitEmulatorTrace(_method, METHOD_TRACE_EXIT); \
+ if (_self->interpBreak.ctl.subMode & kSubModeMethodTrace) { \
+ u4 cpuClockDiff = 0; \
+ u4 wallClockDiff = 0; \
+ dvmMethodTraceReadClocks(_self, &cpuClockDiff, &wallClockDiff); \
+ dvmMethodTraceAdd(_self, _method, METHOD_TRACE_EXIT, \
+ cpuClockDiff, wallClockDiff); \
} \
+ if (_self->interpBreak.ctl.subMode & kSubModeEmulatorTrace) \
+ dvmEmitEmulatorTrace(_method, METHOD_TRACE_EXIT); \
} while(0);
-#define TRACE_METHOD_UNROLL(_self, _method) \
+#define TRACE_METHOD_UNROLL(_self, _method) \
do { \
- if (gDvm.activeProfilers != 0) { \
- if (gDvm.methodTrace.traceEnabled) \
- dvmMethodTraceAdd(_self, _method, METHOD_TRACE_UNROLL); \
- if (gDvm.emulatorTraceEnableCount != 0) \
- dvmEmitEmulatorTrace(_method, METHOD_TRACE_UNROLL); \
+ if (_self->interpBreak.ctl.subMode & kSubModeMethodTrace) { \
+ u4 cpuClockDiff = 0; \
+ u4 wallClockDiff = 0; \
+ dvmMethodTraceReadClocks(_self, &cpuClockDiff, &wallClockDiff); \
+ dvmMethodTraceAdd(_self, _method, METHOD_TRACE_UNROLL, \
+ cpuClockDiff, wallClockDiff); \
} \
+ if (_self->interpBreak.ctl.subMode & kSubModeEmulatorTrace) \
+ dvmEmitEmulatorTrace(_method, METHOD_TRACE_UNROLL); \
} while(0);
-void dvmMethodTraceAdd(struct Thread* self, const Method* method, int action);
+void dvmMethodTraceReadClocks(Thread* self, u4* cpuClockDiff,
+ u4* wallClockDiff);
+void dvmMethodTraceAdd(struct Thread* self, const Method* method, int action,
+ u4 cpuClockDiff, u4 wallClockDiff);
void dvmEmitEmulatorTrace(const Method* method, int action);
void dvmMethodTraceGCBegin(void);
void dvmMethodTraceClassPrepBegin(void);
void dvmMethodTraceClassPrepEnd(void);
+extern "C" void dvmFastMethodTraceEnter(const Method* method, struct Thread* self);
+extern "C" void dvmFastMethodTraceExit(struct Thread* self);
+extern "C" void dvmFastNativeMethodTraceExit(const Method* method, struct Thread* self);
+
/*
* Start/stop alloc counting.
*/
#define METHOD_ACTION(_method) (((unsigned int)(_method)) & METHOD_ACTION_MASK)
#define METHOD_COMBINE(_method, _action) ((_method) | (_action))
-#endif /*_DALVIK_PROFILE*/
+#endif // DALVIK_PROFILE_H_