am 14da4cc: AI 147896: Some more fixes for tests that failed in

Merge commit '14da4ccdd69d8db7cef00b2ae5aabd32b6e1bdb4' into donut

* commit '14da4ccdd69d8db7cef00b2ae5aabd32b6e1bdb4':
  AI 147896: Some more fixes for tests that failed in
diff --git a/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java b/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java
index 2d09edd..d9f11ce 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -153,6 +153,12 @@
         int bufferSize, int flags);
 
     /**
+     * Determine whether method tracing is currently active.
+     * @hide
+     */
+    public static native boolean isMethodTracingActive();
+
+    /**
      * Stops method tracing.
      */
     public static native void stopMethodTracing();
diff --git a/libcore/luni-kernel/src/main/java/java/lang/ClassLoader.java b/libcore/luni-kernel/src/main/java/java/lang/ClassLoader.java
index 822fade..3c2e911 100644
--- a/libcore/luni-kernel/src/main/java/java/lang/ClassLoader.java
+++ b/libcore/luni-kernel/src/main/java/java/lang/ClassLoader.java
@@ -634,7 +634,7 @@
      */
     final boolean isAncestorOf(ClassLoader child) {
         for (ClassLoader current = child; current != null;
-                current = child.parent) {
+                current = current.parent) {
             if (current == this) {
                 return true;
             }
diff --git a/libcore/luni/src/main/native/java_net_InetAddress.cpp b/libcore/luni/src/main/native/java_net_InetAddress.cpp
index cf026bc..0eb2753 100644
--- a/libcore/luni/src/main/native/java_net_InetAddress.cpp
+++ b/libcore/luni/src/main/native/java_net_InetAddress.cpp
@@ -258,14 +258,17 @@
             memset(sin, 0, sizeof(struct sockaddr_in));
             sin->sin_family = AF_INET;
             memcpy(&sin->sin_addr.s_addr, rawAddress, 4);
+            env->ReleaseByteArrayElements(javaAddress, rawAddress, JNI_ABORT);
             break;
         case 16:
             socklen = sizeof(struct sockaddr_in6);
             memset(sin6, 0, sizeof(struct sockaddr_in6));
             sin6->sin6_family = AF_INET6;
             memcpy(&sin6->sin6_addr.s6_addr, rawAddress, 4);
+            env->ReleaseByteArrayElements(javaAddress, rawAddress, JNI_ABORT);
             break;
         default:
+            env->ReleaseByteArrayElements(javaAddress, rawAddress, JNI_ABORT);
             jniThrowException(env, "java/net/UnknownHostException",
                                    "Invalid address length");
             return NULL;
diff --git a/libcore/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp b/libcore/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
index de01295..f79c019 100755
--- a/libcore/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
+++ b/libcore/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
@@ -3084,7 +3084,12 @@
             if ((anOption >> 16) & BROKEN_MULTICAST_IF) {
                 return;
             }
-            result = setsockopt(handle, IPPROTO_IP, IP_MULTICAST_IF, &sockVal, sockSize);
+            struct ip_mreqn mcast_req;
+            memset(&mcast_req, 0, sizeof(mcast_req));
+            memcpy(&(mcast_req.imr_address), &(sockVal.sin_addr),
+                   sizeof(struct in_addr));
+            result = setsockopt(handle, IPPROTO_IP, IP_MULTICAST_IF,
+                                &mcast_req, sizeof(mcast_req));
             if (0 != result) {
                 throwSocketException(env, convertError(errno));
                 return;
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
index e985908..36282e1 100644
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
@@ -146,10 +146,10 @@
         ArrayList<String> array = new ArrayList<String>();
 
         if ((ssl_op_no & SSL_OP_NO_SSLv3) == 0x00000000L) {
-            array.add(supportedProtocols[1]);
+            array.add(supportedProtocols[0]);
         }
         if ((ssl_op_no & SSL_OP_NO_TLSv1) == 0x00000000L) {
-            array.add(supportedProtocols[2]);
+            array.add(supportedProtocols[1]);
         }
         return array.toArray(new String[array.size()]);
     }
diff --git a/vm/Android.mk b/vm/Android.mk
index 25a03fd..f3eed3f 100644
--- a/vm/Android.mk
+++ b/vm/Android.mk
@@ -41,42 +41,46 @@
   LOCAL_CFLAGS += -DWITH_MONITOR_TRACKING
 endif
 
-#
-# "Debug" profile:
-# - debugger enabled
-# - profiling enabled
-# - tracked-reference verification enabled
-# - allocation limits enabled
-# - GDB helpers enabled
-# - LOGV
-# - assert()  (NDEBUG is handled in the build system)
-#
-ifeq ($(TARGET_BUILD_TYPE),debug)
-LOCAL_CFLAGS += -DWITH_INSTR_CHECKS -DWITH_EXTRA_OBJECT_VALIDATION
-LOCAL_CFLAGS += -DWITH_TRACKREF_CHECKS
-LOCAL_CFLAGS += -DWITH_ALLOC_LIMITS
-#LOCAL_CFLAGS += -DCHECK_MUTEX
-#LOCAL_CFLAGS += -DPROFILE_FIELD_ACCESS
-LOCAL_CFLAGS += -DDVM_SHOW_EXCEPTION=3
-# add some extra stuff to make it easier to examine with GDB
-LOCAL_CFLAGS += -DEASY_GDB
+# Make DEBUG_DALVIK_VM default to true when building the simulator.
+ifeq ($(TARGET_SIMULATOR),true)
+  ifeq ($(strip $(DEBUG_DALVIK_VM)),)
+    DEBUG_DALVIK_VM := true
+  endif
 endif
 
-
-#
-# "Performance" profile:
-# - all development features disabled
-# - compiler optimizations enabled (redundant for "release" builds)
-# - (debugging and profiling still enabled)
-#
-ifeq ($(TARGET_BUILD_TYPE),release)
-#LOCAL_CFLAGS += -DNDEBUG -DLOG_NDEBUG=1
-# "-O2" is redundant for device (release) but useful for sim (debug)
-#LOCAL_CFLAGS += -O2 -Winline
-LOCAL_CFLAGS += -DDVM_SHOW_EXCEPTION=1
-# if you want to try with assertions on the device, add:
-#LOCAL_CFLAGS += -UNDEBUG -DDEBUG=1 -DLOG_NDEBUG=1 -DWITH_DALVIK_ASSERT
-endif
+ifeq ($(strip $(DEBUG_DALVIK_VM)),true)
+  #
+  # "Debug" profile:
+  # - debugger enabled
+  # - profiling enabled
+  # - tracked-reference verification enabled
+  # - allocation limits enabled
+  # - GDB helpers enabled
+  # - LOGV
+  # - assert()  (NDEBUG is handled in the build system)
+  #
+  LOCAL_CFLAGS += -DWITH_INSTR_CHECKS -DWITH_EXTRA_OBJECT_VALIDATION
+  LOCAL_CFLAGS += -DWITH_TRACKREF_CHECKS
+  LOCAL_CFLAGS += -DWITH_ALLOC_LIMITS
+  #LOCAL_CFLAGS += -DCHECK_MUTEX
+  #LOCAL_CFLAGS += -DPROFILE_FIELD_ACCESS
+  LOCAL_CFLAGS += -DDVM_SHOW_EXCEPTION=3
+  # add some extra stuff to make it easier to examine with GDB
+  LOCAL_CFLAGS += -DEASY_GDB
+else  # !DALVIK_VM_DEBUG
+  #
+  # "Performance" profile:
+  # - all development features disabled
+  # - compiler optimizations enabled (redundant for "release" builds)
+  # - (debugging and profiling still enabled)
+  #
+  #LOCAL_CFLAGS += -DNDEBUG -DLOG_NDEBUG=1
+  # "-O2" is redundant for device (release) but useful for sim (debug)
+  #LOCAL_CFLAGS += -O2 -Winline
+  LOCAL_CFLAGS += -DDVM_SHOW_EXCEPTION=1
+  # if you want to try with assertions on the device, add:
+  #LOCAL_CFLAGS += -UNDEBUG -DDEBUG=1 -DLOG_NDEBUG=1 -DWITH_DALVIK_ASSERT
+endif  # !DALVIK_VM_DEBUG
 
 # bug hunting: checksum and verify interpreted stack when making JNI calls
 #LOCAL_CFLAGS += -DWITH_JNI_STACK_CHECK
diff --git a/vm/Profile.c b/vm/Profile.c
index 9b47885..f7e6c17 100644
--- a/vm/Profile.c
+++ b/vm/Profile.c
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 /*
  * Android's method call profiling goodies.
  */
@@ -388,6 +389,7 @@
     return;
 
 fail:
+    updateActiveProfilers(-1);
     if (state->traceFile != NULL) {
         fclose(state->traceFile);
         state->traceFile = NULL;
@@ -448,6 +450,15 @@
 }
 
 /*
+ * Returns "true" if method tracing is currently active.
+ */
+bool dvmIsMethodTraceActive(void)
+{
+    const MethodTraceState* state = &gDvm.methodTrace;
+    return state->traceEnabled;
+}
+
+/*
  * Stop method tracing.  We write the buffer to disk and generate a key
  * file so we can interpret it.
  */
@@ -464,6 +475,7 @@
 
     if (!state->traceEnabled) {
         /* somebody already stopped it, or it was never started */
+        LOGD("TRACE stop requested, but not running\n");
         dvmUnlockMutex(&state->startStopLock);
         return;
     } else {
diff --git a/vm/Profile.h b/vm/Profile.h
index f762974..cdaf027 100644
--- a/vm/Profile.h
+++ b/vm/Profile.h
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 /*
  * Android's method call profiling goodies.
  */
@@ -96,6 +97,7 @@
  * Start/stop method tracing.
  */
 void dvmMethodTraceStart(const char* traceFileName, int bufferSize, int flags);
+bool dvmIsMethodTraceActive(void);
 void dvmMethodTraceStop(void);
 
 /*
diff --git a/vm/Thread.c b/vm/Thread.c
index 42b527e..680755c 100644
--- a/vm/Thread.c
+++ b/vm/Thread.c
@@ -43,6 +43,9 @@
 #undef __KERNEL__
 #endif
 
+// Change this to enable logging on cgroup errors
+#define ENABLE_CGROUP_ERR_LOGGING 0
+
 // change this to LOGV/LOGD to debug thread activity
 #define LOG_THREAD  LOGVV
 
@@ -2745,6 +2748,41 @@
 };
 
 /*
+ * Change the scheduler cgroup of a pid
+ */
+int dvmChangeThreadSchedulerGroup(const char *cgroup)
+{
+#ifdef HAVE_ANDROID_OS
+    FILE *fp;
+    char path[255];
+    int rc;
+
+    sprintf(path, "/dev/cpuctl/%s/tasks", (cgroup ? cgroup : ""));
+
+    if (!(fp = fopen(path, "w"))) {
+#if ENABLE_CGROUP_ERR_LOGGING
+        LOGW("Unable to open %s (%s)\n", path, strerror(errno));
+#endif
+        return -errno;
+    }
+
+    rc = fprintf(fp, "0");
+    fclose(fp);
+
+    if (rc < 0) {
+#if ENABLE_CGROUP_ERR_LOGGING
+        LOGW("Unable to move pid %d to cgroup %s (%s)\n", getpid(),
+             (cgroup ? cgroup : "<default>"), strerror(errno));
+#endif
+    }
+
+    return (rc < 0) ? errno : 0;
+#else // HAVE_ANDROID_OS
+    return 0;
+#endif
+}
+
+/*
  * Change the priority of a system thread to match that of the Thread object.
  *
  * We map a priority value from 1-10 to Linux "nice" values, where lower
@@ -2761,6 +2799,12 @@
     }
     newNice = kNiceValues[newPriority-1];
 
+    if (newPriority == ANDROID_PRIORITY_BACKGROUND) {
+        dvmChangeThreadSchedulerGroup("bg_non_interactive");
+    } else if (getpriority(PRIO_PROCESS, pid) == ANDROID_PRIORITY_BACKGROUND) {
+        dvmChangeThreadSchedulerGroup(NULL);
+    }
+
     if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
         char* str = dvmGetThreadName(thread);
         LOGI("setPriority(%d) '%s' to prio=%d(n=%d) failed: %s\n",
diff --git a/vm/Thread.h b/vm/Thread.h
index b64f9b7..86a7845 100644
--- a/vm/Thread.h
+++ b/vm/Thread.h
@@ -398,6 +398,11 @@
 INLINE void dvmSetThreadJNIEnv(Thread* self, JNIEnv* env) { self->jniEnv = env;}
 
 /*
+ * Change the scheduler group of the current process
+ */
+int dvmChangeThreadSchedulerGroup(const char *group);
+
+/*
  * Update the priority value of the underlying pthread.
  */
 void dvmChangeThreadPriority(Thread* thread, int newPriority);
diff --git a/vm/alloc/Heap.c b/vm/alloc/Heap.c
index 9ddc8be..09954ea 100644
--- a/vm/alloc/Heap.c
+++ b/vm/alloc/Heap.c
@@ -774,6 +774,11 @@
         /* Current value is numerically greater than "normal", which
          * in backward UNIX terms means lower priority.
          */
+
+        if (priorityResult == ANDROID_PRIORITY_BACKGROUND) {
+            dvmChangeThreadSchedulerGroup(NULL);
+        }
+
         if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL) != 0) {
             LOGI_HEAP("Unable to elevate priority from %d to %d\n",
                 priorityResult, ANDROID_PRIORITY_NORMAL);
@@ -831,6 +836,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",
@@ -982,7 +989,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
@@ -1016,6 +1024,10 @@
         } else {
             LOGD_HEAP("Reset priority to %d\n", oldThreadPriority);
         }
+
+        if (oldThreadPriority == ANDROID_PRIORITY_BACKGROUND) {
+            dvmChangeThreadSchedulerGroup("bg_non_interactive");
+        }
     }
     gcElapsedTime = (dvmGetRelativeTimeUsec() - gcHeap->gcStartTime) / 1000;
     if (gcElapsedTime < 10000) {
@@ -1046,16 +1058,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/hprof/Hprof.c b/vm/hprof/Hprof.c
index 66b46f4..2e6f7c9 100644
--- a/vm/hprof/Hprof.c
+++ b/vm/hprof/Hprof.c
@@ -111,7 +111,10 @@
     }
 }
 
