#include <stdint.h>
#include <sys/mman.h>
#include <errno.h>
+#include <cutils/ashmem.h>
#define SIZE_MAX UINT_MAX // TODO: get SIZE_MAX from stdint.h
}
/*
+ * A helper for addNewHeap(). Remap the new heap so that it will have
+ * a separate ashmem region with possibly a different name, etc. In
+ * practice, this is used to give the app heap a separate ashmem
+ * region from the zygote heap's.
+ */
+static bool remapNewHeap(HeapSource* hs, Heap* newHeap)
+{
+ char* newHeapBase = newHeap->base;
+ size_t rem_size = hs->heapBase + hs->heapLength - newHeapBase;
+ munmap(newHeapBase, rem_size);
+ int fd = ashmem_create_region("dalvik-heap", rem_size);
+ if (fd == -1) {
+ ALOGE("Unable to create an ashmem region for the new heap");
+ return false;
+ }
+ void* addr = mmap(newHeapBase, rem_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ int ret = close(fd);
+ if (addr == MAP_FAILED) {
+ ALOGE("Unable to map an ashmem region for the new heap");
+ return false;
+ }
+ if (ret == -1) {
+ ALOGE("Unable to close fd for the ashmem region for the new heap");
+ munmap(newHeapBase, rem_size);
+ return false;
+ }
+ return true;
+}
+
+/*
* Adds an additional heap to the heap source. Returns false if there
* are too many heaps or insufficient free space to add another heap.
*/
heap.base = base;
heap.limit = heap.base + heap.maximumSize;
heap.brk = heap.base + morecoreStart;
+ if (!remapNewHeap(hs, &heap)) {
+ return false;
+ }
heap.msp = createMspace(base, morecoreStart, hs->minFree);
if (heap.msp == NULL) {
return false;
* among the heaps managed by the garbage collector.
*/
length = ALIGN_UP_TO_PAGE_SIZE(maximumSize);
- base = dvmAllocRegion(length, PROT_NONE, "dalvik-heap");
+ base = dvmAllocRegion(length, PROT_NONE, gDvm.zygote ? "dalvik-zygote" : "dalvik-heap");
if (base == NULL) {
return NULL;
}
* dalvik.system.VMDebug
*/
#include "Dalvik.h"
+#include "alloc/HeapSource.h"
#include "native/InternalNativePriv.h"
#include "hprof/Hprof.h"
}
}
+/*
+ * public static native void getHeapSpaceStats(long[] data)
+ */
+static void Dalvik_dalvik_system_VMDebug_getHeapSpaceStats(const u4* args,
+ JValue* pResult)
+{
+ ArrayObject* dataArray = (ArrayObject*) args[0];
+
+ if (dataArray == NULL || dataArray->length < 6) {
+ RETURN_VOID();
+ }
+
+ jlong* arr = (jlong*)(void*)dataArray->contents;
+
+ int j = 0;
+ size_t per_heap_allocated[2];
+ size_t per_heap_size[2];
+ memset(per_heap_allocated, 0, sizeof(per_heap_allocated));
+ memset(per_heap_size, 0, sizeof(per_heap_size));
+ dvmHeapSourceGetValue(HS_BYTES_ALLOCATED, (size_t*) &per_heap_allocated, 2);
+ dvmHeapSourceGetValue(HS_FOOTPRINT, (size_t*) &per_heap_size, 2);
+ jlong heapSize = per_heap_size[0];
+ jlong heapUsed = per_heap_allocated[0];
+ jlong heapFree = heapSize - heapUsed;
+ jlong zygoteSize = per_heap_size[1];
+ jlong zygoteUsed = per_heap_allocated[1];
+ jlong zygoteFree = zygoteSize - zygoteUsed;
+ arr[j++] = heapSize;
+ arr[j++] = heapUsed;
+ arr[j++] = heapFree;
+ arr[j++] = zygoteSize;
+ arr[j++] = zygoteUsed;
+ arr[j++] = zygoteFree;
+
+ RETURN_VOID();
+}
+
const DalvikNativeMethod dvm_dalvik_system_VMDebug[] = {
{ "getVmFeatureList", "()[Ljava/lang/String;",
Dalvik_dalvik_system_VMDebug_getVmFeatureList },
{ "getAllocCount", "(I)I",
Dalvik_dalvik_system_VMDebug_getAllocCount },
+ { "getHeapSpaceStats", "([J)V",
+ Dalvik_dalvik_system_VMDebug_getHeapSpaceStats },
{ "resetAllocCount", "(I)V",
Dalvik_dalvik_system_VMDebug_resetAllocCount },
{ "startAllocCounting", "()V",