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 #ifndef _DALVIK_HPROF_HPROF 17 #define _DALVIK_HPROF_HPROF 18 19 #include "Dalvik.h" 20 21 #define HPROF_ID_SIZE (sizeof (u4)) 22 23 #define UNIQUE_ERROR() \ 24 -((((uintptr_t)__func__) << 16 | __LINE__) & (0x7fffffff)) 25 26 #define HPROF_TIME 0 27 #define HPROF_NULL_STACK_TRACE 0 28 #define HPROF_NULL_THREAD 0 29 30 typedef u4 hprof_id; 31 typedef hprof_id hprof_string_id; 32 typedef hprof_id hprof_object_id; 33 typedef hprof_id hprof_class_object_id; 34 #if WITH_HPROF_STACK 35 typedef hprof_id hprof_stack_frame_id; 36 #endif 37 38 typedef enum hprof_basic_type { 39 hprof_basic_object = 2, 40 hprof_basic_boolean = 4, 41 hprof_basic_char = 5, 42 hprof_basic_float = 6, 43 hprof_basic_double = 7, 44 hprof_basic_byte = 8, 45 hprof_basic_short = 9, 46 hprof_basic_int = 10, 47 hprof_basic_long = 11, 48 } hprof_basic_type; 49 50 typedef enum hprof_tag_t { 51 HPROF_TAG_STRING = 0x01, 52 HPROF_TAG_LOAD_CLASS = 0x02, 53 HPROF_TAG_UNLOAD_CLASS = 0x03, 54 HPROF_TAG_STACK_FRAME = 0x04, 55 HPROF_TAG_STACK_TRACE = 0x05, 56 HPROF_TAG_ALLOC_SITES = 0x06, 57 HPROF_TAG_HEAP_SUMMARY = 0x07, 58 HPROF_TAG_START_THREAD = 0x0A, 59 HPROF_TAG_END_THREAD = 0x0B, 60 HPROF_TAG_HEAP_DUMP = 0x0C, 61 HPROF_TAG_HEAP_DUMP_SEGMENT = 0x1C, 62 HPROF_TAG_HEAP_DUMP_END = 0x2C, 63 HPROF_TAG_CPU_SAMPLES = 0x0D, 64 HPROF_TAG_CONTROL_SETTINGS = 0x0E, 65 } hprof_tag_t; 66 67 /* Values for the first byte of 68 * HEAP_DUMP and HEAP_DUMP_SEGMENT 69 * records: 70 */ 71 typedef enum hprof_heap_tag_t { 72 /* standard */ 73 HPROF_ROOT_UNKNOWN = 0xFF, 74 HPROF_ROOT_JNI_GLOBAL = 0x01, 75 HPROF_ROOT_JNI_LOCAL = 0x02, 76 HPROF_ROOT_JAVA_FRAME = 0x03, 77 HPROF_ROOT_NATIVE_STACK = 0x04, 78 HPROF_ROOT_STICKY_CLASS = 0x05, 79 HPROF_ROOT_THREAD_BLOCK = 0x06, 80 HPROF_ROOT_MONITOR_USED = 0x07, 81 HPROF_ROOT_THREAD_OBJECT = 0x08, 82 HPROF_CLASS_DUMP = 0x20, 83 HPROF_INSTANCE_DUMP = 0x21, 84 HPROF_OBJECT_ARRAY_DUMP = 0x22, 85 HPROF_PRIMITIVE_ARRAY_DUMP = 0x23, 86 87 /* Android */ 88 HPROF_HEAP_DUMP_INFO = 0xfe, 89 HPROF_ROOT_INTERNED_STRING = 0x89, 90 HPROF_ROOT_FINALIZING = 0x8a, 91 HPROF_ROOT_DEBUGGER = 0x8b, 92 HPROF_ROOT_REFERENCE_CLEANUP = 0x8c, 93 HPROF_ROOT_VM_INTERNAL = 0x8d, 94 HPROF_ROOT_JNI_MONITOR = 0x8e, 95 HPROF_UNREACHABLE = 0x90, 96 HPROF_PRIMITIVE_ARRAY_NODATA_DUMP = 0xc3, 97 } hprof_heap_tag_t; 98 99 /* Represents a top-level hprof record, whose serialized 100 * format is: 101 * 102 * u1 TAG: denoting the type of the record 103 * u4 TIME: number of microseconds since the time stamp in the header 104 * u4 LENGTH: number of bytes that follow this u4 field 105 * and belong to this record 106 * [u1]* BODY: as many bytes as specified in the above u4 field 107 */ 108 typedef struct hprof_record_t { 109 unsigned char *body; 110 u4 time; 111 u4 length; 112 size_t allocLen; 113 u1 tag; 114 bool dirty; 115 } hprof_record_t; 116 117 typedef enum { 118 HPROF_HEAP_DEFAULT = 0, 119 HPROF_HEAP_ZYGOTE = 'Z', 120 HPROF_HEAP_APP = 'A' 121 } HprofHeapId; 122 123 typedef struct hprof_context_t { 124 /* curRec *must* be first so that we 125 * can cast from a context to a record. 126 */ 127 hprof_record_t curRec; 128 129 u4 gcThreadSerialNumber; 130 u1 gcScanState; 131 HprofHeapId currentHeap; // which heap we're currently emitting 132 u4 stackTraceSerialNumber; 133 size_t objectsInSegment; 134 135 /* 136 * If "directToDdms" is not set, "fileName" is valid, and "fileDataPtr" 137 * and "fileDataSize" are not used. If "directToDdms" is not set, 138 * it's the other way around. 139 */ 140 bool directToDdms; 141 char *fileName; 142 char *fileDataPtr; // for open_memstream 143 size_t fileDataSize; // for open_memstream 144 FILE *fp; 145 } hprof_context_t; 146 147 148 /* 149 * HprofString.c functions 150 */ 151 152 hprof_string_id hprofLookupStringId(const char *str); 153 154 int hprofDumpStrings(hprof_context_t *ctx); 155 156 int hprofStartup_String(void); 157 int hprofShutdown_String(void); 158 159 160 /* 161 * HprofClass.c functions 162 */ 163 164 hprof_class_object_id hprofLookupClassId(const ClassObject *clazz); 165 166 int hprofDumpClasses(hprof_context_t *ctx); 167 168 int hprofStartup_Class(void); 169 int hprofShutdown_Class(void); 170 171 172 /* 173 * HprofHeap.c functions 174 */ 175 176 int hprofStartHeapDump(hprof_context_t *ctx); 177 int hprofFinishHeapDump(hprof_context_t *ctx); 178 179 int hprofSetGcScanState(hprof_context_t *ctx, 180 hprof_heap_tag_t state, u4 threadSerialNumber); 181 int hprofMarkRootObject(hprof_context_t *ctx, 182 const Object *obj, jobject jniObj); 183 184 int hprofDumpHeapObject(hprof_context_t *ctx, const Object *obj); 185 186 /* 187 * HprofOutput.c functions 188 */ 189 190 void hprofContextInit(hprof_context_t *ctx, char *fileName, FILE *fp, 191 bool writeHeader, bool directToDdms); 192 193 int hprofFlushRecord(hprof_record_t *rec, FILE *fp); 194 int hprofFlushCurrentRecord(hprof_context_t *ctx); 195 int hprofStartNewRecord(hprof_context_t *ctx, u1 tag, u4 time); 196 197 int hprofAddU1ToRecord(hprof_record_t *rec, u1 value); 198 int hprofAddU1ListToRecord(hprof_record_t *rec, 199 const u1 *values, size_t numValues); 200 201 int hprofAddUtf8StringToRecord(hprof_record_t *rec, const char *str); 202 203 int hprofAddU2ToRecord(hprof_record_t *rec, u2 value); 204 int hprofAddU2ListToRecord(hprof_record_t *rec, 205 const u2 *values, size_t numValues); 206 207 int hprofAddU4ToRecord(hprof_record_t *rec, u4 value); 208 int hprofAddU4ListToRecord(hprof_record_t *rec, 209 const u4 *values, size_t numValues); 210 211 int hprofAddU8ToRecord(hprof_record_t *rec, u8 value); 212 int hprofAddU8ListToRecord(hprof_record_t *rec, 213 const u8 *values, size_t numValues); 214 215 #define hprofAddIdToRecord(rec, id) hprofAddU4ToRecord((rec), (u4)(id)) 216 #define hprofAddIdListToRecord(rec, values, numValues) \ 217 hprofAddU4ListToRecord((rec), (const u4 *)(values), (numValues)) 218 219 #if WITH_HPROF_STACK 220 221 /* 222 * HprofStack.c functions 223 */ 224 225 void hprofFillInStackTrace(void *objectPtr); 226 227 int hprofDumpStacks(hprof_context_t *ctx); 228 229 int hprofStartup_Stack(void); 230 int hprofShutdown_Stack(void); 231 232 /* 233 * HprofStackFrame.c functions 234 */ 235 236 int hprofDumpStackFrames(hprof_context_t *ctx); 237 238 int hprofStartup_StackFrame(void); 239 int hprofShutdown_StackFrame(void); 240 241 #endif 242 243 /* 244 * Hprof.c functions 245 */ 246 247 hprof_context_t* hprofStartup(const char *outputFileName, bool directToDdms); 248 bool hprofShutdown(hprof_context_t *ctx); 249 void hprofFreeContext(hprof_context_t *ctx); 250 251 /* 252 * Heap.c functions 253 * 254 * The contents of the hprof directory have no knowledge of 255 * the heap implementation; these functions require heap knowledge, 256 * so they are implemented in Heap.c. 257 */ 258 int hprofDumpHeap(const char* fileName, bool directToDdms); 259 void dvmHeapSetHprofGcScanState(hprof_heap_tag_t state, u4 threadSerialNumber); 260 261 #endif // _DALVIK_HPROF_HPROF 262