diff options
-rw-r--r-- | vm/Profile.cpp | 15 | ||||
-rw-r--r-- | vm/alloc/CardTable.cpp | 23 | ||||
-rw-r--r-- | vm/alloc/CardTable.h | 2 | ||||
-rw-r--r-- | vm/alloc/Heap.cpp | 2 | ||||
-rw-r--r-- | vm/alloc/HeapInternal.h | 1 | ||||
-rw-r--r-- | vm/alloc/HeapSource.cpp | 1 |
6 files changed, 33 insertions, 11 deletions
diff --git a/vm/Profile.cpp b/vm/Profile.cpp index bc2a2b05d..e1dfc439a 100644 --- a/vm/Profile.cpp +++ b/vm/Profile.cpp @@ -373,12 +373,6 @@ void dvmMethodTraceStart(const char* traceFileName, int traceFd, int bufferSize, dvmMethodTraceStop(); dvmLockMutex(&state->startStopLock); } - /* - * ENHANCEMENT: To trace just a single thread, modify the - * following to take a Thread* argument, and set the appropriate - * interpBreak flags only on the target thread. - */ - updateActiveProfilers(kSubModeMethodTrace, true); LOGI("TRACE STARTED: '%s' %dKB", traceFileName, bufferSize / 1024); /* @@ -453,11 +447,18 @@ void dvmMethodTraceStart(const char* traceFileName, int traceFd, int bufferSize, * signaled before exiting, so we have to make sure we wake them up. */ android_atomic_release_store(true, &state->traceEnabled); + + /* + * ENHANCEMENT: To trace just a single thread, modify the + * following to take a Thread* argument, and set the appropriate + * interpBreak flags only on the target thread. + */ + updateActiveProfilers(kSubModeMethodTrace, true); + dvmUnlockMutex(&state->startStopLock); return; fail: - updateActiveProfilers(kSubModeMethodTrace, false); if (state->traceFile != NULL) { fclose(state->traceFile); state->traceFile = NULL; diff --git a/vm/alloc/CardTable.cpp b/vm/alloc/CardTable.cpp index c24be0187..212c9d015 100644 --- a/vm/alloc/CardTable.cpp +++ b/vm/alloc/CardTable.cpp @@ -48,7 +48,7 @@ * Initializes the card table; must be called before any other * dvmCardTable*() functions. */ -bool dvmCardTableStartup(size_t heapMaximumSize) +bool dvmCardTableStartup(size_t heapMaximumSize, size_t growthLimit) { size_t length; void *allocBase; @@ -67,7 +67,8 @@ bool dvmCardTableStartup(size_t heapMaximumSize) return false; } gcHeap->cardTableBase = (u1*)allocBase; - gcHeap->cardTableLength = length; + gcHeap->cardTableLength = growthLimit / GC_CARD_SIZE; + gcHeap->cardTableMaxLength = length; gcHeap->cardTableOffset = 0; /* All zeros is the correct initial value; all clean. */ assert(GC_CARD_CLEAN == 0); @@ -96,8 +97,26 @@ void dvmCardTableShutdown() void dvmClearCardTable() { + /* + * The goal is to zero out some mmap-allocated pages. We can accomplish + * this with memset() or madvise(MADV_DONTNEED). The latter has some + * useful properties, notably that the pages are returned to the system, + * so cards for parts of the heap we haven't expanded into won't be + * allocated physical pages. On the other hand, if we un-map the card + * area, we'll have to fault it back in as we resume dirtying objects, + * which reduces performance. (Also, "the kernel is free to ignore the + * advice" makes this sound like something we can't necessarily rely on + * to synchronously clear memory; may need to memset *and* madvise.) + * + * TODO: use memset() to clear out to the current "soft" limit, and + * madvise() to clear out the rest. + * + * Note that cardTableLength is initially set to the growth limit, and + * on request will be expanded to the heap maximum. + */ assert(gDvm.gcHeap->cardTableBase != NULL); memset(gDvm.gcHeap->cardTableBase, GC_CARD_CLEAN, gDvm.gcHeap->cardTableLength); + //madvise(gDvm.gcHeap->cardTableBase, gDvm.gcHeap->cardTableLength, MADV_DONTNEED); } /* diff --git a/vm/alloc/CardTable.h b/vm/alloc/CardTable.h index 532c25963..43b0563b1 100644 --- a/vm/alloc/CardTable.h +++ b/vm/alloc/CardTable.h @@ -32,7 +32,7 @@ * Initializes the card table; must be called before any other * dvmCardTable*() functions. */ -bool dvmCardTableStartup(size_t heapMaximumSize); +bool dvmCardTableStartup(size_t heapMaximumSize, size_t growthLimit); /* * Tears down the entire CardTable structure. diff --git a/vm/alloc/Heap.cpp b/vm/alloc/Heap.cpp index db640a6c1..9eee817e5 100644 --- a/vm/alloc/Heap.cpp +++ b/vm/alloc/Heap.cpp @@ -97,7 +97,7 @@ bool dvmHeapStartup() */ gcHeap->clearedReferences = NULL; - if (!dvmCardTableStartup(gDvm.heapMaximumSize)) { + if (!dvmCardTableStartup(gDvm.heapMaximumSize, gDvm.heapGrowthLimit)) { LOGE_HEAP("card table startup failed."); return false; } diff --git a/vm/alloc/HeapInternal.h b/vm/alloc/HeapInternal.h index a893bb259..185af1cb9 100644 --- a/vm/alloc/HeapInternal.h +++ b/vm/alloc/HeapInternal.h @@ -48,6 +48,7 @@ struct GcHeap { /* GC's card table */ u1* cardTableBase; size_t cardTableLength; + size_t cardTableMaxLength; size_t cardTableOffset; /* Is the GC running? Used to avoid recursive calls to GC. diff --git a/vm/alloc/HeapSource.cpp b/vm/alloc/HeapSource.cpp index d3779d8f9..f61724a40 100644 --- a/vm/alloc/HeapSource.cpp +++ b/vm/alloc/HeapSource.cpp @@ -1069,6 +1069,7 @@ void dvmClearGrowthLimit() HS_BOILERPLATE(); dvmLockHeap(); dvmWaitForConcurrentGcToComplete(); + gDvm.gcHeap->cardTableLength = gDvm.gcHeap->cardTableMaxLength; gHs->growthLimit = gHs->maximumSize; size_t overhead = oldHeapOverhead(gHs, false); gHs->heaps[0].maximumSize = gHs->maximumSize - overhead; |