OSDN Git Service

merge in jb-mr1-release history after reset to jb-mr1-dev
authorThe Android Automerger <android-build@android.com>
Wed, 26 Sep 2012 13:59:14 +0000 (06:59 -0700)
committerThe Android Automerger <android-build@android.com>
Wed, 26 Sep 2012 13:59:14 +0000 (06:59 -0700)
vm/Globals.h
vm/Init.cpp
vm/alloc/HeapSource.cpp
vm/alloc/MarkSweep.cpp

index 3bef865..565c92a 100644 (file)
@@ -90,6 +90,9 @@ struct DvmGlobals {
     size_t      heapStartingSize;
     size_t      heapMaximumSize;
     size_t      heapGrowthLimit;
+    double      heapTargetUtilization;
+    size_t      heapMinFree;
+    size_t      heapMaxFree;
     size_t      stackSize;
     size_t      mainThreadStackSize;
 
index 2c2b13f..1ae458d 100644 (file)
@@ -921,6 +921,36 @@ static int processOptions(int argc, const char* const argv[],
                 dvmFprintf(stderr, "Invalid -XX:HeapGrowthLimit option '%s'\n", argv[i]);
                 return -1;
             }
+        } else if (strncmp(argv[i], "-XX:HeapMinFree=", 16) == 0) {
+            size_t val = parseMemOption(argv[i] + 16, 1024);
+            if (val != 0) {
+                gDvm.heapMinFree = val;
+            } else {
+                dvmFprintf(stderr, "Invalid -XX:HeapMinFree option '%s'\n", argv[i]);
+                return -1;
+            }
+        } else if (strncmp(argv[i], "-XX:HeapMaxFree=", 16) == 0) {
+            size_t val = parseMemOption(argv[i] + 16, 1024);
+            if (val != 0) {
+                gDvm.heapMaxFree = val;
+            } else {
+                dvmFprintf(stderr, "Invalid -XX:HeapMaxFree option '%s'\n", argv[i]);
+                return -1;
+            }
+        } else if (strncmp(argv[i], "-XX:HeapTargetUtilization=", 26) == 0) {
+            const char* start = argv[i] + 26;
+            const char* end = start;
+            double val = strtod(start, const_cast<char**>(&end));
+            // Ensure that we have a value, there was no cruft after it and it
+            // satisfies a sensible range.
+            bool sane_val = (start != end) && (end[0] == '\0') &&
+                (val >= 0.1) && (val <= 0.9);
+            if (sane_val) {
+                gDvm.heapTargetUtilization = val;
+            } else {
+                dvmFprintf(stderr, "Invalid -XX:HeapTargetUtilization option '%s'\n", argv[i]);
+                return -1;
+            }
         } else if (strncmp(argv[i], "-Xss", 4) == 0) {
             size_t val = parseMemOption(argv[i]+4, 1);
             if (val != 0) {
@@ -1209,6 +1239,15 @@ static void setCommandLineDefaults()
     gDvm.heapGrowthLimit = 0;  // 0 means no growth limit
     gDvm.stackSize = kDefaultStackSize;
     gDvm.mainThreadStackSize = kDefaultStackSize;
+    // When the heap is less than the maximum or growth limited size,
+    // fix the free portion of the heap. The utilization is the ratio
+    // of live to free memory, 0.5 implies half the heap is available
+    // to allocate into before a GC occurs. Min free and max free
+    // force the free memory to never be smaller than min free or
+    // larger than max free.
+    gDvm.heapTargetUtilization = 0.5;
+    gDvm.heapMaxFree = 2 * 1024 * 1024;
+    gDvm.heapMinFree = gDvm.heapMaxFree / 4;
 
     gDvm.concurrentMarkSweep = true;
 
index cd2f4df..ee40af8 100644 (file)
@@ -34,9 +34,6 @@ static size_t getMaximumSize(const HeapSource *hs);
 static void trimHeaps();
 
 #define HEAP_UTILIZATION_MAX        1024
-#define DEFAULT_HEAP_UTILIZATION    512     // Range 1..HEAP_UTILIZATION_MAX
-#define HEAP_IDEAL_FREE             (2 * 1024 * 1024)
-#define HEAP_MIN_FREE               (HEAP_IDEAL_FREE / 4)
 
 /* How long to wait after a GC before performing a heap trim
  * operation to reclaim unused pages.
@@ -134,6 +131,18 @@ struct HeapSource {
      */
     size_t softLimit;
 
+    /* Minimum number of free bytes. Used with the target utilization when
+     * setting the softLimit. Never allows less bytes than this to be free
+     * when the heap size is below the maximum size or growth limit.
+     */
+    size_t minFree;
+
+    /* Maximum number of free bytes. Used with the target utilization when
+     * setting the softLimit. Never allows more bytes than this to be free
+     * when the heap size is below the maximum size or growth limit.
+     */
+    size_t maxFree;
+
     /* The heaps; heaps[0] is always the active heap,
      * which new objects should be allocated from.
      */
@@ -393,7 +402,7 @@ static bool addNewHeap(HeapSource *hs)
     size_t overhead = base - hs->heaps[0].base;
     assert(((size_t)hs->heaps[0].base & (SYSTEM_PAGE_SIZE - 1)) == 0);
 
-    if (overhead + HEAP_MIN_FREE >= hs->maximumSize) {
+    if (overhead + hs->minFree >= hs->maximumSize) {
         LOGE_HEAP("No room to create any more heaps "
                   "(%zd overhead, %zd max)",
                   overhead, hs->maximumSize);
@@ -401,11 +410,11 @@ static bool addNewHeap(HeapSource *hs)
     }
     size_t morecoreStart = SYSTEM_PAGE_SIZE;
     heap.maximumSize = hs->growthLimit - overhead;
-    heap.concurrentStartBytes = HEAP_MIN_FREE - CONCURRENT_START;
+    heap.concurrentStartBytes = hs->minFree - CONCURRENT_START;
     heap.base = base;
     heap.limit = heap.base + heap.maximumSize;
     heap.brk = heap.base + morecoreStart;
-    heap.msp = createMspace(base, morecoreStart, HEAP_MIN_FREE);
+    heap.msp = createMspace(base, morecoreStart, hs->minFree);
     if (heap.msp == NULL) {
         return false;
     }
@@ -577,7 +586,9 @@ GcHeap* dvmHeapSourceStartup(size_t startSize, size_t maximumSize,
         goto fail;
     }
 
-    hs->targetUtilization = DEFAULT_HEAP_UTILIZATION;
+    hs->targetUtilization = gDvm.heapTargetUtilization * HEAP_UTILIZATION_MAX;
+    hs->minFree = gDvm.heapMinFree;
+    hs->maxFree = gDvm.heapMaxFree;
     hs->startSize = startSize;
     hs->maximumSize = maximumSize;
     hs->growthLimit = growthLimit;
@@ -588,6 +599,16 @@ GcHeap* dvmHeapSourceStartup(size_t startSize, size_t maximumSize,
     hs->hasGcThread = false;
     hs->heapBase = (char *)base;
     hs->heapLength = length;
+
+    if (hs->maxFree > hs->maximumSize) {
+      hs->maxFree = hs->maximumSize;
+    }
+    if (hs->minFree < CONCURRENT_START) {
+      hs->minFree = CONCURRENT_START;
+    } else if (hs->minFree > hs->maxFree) {
+      hs->minFree = hs->maxFree;
+    }
+
     if (!addInitialHeap(hs, msp, growthLimit)) {
         LOGE_HEAP("Can't add initial heap");
         goto fail;
@@ -1242,23 +1263,21 @@ void dvmSetTargetHeapUtilization(float newTarget)
 /*
  * Given the size of a live set, returns the ideal heap size given
  * the current target utilization and MIN/MAX values.
- *
- * targetUtilization is in the range 1..HEAP_UTILIZATION_MAX.
  */
-static size_t getUtilizationTarget(size_t liveSize, size_t targetUtilization)
+static size_t getUtilizationTarget(const HeapSource* hs, size_t liveSize)
 {
     /* Use the current target utilization ratio to determine the
      * ideal heap size based on the size of the live set.
      */
-    size_t targetSize = (liveSize / targetUtilization) * HEAP_UTILIZATION_MAX;
+    size_t targetSize = (liveSize / hs->targetUtilization) * HEAP_UTILIZATION_MAX;
 
     /* Cap the amount of free space, though, so we don't end up
      * with, e.g., 8MB of free space when the live set size hits 8MB.
      */
-    if (targetSize > liveSize + HEAP_IDEAL_FREE) {
-        targetSize = liveSize + HEAP_IDEAL_FREE;
-    } else if (targetSize < liveSize + HEAP_MIN_FREE) {
-        targetSize = liveSize + HEAP_MIN_FREE;
+    if (targetSize > liveSize + hs->maxFree) {
+        targetSize = liveSize + hs->maxFree;
+    } else if (targetSize < liveSize + hs->minFree) {
+        targetSize = liveSize + hs->minFree;
     }
     return targetSize;
 }
@@ -1285,8 +1304,7 @@ void dvmHeapSourceGrowForUtilization()
      * the current heap.
      */
     size_t currentHeapUsed = heap->bytesAllocated;
-    size_t targetHeapSize =
-            getUtilizationTarget(currentHeapUsed, hs->targetUtilization);
+    size_t targetHeapSize = getUtilizationTarget(hs, currentHeapUsed);
 
     /* The ideal size includes the old heaps; add overhead so that
      * it can be immediately subtracted again in setIdealFootprint().
index 268d880..eb739e5 100644 (file)
@@ -556,9 +556,7 @@ static void scanGrayObjects(GcMarkContext *ctx)
 {
     GcHeap *h = gDvm.gcHeap;
     const u1 *base, *limit, *ptr, *dirty;
-    size_t footprint;
 
-    footprint = dvmHeapSourceGetValue(HS_FOOTPRINT, NULL, 0);
     base = &h->cardTableBase[0];
     limit = dvmCardFromAddr((u1 *)dvmHeapSourceGetLimit());
     assert(limit <= &h->cardTableBase[h->cardTableLength]);