Revert "Put queued compilations in sets."

This reverts commit 123c02bb75e1ddfb8d20bbd6e2e7c62ee64d6772.

Bug: 218444629

Reason for revert: Some tests are failing.

Change-Id: I0b3bc9b169c2264430e09bdfa79c23d01033827b
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index ae3575a..5e01aaa 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -259,14 +259,10 @@
   return true;
 }
 
-bool Jit::CompileMethodInternal(ArtMethod* method,
-                                Thread* self,
-                                CompilationKind compilation_kind,
-                                bool prejit) {
-  if (kIsDebugBuild) {
-    MutexLock mu(self, *Locks::jit_lock_);
-    CHECK(GetCodeCache()->IsMethodBeingCompiled(method, compilation_kind));
-  }
+bool Jit::CompileMethod(ArtMethod* method,
+                        Thread* self,
+                        CompilationKind compilation_kind,
+                        bool prejit) {
   DCHECK(Runtime::Current()->UseJitCompilation());
   DCHECK(!method->IsRuntimeMethod());
 
@@ -327,7 +323,7 @@
             << ArtMethod::PrettyMethod(method_to_compile)
             << " kind=" << compilation_kind;
   bool success = jit_compiler_->CompileMethod(self, region, method_to_compile, compilation_kind);
-  code_cache_->DoneCompiling(method_to_compile, self);
+  code_cache_->DoneCompiling(method_to_compile, self, compilation_kind);
   if (!success) {
     VLOG(jit) << "Failed to compile method "
               << ArtMethod::PrettyMethod(method_to_compile)
@@ -747,48 +743,6 @@
   child_mapping_methods.Reset();
 }
 
-class ScopedCompilation {
- public:
-  ScopedCompilation(ScopedCompilation&& other) :
-      jit_(other.jit_),
-      method_(other.method_),
-      compilation_kind_(other.compilation_kind_),
-      owns_compilation_(other.owns_compilation_) {
-    other.owns_compilation_ = false;
-  }
-
-  ScopedCompilation(Jit* jit, ArtMethod* method, CompilationKind compilation_kind)
-      : jit_(jit),
-        method_(method),
-        compilation_kind_(compilation_kind),
-        owns_compilation_(true) {
-    MutexLock mu(Thread::Current(), *Locks::jit_lock_);
-    if (jit_->GetCodeCache()->IsMethodBeingCompiled(method_, compilation_kind_)) {
-      owns_compilation_ = false;
-      return;
-    }
-    jit_->GetCodeCache()->AddMethodBeingCompiled(method_, compilation_kind_);
-  }
-
-  bool OwnsCompilation() const {
-    return owns_compilation_;
-  }
-
-
-  ~ScopedCompilation() {
-    if (owns_compilation_) {
-      MutexLock mu(Thread::Current(), *Locks::jit_lock_);
-      jit_->GetCodeCache()->RemoveMethodBeingCompiled(method_, compilation_kind_);
-    }
-  }
-
- private:
-  Jit* const jit_;
-  ArtMethod* const method_;
-  const CompilationKind compilation_kind_;
-  bool owns_compilation_;
-};
-
 class JitCompileTask final : public Task {
  public:
   enum class TaskKind {
@@ -796,16 +750,25 @@
     kPreCompile,
   };
 
-  JitCompileTask(ArtMethod* method,
-                 TaskKind task_kind,
-                 CompilationKind compilation_kind,
-                 ScopedCompilation&& sc)
-      : method_(method),
-        kind_(task_kind),
-        compilation_kind_(compilation_kind),
-        scoped_compilation_(std::move(sc)) {
-    DCHECK(scoped_compilation_.OwnsCompilation());
-    DCHECK(!sc.OwnsCompilation());
+  JitCompileTask(ArtMethod* method, TaskKind task_kind, CompilationKind compilation_kind)
+      : method_(method), kind_(task_kind), compilation_kind_(compilation_kind), klass_(nullptr) {
+    ScopedObjectAccess soa(Thread::Current());
+    // For a non-bootclasspath class, add a global ref to the class to prevent class unloading
+    // until compilation is done.
+    // When we precompile, this is either with boot classpath methods, or main
+    // class loader methods, so we don't need to keep a global reference.
+    if (method->GetDeclaringClass()->GetClassLoader() != nullptr &&
+        kind_ != TaskKind::kPreCompile) {
+      klass_ = soa.Vm()->AddGlobalRef(soa.Self(), method_->GetDeclaringClass());
+      CHECK(klass_ != nullptr);
+    }
+  }
+
+  ~JitCompileTask() {
+    if (klass_ != nullptr) {
+      ScopedObjectAccess soa(Thread::Current());
+      soa.Vm()->DeleteGlobalRef(soa.Self(), klass_);
+    }
   }
 
   void Run(Thread* self) override {
@@ -814,7 +777,7 @@
       switch (kind_) {
         case TaskKind::kCompile:
         case TaskKind::kPreCompile: {
-          Runtime::Current()->GetJit()->CompileMethodInternal(
+          Runtime::Current()->GetJit()->CompileMethod(
               method_,
               self,
               compilation_kind_,
@@ -834,7 +797,7 @@
   ArtMethod* const method_;
   const TaskKind kind_;
   const CompilationKind compilation_kind_;
-  ScopedCompilation scoped_compilation_;
+  jobject klass_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(JitCompileTask);
 };
@@ -1322,21 +1285,6 @@
   }
 }
 
-void Jit::AddCompileTask(Thread* self,
-                         ArtMethod* method,
-                         CompilationKind compilation_kind,
-                         bool precompile) {
-  ScopedCompilation sc(this, method, compilation_kind);
-  if (!sc.OwnsCompilation()) {
-    return;
-  }
-  JitCompileTask::TaskKind task_kind = precompile
-      ? JitCompileTask::TaskKind::kPreCompile
-      : JitCompileTask::TaskKind::kCompile;
-  thread_pool_->AddTask(
-      self, new JitCompileTask(method, task_kind, compilation_kind, std::move(sc)));
-}
-
 bool Jit::CompileMethodFromProfile(Thread* self,
                                    ClassLinker* class_linker,
                                    uint32_t method_idx,
@@ -1357,7 +1305,6 @@
     // Already seen by another profile.
     return false;
   }
-  CompilationKind compilation_kind = CompilationKind::kOptimized;
   const void* entry_point = method->GetEntryPointFromQuickCompiledCode();
   if (class_linker->IsQuickToInterpreterBridge(entry_point) ||
       class_linker->IsQuickGenericJniStub(entry_point) ||
@@ -1368,15 +1315,11 @@
     VLOG(jit) << "JIT Zygote processing method " << ArtMethod::PrettyMethod(method)
               << " from profile";
     method->SetPreCompiled();
-    ScopedCompilation sc(this, method, compilation_kind);
-    if (!sc.OwnsCompilation()) {
-      return false;
-    }
     if (!add_to_queue) {
-      CompileMethodInternal(method, self, compilation_kind, /* prejit= */ true);
+      CompileMethod(method, self, CompilationKind::kOptimized, /* prejit= */ true);
     } else {
       Task* task = new JitCompileTask(
-          method, JitCompileTask::TaskKind::kPreCompile, compilation_kind, std::move(sc));
+          method, JitCompileTask::TaskKind::kPreCompile, CompilationKind::kOptimized);
       if (compile_after_boot) {
         AddPostBootTask(self, task);
       } else {
@@ -1527,7 +1470,11 @@
   // hotness threshold. If we're not only using the baseline compiler, enqueue a compilation
   // task that will compile optimize the method.
   if (!options_->UseBaselineCompiler()) {
-    AddCompileTask(self, method, CompilationKind::kOptimized);
+    thread_pool_->AddTask(
+        self,
+        new JitCompileTask(method,
+                           JitCompileTask::TaskKind::kCompile,
+                           CompilationKind::kOptimized));
   }
 }
 
@@ -1547,17 +1494,23 @@
   bool was_runtime_thread_;
 };
 
-void Jit::MethodEntered(Thread* self, ArtMethod* method) {
+void Jit::MethodEntered(Thread* thread, ArtMethod* method) {
   Runtime* runtime = Runtime::Current();
   if (UNLIKELY(runtime->UseJitCompilation() && JitAtFirstUse())) {
     ArtMethod* np_method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
     if (np_method->IsCompilable()) {
-      CompileMethod(method, self, CompilationKind::kOptimized, /* prejit= */ false);
+      // TODO(ngeoffray): For JIT at first use, use kPreCompile. Currently we don't due to
+      // conflicts with jitzygote optimizations.
+      JitCompileTask compile_task(
+          method, JitCompileTask::TaskKind::kCompile, CompilationKind::kOptimized);
+      // Fake being in a runtime thread so that class-load behavior will be the same as normal jit.
+      ScopedSetRuntimeThread ssrt(thread);
+      compile_task.Run(thread);
     }
     return;
   }
 
-  AddSamples(self, method);
+  AddSamples(thread, method);
 }
 
 void Jit::WaitForCompilationToFinish(Thread* self) {
@@ -1787,7 +1740,9 @@
     if (!method->IsNative() && !code_cache_->IsOsrCompiled(method)) {
       // If we already have compiled code for it, nterp may be stuck in a loop.
       // Compile OSR.
-      AddCompileTask(self, method, CompilationKind::kOsr);
+      thread_pool_->AddTask(
+          self,
+          new JitCompileTask(method, JitCompileTask::TaskKind::kCompile, CompilationKind::kOsr));
     }
     return;
   }
@@ -1821,27 +1776,17 @@
   }
 
   if (!method->IsNative() && GetCodeCache()->CanAllocateProfilingInfo()) {
-    AddCompileTask(self, method, CompilationKind::kBaseline);
+    thread_pool_->AddTask(
+        self,
+        new JitCompileTask(method, JitCompileTask::TaskKind::kCompile, CompilationKind::kBaseline));
   } else {
-    AddCompileTask(self, method, CompilationKind::kOptimized);
+    thread_pool_->AddTask(
+        self,
+        new JitCompileTask(method,
+                           JitCompileTask::TaskKind::kCompile,
+                           CompilationKind::kOptimized));
   }
 }
 
-bool Jit::CompileMethod(ArtMethod* method,
-                        Thread* self,
-                        CompilationKind compilation_kind,
-                        bool prejit) {
-  ScopedCompilation sc(this, method, compilation_kind);
-  // TODO: all current users of this method expect us to wait if it is being compiled.
-  if (!sc.OwnsCompilation()) {
-    return false;
-  }
-  // Fake being in a runtime thread so that class-load behavior will be the same as normal jit.
-  ScopedSetRuntimeThread ssrt(self);
-  // TODO(ngeoffray): For JIT at first use, use kPreCompile. Currently we don't due to
-  // conflicts with jitzygote optimizations.
-  return CompileMethodInternal(method, self, compilation_kind, prejit);
-}
-
 }  // namespace jit
 }  // namespace art
diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h
index fd92451..b439c8e 100644
--- a/runtime/jit/jit.h
+++ b/runtime/jit/jit.h
@@ -53,7 +53,6 @@
 namespace jit {
 
 class JitCodeCache;
-class JitCompileTask;
 class JitMemoryRegion;
 class JitOptions;
 
@@ -462,17 +461,6 @@
 
   static bool BindCompilerMethods(std::string* error_msg);
 
-  void AddCompileTask(Thread* self,
-                      ArtMethod* method,
-                      CompilationKind compilation_kind,
-                      bool precompile = false);
-
-  bool CompileMethodInternal(ArtMethod* method,
-                             Thread* self,
-                             CompilationKind compilation_kind,
-                             bool prejit)
-      REQUIRES_SHARED(Locks::mutator_lock_);
-
   // JIT compiler
   static void* jit_library_handle_;
   static JitCompilerInterface* jit_compiler_;
@@ -519,8 +507,6 @@
   // between the zygote and apps.
   std::map<ArtMethod*, uint16_t> shared_method_counters_;
 
-  friend class art::jit::JitCompileTask;
-
   DISALLOW_COPY_AND_ASSIGN(Jit);
 };
 
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 70edc44..0b34688 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -1594,28 +1594,10 @@
   return osr_code_map_.find(method) != osr_code_map_.end();
 }
 
-void JitCodeCache::VisitRoots(RootVisitor* visitor) {
-  MutexLock mu(Thread::Current(), *Locks::jit_lock_);
-  UnbufferedRootVisitor root_visitor(visitor, RootInfo(kRootStickyClass));
-  for (ArtMethod* method : current_optimized_compilations_) {
-    method->VisitRoots(root_visitor, kRuntimePointerSize);
-  }
-  for (ArtMethod* method : current_baseline_compilations_) {
-    method->VisitRoots(root_visitor, kRuntimePointerSize);
-  }
-  for (ArtMethod* method : current_osr_compilations_) {
-    method->VisitRoots(root_visitor, kRuntimePointerSize);
-  }
-}
-
 bool JitCodeCache::NotifyCompilationOf(ArtMethod* method,
                                        Thread* self,
                                        CompilationKind compilation_kind,
                                        bool prejit) {
-  if (kIsDebugBuild) {
-    MutexLock mu(self, *Locks::jit_lock_);
-    CHECK(IsMethodBeingCompiled(method, compilation_kind));
-  }
   const void* existing_entry_point = method->GetEntryPointFromQuickCompiledCode();
   if (compilation_kind != CompilationKind::kOsr && ContainsPc(existing_entry_point)) {
     OatQuickMethodHeader* method_header =
@@ -1704,8 +1686,13 @@
         }
       }
     }
+    MutexLock mu(self, *Locks::jit_lock_);
+    if (IsMethodBeingCompiled(method, compilation_kind)) {
+      return false;
+    }
+    AddMethodBeingCompiled(method, compilation_kind);
+    return true;
   }
