/* *查询hprof class id. */ hprof_class_object_id hprofLookupClassId(const ClassObject *clazz) { void *val; if (clazz == NULL) { /* Someone's probably looking up the superclass * of java.lang.Object or of a primitive class. */ return (hprof_class_object_id)0; } dvmHashTableLock(gClassHashTable); /* We're using the hash table as a list. * TODO: replace the hash table with a more suitable structure */ val = dvmHashTableLookup(gClassHashTable, computeClassHash(clazz), (void *)clazz, classCmp, true); assert(val != NULL); dvmHashTableUnlock(gClassHashTable); /* Make sure that the class's name is in the string table. * This is a bunch of extra work that we only have to do * because of the order of tables in the output file * (strings need to be dumped before classes). */ getPrettyClassNameId(clazz->descriptor); return (hprof_class_object_id)clazz; }
int hprofDumpClasses(hprof_context_t *ctx) { HashIter iter; hprof_record_t *rec = &ctx->curRec; int err; dvmHashTableLock(gClassHashTable); for (err = 0, dvmHashIterBegin(gClassHashTable, &iter); err == 0 && !dvmHashIterDone(&iter); dvmHashIterNext(&iter)) { err = hprofStartNewRecord(ctx, HPROF_TAG_LOAD_CLASS, HPROF_TIME); if (err == 0) { const ClassObject *clazz; clazz = (const ClassObject *)dvmHashIterData(&iter); assert(clazz != NULL); /* LOAD CLASS format: * * u4: class serial number (always > 0) * ID: class object ID * u4: stack trace serial number * ID: class name string ID * * We use the address of the class object structure as its ID. */ hprofAddU4ToRecord(rec, clazz->serialNumber); hprofAddIdToRecord(rec, (hprof_class_object_id)clazz); hprofAddU4ToRecord(rec, HPROF_NULL_STACK_TRACE); hprofAddIdToRecord(rec, getPrettyClassNameId(clazz->descriptor)); } } dvmHashTableUnlock(gClassHashTable); return err; }