Jit: Start the Jit when framework signals on first screen draw

Cleanup of delayed start - introduce dvmRelativeCondWait in Sync.c.
Additionally, support for deadman timer to start Jit when no screen draws
happen, and to start immediately when running stand-alone.

Fixed bug in assert variant of libdvm - recent MONITOR change had neglected
to add a new type of exit to the exit stats.
diff --git a/vm/Globals.h b/vm/Globals.h
index 5642e6f..5e332dd 100644
--- a/vm/Globals.h
+++ b/vm/Globals.h
@@ -655,6 +655,7 @@
     kInlineCacheMiss = 0,
     kCallsiteInterpreted,
     kSwitchOverflow,
+    kHeavyweightMonitor,
     kNoChainExitLast,
 } NoChainExits;
 
@@ -787,6 +788,9 @@
     volatile bool selfVerificationSpin;
 #endif
 
+    /* Framework or stand-alone? */
+    bool runningInAndroidFramework;
+
     /* Place arrays at the end to ease the display in gdb sessions */
 
     /* Work order queue for compilations */
diff --git a/vm/Init.c b/vm/Init.c
index 5d49986..003e7c1 100644
--- a/vm/Init.c
+++ b/vm/Init.c
@@ -844,6 +844,9 @@
             gDvm.noQuitHandler = true;
         } else if (strcmp(argv[i], "-Xzygote") == 0) {
             gDvm.zygote = true;
+#if defined(WITH_JIT)
+            gDvmJit.runningInAndroidFramework = true;
+#endif
         } else if (strncmp(argv[i], "-Xdexopt:", 9) == 0) {
             if (strcmp(argv[i] + 9, "none") == 0)
                 gDvm.dexOptMode = OPTIMIZE_MODE_NONE;
diff --git a/vm/Sync.c b/vm/Sync.c
index 5340d86..595f9db 100644
--- a/vm/Sync.c
+++ b/vm/Sync.c
@@ -504,7 +504,7 @@
 /*
  * Converts the given relative waiting time into an absolute time.
  */
-void dvmAbsoluteTime(s8 msec, s4 nsec, struct timespec *ts)
+void absoluteTime(s8 msec, s4 nsec, struct timespec *ts)
 {
     s8 endSec;
 
@@ -533,6 +533,21 @@
     }
 }
 
+int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
+                        s8 msec, s4 nsec)
+{
+    int ret;
+    struct timespec ts;
+    absoluteTime(msec, nsec, &ts);
+#if defined(HAVE_TIMEDWAIT_MONOTONIC)
+    ret = pthread_cond_timedwait_monotonic(cond, mutex, &ts);
+#else
+    ret = pthread_cond_timedwait(cond, mutex, &ts);
+#endif
+    assert(ret == 0 || ret == ETIMEDOUT);
+    return ret;
+}
+
 /*
  * Wait on a monitor until timeout, interrupt, or notification.  Used for
  * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join().
@@ -589,7 +604,7 @@
     if (msec == 0 && nsec == 0) {
         timed = false;
     } else {
-        dvmAbsoluteTime(msec, nsec, &ts);
+        absoluteTime(msec, nsec, &ts);
         timed = true;
     }
 
diff --git a/vm/Sync.h b/vm/Sync.h
index 0832608..b273538 100644
--- a/vm/Sync.h
+++ b/vm/Sync.h
@@ -146,9 +146,10 @@
 bool dvmHoldsLock(struct Thread* thread, struct Object* obj);
 
 /*
- * Converts the given relative time into an absolute time
+ * Relative timed wait on condition
  */
-void dvmAbsoluteTime(s8 msec, s4 nsec, struct timespec *ts);
+int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
+                         s8 msec, s4 nsec);
 
 /*
  * Debug.
diff --git a/vm/compiler/Compiler.c b/vm/compiler/Compiler.c
index c16e78c..2fafd4e 100644
--- a/vm/compiler/Compiler.c
+++ b/vm/compiler/Compiler.c
@@ -378,33 +378,23 @@
     dvmChangeStatus(NULL, THREAD_VMWAIT);
 
     /*
-     * Wait a little before recieving translation requests on the assumption
-     * that process start-up code isn't worth compiling.
+     * If we're not running stand-alone, wait a little before
+     * recieving translation requests on the assumption that process start
+     * up code isn't worth compiling.  We'll resume when the framework
+     * signals us that the first screen draw has happened, or the timer
+     * below expires (to catch daemons).
      */