-void
+/*
+ * Finish up the hprof dump.  Returns true on success.
+ */
+bool
 hprofShutdown(hprof_context_t *ctx)
 {
     FILE *tempFp = ctx->fp;
@@ -131,7 +134,7 @@
         fclose(tempFp);
         free(ctx->fileName);
         free(ctx);
-        return;
+        return false;
     }
     hprofContextInit(ctx, ctx->fileName, fp, true);
 
@@ -179,4 +182,5 @@
 
     /* throw out a log message for the benefit of "runhat" */
     LOGI("hprof: heap dump completed, temp file removed\n");
+    return true;
 }
diff --git a/vm/hprof/Hprof.h b/vm/hprof/Hprof.h
index e0e2d4b..696b0a7 100644
--- a/vm/hprof/Hprof.h
+++ b/vm/hprof/Hprof.h
@@ -235,7 +235,7 @@
  */
 
 hprof_context_t *hprofStartup(const char *outputFileName);
-void hprofShutdown(hprof_context_t *ctx);
+bool hprofShutdown(hprof_context_t *ctx);
 
 /*
  * Heap.c functions
@@ -244,7 +244,7 @@
  * the heap implementation; these functions require heap knowledge,
  * so they are implemented in Heap.c.
  */
-void hprofDumpHeap(const char* fileName);
+int hprofDumpHeap(const char* fileName);
 void dvmHeapSetHprofGcScanState(hprof_heap_tag_t state, u4 threadSerialNumber);
 
 #endif  // _DALVIK_HPROF_HPROF
