Prevent jit-compilation from loading classes in jit-on-first-use
Unlike with normal jit, jit-on-first-use (-Xjitthreshold:0) causes the
jit-compilation to be done synchronously on the current thread. Since
this thread is not a runtime thread it will allow the jit to load
classes even on a debuggable runtime. This can cause some tests to
fail. To fix this (and prevent any future issues) we mark threads
running in jit-code for jit-on-first-use as runtime-threads
temporarily.
Test: ./test/run-test --host --jit --runtime-option -Xjitthreshold:0 1953
Change-Id: I06410bc3cbdb28ba51e907b71556481ba405c1d0
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index d831628..c1f69b8 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -718,6 +718,22 @@
method->SetCounter(new_count);
}
+class ScopedSetRuntimeThread {
+ public:
+ explicit ScopedSetRuntimeThread(Thread* self)
+ : self_(self), was_runtime_thread_(self_->IsRuntimeThread()) {
+ self_->SetIsRuntimeThread(true);
+ }
+
+ ~ScopedSetRuntimeThread() {
+ self_->SetIsRuntimeThread(was_runtime_thread_);
+ }
+
+ private:
+ Thread* self_;
+ bool was_runtime_thread_;
+};
+
void Jit::MethodEntered(Thread* thread, ArtMethod* method) {
Runtime* runtime = Runtime::Current();
if (UNLIKELY(runtime->UseJitCompilation() && runtime->GetJit()->JitAtFirstUse())) {
@@ -728,6 +744,8 @@
ProfilingInfo::Create(thread, np_method, /* retry_allocation */ true);
}
JitCompileTask compile_task(method, JitCompileTask::kCompile);
+ // 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;