-  return true;
 }
 
 ProfilingInfo* JitCodeCache::NotifyCompilerUse(ArtMethod* method, Thread* self) {
@@ -1728,7 +1715,9 @@
   it->second->DecrementInlineUse();
 }
 
-void JitCodeCache::DoneCompiling(ArtMethod* method, Thread* self) {
+void JitCodeCache::DoneCompiling(ArtMethod* method,
+                                 Thread* self,
+                                 CompilationKind compilation_kind) {
   DCHECK_EQ(Thread::Current(), self);
   MutexLock mu(self, *Locks::jit_lock_);
   if (UNLIKELY(method->IsNative())) {
@@ -1740,6 +1729,8 @@
       // Failed to compile; the JNI compiler never fails, but the cache may be full.
       jni_stubs_map_.erase(it);  // Remove the entry added in NotifyCompilationOf().
     }  // else Commit() updated entrypoints of all methods in the JniStubData.
+  } else {
+    RemoveMethodBeingCompiled(method, compilation_kind);
   }
 }
 
diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h
index a534ba9..fb861a4 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -215,7 +215,7 @@
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Locks::jit_lock_);
 
-  void DoneCompiling(ArtMethod* method, Thread* self)
+  void DoneCompiling(ArtMethod* method, Thread* self, CompilationKind compilation_kind)
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Locks::jit_lock_);
 