diff --git a/vm/mterp/armv4/OP_AGET_WIDE.S b/vm/mterp/armv4t/OP_AGET_WIDE.S
similarity index 100%
rename from vm/mterp/armv4/OP_AGET_WIDE.S
rename to vm/mterp/armv4t/OP_AGET_WIDE.S
diff --git a/vm/mterp/armv4/OP_APUT_WIDE.S b/vm/mterp/armv4t/OP_APUT_WIDE.S
similarity index 100%
rename from vm/mterp/armv4/OP_APUT_WIDE.S
rename to vm/mterp/armv4t/OP_APUT_WIDE.S
diff --git a/vm/mterp/armv4/OP_IGET_WIDE.S b/vm/mterp/armv4t/OP_IGET_WIDE.S
similarity index 100%
rename from vm/mterp/armv4/OP_IGET_WIDE.S
rename to vm/mterp/armv4t/OP_IGET_WIDE.S
diff --git a/vm/mterp/armv4/OP_IGET_WIDE_QUICK.S b/vm/mterp/armv4t/OP_IGET_WIDE_QUICK.S
similarity index 100%
rename from vm/mterp/armv4/OP_IGET_WIDE_QUICK.S
rename to vm/mterp/armv4t/OP_IGET_WIDE_QUICK.S
diff --git a/vm/mterp/armv4/OP_IPUT_WIDE.S b/vm/mterp/armv4t/OP_IPUT_WIDE.S
similarity index 100%
rename from vm/mterp/armv4/OP_IPUT_WIDE.S
rename to vm/mterp/armv4t/OP_IPUT_WIDE.S
diff --git a/vm/mterp/armv4/OP_IPUT_WIDE_QUICK.S b/vm/mterp/armv4t/OP_IPUT_WIDE_QUICK.S
similarity index 100%
rename from vm/mterp/armv4/OP_IPUT_WIDE_QUICK.S
rename to vm/mterp/armv4t/OP_IPUT_WIDE_QUICK.S
diff --git a/vm/mterp/armv4/OP_SGET_WIDE.S b/vm/mterp/armv4t/OP_SGET_WIDE.S
similarity index 100%
rename from vm/mterp/armv4/OP_SGET_WIDE.S
rename to vm/mterp/armv4t/OP_SGET_WIDE.S
diff --git a/vm/mterp/armv4/OP_SPUT_WIDE.S b/vm/mterp/armv4t/OP_SPUT_WIDE.S
similarity index 100%
rename from vm/mterp/armv4/OP_SPUT_WIDE.S
rename to vm/mterp/armv4t/OP_SPUT_WIDE.S
diff --git a/vm/mterp/armv4/platform.S b/vm/mterp/armv4t/platform.S
similarity index 100%
rename from vm/mterp/armv4/platform.S
rename to vm/mterp/armv4t/platform.S
diff --git a/vm/mterp/config-armv4 b/vm/mterp/config-armv4t
similarity index 80%
rename from vm/mterp/config-armv4
rename to vm/mterp/config-armv4t
index 4f64c11..01eddb2 100644
--- a/vm/mterp/config-armv4
+++ b/vm/mterp/config-armv4t
@@ -13,8 +13,8 @@
 # limitations under the License.
 
 #
