void dvmDdmSendHeapInfo(int reason, bool shouldLock) { struct timeval now; u8 nowMs; u1 *buf, *b; buf = (u1 *)malloc(HPIF_SIZE(1)); if (buf == NULL) { return; } b = buf; /* If there's a one-shot 'when', reset it. */ if (reason == gDvm.gcHeap->ddmHpifWhen) { if (shouldLock && ! dvmLockHeap()) { ALOGW("%s(): can't lock heap to clear when", __func__); goto skip_when; } if (reason == gDvm.gcHeap->ddmHpifWhen) { if (gDvm.gcHeap->ddmHpifWhen == HPIF_WHEN_NEXT_GC) { gDvm.gcHeap->ddmHpifWhen = HPIF_WHEN_NEVER; } } if (shouldLock) { dvmUnlockHeap(); } } skip_when: /* The current time, in milliseconds since 0:00 GMT, 1/1/70. */ if (gettimeofday(&now, NULL) < 0) { nowMs = 0; } else { nowMs = (u8)now.tv_sec * 1000 + now.tv_usec / 1000; } /* number of heaps */ set4BE(b, 1); b += 4; /* For each heap (of which there is one) */ { /* heap ID */ set4BE(b, DEFAULT_HEAP_ID); b += 4; /* timestamp */ set8BE(b, nowMs); b += 8; /* 'when' value */ *b++ = (u1)reason; /* max allowed heap size in bytes */ set4BE(b, dvmHeapSourceGetMaximumSize()); b += 4; /* current heap size in bytes */ set4BE(b, dvmHeapSourceGetValue(HS_FOOTPRINT, NULL, 0)); b += 4; /* number of bytes allocated */ set4BE(b, dvmHeapSourceGetValue(HS_BYTES_ALLOCATED, NULL, 0)); b += 4; /* number of objects allocated */ set4BE(b, dvmHeapSourceGetValue(HS_OBJECTS_ALLOCATED, NULL, 0)); b += 4; } assert((intptr_t)b == (intptr_t)buf + (intptr_t)HPIF_SIZE(1)); dvmDbgDdmSendChunk(CHUNK_TYPE("HPIF"), b - buf, buf); }
/* * Append eight big-endian bytes. */ void expandBufAdd8BE(ExpandBuf *pBuf, u8 val) { ensureSpace(pBuf, sizeof(val)); set8BE(pBuf->storage + pBuf->curLen, val); pBuf->curLen += sizeof(val); }