static void heapDumpCallback(void* ptr, unsigned char kind, size_t sz, void* data) { if ((kind == GC_gcj_kind || kind == objectArrayGCKind) && ptr) { Object* obj = (Object*) ptr; if (obj->clazz) { if (obj->clazz == java_lang_Class) { Class* clazz = (Class*) obj; fprintf(stderr, " n%p [label=\"Class %s]\n", clazz, clazz->name); //, clazz->classDataSize); if (clazz->_data) { fprintf(stderr, " n%p -> n%p\n", clazz, clazz->_data); } void** start = (void**) (((char*) clazz) + offsetof(Class, data)); void** end = (void**) (((char*) start) + clazz->classRefCount * sizeof(Object*)); dumpRefs(clazz, start, end); } else if (CLASS_IS_ARRAY(obj->clazz)) { if (obj->clazz->name[1] == 'C') { // Array of chars. Include the 29 first characters in the dump. char s[30]; memset(s, 0, sizeof(s)); jint length = ((Array*) obj)->length; length = length > sizeof(s) - 1 ? sizeof(s) - 1 : length; for (jint i = 0; i < length; i++) { s[i] = (char) ((CharArray*) obj)->values[i]; } fprintf(stderr, " n%p [label=\"%s[%d] = %s\"]\n", obj, obj->clazz->name, ((Array*) obj)->length, s); } else { fprintf(stderr, " n%p [label=\"%s[%d]\"]\n", obj, obj->clazz->name, ((Array*) obj)->length); if (!CLASS_IS_PRIMITIVE(obj->clazz->componentType)) { ObjectArray* array = (ObjectArray*) obj; void** start = (void**) (((char*) array) + offsetof(ObjectArray, values)); void** end = (void**) (((char*) start) + sizeof(Object*) * array->length); dumpRefs(array, start, end); } } } else { Class* clazz = obj->clazz; fprintf(stderr, " n%p [label=\"Instance %s\"]\n", obj, obj->clazz->name); while (clazz != NULL) { void** start = (void**) (((char*) obj) + clazz->instanceDataOffset); void** end = (void**) (((char*) start) + clazz->instanceRefCount * sizeof(Object*)); if (clazz == java_lang_ref_Reference) { void** referent_start = (void**) (((char*) obj) + java_lang_ref_Reference_referent->offset); void** referent_end = (void**) (((char*) referent_start) + sizeof(Object*)); //if (*referent_start) { //fprintf(stderr, "\t%p (weak)\n", *referent_start); //} dumpRefs(obj, start, referent_start); dumpRefs(obj, referent_end, end); } else { dumpRefs(obj, start, end); } clazz = clazz->superclass; } } } } }
static void heapDumpCallback(void* ptr, unsigned char kind, size_t sz, void* data) { if (kind == objectGCKind || kind == largeArrayGCKind || kind == atomicObjectGCKind) { Object* obj = (Object*) ptr; if (obj->clazz == java_lang_Class) { Class* clazz = (Class*) obj; fprintf(stderr, "%p (class %s of size %d bytes)\n", clazz, clazz->name, clazz->classDataSize); if (clazz->_data) { fprintf(stderr, "\t%p\n", clazz->_data); } void** start = (void**) (((char*) clazz) + offsetof(Class, data)); void** end = (void**) (((char*) start) + clazz->classRefCount * sizeof(Object*)); dumpRefs(start, end); } else if (CLASS_IS_ARRAY(obj->clazz)) { fprintf(stderr, "%p (array of type %s of length %d elements)\n", obj, obj->clazz->name, ((Array*) obj)->length); if (!CLASS_IS_PRIMITIVE(obj->clazz->componentType)) { ObjectArray* array = (ObjectArray*) obj; void** start = (void**) (((char*) array) + offsetof(ObjectArray, values)); void** end = (void**) (((char*) start) + sizeof(Object*) * array->length); dumpRefs(start, end); } } else { Class* clazz = obj->clazz; fprintf(stderr, "%p (object of type %s of size %d bytes)\n", obj, clazz->name, clazz->instanceDataSize); while (clazz != NULL) { void** start = (void**) (((char*) obj) + clazz->instanceDataOffset); void** end = (void**) (((char*) start) + clazz->instanceRefCount * sizeof(Object*)); if (clazz == java_lang_ref_Reference) { void** referent_start = (void**) (((char*) obj) + java_lang_ref_Reference_referent->offset); void** referent_end = (void**) (((char*) referent_start) + sizeof(Object*)); if (*referent_start) { fprintf(stderr, "\t%p (weak)\n", *referent_start); } dumpRefs(start, referent_start); dumpRefs(referent_end, end); } else { dumpRefs(start, end); } clazz = clazz->superclass; } } } }