-# Configuration for ARMv4 architecture targets.  This is largely pulled
-# from the ARMv5 sources, but we can't use certain instructions introduced
+# Configuration for ARMv4T architecture targets.  This is largely pulled
+# from the ARMv5TE sources, but we can't use certain instructions introduced
 # in ARMv5 (BLX, CLZ, LDC2, MCR2, MRC2, STC2) or ARMv5TE (PLD, LDRD, MCRR,
 # MRRC, QADD, QDADD, QDSUB, QSUB, SMLA, SMLAL, SMLAW, SMUL, SMULW, STRD).
 #
@@ -42,14 +42,14 @@
 
 # opcode list; argument to op-start is default directory
 op-start armv5te
-    op OP_AGET_WIDE armv4
-    op OP_APUT_WIDE armv4
-    op OP_IGET_WIDE armv4
-    op OP_IGET_WIDE_QUICK armv4
-    op OP_IPUT_WIDE armv4
-    op OP_IPUT_WIDE_QUICK armv4
-    op OP_SGET_WIDE armv4
-    op OP_SPUT_WIDE armv4
+    op OP_AGET_WIDE armv4t
+    op OP_APUT_WIDE armv4t
+    op OP_IGET_WIDE armv4t
+    op OP_IGET_WIDE_QUICK armv4t
+    op OP_IPUT_WIDE armv4t
+    op OP_IPUT_WIDE_QUICK armv4t
+    op OP_SGET_WIDE armv4t
+    op OP_SPUT_WIDE armv4t
 op-end
 
 # "helper" code for C; include if you use any of the C stubs (this generates
