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;