summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vm/Profile.cpp15
-rw-r--r--vm/alloc/CardTable.cpp23
-rw-r--r--vm/alloc/CardTable.h2
-rw-r--r--vm/alloc/Heap.cpp2
-rw-r--r--vm/alloc/HeapInternal.h1
-rw-r--r--vm/alloc/HeapSource.cpp1
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;