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#include <fcntl.h> 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <malloc.h> 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "HeapInternal.h" 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "HeapSource.h" 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Float12.h" 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmGetHeapDebugInfo(HeapDebugInfoType info) 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (info) { 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kVirtualHeapSize: 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (int)dvmHeapSourceGetValue(HS_FOOTPRINT, NULL, 0); 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case kVirtualHeapAllocated: 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (int)dvmHeapSourceGetValue(HS_BYTES_ALLOCATED, NULL, 0); 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Looks up the cmdline for the process and tries to find 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the most descriptive five characters, then inserts the 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * short name into the provided event value. 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define PROC_NAME_LEN 5 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void insertProcessName(long long *ep) 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static bool foundRealName = false; 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static char name[PROC_NAME_LEN] = { 'X', 'X', 'X', 'X', 'X' }; 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long long event = *ep; 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!foundRealName) { 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int fd = open("/proc/self/cmdline", O_RDONLY); 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fd > 0) { 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[128]; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ssize_t n = read(fd, buf, sizeof(buf) - 1); 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project close(fd); 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (n > 0) { 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(name, 0, sizeof(name)); 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (n <= PROC_NAME_LEN) { 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The whole name fits. 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(name, buf, n); 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* We need to truncate. The name will look something 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * like "com.android.home". Favor the characters 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * immediately following the last dot. 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[n] = '\0'; 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *dot = strrchr(buf, '.'); 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dot == NULL) { 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Or, look for a slash, in case it's something like 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "/system/bin/runtime". 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dot = strrchr(buf, '/'); 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dot != NULL) { 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dot++; // Skip the dot 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t dotlen = strlen(dot); 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dotlen < PROC_NAME_LEN) { 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Use all available characters. We know that 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * n > PROC_NAME_LEN from the check above. 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dot -= PROC_NAME_LEN - dotlen; 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strncpy(name, dot, PROC_NAME_LEN); 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // No dot; just use the leading characters. 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(name, buf, PROC_NAME_LEN); 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(buf, "zygote") != 0) { 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If the process is no longer called "zygote", 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * cache this name. 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project foundRealName = true; 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project event &= ~(0xffffffffffLL << 24); 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project event |= (long long)name[0] << 56; 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project event |= (long long)name[1] << 48; 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project event |= (long long)name[2] << 40; 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project event |= (long long)name[3] << 32; 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project event |= (long long)name[4] << 24; 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *ep = event; 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// See device/data/etc/event-log-tags 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define EVENT_LOG_TAG_dvm_gc_info 20001 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define EVENT_LOG_TAG_dvm_gc_madvise_info 20002 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmLogGcStats(size_t numFreed, size_t sizeFreed, size_t gcTimeMs) 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const GcHeap *gcHeap = gDvm.gcHeap; 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t perHeapActualSize[HEAP_SOURCE_MAX_HEAP_COUNT], 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project perHeapAllowedSize[HEAP_SOURCE_MAX_HEAP_COUNT], 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project perHeapNumAllocated[HEAP_SOURCE_MAX_HEAP_COUNT], 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project perHeapSizeAllocated[HEAP_SOURCE_MAX_HEAP_COUNT]; 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned char eventBuf[1 + (1 + sizeof(long long)) * 4]; 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t actualSize, allowedSize, numAllocated, sizeAllocated; 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t i; 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t softLimit = dvmHeapSourceGetIdealFootprint(); 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t nHeaps = dvmHeapSourceGetNumHeaps(); 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Enough to quiet down gcc for unitialized variable check */ 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project perHeapActualSize[0] = perHeapAllowedSize[0] = perHeapNumAllocated[0] = 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project perHeapSizeAllocated[0] = 0; 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualSize = dvmHeapSourceGetValue(HS_FOOTPRINT, perHeapActualSize, 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HEAP_SOURCE_MAX_HEAP_COUNT); 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project allowedSize = dvmHeapSourceGetValue(HS_ALLOWED_FOOTPRINT, 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project perHeapAllowedSize, HEAP_SOURCE_MAX_HEAP_COUNT); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numAllocated = dvmHeapSourceGetValue(HS_OBJECTS_ALLOCATED, 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project perHeapNumAllocated, HEAP_SOURCE_MAX_HEAP_COUNT); 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sizeAllocated = dvmHeapSourceGetValue(HS_BYTES_ALLOCATED, 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project perHeapSizeAllocated, HEAP_SOURCE_MAX_HEAP_COUNT); 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Construct the the first 64-bit value to write to the log. 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Global information: 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [63 ] Must be zero 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [62-24] ASCII process identifier 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [23-12] GC time in ms 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [11- 0] Bytes freed 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long long event0; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project event0 = 0LL << 63 | 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(gcTimeMs) << 12 | 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(sizeFreed); 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insertProcessName(&event0); 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Aggregated heap stats: 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [63-62] 10 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [61-60] Reserved; must be zero 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [59-48] Objects freed 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [47-36] Actual size (current footprint) 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [35-24] Allowed size (current hard max) 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [23-12] Objects allocated 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [11- 0] Bytes allocated 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long long event1; 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project event1 = 2LL << 62 | 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(numFreed) << 48 | 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(actualSize) << 36 | 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(allowedSize) << 24 | 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(numAllocated) << 12 | 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(sizeAllocated); 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Report the current state of the zygote heap(s). 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The active heap is always heap[0]. We can be in one of three states 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * at present: 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (1) Still in the zygote. Zygote using heap[0]. 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (2) In the zygote, when the first child is started. We created a 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * new heap just before the first fork() call, so the original 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "zygote heap" is now heap[1], and we have a small heap[0] for 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * anything we do from here on. 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (3) In an app process. The app gets a new heap[0], and can also 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * see the two zygote heaps [1] and [2] (probably unwise to 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * assume any specific ordering). 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * So if nHeaps == 1, we want the stats from heap[0]; else we want 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the sum of the values from heap[1] to heap[nHeaps-1]. 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Zygote heap stats (except for the soft limit, which belongs to the 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * active heap): 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [63-62] 11 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [61-60] Reserved; must be zero 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [59-48] Soft Limit (for the active heap) 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [47-36] Actual size (current footprint) 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [35-24] Allowed size (current hard max) 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [23-12] Objects allocated 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [11- 0] Bytes allocated 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long long event2; 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t zActualSize, zAllowedSize, zNumAllocated, zSizeAllocated; 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int firstHeap = (nHeaps == 1) ? 0 : 1; 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t hh; 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project zActualSize = zAllowedSize = zNumAllocated = zSizeAllocated = 0; 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (hh = firstHeap; hh < nHeaps; hh++) { 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project zActualSize += perHeapActualSize[hh]; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project zAllowedSize += perHeapAllowedSize[hh]; 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project zNumAllocated += perHeapNumAllocated[hh]; 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project zSizeAllocated += perHeapSizeAllocated[hh]; 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project event2 = 3LL << 62 | 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(softLimit) << 48 | 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(zActualSize) << 36 | 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(zAllowedSize) << 24 | 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(zNumAllocated) << 12 | 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(zSizeAllocated); 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Report the current external allocation stats and the native heap 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * summary. 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [63-48] Reserved; must be zero (TODO: put new data in these slots) 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [47-36] dlmalloc_footprint 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [35-24] mallinfo: total allocated space 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [23-12] External byte limit 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [11- 0] External bytes allocated 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long long event3; 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t externalLimit, externalBytesAllocated; 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t uordblks, footprint; 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This adds 2-5msec to the GC cost on a DVT, or about 2-3% of the cost 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of a GC, so it's not horribly expensive but it's not free either. 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project extern size_t dlmalloc_footprint(void); 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct mallinfo mi; 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //u8 start, end; 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //start = dvmGetRelativeTimeNsec(); 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mi = mallinfo(); 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uordblks = mi.uordblks; 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project footprint = dlmalloc_footprint(); 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //end = dvmGetRelativeTimeNsec(); 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGD("mallinfo+footprint took %dusec; used=%zd footprint=%zd\n", 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // (int)((end - start) / 1000), mi.uordblks, footprint); 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uordblks = footprint = 0; 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project externalLimit = 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHeapSourceGetValue(HS_EXTERNAL_LIMIT, NULL, 0); 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project externalBytesAllocated = 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHeapSourceGetValue(HS_EXTERNAL_BYTES_ALLOCATED, NULL, 0); 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project event3 = 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(footprint) << 36 | 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(uordblks) << 24 | 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(externalLimit) << 12 | 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (long long)intToFloat12(externalBytesAllocated); 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Build the event data. 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [ 0: 0] item count (4) 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [ 1: 1] EVENT_TYPE_LONG 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [ 2: 9] event0 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [10:10] EVENT_TYPE_LONG 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [11:18] event1 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [19:19] EVENT_TYPE_LONG 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [20:27] event2 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [28:28] EVENT_TYPE_LONG 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [29:36] event2 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned char *c = eventBuf; 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *c++ = 4; 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *c++ = EVENT_TYPE_LONG; 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(c, &event0, sizeof(event0)); 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c += sizeof(event0); 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *c++ = EVENT_TYPE_LONG; 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(c, &event1, sizeof(event1)); 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c += sizeof(event1); 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *c++ = EVENT_TYPE_LONG; 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(c, &event2, sizeof(event2)); 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c += sizeof(event2); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *c++ = EVENT_TYPE_LONG; 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(c, &event3, sizeof(event3)); 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (void) android_btWriteLog(EVENT_LOG_TAG_dvm_gc_info, EVENT_TYPE_LIST, 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project eventBuf, sizeof(eventBuf)); 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmLogMadviseStats(size_t madvisedSizes[], size_t arrayLen) 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned char eventBuf[1 + (1 + sizeof(int)) * 2]; 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t total, zyg; 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t firstHeap, i; 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t nHeaps = dvmHeapSourceGetNumHeaps(); 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(arrayLen >= nHeaps); 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project firstHeap = nHeaps > 1 ? 1 : 0; 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project total = 0; 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project zyg = 0; 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < nHeaps; i++) { 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project total += madvisedSizes[i]; 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i >= firstHeap) { 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project zyg += madvisedSizes[i]; 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Build the event data. 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [ 0: 0] item count (2) 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [ 1: 1] EVENT_TYPE_INT 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [ 2: 5] total madvise byte count 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [ 6: 6] EVENT_TYPE_INT 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * [ 7:10] zygote heap madvise byte count 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned char *c = eventBuf; 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *c++ = 2; 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *c++ = EVENT_TYPE_INT; 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(c, &total, sizeof(total)); 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c += sizeof(total); 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *c++ = EVENT_TYPE_INT; 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(c, &zyg, sizeof(zyg)); 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project c += sizeof(zyg); 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (void) android_btWriteLog(EVENT_LOG_TAG_dvm_gc_madvise_info, 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EVENT_TYPE_LIST, eventBuf, sizeof(eventBuf)); 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <errno.h> 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdio.h> 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct HeapDumpContext { 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FILE *fp; 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void *chunkStart; 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t chunkLen; 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool chunkFree; 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} HeapDumpContext; 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectdump_context(const HeapDumpContext *ctx) 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(ctx->fp, "0x%08x %12.12zd %s\n", (uintptr_t)ctx->chunkStart, 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->chunkLen, ctx->chunkFree ? "FREE" : "USED"); 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectheap_chunk_callback(const void *chunkptr, size_t chunklen, 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const void *userptr, size_t userlen, void *arg) 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HeapDumpContext *ctx = (HeapDumpContext *)arg; 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool chunkFree = (userptr == NULL); 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (chunkFree != ctx->chunkFree || 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ((char *)ctx->chunkStart + ctx->chunkLen) != chunkptr) 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* The new chunk is of a different type or isn't 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contiguous with the current chunk. Dump the 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * old one and start a new one. 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ctx->chunkStart != NULL) { 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* It's not the first chunk. */ 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dump_context(ctx); 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->chunkStart = (void *)chunkptr; 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->chunkLen = chunklen; 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->chunkFree = chunkFree; 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Extend the current chunk. 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx->chunkLen += chunklen; 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Dumps free and used ranges, as text, to the named file. 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDumpHeapToFile(const char *fileName) 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HeapDumpContext ctx; 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FILE *fp; 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fp = fopen(fileName, "w+"); 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fp == NULL) { 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Can't open %s for writing: %s\n", fileName, strerror(errno)); 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Dumping heap to %s...\n", fileName); 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(fp, "==== Dalvik heap dump ====\n"); 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(&ctx, 0, sizeof(ctx)); 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ctx.fp = fp; 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmHeapSourceWalk(heap_chunk_callback, (void *)&ctx); 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dump_context(&ctx); 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(fp, "==== end heap dump ====\n"); 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("Dumped heap to %s.\n", fileName); 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fclose(fp); 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 404