diff --git a/vm/mterp/out/InterpAsm-armv4.S b/vm/mterp/out/InterpAsm-armv4t.S
similarity index 99%
rename from vm/mterp/out/InterpAsm-armv4.S
rename to vm/mterp/out/InterpAsm-armv4t.S
index 3de7aea..d60571b 100644
--- a/vm/mterp/out/InterpAsm-armv4.S
+++ b/vm/mterp/out/InterpAsm-armv4t.S
@@ -1,5 +1,5 @@
 /*
- * This file was generated automatically by gen-mterp.py for 'armv4'.
+ * This file was generated automatically by gen-mterp.py for 'armv4t'.
  *
  * --> DO NOT EDIT <--
  */
@@ -1855,7 +1855,7 @@
 /* ------------------------------ */
     .balign 64
 .L_OP_AGET_WIDE: /* 0x45 */
-/* File: armv4/OP_AGET_WIDE.S */
+/* File: armv4t/OP_AGET_WIDE.S */
     /*
      * Array get, 64 bits.  vAA <- vBB[vCC].
      *
@@ -2078,7 +2078,7 @@
 /* ------------------------------ */
     .balign 64
 .L_OP_APUT_WIDE: /* 0x4c */
-/* File: armv4/OP_APUT_WIDE.S */
+/* File: armv4t/OP_APUT_WIDE.S */
     /*
      * Array put, 64 bits.  vBB[vCC] <- vAA.
      */
