The "partial GC" code should not copy immune bits when doing a full GC.

Change-Id: I09f032e9a1dda585bd2475fc6d6f93f3ef1fc036
diff --git a/vm/alloc/HeapSource.c b/vm/alloc/HeapSource.c
index 98a9ba3..133c58a 100644
--- a/vm/alloc/HeapSource.c
+++ b/vm/alloc/HeapSource.c
@@ -667,7 +667,7 @@
     dvmHeapBitmapZero(&gHs->markBits);
 }
 
-void dvmMarkImmuneObjects(void)
+void dvmMarkImmuneObjects(const char *immuneLimit)
 {
     char *dst, *src;
     size_t i, offset, index, length;
@@ -676,21 +676,34 @@
      * Copy the contents of the live bit vector for immune object
      * range into the mark bit vector.
      */
+    /* The only values generated by dvmHeapSourceGetImmuneLimit() */
+    assert(immuneLimit == gHs->heaps[0].base ||
+           immuneLimit == NULL);
     assert(gHs->liveBits.base == gHs->markBits.base);
     assert(gHs->liveBits.bitsLen == gHs->markBits.bitsLen);
+    /* heap[0] is never immune */
+    assert(gHs->heaps[0].base >= immuneLimit);
+    assert(gHs->heaps[0].limit > immuneLimit);
+
     for (i = 1; i < gHs->numHeaps; ++i) {
-        /* Compute the number of words to copy in the bitmap. */
-        index = HB_OFFSET_TO_INDEX((uintptr_t)gHs->heaps[i].base - gHs->liveBits.base);
-        /* Compute the starting offset in the live and mark bits. */
-        src = (char *)(gHs->liveBits.bits + index);
-        dst = (char *)(gHs->markBits.bits + index);
-        /* Compute the number of bytes of the live bitmap to copy. */
-        length = HB_OFFSET_TO_BYTE_INDEX(gHs->heaps[i].limit - gHs->heaps[i].base);
-        /* Do the copy. */
-        memcpy(dst, src, length);
-        /* Make sure max points to the address of the highest set bit. */
-        if (gHs->markBits.max < (uintptr_t)gHs->heaps[i].limit) {
-            gHs->markBits.max = (uintptr_t)gHs->heaps[i].limit;
+        if (gHs->heaps[i].base < immuneLimit) {
+            assert(gHs->heaps[i].limit <= immuneLimit);
+            LOGV("Copying markBits for immune heap %d", i);
+            /* Compute the number of words to copy in the bitmap. */
+            index = HB_OFFSET_TO_INDEX(
+                (uintptr_t)gHs->heaps[i].base - gHs->liveBits.base);
+            /* Compute the starting offset in the live and mark bits. */
+            src = (char *)(gHs->liveBits.bits + index);
+            dst = (char *)(gHs->markBits.bits + index);
+            /* Compute the number of bytes of the live bitmap to copy. */
+            length = HB_OFFSET_TO_BYTE_INDEX(
+                gHs->heaps[i].limit - gHs->heaps[i].base);
+            /* Do the copy. */
+            memcpy(dst, src, length);
+            /* Make sure max points to the address of the highest set bit. */
+            if (gHs->markBits.max < (uintptr_t)gHs->heaps[i].limit) {
+                gHs->markBits.max = (uintptr_t)gHs->heaps[i].limit;
+            }
         }
     }
 }
diff --git a/vm/alloc/HeapSource.h b/vm/alloc/HeapSource.h
index 50f9872..772d38d 100644
--- a/vm/alloc/HeapSource.h
+++ b/vm/alloc/HeapSource.h
@@ -162,14 +162,16 @@
 void dvmHeapSourceSwapBitmaps(void);
 
 /*
- * Marks all objects outside the threatened region of the heap.
+ * Marks all objects inside the immune region of the heap. Addresses
+ * at or above this pointer are threatened, addresses below this
+ * pointer are immune.
  */
-void dvmMarkImmuneObjects(void);
+void dvmMarkImmuneObjects(const char *immuneLimit);
 
 /*
  * Returns a pointer that demarcates the threatened region of the
  * heap.  Addresses at or above this pointer are threatened, addresses
- * below this pointer are not.
+ * below this pointer are immune.
  */
 void *dvmHeapSourceGetImmuneLimit(GcMode mode);
 
diff --git a/vm/alloc/MarkSweep.c b/vm/alloc/MarkSweep.c
index d9860d9..558aa8b 100644
--- a/vm/alloc/MarkSweep.c
+++ b/vm/alloc/MarkSweep.c
@@ -272,7 +272,7 @@
     HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_STICKY_CLASS, 0);
 
     LOG_SCAN("immune objects");
-    dvmMarkImmuneObjects();
+    dvmMarkImmuneObjects(gcHeap->markContext.immuneLimit);
 
     LOG_SCAN("root class loader\n");
     dvmGcScanRootClassLoader();