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 * DDM-related heap functions 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <sys/time.h> 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <time.h> 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "alloc/Heap.h" 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "alloc/HeapInternal.h" 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "alloc/DdmHeap.h" 26808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers#include "alloc/DlMalloc.h" 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "alloc/HeapSource.h" 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define DEFAULT_HEAP_ID 1 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum HpifWhen { 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPIF_WHEN_NEVER = 0, 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPIF_WHEN_NOW = 1, 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPIF_WHEN_NEXT_GC = 2, 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPIF_WHEN_EVERY_GC = 3 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Chunk HPIF (client --> server) 40de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Heap Info. General information about the heap, 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * suitable for a summary display. 43de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u4]: number of heaps 45de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For each heap: 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u4]: heap ID 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u8]: timestamp in ms since Unix epoch 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u1]: capture reason (same as 'when' value from server) 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u4]: max heap size in bytes (-Xmx) 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u4]: current heap size in bytes 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u4]: current number of bytes allocated 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u4]: current number of objects allocated 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HPIF_SIZE(numHeaps) \ 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (sizeof(u4) + (numHeaps) * (5 * sizeof(u4) + sizeof(u1) + sizeof(u8))) 5706f120f6092185003bc9b70e06eb44866e9676f8Carl Shapirovoid dvmDdmSendHeapInfo(int reason, bool shouldLock) 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct timeval now; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u8 nowMs; 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 *buf, *b; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf = (u1 *)malloc(HPIF_SIZE(1)); 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (buf == NULL) { 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project b = buf; 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If there's a one-shot 'when', reset it. 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (reason == gDvm.gcHeap->ddmHpifWhen) { 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (shouldLock && ! dvmLockHeap()) { 73e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("%s(): can't lock heap to clear when", __func__); 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto skip_when; 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (reason == gDvm.gcHeap->ddmHpifWhen) { 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.gcHeap->ddmHpifWhen == HPIF_WHEN_NEXT_GC) { 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.gcHeap->ddmHpifWhen = HPIF_WHEN_NEVER; 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (shouldLock) { 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockHeap(); 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectskip_when: 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* The current time, in milliseconds since 0:00 GMT, 1/1/70. 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gettimeofday(&now, NULL) < 0) { 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nowMs = 0; 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nowMs = (u8)now.tv_sec * 1000 + now.tv_usec / 1000; 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* number of heaps */ 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(b, 1); b += 4; 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* For each heap (of which there is one) */ 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* heap ID */ 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(b, DEFAULT_HEAP_ID); b += 4; 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* timestamp */ 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set8BE(b, nowMs); b += 8; 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 'when' value */ 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *b++ = (u1)reason; 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* max allowed heap size in bytes */ 110df9f08b877ecfd8ebadea822bb9e066ee7d30433Carl Shapiro set4BE(b, dvmHeapSourceGetMaximumSize()); b += 4; 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* current heap size in bytes */ 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(b, dvmHeapSourceGetValue(HS_FOOTPRINT, NULL, 0)); b += 4; 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* number of bytes allocated */ 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(b, dvmHeapSourceGetValue(HS_BYTES_ALLOCATED, NULL, 0)); b += 4; 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* number of objects allocated */ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(b, dvmHeapSourceGetValue(HS_OBJECTS_ALLOCATED, NULL, 0)); b += 4; 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert((intptr_t)b == (intptr_t)buf + (intptr_t)HPIF_SIZE(1)); 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgDdmSendChunk(CHUNK_TYPE("HPIF"), b - buf, buf); 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 12606f120f6092185003bc9b70e06eb44866e9676f8Carl Shapirobool dvmDdmHandleHpifChunk(int when) 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (when) { 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPIF_WHEN_NOW: 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDdmSendHeapInfo(when, true); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPIF_WHEN_NEVER: 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPIF_WHEN_NEXT_GC: 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPIF_WHEN_EVERY_GC: 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmLockHeap()) { 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.gcHeap->ddmHpifWhen = when; 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockHeap(); 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1394308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("%s(): can't lock heap to set when", __func__); 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 1444308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("%s(): bad when value 0x%08x", __func__, when); 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum HpsgSolidity { 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_FREE = 0, 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_HARD = 1, 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_SOFT = 2, 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_WEAK = 3, 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_PHANTOM = 4, 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_FINALIZABLE = 5, 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_SWEEP = 6, 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum HpsgKind { 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_OBJECT = 0, 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_CLASS_OBJECT = 1, 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_ARRAY_1 = 2, 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_ARRAY_2 = 3, 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_ARRAY_4 = 4, 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_ARRAY_8 = 5, 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_UNKNOWN = 6, 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_NATIVE = 7, 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HPSG_PARTIAL (1<<7) 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HPSG_STATE(solidity, kind) \ 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ((u1)((((kind) & 0x7) << 3) | ((solidity) & 0x7))) 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17650e5fd5984c9b0a6f0927ed5ddf13bde40e338c7Carl Shapirostruct HeapChunkContext { 177808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers void* startOfNextMemoryChunk; 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 *buf; 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 *p; 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 *pieceLenField; 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t bufLen; 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t totalAllocationUnits; 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int type; 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool merge; 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool needHeader; 18650e5fd5984c9b0a6f0927ed5ddf13bde40e338c7Carl Shapiro}; 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define ALLOCATION_UNIT_SIZE 8 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19006f120f6092185003bc9b70e06eb44866e9676f8Carl Shapirostatic void flush_hpsg_chunk(HeapChunkContext *ctx) 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 19222d8dba8ae5be7aecb07322a410712206896fa15Tim Murray if (ctx->pieceLenField == NULL && ctx->needHeader) { 19322d8dba8ae5be7aecb07322a410712206896fa15Tim Murray /* Already flushed */ 19422d8dba8ae5be7aecb07322a410712206896fa15Tim Murray return; 19522d8dba8ae5be7aecb07322a410712206896fa15Tim Murray } 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Patch the "length of piece" field. 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(ctx->buf <= ctx->pieceLenField && 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->pieceLenField <= ctx->p); 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(ctx->pieceLenField, ctx->totalAllocationUnits); 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Send the chunk. 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgDdmSendChunk(ctx->type, ctx->p - ctx->buf, ctx->buf); 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Reset the context. 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->p = ctx->buf; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->totalAllocationUnits = 0; 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->needHeader = true; 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->pieceLenField = NULL; 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 214808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogersstatic void append_chunk(HeapChunkContext *ctx, u1 state, void* ptr, size_t length) { 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Make sure there's enough room left in the buffer. 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need to use two bytes for every fractional 256 217808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers * allocation units used by the chunk and 17 bytes for 218808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers * any header. 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 221808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers size_t needed = (((length/ALLOCATION_UNIT_SIZE + 255) / 256) * 2) + 17; 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t bytesLeft = ctx->bufLen - (size_t)(ctx->p - ctx->buf); 22334f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden if (bytesLeft < needed) { 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flush_hpsg_chunk(ctx); 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 22634f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden bytesLeft = ctx->bufLen - (size_t)(ctx->p - ctx->buf); 22734f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden if (bytesLeft < needed) { 228808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers ALOGW("chunk is too big to transmit (length=%zd, %zd bytes)", 229808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers length, needed); 23034f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden return; 23134f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden } 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ctx->needHeader) { 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Start a new HPSx chunk. 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* [u4]: heap ID */ 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(ctx->p, DEFAULT_HEAP_ID); ctx->p += 4; 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* [u1]: size of allocation unit, in bytes */ 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *ctx->p++ = 8; 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* [u4]: virtual address of segment start */ 245808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers set4BE(ctx->p, (uintptr_t)ptr); ctx->p += 4; 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* [u4]: offset of this piece (relative to the virtual address) */ 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(ctx->p, 0); ctx->p += 4; 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* [u4]: length of piece, in allocation units 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We won't know this until we're done, so save the offset 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and stuff in a dummy value. 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->pieceLenField = ctx->p; 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(ctx->p, 0x55555555); ctx->p += 4; 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->needHeader = false; 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 259808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers /* Write out the chunk description. 260808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers */ 261808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers length /= ALLOCATION_UNIT_SIZE; // convert to allocation units 262808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers ctx->totalAllocationUnits += length; 263808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers while (length > 256) { 264808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers *ctx->p++ = state | HPSG_PARTIAL; 265808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers *ctx->p++ = 255; // length - 1 266808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers length -= 256; 267808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers } 268808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers *ctx->p++ = state; 269808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers *ctx->p++ = length - 1; 270808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers} 271808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers 272808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers/* 273808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers * Called by dlmalloc_inspect_all. If used_bytes != 0 then start is 274808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers * the start of a malloc-ed piece of memory of size used_bytes. If 275808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers * start is 0 then start is the beginning of any free space not 276808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers * including dlmalloc's book keeping and end the start of the next 277808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers * dlmalloc chunk. Regions purely containing book keeping don't 278808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers * callback. 279808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers */ 280808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogersstatic void heap_chunk_callback(void* start, void* end, size_t used_bytes, 281808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers void* arg) 282808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers{ 283808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers u1 state; 284808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers HeapChunkContext *ctx = (HeapChunkContext *)arg; 285808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers UNUSED_PARAMETER(end); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 287808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers if (used_bytes == 0) { 288808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers if (start == NULL) { 289808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers // Reset for start of new heap. 290808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers ctx->startOfNextMemoryChunk = NULL; 291808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers flush_hpsg_chunk(ctx); 292808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers } 293808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers // Only process in use memory so that free region information 294808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers // also includes dlmalloc book keeping. 295808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers return; 296808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers } 297808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers 298808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers /* If we're looking at the native heap, we'll just return 299808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers * (SOLIDITY_HARD, KIND_NATIVE) for all allocated chunks 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 301808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers bool native = ctx->type == CHUNK_TYPE("NHSG"); 302808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers 303808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers if (ctx->startOfNextMemoryChunk != NULL) { 304808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers // Transmit any pending free memory. Native free memory of 305808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers // over kMaxFreeLen could be because of the use of mmaps, so 306808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers // don't report. If not free memory then start a new segment. 307808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers bool flush = true; 308808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers if (start > ctx->startOfNextMemoryChunk) { 309808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers const size_t kMaxFreeLen = 2 * SYSTEM_PAGE_SIZE; 310808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers void* freeStart = ctx->startOfNextMemoryChunk; 311808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers void* freeEnd = start; 312808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers size_t freeLen = (char*)freeEnd - (char*)freeStart; 313808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers if (!native || freeLen < kMaxFreeLen) { 314808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers append_chunk(ctx, HPSG_STATE(SOLIDITY_FREE, 0), 315808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers freeStart, freeLen); 316808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers flush = false; 317808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers } 318808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers } 319808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers if (flush) { 320808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers ctx->startOfNextMemoryChunk = NULL; 321808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers flush_hpsg_chunk(ctx); 322808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers } 323808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers } 324808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers const Object *obj = (const Object *)start; 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 326808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers /* It's an allocated chunk. Figure out what it is. 327808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers */ 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//TODO: if ctx.merge, see if this chunk is different from the last chunk. 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// If it's the same, we should combine them. 330808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers if (!native && dvmIsValidObject(obj)) { 331808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers ClassObject *clazz = obj->clazz; 332808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers if (clazz == NULL) { 333808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers /* The object was probably just created 334808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers * but hasn't been initialized yet. 335808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers */ 336808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers state = HPSG_STATE(SOLIDITY_HARD, KIND_OBJECT); 337808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers } else if (dvmIsTheClassClass(clazz)) { 338808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers state = HPSG_STATE(SOLIDITY_HARD, KIND_CLASS_OBJECT); 339808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers } else if (IS_CLASS_FLAG_SET(clazz, CLASS_ISARRAY)) { 340808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers if (IS_CLASS_FLAG_SET(clazz, CLASS_ISOBJECTARRAY)) { 341808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_4); 342808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers } else { 343808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers switch (clazz->elementClass->primitiveType) { 344808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers case PRIM_BOOLEAN: 345808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers case PRIM_BYTE: 346808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_1); 347808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers break; 348808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers case PRIM_CHAR: 349808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers case PRIM_SHORT: 350808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_2); 351808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers break; 352808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers case PRIM_INT: 353808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers case PRIM_FLOAT: 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_4); 355808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers break; 356808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers case PRIM_DOUBLE: 357808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers case PRIM_LONG: 358808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_8); 359808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers break; 360808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers default: 361808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers assert(!"Unknown GC heap object type"); 362808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers state = HPSG_STATE(SOLIDITY_HARD, KIND_UNKNOWN); 363808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers break; 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 367808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers state = HPSG_STATE(SOLIDITY_HARD, KIND_OBJECT); 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 369808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers } else { 370808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers obj = NULL; // it's not actually an object 371808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers state = HPSG_STATE(SOLIDITY_HARD, KIND_NATIVE); 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 373808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers append_chunk(ctx, state, start, used_bytes + HEAP_SOURCE_CHUNK_OVERHEAD); 374808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers ctx->startOfNextMemoryChunk = 375808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers (char*)start + used_bytes + HEAP_SOURCE_CHUNK_OVERHEAD; 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum HpsgWhen { 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPSG_WHEN_NEVER = 0, 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPSG_WHEN_EVERY_GC = 1, 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum HpsgWhat { 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPSG_WHAT_MERGED_OBJECTS = 0, 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPSG_WHAT_DISTINCT_OBJECTS = 1, 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 38734f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden/* 38834f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden * Maximum chunk size. Obtain this from the formula: 38934f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden * 39034f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden * (((maximum_heap_size / ALLOCATION_UNIT_SIZE) + 255) / 256) * 2 39134f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden */ 39234f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden#define HPSx_CHUNK_SIZE (16384 - 16) 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 39406f120f6092185003bc9b70e06eb44866e9676f8Carl Shapirostatic void walkHeap(bool merge, bool native) 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HeapChunkContext ctx; 397de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(&ctx, 0, sizeof(ctx)); 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.bufLen = HPSx_CHUNK_SIZE; 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.buf = (u1 *)malloc(ctx.bufLen); 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ctx.buf == NULL) { 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.merge = merge; 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (native) { 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.type = CHUNK_TYPE("NHSG"); 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ctx.merge) { 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.type = CHUNK_TYPE("HPSG"); 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.type = CHUNK_TYPE("HPSO"); 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.p = ctx.buf; 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.needHeader = true; 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (native) { 419808a7c0e7e39b7ca3c7db1366e6e4089166052bbIan Rogers dlmalloc_inspect_all(heap_chunk_callback, (void*)&ctx); 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHeapSourceWalk(heap_chunk_callback, (void *)&ctx); 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ctx.p > ctx.buf) { 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flush_hpsg_chunk(&ctx); 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(ctx.buf); 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 43006f120f6092185003bc9b70e06eb44866e9676f8Carl Shapirovoid dvmDdmSendHeapSegments(bool shouldLock, bool native) 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 heapId[sizeof(u4)]; 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GcHeap *gcHeap = gDvm.gcHeap; 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int when, what; 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool merge; 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Don't even grab the lock if there's nothing to do when we're called. 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!native) { 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project when = gcHeap->ddmHpsgWhen; 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project what = gcHeap->ddmHpsgWhat; 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (when == HPSG_WHEN_NEVER) { 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project when = gcHeap->ddmNhsgWhen; 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project what = gcHeap->ddmNhsgWhat; 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (when == HPSG_WHEN_NEVER) { 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (shouldLock && !dvmLockHeap()) { 453e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("Can't lock heap for DDM HPSx dump"); 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Figure out what kind of chunks we'll be sending. 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (what == HPSG_WHAT_MERGED_OBJECTS) { 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project merge = true; 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (what == HPSG_WHAT_DISTINCT_OBJECTS) { 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project merge = false; 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!"bad HPSG.what value"); 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* First, send a heap start chunk. 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(heapId, DEFAULT_HEAP_ID); 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgDdmSendChunk(native ? CHUNK_TYPE("NHST") : CHUNK_TYPE("HPST"), 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sizeof(u4), heapId); 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Send a series of heap segment chunks. 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project walkHeap(merge, native); 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Finally, send a heap end chunk. 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgDdmSendChunk(native ? CHUNK_TYPE("NHEN") : CHUNK_TYPE("HPEN"), 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sizeof(u4), heapId); 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (shouldLock) { 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockHeap(); 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 48806f120f6092185003bc9b70e06eb44866e9676f8Carl Shapirobool dvmDdmHandleHpsgNhsgChunk(int when, int what, bool native) 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 4904308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("dvmDdmHandleHpsgChunk(when %d, what %d, heap %d)", when, what, 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project native); 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (when) { 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPSG_WHEN_NEVER: 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPSG_WHEN_EVERY_GC: 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 4974308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("%s(): bad when value 0x%08x", __func__, when); 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (what) { 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPSG_WHAT_MERGED_OBJECTS: 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPSG_WHAT_DISTINCT_OBJECTS: 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 5064308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("%s(): bad what value 0x%08x", __func__, what); 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmLockHeap()) { 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!native) { 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.gcHeap->ddmHpsgWhen = when; 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.gcHeap->ddmHpsgWhat = what; 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.gcHeap->ddmNhsgWhen = when; 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.gcHeap->ddmNhsgWhat = what; 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//TODO: if what says we should dump immediately, signal (or do) it from here 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockHeap(); 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 5214308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("%s(): can't lock heap to set when/what", __func__); 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 527