OSDN Git Service

Do not JIT boot image during native-debugging (keep AOT code instead).
authorDavid Srbecky <dsrbecky@google.com>
Wed, 16 Mar 2016 00:06:24 +0000 (00:06 +0000)
committerDavid Srbecky <dsrbecky@google.com>
Thu, 17 Mar 2016 11:54:49 +0000 (11:54 +0000)
The performance impact is currently significant and being able
to debug framework is not our primary goal for native debugging.

Change-Id: I3366c2a6317004f9dd16700b271a6c9b974f1c6e

runtime/class_linker.cc
runtime/debugger.cc
runtime/native/dalvik_system_ZygoteHooks.cc
runtime/runtime.cc
runtime/runtime.h

index 3c69323..902ba03 100644 (file)
@@ -2722,13 +2722,18 @@ bool ClassLinker::ShouldUseInterpreterEntrypoint(ArtMethod* method, const void*
     return true;
   }
 
-  if (runtime->UseJit() && runtime->GetJit()->JitAtFirstUse()) {
-    // The force JIT uses the interpreter entry point to execute the JIT.
-    return true;
+  if (runtime->IsNativeDebuggable()) {
+    DCHECK(runtime->UseJit() && runtime->GetJit()->JitAtFirstUse());
+    // If we are doing native debugging, ignore application's AOT code,
+    // since we want to JIT it with extra stackmaps for native debugging.
+    // On the other hand, keep all AOT code from the boot image, since the
+    // blocking JIT would results in non-negligible performance impact.
+    return !runtime->GetHeap()->IsInBootImageOatFile(quick_code);
   }
 
   if (Dbg::IsDebuggerActive()) {
-    // Boot image classes are AOT-compiled as non-debuggable.
+    // Boot image classes may be AOT-compiled as non-debuggable.
+    // This is not suitable for the Java debugger, so ignore the AOT code.
     return runtime->GetHeap()->IsInBootImageOatFile(quick_code);
   }
 
index bc65893..c375bba 100644 (file)
@@ -622,9 +622,11 @@ void Dbg::GoActive() {
   }
 
   Runtime* runtime = Runtime::Current();
-  // Since boot image code is AOT compiled as not debuggable, we need to patch
+  // Since boot image code may be AOT compiled as not debuggable, we need to patch
   // entry points of methods in boot image to interpreter bridge.
-  if (!runtime->GetInstrumentation()->IsForcedInterpretOnly()) {
+  // However, the performance cost of this is non-negligible during native-debugging due to the
+  // forced JIT, so we keep the AOT code in that case in exchange for limited native debugging.
+  if (!runtime->GetInstrumentation()->IsForcedInterpretOnly() && !runtime->IsNativeDebuggable()) {
     ScopedObjectAccess soa(self);
     UpdateEntryPointsClassVisitor visitor(runtime->GetInstrumentation());
     runtime->GetClassLinker()->VisitClasses(&visitor);
index 65002df..887eee0 100644 (file)
@@ -121,6 +121,7 @@ static void EnableDebugFeatures(uint32_t debug_flags) {
   if ((debug_flags & DEBUG_NATIVE_DEBUGGABLE) != 0) {
     runtime->AddCompilerOption("--debuggable");
     runtime->AddCompilerOption("--generate-debug-info");
+    runtime->SetNativeDebuggable(true);
     debug_flags &= ~DEBUG_NATIVE_DEBUGGABLE;
   }
 
index c8085fb..78e00fd 100644 (file)
@@ -203,6 +203,7 @@ Runtime::Runtime()
       implicit_suspend_checks_(false),
       no_sig_chain_(false),
       is_native_bridge_loaded_(false),
+      is_native_debuggable_(false),
       zygote_max_failed_boots_(0),
       experimental_flags_(ExperimentalFlags::kNone),
       oat_file_manager_(nullptr),
index 8e99f80..aff7c06 100644 (file)
@@ -583,6 +583,14 @@ class Runtime {
 
   bool IsDebuggable() const;
 
+  bool IsNativeDebuggable() const {
+    return is_native_debuggable_;
+  }
+
+  void SetNativeDebuggable(bool value) {
+    is_native_debuggable_ = value;
+  }
+
   // Returns the build fingerprint, if set. Otherwise an empty string is returned.
   std::string GetFingerprint() {
     return fingerprint_;
@@ -796,6 +804,9 @@ class Runtime {
   // that there's no native bridge.
   bool is_native_bridge_loaded_;
 
+  // Whether we are running under native debugger.
+  bool is_native_debuggable_;
+
   // The maximum number of failed boots we allow before pruning the dalvik cache
   // and trying again. This option is only inspected when we're running as a
   // zygote.