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);