@@ -403,20 +403,6 @@
   ProfilingInfo* GetProfilingInfo(ArtMethod* method, Thread* self);
   void ResetHotnessCounter(ArtMethod* method, Thread* self);
 
-  void VisitRoots(RootVisitor* visitor);
-
-  // Return whether `method` is being compiled with the given mode.
-  bool IsMethodBeingCompiled(ArtMethod* method, CompilationKind compilation_kind)
-      REQUIRES(Locks::jit_lock_);
-
-  // Remove `method` from the list of methods meing compiled with the given mode.
-  void RemoveMethodBeingCompiled(ArtMethod* method, CompilationKind compilation_kind)
-      REQUIRES(Locks::jit_lock_);
-
-  // Record that `method` is being compiled with the given mode.
-  void AddMethodBeingCompiled(ArtMethod* method, CompilationKind compilation_kind)
-      REQUIRES(Locks::jit_lock_);
-
  private:
   JitCodeCache();
 
@@ -506,6 +492,18 @@
       REQUIRES(!Locks::jit_lock_)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  // Record that `method` is being compiled with the given mode.
+  void AddMethodBeingCompiled(ArtMethod* method, CompilationKind compilation_kind)
+      REQUIRES(Locks::jit_lock_);
+
+  // Remove `method` from the list of methods meing compiled with the given mode.
+  void RemoveMethodBeingCompiled(ArtMethod* method, CompilationKind compilation_kind)
+      REQUIRES(Locks::jit_lock_);
+
+  // Return whether `method` is being compiled with the given mode.
+  bool IsMethodBeingCompiled(ArtMethod* method, CompilationKind compilation_kind)
+      REQUIRES(Locks::jit_lock_);
+
   // Return whether `method` is being compiled in any mode.
   bool IsMethodBeingCompiled(ArtMethod* method) REQUIRES(Locks::jit_lock_);
 
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index d2eb3bd..42f706a 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -2457,9 +2457,6 @@
   class_linker_->VisitRoots(visitor, flags);
   jni_id_manager_->VisitRoots(visitor);
   heap_->VisitAllocationRecords(visitor);
-  if (jit_ != nullptr) {
-    jit_->GetCodeCache()->VisitRoots(visitor);
-  }
   if ((flags & kVisitRootFlagNewRoots) == 0) {
     // Guaranteed to have no new roots in the constant roots.
     VisitConstantRoots(visitor);