@@ -2289,7 +2289,7 @@
 /* ------------------------------ */
     .balign 64
 .L_OP_IGET_WIDE: /* 0x53 */
-/* File: armv4/OP_IGET_WIDE.S */
+/* File: armv4t/OP_IGET_WIDE.S */
     /*
      * Wide 32-bit instance field get.
      */
@@ -2483,7 +2483,7 @@
 /* ------------------------------ */
     .balign 64
 .L_OP_IPUT_WIDE: /* 0x5a */
-/* File: armv4/OP_IPUT_WIDE.S */
+/* File: armv4t/OP_IPUT_WIDE.S */
     /* iput-wide vA, vB, field@CCCC */
     mov     r0, rINST, lsr #12          @ r0<- B
     ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
@@ -2672,7 +2672,7 @@
 /* ------------------------------ */
     .balign 64
 .L_OP_SGET_WIDE: /* 0x61 */
-/* File: armv4/OP_SGET_WIDE.S */
+/* File: armv4t/OP_SGET_WIDE.S */
     /*
      * 64-bit SGET handler.
      */
@@ -2850,7 +2850,7 @@
 /* ------------------------------ */
     .balign 64
 .L_OP_SPUT_WIDE: /* 0x68 */
-/* File: armv4/OP_SPUT_WIDE.S */
+/* File: armv4t/OP_SPUT_WIDE.S */
     /*
      * 64-bit SPUT handler.
      */
@@ -7522,7 +7522,7 @@
 /* ------------------------------ */
     .balign 64
 .L_OP_IGET_WIDE_QUICK: /* 0xf3 */
-/* File: armv4/OP_IGET_WIDE_QUICK.S */
+/* File: armv4t/OP_IGET_WIDE_QUICK.S */
     /* iget-wide-quick vA, vB, offset@CCCC */
     mov     r2, rINST, lsr #12          @ r2<- B
     GET_VREG(r3, r2)                    @ r3<- object we're operating on
