Make it possible to enable native debugging through debug flags

* Add support for a new debug flag disabling the optimizations in
  the compiler and enable the generation of some additional debug
  info (--native-debuggable).
* Ignore the content of the oat files if force JIT is enabled so
  the runtime ignores the AOT-ed code what doesn't contain any
  debug info.

Time measurements on a Nexus 5 with running:
am start -n com.facebook.katana/com.facebook.katana.LoginActivity -W

Before change:             | AVG | DEV
--------------------------------------
ThisTime:  549 492 512 511 | 516 | 24
TotalTime: 549 492 512 511 | 516 | 24
WaitTime:  662 511 528 526 | 557 | 71

After change:              | AVG | DEV
--------------------------------------
ThisTime:  530 467 503 544 | 511 | 34
TotalTime: 530 467 503 544 | 511 | 34
WaitTime:  551 497 536 583 | 541 | 36

Based on the numbers the speed impact of the change is less then the
accuracy of the measurement and it is also negligible.

The minor speed improvement displayed in the measurements are just
the cause of the variance of the measurement and not caused by this
change.

Change-Id: Ia9022cbc1bbfcc072314b6c95f63a4bf8060c36c
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 04fe79a..7f7f2db 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2593,19 +2593,37 @@
   return oat_class.GetOatMethod(oat_method_idx).GetQuickCode();
 }
 
-// Returns true if the method must run with interpreter, false otherwise.
-static bool NeedsInterpreter(ArtMethod* method, const void* quick_code)
-    SHARED_REQUIRES(Locks::mutator_lock_) {
+bool ClassLinker::CanUseAOTCode(ArtMethod* method, const void* quick_code) {
   if (quick_code == nullptr) {
     // No code: need interpreter.
-    // May return true for native code, in the case of generic JNI
-    // DCHECK(!method->IsNative());
+    return false;
+  }
+
+  if (UNLIKELY(method->IsNative() || method->IsProxyMethod())) {
     return true;
   }
-  // If interpreter mode is enabled, every method (except native and proxy) must
-  // be run with interpreter.
-  return Runtime::Current()->GetInstrumentation()->InterpretOnly() &&
-         !method->IsNative() && !method->IsProxyMethod();
+
+  Runtime* runtime = Runtime::Current();
+  instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
+  if (instr->InterpretOnly()) {
+    return false;
+  }
+
+  if (runtime->GetClassLinker()->IsQuickToInterpreterBridge(quick_code)) {
+    // Doing this check avoids doing compiled/interpreter transitions.
+    return false;
+  }
+
+  if (Dbg::IsForcedInterpreterNeededForCalling(Thread::Current(), method)) {
+    // Force the use of interpreter when it is required by the debugger.
+    return false;
+  }
+
+  if (runtime->UseJit() && runtime->GetJit()->JitAtFirstUse()) {
+    // Don't use AOT code in force JIT mode.
+    return false;
+  }
+  return true;
 }
 
 void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) {
@@ -2650,8 +2668,7 @@
       OatFile::OatMethod oat_method = oat_class.GetOatMethod(method_index);
       quick_code = oat_method.GetQuickCode();
     }
