DdmHeap.cpp revision 34f33c5e531650dda8d5159ebf34178bb770c828
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" 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "alloc/HeapSource.h" 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define DEFAULT_HEAP_ID 1 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum HpifWhen { 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPIF_WHEN_NEVER = 0, 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPIF_WHEN_NOW = 1, 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPIF_WHEN_NEXT_GC = 2, 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPIF_WHEN_EVERY_GC = 3 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Chunk HPIF (client --> server) 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Heap Info. General information about the heap, 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * suitable for a summary display. 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u4]: number of heaps 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For each heap: 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u4]: heap ID 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u8]: timestamp in ms since Unix epoch 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u1]: capture reason (same as 'when' value from server) 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u4]: max heap size in bytes (-Xmx) 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u4]: current heap size in bytes 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u4]: current number of bytes allocated 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [u4]: current number of objects allocated 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HPIF_SIZE(numHeaps) \ 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (sizeof(u4) + (numHeaps) * (5 * sizeof(u4) + sizeof(u1) + sizeof(u8))) 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectdvmDdmSendHeapInfo(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()) { 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("%s(): can't lock heap to clear when\n", __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 */ 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(b, gDvm.heapSizeMax); 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 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectdvmDdmHandleHpifChunk(int when) 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (when) { 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPIF_WHEN_NOW: 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDdmSendHeapInfo(when, true); 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPIF_WHEN_NEVER: 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPIF_WHEN_NEXT_GC: 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPIF_WHEN_EVERY_GC: 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmLockHeap()) { 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.gcHeap->ddmHpifWhen = when; 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockHeap(); 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("%s(): can't lock heap to set when\n", __func__); 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("%s(): bad when value 0x%08x\n", __func__, when); 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum HpsgSolidity { 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_FREE = 0, 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_HARD = 1, 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_SOFT = 2, 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_WEAK = 3, 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_PHANTOM = 4, 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_FINALIZABLE = 5, 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SOLIDITY_SWEEP = 6, 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum HpsgKind { 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_OBJECT = 0, 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_CLASS_OBJECT = 1, 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_ARRAY_1 = 2, 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_ARRAY_2 = 3, 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_ARRAY_4 = 4, 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_ARRAY_8 = 5, 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_UNKNOWN = 6, 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KIND_NATIVE = 7, 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HPSG_PARTIAL (1<<7) 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HPSG_STATE(solidity, kind) \ 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ((u1)((((kind) & 0x7) << 3) | ((solidity) & 0x7))) 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct HeapChunkContext { 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; 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} HeapChunkContext; 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define ALLOCATION_UNIT_SIZE 8 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectflush_hpsg_chunk(HeapChunkContext *ctx) 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Patch the "length of piece" field. 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(ctx->buf <= ctx->pieceLenField && 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->pieceLenField <= ctx->p); 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(ctx->pieceLenField, ctx->totalAllocationUnits); 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Send the chunk. 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgDdmSendChunk(ctx->type, ctx->p - ctx->buf, ctx->buf); 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Reset the context. 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->p = ctx->buf; 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->totalAllocationUnits = 0; 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->needHeader = true; 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->pieceLenField = NULL; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectheap_chunk_callback(const void *chunkptr, size_t chunklen, 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const void *userptr, size_t userlen, void *arg) 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HeapChunkContext *ctx = (HeapChunkContext *)arg; 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 state; 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNUSED_PARAMETER(userlen); 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert((chunklen & (ALLOCATION_UNIT_SIZE-1)) == 0); 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Make sure there's enough room left in the buffer. 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need to use two bytes for every fractional 256 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * allocation units used by the chunk. 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 22734f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden size_t needed = (((chunklen/ALLOCATION_UNIT_SIZE + 255) / 256) * 2); 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t bytesLeft = ctx->bufLen - (size_t)(ctx->p - ctx->buf); 22934f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden if (bytesLeft < needed) { 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flush_hpsg_chunk(ctx); 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 23234f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden 23334f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden bytesLeft = ctx->bufLen - (size_t)(ctx->p - ctx->buf); 23434f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden if (bytesLeft < needed) { 23534f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden LOGW("chunk is too big to transmit (chunklen=%zd, %zd bytes)\n", 23634f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden chunklen, needed); 23734f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden return; 23834f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden } 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//TODO: notice when there's a gap and start a new heap, or at least a new range. 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ctx->needHeader) { 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Start a new HPSx chunk. 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* [u4]: heap ID */ 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(ctx->p, DEFAULT_HEAP_ID); ctx->p += 4; 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* [u1]: size of allocation unit, in bytes */ 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *ctx->p++ = 8; 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* [u4]: virtual address of segment start */ 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(ctx->p, (uintptr_t)chunkptr); ctx->p += 4; 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* [u4]: offset of this piece (relative to the virtual address) */ 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(ctx->p, 0); ctx->p += 4; 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* [u4]: length of piece, in allocation units 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We won't know this until we're done, so save the offset 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and stuff in a dummy value. 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->pieceLenField = ctx->p; 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(ctx->p, 0x55555555); ctx->p += 4; 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->needHeader = false; 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Determine the type of this chunk. 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (userptr == NULL) { 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* It's a free chunk. 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = HPSG_STATE(SOLIDITY_FREE, 0); 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DvmHeapChunk *hc = (const DvmHeapChunk *)userptr; 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Object *obj = chunk2ptr(hc); 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If we're looking at the native heap, we'll just return 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (SOLIDITY_HARD, KIND_NATIVE) for all allocated chunks 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool native = ctx->type == CHUNK_TYPE("NHSG"); 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* It's an allocated chunk. Figure out what it is. 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//TODO: if ctx.merge, see if this chunk is different from the last chunk. 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// If it's the same, we should combine them. 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!native && dvmIsValidObject(obj)) { 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject *clazz = obj->clazz; 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (clazz == NULL) { 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* The object was probably just created 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * but hasn't been initialized yet. 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = HPSG_STATE(SOLIDITY_HARD, KIND_OBJECT); 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (clazz == gDvm.unlinkedJavaLangClass || 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clazz == gDvm.classJavaLangClass) 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = HPSG_STATE(SOLIDITY_HARD, KIND_CLASS_OBJECT); 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (IS_CLASS_FLAG_SET(clazz, CLASS_ISARRAY)) { 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (IS_CLASS_FLAG_SET(clazz, CLASS_ISOBJECTARRAY)) { 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_4); 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (clazz->elementClass->primitiveType) { 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_BOOLEAN: 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_BYTE: 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_1); 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_CHAR: 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_SHORT: 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_2); 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_INT: 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_FLOAT: 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_4); 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_DOUBLE: 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case PRIM_LONG: 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_8); 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!"Unknown GC heap object type"); 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = HPSG_STATE(SOLIDITY_HARD, KIND_UNKNOWN); 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = HPSG_STATE(SOLIDITY_HARD, KIND_OBJECT); 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project obj = NULL; // it's not actually an object 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = HPSG_STATE(SOLIDITY_HARD, KIND_NATIVE); 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Write out the chunk description. 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project chunklen /= ALLOCATION_UNIT_SIZE; // convert to allocation units 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->totalAllocationUnits += chunklen; 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (chunklen > 256) { 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *ctx->p++ = state | HPSG_PARTIAL; 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *ctx->p++ = 255; // length - 1 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project chunklen -= 256; 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *ctx->p++ = state; 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *ctx->p++ = chunklen - 1; 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum HpsgWhen { 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPSG_WHEN_NEVER = 0, 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPSG_WHEN_EVERY_GC = 1, 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum HpsgWhat { 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPSG_WHAT_MERGED_OBJECTS = 0, 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPSG_WHAT_DISTINCT_OBJECTS = 1, 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 35634f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden/* 35734f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden * Maximum chunk size. Obtain this from the formula: 35834f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden * 35934f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden * (((maximum_heap_size / ALLOCATION_UNIT_SIZE) + 255) / 256) * 2 36034f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden */ 36134f33c5e531650dda8d5159ebf34178bb770c828Andy McFadden#define HPSx_CHUNK_SIZE (16384 - 16) 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dlmalloc_walk_heap(void(*)(const void*, size_t, const void*, size_t, void*),void*); 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectwalkHeap(bool merge, bool native) 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HeapChunkContext ctx; 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(&ctx, 0, sizeof(ctx)); 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.bufLen = HPSx_CHUNK_SIZE; 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.buf = (u1 *)malloc(ctx.bufLen); 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ctx.buf == NULL) { 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.merge = merge; 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (native) { 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.type = CHUNK_TYPE("NHSG"); 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ctx.merge) { 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.type = CHUNK_TYPE("HPSG"); 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.type = CHUNK_TYPE("HPSO"); 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.p = ctx.buf; 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.needHeader = true; 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (native) { 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dlmalloc_walk_heap(heap_chunk_callback, (void *)&ctx); 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHeapSourceWalk(heap_chunk_callback, (void *)&ctx); 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ctx.p > ctx.buf) { 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flush_hpsg_chunk(&ctx); 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(ctx.buf); 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectdvmDdmSendHeapSegments(bool shouldLock, bool native) 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 heapId[sizeof(u4)]; 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GcHeap *gcHeap = gDvm.gcHeap; 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int when, what; 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool merge; 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Don't even grab the lock if there's nothing to do when we're called. 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!native) { 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project when = gcHeap->ddmHpsgWhen; 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project what = gcHeap->ddmHpsgWhat; 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (when == HPSG_WHEN_NEVER) { 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project when = gcHeap->ddmNhsgWhen; 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project what = gcHeap->ddmNhsgWhat; 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (when == HPSG_WHEN_NEVER) { 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (shouldLock && !dvmLockHeap()) { 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Can't lock heap for DDM HPSx dump\n"); 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Figure out what kind of chunks we'll be sending. 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (what == HPSG_WHAT_MERGED_OBJECTS) { 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project merge = true; 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (what == HPSG_WHAT_DISTINCT_OBJECTS) { 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project merge = false; 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!"bad HPSG.what value"); 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* First, send a heap start chunk. 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(heapId, DEFAULT_HEAP_ID); 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgDdmSendChunk(native ? CHUNK_TYPE("NHST") : CHUNK_TYPE("HPST"), 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sizeof(u4), heapId); 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Send a series of heap segment chunks. 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project walkHeap(merge, native); 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Finally, send a heap end chunk. 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgDdmSendChunk(native ? CHUNK_TYPE("NHEN") : CHUNK_TYPE("HPEN"), 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sizeof(u4), heapId); 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (shouldLock) { 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockHeap(); 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectdvmDdmHandleHpsgNhsgChunk(int when, int what, bool native) 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("dvmDdmHandleHpsgChunk(when %d, what %d, heap %d)\n", when, what, 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project native); 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (when) { 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPSG_WHEN_NEVER: 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPSG_WHEN_EVERY_GC: 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("%s(): bad when value 0x%08x\n", __func__, when); 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (what) { 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPSG_WHAT_MERGED_OBJECTS: 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPSG_WHAT_DISTINCT_OBJECTS: 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("%s(): bad what value 0x%08x\n", __func__, what); 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmLockHeap()) { 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!native) { 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.gcHeap->ddmHpsgWhen = when; 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.gcHeap->ddmHpsgWhat = what; 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.gcHeap->ddmNhsgWhen = when; 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.gcHeap->ddmNhsgWhat = what; 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//TODO: if what says we should dump immediately, signal (or do) it from here 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockHeap(); 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("%s(): can't lock heap to set when/what\n", __func__); 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 501