std::string dvmHumanReadableType(const Object* obj) { if (obj == NULL) { return "null"; } if (obj->clazz == NULL) { /* should only be possible right after a plain dvmMalloc() */ return "(raw)"; } std::string result(dvmHumanReadableDescriptor(obj->clazz->descriptor)); if (dvmIsClassObject(obj)) { const ClassObject* clazz = reinterpret_cast<const ClassObject*>(obj); result += "<" + dvmHumanReadableDescriptor(clazz->descriptor) + ">"; } return result; }
/* * dump一些关于某个对象的信息 * */ void dvmDumpObject(const Object* obj) { ClassObject* clazz; int i; if (obj == NULL || obj->clazz == NULL) { ALOGW("Null or malformed object not dumped"); return; } clazz = obj->clazz; ALOGD("----- Object dump: %p (%s, %d bytes) -----", obj, clazz->descriptor, (int) clazz->objectSize); //printHexDump(obj, clazz->objectSize); ALOGD(" Fields:"); while (clazz != NULL) { ALOGD(" -- %s", clazz->descriptor); for (i = 0; i < clazz->ifieldCount; i++) { const InstField* pField = &clazz->ifields[i]; char type = pField->signature[0]; if (type == 'F' || type == 'D') { double dval; if (type == 'F') dval = dvmGetFieldFloat(obj, pField->byteOffset); else dval = dvmGetFieldDouble(obj, pField->byteOffset); ALOGD(" %2d: '%s' '%s' af=%04x off=%d %.3f", i, pField->name, pField->signature, pField->accessFlags, pField->byteOffset, dval); } else { u8 lval; if (type == 'J') lval = dvmGetFieldLong(obj, pField->byteOffset); else if (type == 'Z') lval = dvmGetFieldBoolean(obj, pField->byteOffset); else lval = dvmGetFieldInt(obj, pField->byteOffset); ALOGD(" %2d: '%s' '%s' af=%04x off=%d 0x%08llx", i, pField->name, pField->signature, pField->accessFlags, pField->byteOffset, lval); } } clazz = clazz->super; } if (dvmIsClassObject(obj)) { ALOGD(" Static fields:"); const StaticField* sfields = &((ClassObject *)obj)->sfields[0]; for (i = 0; i < ((ClassObject *)obj)->sfieldCount; ++i) { const StaticField* pField = &sfields[i]; size_t byteOffset = (size_t)pField - (size_t)sfields; char type = pField->signature[0]; if (type == 'F' || type == 'D') { double dval; if (type == 'F') dval = pField->value.f; else dval = pField->value.d; ALOGD(" %2d: '%s' '%s' af=%04x off=%zd %.3f", i, pField->name, pField->signature, pField->accessFlags, byteOffset, dval); } else { u8 lval; if (type == 'J') lval = pField->value.j; else if (type == 'Z') lval = pField->value.z; else lval = pField->value.i; ALOGD(" %2d: '%s' '%s' af=%04x off=%zd 0x%08llx", i, pField->name, pField->signature, pField->accessFlags, byteOffset, lval); } } } }
retry: hashState = LW_HASH_STATE(*lw); if (hashState == LW_HASH_STATE_HASHED) { /* * The object has been hashed but has not had its hash code * relocated by the garbage collector. Use the raw object * address. */ return (u4)obj >> 3; } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) { /* * The object has been hashed and its hash code has been * relocated by the collector. Use the value of the naturally * aligned word following the instance data. */ assert(!dvmIsClassObject(obj)); if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) { size = dvmArrayObjectSize((ArrayObject *)obj); size = (size + 2) & ~2; } else { size = obj->clazz->objectSize; } return *(u4 *)(((char *)obj) + size); } else if (hashState == LW_HASH_STATE_UNHASHED) { /* * The object has never been hashed. Change the hash state to * hashed and use the raw object address. */ self = dvmThreadSelf(); if (self->threadId == lockOwner(obj)) { /*