auto import //branches/master/...@140412
diff --git a/vm/alloc/Alloc.h b/vm/alloc/Alloc.h
index 0489db7..8bf4520 100644
--- a/vm/alloc/Alloc.h
+++ b/vm/alloc/Alloc.h
@@ -133,7 +133,7 @@
}
#ifdef WITH_EXTRA_OBJECT_VALIDATION
if (!dvmIsValidObject(obj)) {
- //abort();
+ //dvmAbort();
dvmThrowException("Ljava/lang/InternalError;",
"VM detected invalid object ptr");
return false;
@@ -142,7 +142,7 @@
#ifndef NDEBUG
/* check for heap corruption */
if (obj->clazz == NULL || ((u4) obj->clazz) <= 65536) {
- abort();
+ dvmAbort();
dvmThrowException("Ljava/lang/InternalError;",
"VM detected invalid object class ptr");
return false;
diff --git a/vm/alloc/Heap.c b/vm/alloc/Heap.c
index 9ddc8be..6f3c7c1 100644
--- a/vm/alloc/Heap.c
+++ b/vm/alloc/Heap.c
@@ -174,6 +174,7 @@
if (self != NULL) {
oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
} else {
+ LOGI("ODD: waiting on heap lock, no self\n");
oldStatus = -1; // shut up gcc
}
@@ -831,6 +832,8 @@
if (gcHeap->hprofDumpOnGc) {
char nameBuf[128];
+ gcHeap->hprofResult = -1;
+
if (gcHeap->hprofFileName == NULL) {
/* no filename was provided; invent one */
sprintf(nameBuf, "/data/misc/heap-dump-tm%d-pid%d.hprof",
@@ -860,7 +863,10 @@
/* Set up the marking context.
*/
- dvmHeapBeginMarkStep();
+ if (!dvmHeapBeginMarkStep()) {
+ LOGE_HEAP("dvmHeapBeginMarkStep failed; aborting\n");
+ dvmAbort();
+ }
/* Mark the set of objects that are strongly reachable from the roots.
*/
@@ -982,7 +988,8 @@
if (gcHeap->hprofContext != NULL) {
hprofFinishHeapDump(gcHeap->hprofContext);
//TODO: write a HEAP_SUMMARY record
- hprofShutdown(gcHeap->hprofContext);
+ if (hprofShutdown(gcHeap->hprofContext))
+ gcHeap->hprofResult = 0; /* indicate success */
gcHeap->hprofContext = NULL;
}
#endif
@@ -1046,16 +1053,23 @@
* Perform garbage collection, writing heap information to the specified file.
*
* If "fileName" is NULL, a suitable name will be generated automatically.
+ *
+ * Returns 0 on success, or an error code on failure.
*/
-void hprofDumpHeap(const char* fileName)
+int hprofDumpHeap(const char* fileName)
{
+ int result;
+
dvmLockMutex(&gDvm.gcHeapLock);
gDvm.gcHeap->hprofDumpOnGc = true;
gDvm.gcHeap->hprofFileName = fileName;
dvmCollectGarbageInternal(false);
+ result = gDvm.gcHeap->hprofResult;
dvmUnlockMutex(&gDvm.gcHeapLock);
+
+ return result;
}
void dvmHeapSetHprofGcScanState(hprof_heap_tag_t state, u4 threadSerialNumber)
diff --git a/vm/alloc/HeapInternal.h b/vm/alloc/HeapInternal.h
index 7851983..fafb87a 100644
--- a/vm/alloc/HeapInternal.h
+++ b/vm/alloc/HeapInternal.h
@@ -189,6 +189,7 @@
bool hprofDumpOnGc;
const char* hprofFileName;
hprof_context_t *hprofContext;
+ int hprofResult;
#endif
};
diff --git a/vm/alloc/HeapWorker.c b/vm/alloc/HeapWorker.c
index 0244cca..b4a2d0e 100644
--- a/vm/alloc/HeapWorker.c
+++ b/vm/alloc/HeapWorker.c
@@ -111,7 +111,7 @@
}
/* Make sure that the HeapWorker thread hasn't spent an inordinate
- * amount of time inside interpreted a finalizer.
+ * amount of time inside a finalizer.
*
* Aborts the VM if the thread appears to be wedged.
*
@@ -132,12 +132,16 @@
u8 nowCpu = dvmGetOtherThreadCpuTimeUsec(gDvm.heapWorkerHandle);
u8 deltaCpu = nowCpu - heapWorkerInterpCpuStartTime;
- if (delta > HEAP_WORKER_WATCHDOG_TIMEOUT && gDvm.debuggerActive) {
+ if (delta > HEAP_WORKER_WATCHDOG_TIMEOUT &&
+ (gDvm.debuggerActive || gDvm.nativeDebuggerActive))
+ {
/*
* Debugger suspension can block the thread indefinitely. For
* best results we should reset this explicitly whenever the
- * HeapWorker thread is resumed. Ignoring the yelp isn't
- * quite right but will do for a quick fix.
+ * HeapWorker thread is resumed. Unfortunately this is also
+ * affected by native debuggers, and we have no visibility
+ * into how they're manipulating us. So, we ignore the
+ * watchdog and just reset the timer.
*/
LOGI("Debugger is attached -- suppressing HeapWorker watchdog\n");
heapWorkerInterpStartTime = now; /* reset timer */
diff --git a/vm/alloc/MarkSweep.c b/vm/alloc/MarkSweep.c
index a0601d7..0905bce 100644
--- a/vm/alloc/MarkSweep.c
+++ b/vm/alloc/MarkSweep.c
@@ -22,6 +22,7 @@
#include <limits.h> // for ULONG_MAX
#include <sys/mman.h> // for madvise(), mmap()
#include <cutils/ashmem.h>
+#include <errno.h>
#define GC_DEBUG_PARANOID 2
#define GC_DEBUG_BASIC 1
@@ -92,7 +93,7 @@
{
const Object **limit;
size_t size;
- int fd;
+ int fd, err;
/* Create a stack big enough for the worst possible case,
* where the heap is perfectly full of the smallest object.
@@ -104,14 +105,17 @@
size = ALIGN_UP_TO_PAGE_SIZE(size);
fd = ashmem_create_region("dalvik-heap-markstack", size);
if (fd < 0) {
- LOGE_GC("Could not create %d-byte ashmem mark stack\n", size);
+ LOGE_GC("Could not create %d-byte ashmem mark stack: %s\n",
+ size, strerror(errno));
return false;
}
limit = (const Object **)mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);
+ err = errno;
close(fd);
if (limit == MAP_FAILED) {
- LOGE_GC("Could not mmap %d-byte ashmem mark stack\n", size);
+ LOGE_GC("Could not mmap %d-byte ashmem mark stack: %s\n",
+ size, strerror(err));
return false;
}