Fix JIT options with late init

Previously we couldn't create the JIT since we didn't have any
JITOptions.

Bug: 19735273

Change-Id: I24b8ed131ed8b18f75ec94291e135d8a1c089ebd
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 729791f..13c1f81 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -32,10 +32,8 @@
 namespace jit {
 
 JitOptions* JitOptions::CreateFromRuntimeArguments(const RuntimeArgumentMap& options) {
-  if (!options.GetOrDefault(RuntimeArgumentMap::UseJIT)) {
-    return nullptr;
-  }
   auto* jit_options = new JitOptions;
+  jit_options->use_jit_ = options.GetOrDefault(RuntimeArgumentMap::UseJIT);
   jit_options->code_cache_capacity_ =
       options.GetOrDefault(RuntimeArgumentMap::JITCodeCacheCapacity);
   jit_options->compile_threshold_ =
diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h
index 6b206d1..3e80aef 100644
--- a/runtime/jit/jit.h
+++ b/runtime/jit/jit.h
@@ -100,13 +100,21 @@
   bool DumpJitInfoOnShutdown() const {
     return dump_info_on_shutdown_;
   }
+  bool UseJIT() const {
+    return use_jit_;
+  }
+  void SetUseJIT(bool b) {
+    use_jit_ = b;
+  }
 
  private:
+  bool use_jit_;
   size_t code_cache_capacity_;
   size_t compile_threshold_;
   bool dump_info_on_shutdown_;
 
-  JitOptions() : code_cache_capacity_(0), compile_threshold_(0), dump_info_on_shutdown_(false) {
+  JitOptions() : use_jit_(false), code_cache_capacity_(0), compile_threshold_(0),
+      dump_info_on_shutdown_(false) {
   }
 };
 
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index 8395150..022c56f 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -21,6 +21,7 @@
 #include "arch/instruction_set.h"
 #include "debugger.h"
 #include "java_vm_ext.h"
+#include "jit/jit.h"
 #include "jni_internal.h"
 #include "JNIHelp.h"
 #include "ScopedUtfChars.h"
@@ -94,18 +95,17 @@
     debug_flags &= ~DEBUG_ENABLE_SAFEMODE;
   }
 
+  bool use_jit = false;
   if ((debug_flags & DEBUG_ENABLE_JIT) != 0) {
     if (safe_mode) {
-      LOG(INFO) << "Not enabling JIT due to VM safe mode";
+      LOG(INFO) << "Not enabling JIT due to safe mode";
     } else {
-      if (runtime->GetJit() == nullptr) {
-        runtime->CreateJit();
-      } else {
-        LOG(INFO) << "Not late-enabling JIT (already on)";
-      }
+      use_jit = true;
+      LOG(INFO) << "Late-enabling JIT";
     }
     debug_flags &= ~DEBUG_ENABLE_JIT;
   }
+  runtime->GetJITOptions()->SetUseJIT(use_jit);
 
   // This is for backwards compatibility with Dalvik.
   debug_flags &= ~DEBUG_ENABLE_ASSERT;
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 189559e..0f0c327 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -483,11 +483,10 @@
     }
   }
 
-  // If we are the zygote then we need to wait until after forking to create the code cache due to
-  // SELinux restrictions on r/w/x memory regions.
-  if (!IsZygote() && jit_.get() != nullptr) {
-    jit_->CreateInstrumentationCache(jit_options_->GetCompileThreshold());
-    jit_->CreateThreadPool();
+  // If we are the zygote then we need to wait until after forking to create the code cache
+  // due to SELinux restrictions on r/w/x memory regions.
+  if (!IsZygote() && jit_options_->UseJIT()) {
+    CreateJit();
   }
 
   if (!IsImageDex2OatEnabled() || !GetHeap()->HasImageSpace()) {
@@ -611,11 +610,9 @@
 
   // Create the thread pools.
   heap_->CreateThreadPool();
-  if (jit_options_.get() != nullptr && jit_.get() == nullptr) {
+  if (jit_.get() == nullptr && jit_options_->UseJIT()) {
     // Create the JIT if the flag is set and we haven't already create it (happens for run-tests).
     CreateJit();
-    jit_->CreateInstrumentationCache(jit_options_->GetCompileThreshold());
-    jit_->CreateThreadPool();
   }
 
   StartSignalCatcher();
@@ -843,20 +840,19 @@
     Dbg::ConfigureJdwp(runtime_options.GetOrDefault(Opt::JdwpOptions));
   }
 
-  if (!IsAotCompiler()) {
+  jit_options_.reset(jit::JitOptions::CreateFromRuntimeArguments(runtime_options));
+  bool use_jit = jit_options_->UseJIT();
+  if (IsAotCompiler()) {
     // If we are already the compiler at this point, we must be dex2oat. Don't create the jit in
     // this case.
     // If runtime_options doesn't have UseJIT set to true then CreateFromRuntimeArguments returns
     // nullptr and we don't create the jit.
-    jit_options_.reset(jit::JitOptions::CreateFromRuntimeArguments(runtime_options));
-  }
-  if (!IsZygote() && jit_options_.get() != nullptr) {
-    CreateJit();
+    use_jit = false;
   }
 
   // Use MemMap arena pool for jit, malloc otherwise. Malloc arenas are faster to allocate but
   // can't be trimmed as easily.
-  const bool use_malloc = jit_options_.get() == nullptr;
+  const bool use_malloc = !use_jit;
   arena_pool_.reset(new ArenaPool(use_malloc));
 
   BlockSignals();
@@ -1661,11 +1657,13 @@
 }
 
 void Runtime::CreateJit() {
-  CHECK(jit_options_.get() != nullptr);
+  CHECK(!IsAotCompiler());
   std::string error_msg;
   jit_.reset(jit::Jit::Create(jit_options_.get(), &error_msg));
   if (jit_.get() != nullptr) {
     compiler_callbacks_ = jit_->GetCompilerCallbacks();
+    jit_->CreateInstrumentationCache(jit_options_->GetCompileThreshold());
+    jit_->CreateThreadPool();
   } else {
     LOG(WARNING) << "Failed to create JIT " << error_msg;
   }
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 3cf22bf..7f33547 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -540,6 +540,7 @@
     return zygote_max_failed_boots_;
   }
 
+  // Create the JIT and instrumentation and code cache.
   void CreateJit();
 
   ArenaPool* GetArenaPool() {
@@ -549,6 +550,10 @@
     return arena_pool_.get();
   }
 
+  jit::JitOptions* GetJITOptions() {
+    return jit_options_.get();
+  }
+
  private:
   static void InitPlatformSignalHandlers();