Special case JIT update for native methods.
The update might apply to ArtMethods that are going to be
unloaded, so ensure we don't do read barriers there.
Test: while ./art/test/run-test --host --no-dex2oat --jit --host --no-prebuild \
--compact-dex-level none --dex2oat-jobs 4 --no-relocate --runtime-option -Xcheck:jni \
--build-with-javac-dx 674-hiddenapi ; do true; done
Change-Id: I95ec6107c65da25f4b98f7fb77647b3ab382a93f
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 4524448..2101f68 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -776,6 +776,17 @@
UpdateEntrypoints(method, new_quick_code);
}
+void Instrumentation::UpdateNativeMethodsCodeToJitCode(ArtMethod* method, const void* quick_code) {
+ // We don't do any read barrier on `method`'s declaring class in this code, as the JIT might
+ // enter here on a soon-to-be deleted ArtMethod. Updating the entrypoint is OK though, as
+ // the ArtMethod is still in memory.
+ const void* new_quick_code = quick_code;
+ if (UNLIKELY(instrumentation_stubs_installed_) && entry_exit_stubs_installed_) {
+ new_quick_code = GetQuickInstrumentationEntryPoint();
+ }
+ UpdateEntrypoints(method, new_quick_code);
+}
+
void Instrumentation::UpdateMethodsCode(ArtMethod* method, const void* quick_code) {
DCHECK(method->GetDeclaringClass()->IsResolved());
UpdateMethodsCodeImpl(method, quick_code);
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index da63152..46b3f8d 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -280,6 +280,10 @@
void UpdateMethodsCode(ArtMethod* method, const void* quick_code)
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
+ // Update the code of a native method to a JITed stub.
+ void UpdateNativeMethodsCodeToJitCode(ArtMethod* method, const void* quick_code)
+ REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
+
// Update the code of a method to the interpreter respecting any installed stubs from debugger.
void UpdateMethodsCodeToInterpreterEntryPoint(ArtMethod* method)
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 3d3e61b..7f04477 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -1699,7 +1699,9 @@
// can avoid a few expensive GenericJNI calls.
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
for (ArtMethod* m : data->GetMethods()) {
- instrumentation->UpdateMethodsCode(m, entrypoint);
+ // Call the dedicated method instead of the more generic UpdateMethodsCode, because
+ // `m` might be in the process of being deleted.
+ instrumentation->UpdateNativeMethodsCodeToJitCode(m, entrypoint);
}
if (collection_in_progress_) {
GetLiveBitmap()->AtomicTestAndSet(FromCodeToAllocation(data->GetCode()));