/*
* 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>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
struct Thread; // extern
* Method trace state. This is currently global. In theory we could make
* most of this per-thread.
*/
-typedef struct MethodTraceState {
+struct MethodTraceState {
/* active state */
pthread_mutex_t startStopLock;
pthread_cond_t threadExitCond;
volatile int curOffset;
u8 startWhen;
int overflow;
-} MethodTraceState;
+
+ int traceVersion;
+ size_t recordSize;
+
+ 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)
-} 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);
*/
#define TRACE_METHOD_ENTER(_self, _method) \
do { \
- if (_self->interpBreak.ctl.subMode & kSubModeMethodTrace) \
- dvmMethodTraceAdd(_self, _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) \
do { \
- if (_self->interpBreak.ctl.subMode & kSubModeMethodTrace) \
- dvmMethodTraceAdd(_self, _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) \
do { \
- if (_self->interpBreak.ctl.subMode & kSubModeMethodTrace) \
- dvmMethodTraceAdd(_self, _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);
-void dvmFastMethodTraceEnter(const Method* method, struct Thread* self);
-void dvmFastMethodTraceExit(struct Thread* self);
-void dvmFastNativeMethodTraceExit(const Method* method, struct Thread* self);
+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 TOKEN_CHAR '*'
-#define TRACE_VERSION 1
/*
* Common definitions, shared with the dump tool.
#define METHOD_ACTION(_method) (((unsigned int)(_method)) & METHOD_ACTION_MASK)
#define METHOD_COMBINE(_method, _action) ((_method) | (_action))
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*_DALVIK_PROFILE*/
+#endif // DALVIK_PROFILE_H_