-    const bool enter_interpreter = NeedsInterpreter(method, quick_code);
-    if (enter_interpreter) {
+    if (!CanUseAOTCode(method, quick_code)) {
       // Use interpreter entry point.
       // Check whether the method is native, in which case it's generic JNI.
       if (quick_code == nullptr && method->IsNative()) {
@@ -2688,8 +2705,7 @@
     oat_method.LinkMethod(method);
   }
 
-  // Install entry point from interpreter.
-  bool enter_interpreter = NeedsInterpreter(method, method->GetEntryPointFromQuickCompiledCode());
+  bool has_usable_oat_code = CanUseAOTCode(method, method->GetEntryPointFromQuickCompiledCode());
 
   if (!method->IsInvokable()) {
     EnsureThrowsInvocationError(method);
@@ -2701,7 +2717,7 @@
     // It will be replaced by the proper entry point by ClassLinker::FixupStaticTrampolines
     // after initializing class (see ClassLinker::InitializeClass method).
     method->SetEntryPointFromQuickCompiledCode(GetQuickResolutionStub());
-  } else if (enter_interpreter) {
+  } else if (!has_usable_oat_code) {
     if (!method->IsNative()) {
       // Set entry point from compiled code if there's no code or in interpreter only mode.
       method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
@@ -2714,7 +2730,7 @@
     // Unregistering restores the dlsym lookup stub.
     method->UnregisterNative();
 
-    if (enter_interpreter) {
+    if (!has_usable_oat_code) {
       // We have a native method here without code. Then it should have either the generic JNI
       // trampoline as entrypoint (non-static), or the resolution trampoline (static).
       // TODO: this doesn't handle all the cases where trampolines may be installed.
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 71fcf29..8e1e2a0 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -592,6 +592,9 @@
       REQUIRES(!Locks::classlinker_classes_lock_)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
+  static bool CanUseAOTCode(ArtMethod* method, const void* quick_code)
+      SHARED_REQUIRES(Locks::mutator_lock_);
+
   struct DexCacheData {
     // Weak root to the DexCache. Note: Do not decode this unnecessarily or else class unloading may
     // not work properly.
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 0b2471b..4fd3c78 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -27,6 +27,7 @@
 #include "unstarted_runtime.h"
 #include "mterp/mterp.h"
 #include "jit/jit.h"
+#include "jit/jit_code_cache.h"
 
 namespace art {
 namespace interpreter {
@@ -293,9 +294,10 @@
                                         method, 0);
     }
 
-    if (UNLIKELY(Runtime::Current()->GetJit() != nullptr &&
-                 Runtime::Current()->GetJit()->JitAtFirstUse() &&
-                 method->HasAnyCompiledCode())) {
+    jit::Jit* jit = Runtime::Current()->GetJit();
+    if (UNLIKELY(jit != nullptr &&
+                 jit->JitAtFirstUse() &&
+                 jit->GetCodeCache()->ContainsMethod(method))) {
       JValue result;
 
       // Pop the shadow frame before calling into compiled code.
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 09d8601..2c7f1fd 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -20,6 +20,7 @@
 
 #include "debugger.h"
 #include "entrypoints/runtime_asm_entrypoints.h"
+#include "jit/jit.h"
 #include "mirror/array-inl.h"
 #include "stack.h"
 #include "unstarted_runtime.h"
@@ -501,23 +502,6 @@
                                 uint32_t (&arg)[kVarArgMax],
                                 uint32_t vregC) ALWAYS_INLINE;
 
-SHARED_REQUIRES(Locks::mutator_lock_)
-static inline bool NeedsInterpreter(Thread* self, ShadowFrame* new_shadow_frame) ALWAYS_INLINE;
-
-static inline bool NeedsInterpreter(Thread* self, ShadowFrame* new_shadow_frame) {
-  ArtMethod* target = new_shadow_frame->GetMethod();
-  if (UNLIKELY(target->IsNative() || target->IsProxyMethod())) {
-    return false;
-  }
-  Runtime* runtime = Runtime::Current();
-  ClassLinker* class_linker = runtime->GetClassLinker();
-  return runtime->GetInstrumentation()->IsForcedInterpretOnly() ||
-        // Doing this check avoids doing compiled/interpreter transitions.
-        class_linker->IsQuickToInterpreterBridge(target->GetEntryPointFromQuickCompiledCode()) ||
-        // Force the use of interpreter when it is required by the debugger.
-        Dbg::IsForcedInterpreterNeededForCalling(self, target);
-}
-
 void ArtInterpreterToCompiledCodeBridge(Thread* self,
                                         const DexFile::CodeItem* code_item,
                                         ShadowFrame* shadow_frame,
@@ -736,10 +720,11 @@
 
   // Do the call now.
   if (LIKELY(Runtime::Current()->IsStarted())) {
-    if (NeedsInterpreter(self, new_shadow_frame)) {
-      ArtInterpreterToInterpreterBridge(self, code_item, new_shadow_frame, result);
-    } else {
+    ArtMethod* target = new_shadow_frame->GetMethod();
+    if (ClassLinker::CanUseAOTCode(target, target->GetEntryPointFromQuickCompiledCode())) {
       ArtInterpreterToCompiledCodeBridge(self, code_item, new_shadow_frame, result);
+    } else {
+      ArtInterpreterToInterpreterBridge(self, code_item, new_shadow_frame, result);
     }
   } else {
     UnstartedRuntime::Invoke(self, code_item, new_shadow_frame, result, first_dest_reg);
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index a7881ac..a092b9f 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -66,6 +66,7 @@
     DEBUG_ENABLE_JNI_LOGGING        = 1 << 4,
     DEBUG_GENERATE_DEBUG_INFO       = 1 << 5,
     DEBUG_ALWAYS_JIT                = 1 << 6,
+    DEBUG_NATIVE_DEBUGGABLE         = 1 << 7,
   };
 
   Runtime* const runtime = Runtime::Current();
@@ -117,6 +118,11 @@
     debug_flags &= ~DEBUG_ALWAYS_JIT;
   }
 
+  if ((debug_flags & DEBUG_NATIVE_DEBUGGABLE) != 0) {
+    runtime->AddCompilerOption("--native-debuggable");
+    debug_flags &= ~DEBUG_NATIVE_DEBUGGABLE;
+  }
+
   if (debug_flags != 0) {
     LOG(ERROR) << StringPrintf("Unknown bits set in debug_flags: %#x", debug_flags);
   }