-
-    dvmLockMutex(&gDvmJit.compilerLock);
-    /*
-     * TUNING: once framework is calling VMRuntime.startJitCompilation,
-     * experiment with the delay time (and perhaps have target-dependent
-     * values?
-     */
-    dvmAbsoluteTime(1000, 0, &ts);
-#if defined(HAVE_TIMEDWAIT_MONOTONIC)
-    ret = pthread_cond_timedwait_monotonic(&gDvmJit.compilerQueueActivity,
-                                           &gDvmJit.compilerLock, &ts);
-#else
-    ret = pthread_cond_timedwait(&gDvmJit.compilerQueueActivity,
-                                 &gDvmJit.compilerLock, &ts);
-#endif
-    assert(ret == 0 || ret == ETIMEDOUT);
-
-    if (gDvmJit.haltCompilerThread) {
+    if (gDvmJit.runningInAndroidFramework) {
+        dvmLockMutex(&gDvmJit.compilerLock);
+        // TUNING: experiment with the delay & perhaps make it target-specific
+        dvmRelativeCondWait(&gDvmJit.compilerQueueActivity,
+                             &gDvmJit.compilerLock, 3000, 0);
         dvmUnlockMutex(&gDvmJit.compilerLock);
-        return NULL;
+        if (gDvmJit.haltCompilerThread) {
+             return NULL;
+        }
     }
 
-    dvmUnlockMutex(&gDvmJit.compilerLock);
-
     compilerThreadStartup();
 
     dvmLockMutex(&gDvmJit.compilerLock);
diff --git a/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER.S b/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER.S
index fa931bb..52b0fbb 100644
--- a/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER.S
+++ b/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER.S
@@ -19,5 +19,8 @@
     ldr     r2, .LdvmJitToInterpNoChain
     str     r0, [rGLUE, #offGlue_pJitProfTable]
     @ Bail to interpreter - no chain [note - r4 still contains rPC]
+#if defined(EXIT_STATS)
+    mov     r0, #kHeavyweightMonitor
+#endif
     bx      r2
 
diff --git a/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER_DEBUG.S b/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER_DEBUG.S
index c030cec..31f57c4 100644
--- a/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER_DEBUG.S
+++ b/vm/compiler/template/armv5te/TEMPLATE_MONITOR_ENTER_DEBUG.S
@@ -26,4 +26,7 @@
     bx      r2
 1:
     @ Bail to interpreter - no chain [note - r4 still contains rPC]
+#if defined(EXIT_STATS)
+    mov     r0, #kHeavyweightMonitor
+#endif
     ldr     pc, .LdvmJitToInterpNoChain
diff --git a/vm/compiler/template/armv7-a/TEMPLATE_MONITOR_ENTER.S b/vm/compiler/template/armv7-a/TEMPLATE_MONITOR_ENTER.S
index a26e528..114bbdc 100644
--- a/vm/compiler/template/armv7-a/TEMPLATE_MONITOR_ENTER.S
+++ b/vm/compiler/template/armv7-a/TEMPLATE_MONITOR_ENTER.S
@@ -25,5 +25,8 @@
     ldr     r2, .LdvmJitToInterpNoChain
     str     r0, [rGLUE, #offGlue_pJitProfTable]
     @ Bail to interpreter - no chain [note - r4 still contains rPC]
+#if defined(EXIT_STATS)
+    mov     r0, #kHeavyweightMonitor
+#endif
     bx      r2
 
diff --git a/vm/compiler/template/out/CompilerTemplateAsm-armv5te-vfp.S b/vm/compiler/template/out/CompilerTemplateAsm-armv5te-vfp.S
index 7ecad39..ef4bc8a 100644
--- a/vm/compiler/template/out/CompilerTemplateAsm-armv5te-vfp.S
+++ b/vm/compiler/template/out/CompilerTemplateAsm-armv5te-vfp.S
@@ -1393,6 +1393,9 @@
     ldr     r2, .LdvmJitToInterpNoChain
     str     r0, [rGLUE, #offGlue_pJitProfTable]
     @ Bail to interpreter - no chain [note - r4 still contains rPC]
+#if defined(EXIT_STATS)
+    mov     r0, #kHeavyweightMonitor
+#endif
     bx      r2
 
 
@@ -1429,6 +1432,9 @@
     bx      r2
 1:
     @ Bail to interpreter - no chain [note - r4 still contains rPC]
+#if defined(EXIT_STATS)
+    mov     r0, #kHeavyweightMonitor
+#endif
     ldr     pc, .LdvmJitToInterpNoChain
 
     .size   dvmCompilerTemplateStart, .-dvmCompilerTemplateStart
diff --git a/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S b/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S
index 173cec0..a57907a 100644
--- a/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S
+++ b/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S
@@ -1121,6 +1121,9 @@
     ldr     r2, .LdvmJitToInterpNoChain
     str     r0, [rGLUE, #offGlue_pJitProfTable]
     @ Bail to interpreter - no chain [note - r4 still contains rPC]
+#if defined(EXIT_STATS)
+    mov     r0, #kHeavyweightMonitor
+#endif
     bx      r2
 
 
@@ -1157,6 +1160,9 @@
     bx      r2
 1:
     @ Bail to interpreter - no chain [note - r4 still contains rPC]
+#if defined(EXIT_STATS)
+    mov     r0, #kHeavyweightMonitor
+#endif
     ldr     pc, .LdvmJitToInterpNoChain
 
     .size   dvmCompilerTemplateStart, .-dvmCompilerTemplateStart
diff --git a/vm/compiler/template/out/CompilerTemplateAsm-armv7-a.S b/vm/compiler/template/out/CompilerTemplateAsm-armv7-a.S
index 872a1df..6d9b7f0 100644
--- a/vm/compiler/template/out/CompilerTemplateAsm-armv7-a.S
+++ b/vm/compiler/template/out/CompilerTemplateAsm-armv7-a.S
@@ -1399,6 +1399,9 @@
     ldr     r2, .LdvmJitToInterpNoChain
     str     r0, [rGLUE, #offGlue_pJitProfTable]
     @ Bail to interpreter - no chain [note - r4 still contains rPC]
+#if defined(EXIT_STATS)
+    mov     r0, #kHeavyweightMonitor
+#endif
     bx      r2
 
 
@@ -1435,6 +1438,9 @@
     bx      r2
 1:
     @ Bail to interpreter - no chain [note - r4 still contains rPC]
+#if defined(EXIT_STATS)
+    mov     r0, #kHeavyweightMonitor
+#endif
     ldr     pc, .LdvmJitToInterpNoChain
 
     .size   dvmCompilerTemplateStart, .-dvmCompilerTemplateStart
diff --git a/vm/mterp/common/asm-constants.h b/vm/mterp/common/asm-constants.h
index 4fff3dc..f64aeee 100644
--- a/vm/mterp/common/asm-constants.h
+++ b/vm/mterp/common/asm-constants.h
@@ -268,6 +268,7 @@
 MTERP_CONSTANT(kInlineCacheMiss,        0)
 MTERP_CONSTANT(kCallsiteInterpreted,    1)
 MTERP_CONSTANT(kSwitchOverflow,         2)
+MTERP_CONSTANT(kHeavyweightMonitor,     3)
 
 /* Size of callee save area */
 MTERP_CONSTANT(JIT_CALLEE_SAVE_DOUBLE_COUNT,   8)
diff --git a/vm/native/dalvik_system_VMRuntime.c b/vm/native/dalvik_system_VMRuntime.c
index df0e73b..5617e2e 100644
--- a/vm/native/dalvik_system_VMRuntime.c
+++ b/vm/native/dalvik_system_VMRuntime.c
@@ -188,17 +188,10 @@
     JValue* pResult)
 {
 #if defined(WITH_JIT)
-#if 0
-    /*
-     * TODO - experiment with the timing.
-     * The tentative plan is onResume() will invoke the callback.
-     */
     dvmLockMutex(&gDvmJit.compilerLock);
     pthread_cond_signal(&gDvmJit.compilerQueueActivity);
     dvmUnlockMutex(&gDvmJit.compilerLock);
 #endif
-#endif
-
     RETURN_VOID();
 }