@@ -7585,7 +7585,7 @@
 /* ------------------------------ */
     .balign 64
 .L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
-/* File: armv4/OP_IPUT_WIDE_QUICK.S */
+/* File: armv4t/OP_IPUT_WIDE_QUICK.S */
     /* iput-wide-quick vA, vB, offset@CCCC */
     mov     r0, rINST, lsr #8           @ r0<- A(+)
     mov     r1, rINST, lsr #12          @ r1<- B
diff --git a/vm/mterp/out/InterpC-armv4.c b/vm/mterp/out/InterpC-armv4t.c
similarity index 99%
rename from vm/mterp/out/InterpC-armv4.c
rename to vm/mterp/out/InterpC-armv4t.c
index 2fcdcab..7f101a9 100644
--- a/vm/mterp/out/InterpC-armv4.c
+++ b/vm/mterp/out/InterpC-armv4t.c
@@ -1,5 +1,5 @@
 /*
- * This file was generated automatically by gen-mterp.py for 'armv4'.
+ * This file was generated automatically by gen-mterp.py for 'armv4t'.
  *
  * --> DO NOT EDIT <--
  */
diff --git a/vm/mterp/rebuild.sh b/vm/mterp/rebuild.sh
index d1c6983..1380f69 100755
--- a/vm/mterp/rebuild.sh
+++ b/vm/mterp/rebuild.sh
@@ -19,7 +19,7 @@
 # generated as part of the build.
 #
 set -e
-for arch in portstd portdbg allstubs armv4 armv5te x86; do TARGET_ARCH_EXT=$arch make -f Makefile-mterp; done
+for arch in portstd portdbg allstubs armv4t armv5te x86; do TARGET_ARCH_EXT=$arch make -f Makefile-mterp; done
 
 # These aren't actually used, so just go ahead and remove them.  The correct
 # approach is to prevent them from being generated in the first place, but
diff --git a/vm/native/dalvik_system_VMDebug.c b/vm/native/dalvik_system_VMDebug.c
index 9eccb76..ec6d92e 100644
--- a/vm/native/dalvik_system_VMDebug.c
+++ b/vm/native/dalvik_system_VMDebug.c
@@ -244,6 +244,23 @@
 }
 
 /*
+ * static boolean isMethodTracingActive()
+ *
+ * Determine whether method tracing is currently active.
+ */
+static void Dalvik_dalvik_system_VMDebug_isMethodTracingActive(const u4* args,
+    JValue* pResult)
+{
+    UNUSED_PARAMETER(args);
+
+#ifdef WITH_PROFILER
+    RETURN_BOOLEAN(dvmIsMethodTraceActive());
+#else
+    RETURN_BOOLEAN(false);
+#endif
+}
+
+/*
  * static void stopMethodTracing()
  *
  * Stop method tracing.
@@ -527,6 +544,7 @@
 #ifdef WITH_HPROF
     StringObject* fileNameStr = (StringObject*) args[0];
     char* fileName;
+    int result;
 
     if (fileNameStr == NULL) {
         dvmThrowException("Ljava/lang/NullPointerException;", NULL);
@@ -540,8 +558,15 @@
         RETURN_VOID();
     }
 
-    hprofDumpHeap(fileName);
+    result = hprofDumpHeap(fileName);
     free(fileName);
+
+    if (result != 0) {
+        /* ideally we'd throw something more specific based on actual failure */
+        dvmThrowException("Ljava/lang/RuntimeException;",
+            "Failure during heap dump -- check log output for details");
+        RETURN_VOID();
+    }
 #else
     dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL);
 #endif
@@ -562,6 +587,8 @@
         Dalvik_dalvik_system_VMDebug_stopAllocCounting },
     { "startMethodTracing",         "(Ljava/lang/String;II)V",
         Dalvik_dalvik_system_VMDebug_startMethodTracing },
+    { "isMethodTracingActive",      "()Z",
+        Dalvik_dalvik_system_VMDebug_isMethodTracingActive },
     { "stopMethodTracing",          "()V",
         Dalvik_dalvik_system_VMDebug_stopMethodTracing },
     { "startEmulatorTracing",       "()V",