1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Heap object dump 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Hprof.h" 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "alloc/HeapInternal.h" 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "alloc/HeapSource.h" 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Set DUMP_PRIM_DATA to 1 if you want to include the contents 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of primitive arrays (byte arrays, character arrays, etc.) 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in heap dumps. This can be a large amount of data. 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define DUMP_PRIM_DATA 1 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define OBJECTS_PER_SEGMENT ((size_t)128) 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define BYTES_PER_SEGMENT ((size_t)4096) 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3303aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes/* The static field-name for the synthetic object generated to account 3403aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes * for class Static overhead. 3503aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes */ 3603aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes#define STATIC_OVERHEAD_NAME "$staticOverhead" 3703aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes/* The ID for the synthetic object generated to account for class 3803aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes * Static overhead. 3903aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes */ 4003aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes#define CLASS_STATICS_ID(clazz) ((hprof_object_id)(((u4)(clazz)) | 1)) 4103aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjecthprofStartHeapDump(hprof_context_t *ctx) 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNUSED_PARAMETER(ctx); 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->objectsInSegment = OBJECTS_PER_SEGMENT; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->currentHeap = HPROF_HEAP_DEFAULT; 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjecthprofFinishHeapDump(hprof_context_t *ctx) 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return hprofStartNewRecord(ctx, HPROF_TAG_HEAP_DUMP_END, HPROF_TIME); 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjecthprofSetGcScanState(hprof_context_t *ctx, 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprof_heap_tag_t state, u4 threadSerialNumber) 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Used by hprofMarkRootObject() 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->gcScanState = state; 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->gcThreadSerialNumber = threadSerialNumber; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic hprof_basic_type 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectsignatureToBasicTypeAndSize(const char *sig, size_t *sizeOut) 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char c = sig[0]; 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprof_basic_type ret; 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t size; 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (c) { 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '[': 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'L': ret = hprof_basic_object; size = 4; break; 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Z': ret = hprof_basic_boolean; size = 1; break; 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'C': ret = hprof_basic_char; size = 2; break; 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'F': ret = hprof_basic_float; size = 4; break; 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': ret = hprof_basic_double; size = 8; break; 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': ret = hprof_basic_byte; size = 1; break; 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'S': ret = hprof_basic_short; size = 2; break; 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: assert(false); 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'I': ret = hprof_basic_int; size = 4; break; 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'J': ret = hprof_basic_long; size = 8; break; 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sizeOut != NULL) { 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *sizeOut = size; 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ret; 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic hprof_basic_type 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectprimitiveToBasicTypeAndSize(PrimitiveType prim, size_t *sizeOut) 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprof_basic_type ret; 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t size; 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (prim) { 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_BOOLEAN: ret = hprof_basic_boolean; size = 1; break; 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_CHAR: ret = hprof_basic_char; size = 2; break; 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_FLOAT: ret = hprof_basic_float; size = 4; break; 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_DOUBLE: ret = hprof_basic_double; size = 8; break; 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_BYTE: ret = hprof_basic_byte; size = 1; break; 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_SHORT: ret = hprof_basic_short; size = 2; break; 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: assert(false); 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_INT: ret = hprof_basic_int; size = 4; break; 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_LONG: ret = hprof_basic_long; size = 8; break; 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sizeOut != NULL) { 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *sizeOut = size; 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ret; 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Always called when marking objects, but only does 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * something when ctx->gcScanState is non-zero, which is usually 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * only true when marking the root set or unreachable 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * objects. Used to add rootset references to obj. 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjecthprofMarkRootObject(hprof_context_t *ctx, const Object *obj, jobject jniObj) 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprof_record_t *rec = &ctx->curRec; 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int err; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprof_heap_tag_t heapTag = ctx->gcScanState; 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (heapTag == 0) { 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ctx->objectsInSegment >= OBJECTS_PER_SEGMENT || 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rec->length >= BYTES_PER_SEGMENT) 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* This flushes the old segment and starts a new one. 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofStartNewRecord(ctx, HPROF_TAG_HEAP_DUMP_SEGMENT, HPROF_TIME); 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->objectsInSegment = 0; 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (heapTag) { 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* ID: object ID 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_UNKNOWN: 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_STICKY_CLASS: 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_MONITOR_USED: 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_INTERNED_STRING: 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_FINALIZING: 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_DEBUGGER: 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_REFERENCE_CLEANUP: 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_VM_INTERNAL: 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ToRecord(rec, heapTag); 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_object_id)obj); 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* ID: object ID 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ID: JNI global ref ID 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_JNI_GLOBAL: 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ToRecord(rec, heapTag); 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_object_id)obj); 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_id)jniObj); 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* ID: object ID 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * u4: thread serial number 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * u4: frame number in stack trace (-1 for empty) 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_JNI_LOCAL: 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_JNI_MONITOR: 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_JAVA_FRAME: 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ToRecord(rec, heapTag); 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_object_id)obj); 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, ctx->gcThreadSerialNumber); 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, (u4)-1); 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* ID: object ID 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * u4: thread serial number 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_NATIVE_STACK: 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_THREAD_BLOCK: 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ToRecord(rec, heapTag); 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_object_id)obj); 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, ctx->gcThreadSerialNumber); 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* ID: thread object ID 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * u4: thread serial number 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * u4: stack trace serial number 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_THREAD_OBJECT: 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ToRecord(rec, heapTag); 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_object_id)obj); 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, ctx->gcThreadSerialNumber); 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, (u4)-1); //xxx 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project err = 0; 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->objectsInSegment++; 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return err; 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectstackTraceSerialNumber(const void *obj) 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if WITH_HPROF_STACK 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DvmHeapChunk *chunk = ptr2chunk(obj); 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return chunk->stackTraceSerialNumber; 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return HPROF_NULL_STACK_TRACE; 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjecthprofDumpHeapObject(hprof_context_t *ctx, const Object *obj) 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const ClassObject *clazz; 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprof_record_t *rec = &ctx->curRec; 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HprofHeapId desiredHeap; 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 234de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro desiredHeap = 2356343bd071555458d0cb071f2eaf15b59b36771bfCarl Shapiro dvmHeapSourceGetPtrFlag(obj, HS_ALLOCATED_IN_ZYGOTE) ? 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_HEAP_ZYGOTE : HPROF_HEAP_APP; 237de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ctx->objectsInSegment >= OBJECTS_PER_SEGMENT || 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rec->length >= BYTES_PER_SEGMENT) 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* This flushes the old segment and starts a new one. 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofStartNewRecord(ctx, HPROF_TAG_HEAP_DUMP_SEGMENT, HPROF_TIME); 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->objectsInSegment = 0; 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Starting a new HEAP_DUMP resets the heap to default. 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->currentHeap = HPROF_HEAP_DEFAULT; 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (desiredHeap != ctx->currentHeap) { 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprof_string_id nameId; 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* This object is in a different heap than the current one. 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Emit a HEAP_DUMP_INFO tag to change heaps. 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ToRecord(rec, HPROF_HEAP_DUMP_INFO); 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, (u4)desiredHeap); // u4: heap id 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (desiredHeap) { 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_HEAP_APP: 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nameId = hprofLookupStringId("app"); 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_HEAP_ZYGOTE: 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nameId = hprofLookupStringId("zygote"); 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Internal error. */ 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!"Unexpected desiredHeap"); 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nameId = hprofLookupStringId("<ILLEGAL>"); 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, nameId); 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->currentHeap = desiredHeap; 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz = obj->clazz; 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == NULL) { 279b4bad121113179f15934d0f97a613232158bc559Barry Hayes /* This object will bother HprofReader, because it has a NULL 280b4bad121113179f15934d0f97a613232158bc559Barry Hayes * class, so just don't dump it. It could be 281b4bad121113179f15934d0f97a613232158bc559Barry Hayes * gDvm.unlinkedJavaLangClass or it could be an object just 282b4bad121113179f15934d0f97a613232158bc559Barry Hayes * allocated which hasn't been initialized yet. 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprof_class_object_id clazzId; 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazzId = hprofLookupClassId(clazz); 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == gDvm.classJavaLangClass) { 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const ClassObject *thisClass = (const ClassObject *)obj; 29103aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes int i, sFieldCount, iFieldCount; 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* obj is a ClassObject. 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 29403aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes sFieldCount = thisClass->sfieldCount; 29503aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes if (sFieldCount != 0) { 29603aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes int byteLength = sFieldCount*sizeof(StaticField); 29703aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes /* Create a byte array to reflect the allocation of the 29803aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes * StaticField array at the end of this class. 29903aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes */ 30003aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU1ToRecord(rec, HPROF_PRIMITIVE_ARRAY_DUMP); 30103aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddIdToRecord(rec, CLASS_STATICS_ID(obj)); 30203aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU4ToRecord(rec, stackTraceSerialNumber(obj)); 30303aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU4ToRecord(rec, byteLength); 30403aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU1ToRecord(rec, hprof_basic_byte); 30503aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes for (i = 0; i < byteLength; i++) { 30603aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU1ToRecord(rec, 0); 30703aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes } 30803aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes } 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31003aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU1ToRecord(rec, HPROF_CLASS_DUMP); 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, hprofLookupClassId(thisClass)); 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, stackTraceSerialNumber(thisClass)); 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, hprofLookupClassId(thisClass->super)); 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_object_id)thisClass->classLoader); 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_object_id)0); // no signer 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_object_id)0); // no prot domain 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_id)0); // reserved 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_id)0); // reserved 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == (Object *)gDvm.classJavaLangClass) { 32003aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes // ClassObjects have their static fields appended, so 32103aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes // aren't all the same size. But they're at least this 32203aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes // size. 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, sizeof(ClassObject)); // instance size 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, thisClass->objectSize); // instance size 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU2ToRecord(rec, 0); // empty const pool 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Static fields 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 33203aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes if (sFieldCount == 0) { 33303aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU2ToRecord(rec, (u2)0); 33403aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes } else { 33503aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU2ToRecord(rec, (u2)(sFieldCount+1)); 33603aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddIdToRecord(rec, 33703aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofLookupStringId(STATIC_OVERHEAD_NAME)); 33803aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU1ToRecord(rec, hprof_basic_object); 33903aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddIdToRecord(rec, CLASS_STATICS_ID(obj)); 34003aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes for (i = 0; i < sFieldCount; i++) { 34103aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprof_basic_type t; 34203aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes size_t size; 34303aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes const StaticField *f = &thisClass->sfields[i]; 34403aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes 34503aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes t = signatureToBasicTypeAndSize(f->field.signature, &size); 34603aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddIdToRecord(rec, hprofLookupStringId(f->field.name)); 34703aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU1ToRecord(rec, t); 34803aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes if (size == 1) { 34903aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU1ToRecord(rec, (u1)f->value.b); 35003aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes } else if (size == 2) { 35103aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU2ToRecord(rec, (u2)f->value.c); 35203aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes } else if (size == 4) { 35303aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU4ToRecord(rec, (u4)f->value.i); 35403aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes } else if (size == 8) { 35503aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU8ToRecord(rec, (u8)f->value.j); 35603aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes } else { 35703aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes assert(false); 35803aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes } 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Instance fields for this class (no superclass fields) 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 36403aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes iFieldCount = thisClass->ifieldCount; 36503aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes hprofAddU2ToRecord(rec, (u2)iFieldCount); 36603aa70ae413c6c5fb2ee4424afd30608bfb465eeBarry Hayes for (i = 0; i < iFieldCount; i++) { 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const InstField *f = &thisClass->ifields[i]; 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprof_basic_type t; 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project t = signatureToBasicTypeAndSize(f->field.signature, NULL); 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, hprofLookupStringId(f->field.name)); 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ToRecord(rec, t); 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (IS_CLASS_FLAG_SET(clazz, CLASS_ISARRAY)) { 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const ArrayObject *aobj = (const ArrayObject *)obj; 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 length = aobj->length; 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (IS_CLASS_FLAG_SET(clazz, CLASS_ISOBJECTARRAY)) { 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* obj is an object array. 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ToRecord(rec, HPROF_OBJECT_ARRAY_DUMP); 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_object_id)obj); 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, stackTraceSerialNumber(obj)); 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, length); 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, hprofLookupClassId(clazz)); 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Dump the elements, which are always objects or NULL. 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdListToRecord(rec, 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (const hprof_object_id *)aobj->contents, length); 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprof_basic_type t; 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t size; 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project t = primitiveToBasicTypeAndSize(clazz->elementClass-> 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project primitiveType, &size); 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* obj is a primitive array. 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if DUMP_PRIM_DATA 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ToRecord(rec, HPROF_PRIMITIVE_ARRAY_DUMP); 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ToRecord(rec, HPROF_PRIMITIVE_ARRAY_NODATA_DUMP); 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_object_id)obj); 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, stackTraceSerialNumber(obj)); 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, length); 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ToRecord(rec, t); 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if DUMP_PRIM_DATA 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Dump the raw, packed element values. 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size == 1) { 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ListToRecord(rec, (const u1 *)aobj->contents, 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length); 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (size == 2) { 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU2ListToRecord(rec, (const u2 *)aobj->contents, 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length); 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (size == 4) { 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ListToRecord(rec, (const u4 *)aobj->contents, 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length); 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (size == 8) { 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU8ListToRecord(rec, (const u8 *)aobj->contents, 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length); 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const ClassObject *sclass; 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t sizePatchOffset, savedLen; 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* obj is an instance object. 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ToRecord(rec, HPROF_INSTANCE_DUMP); 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, (hprof_object_id)obj); 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, stackTraceSerialNumber(obj)); 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddIdToRecord(rec, hprofLookupClassId(clazz)); 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Reserve some space for the length of the instance 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * data, which we won't know until we're done writing 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * it. 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sizePatchOffset = rec->length; 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, 0x77777777); 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Write the instance data; fields for this 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class, followed by super class fields, and so on. 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sclass = clazz; 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (sclass != NULL) { 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, ifieldCount; 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ifieldCount = sclass->ifieldCount; 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < ifieldCount; i++) { 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const InstField *f = &sclass->ifields[i]; 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprof_basic_type t; 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t size; 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project t = signatureToBasicTypeAndSize(f->field.signature, &size); 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size == 1) { 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU1ToRecord(rec, 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (u1)dvmGetFieldByte(obj, f->byteOffset)); 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (size == 2) { 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU2ToRecord(rec, 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (u2)dvmGetFieldChar(obj, f->byteOffset)); 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (size == 4) { 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (u4)dvmGetFieldInt(obj, f->byteOffset)); 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (size == 8) { 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU8ToRecord(rec, 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (u8)dvmGetFieldLong(obj, f->byteOffset)); 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sclass = sclass->super; 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Patch the instance field length. 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project savedLen = rec->length; 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rec->length = sizePatchOffset; 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofAddU4ToRecord(rec, savedLen - (sizePatchOffset + 4)); 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rec->length = savedLen; 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->objectsInSegment++; 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 495