Enable InMemoryDexClassLoader vdex only for Q+ targets
Some legacy apps depend on InMemoryDexClassLoader not loading classes
immediately. Disable verification result caching for them.
Bug: 2131483
Test: art/test.py -b -r -t 692 -t 693
Change-Id: Ie230b837c2fdd5cda13e06faba501fe07e1f65bc
diff --git a/libartbase/base/sdk_version.h b/libartbase/base/sdk_version.h
index e2dbc50..219ac86 100644
--- a/libartbase/base/sdk_version.h
+++ b/libartbase/base/sdk_version.h
@@ -33,6 +33,7 @@
kO = 26u,
kO_MR1 = 27u,
kP = 28u,
+ kQ = 29u,
kMax = std::numeric_limits<uint32_t>::max(),
};
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index 92acdd0..0543644 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -29,6 +29,7 @@
#include "base/file_utils.h"
#include "base/logging.h" // For VLOG.
#include "base/mutex-inl.h"
+#include "base/sdk_version.h"
#include "base/stl_util.h"
#include "base/systrace.h"
#include "class_linker.h"
@@ -965,15 +966,22 @@
void OatFileManager::RunBackgroundVerification(const std::vector<const DexFile*>& dex_files,
jobject class_loader,
const char* class_loader_context) {
- if (Runtime::Current()->IsJavaDebuggable()) {
+ Runtime* const runtime = Runtime::Current();
+ Thread* const self = Thread::Current();
+
+ if (runtime->IsJavaDebuggable()) {
// Threads created by ThreadPool ("runtime threads") are not allowed to load
// classes when debuggable to match class-initialization semantics
// expectations. Do not verify in the background.
return;
}
- Thread* const self = Thread::Current();
- if (Runtime::Current()->IsShuttingDown(self)) {
+ if (!IsSdkVersionSetAndAtLeast(runtime->GetTargetSdkVersion(), SdkVersion::kQ)) {
+ // Do not run for legacy apps as they may depend on the previous class loader behaviour.
+ return;
+ }
+
+ if (runtime->IsShuttingDown(self)) {
// Not allowed to create new threads during runtime shutdown.
return;
}
diff --git a/test/692-vdex-inmem-loader/src/Main.java b/test/692-vdex-inmem-loader/src/Main.java
index 6beef5c..53f4c36 100644
--- a/test/692-vdex-inmem-loader/src/Main.java
+++ b/test/692-vdex-inmem-loader/src/Main.java
@@ -64,6 +64,9 @@
System.loadLibrary(args[0]);
ClassLoader[] loaders = null;
+ // Feature only enabled for target SDK version Q and later.
+ setTargetSdkVersion(/* Q */ 29);
+
// Feature is disabled in debuggable mode because runtime threads are not
// allowed to load classes.
boolean featureEnabled = !isDebuggable();
@@ -108,6 +111,7 @@
}
private static native boolean isDebuggable();
+ private static native int setTargetSdkVersion(int version);
private static native void setProcessDataDir(String path);
private static native void waitForVerifier();
private static native boolean areClassesVerified(ClassLoader loader);
diff --git a/test/693-vdex-inmem-loader-evict/src/Main.java b/test/693-vdex-inmem-loader-evict/src/Main.java
index 7d9da1b..e06f232 100644
--- a/test/693-vdex-inmem-loader-evict/src/Main.java
+++ b/test/693-vdex-inmem-loader-evict/src/Main.java
@@ -24,6 +24,9 @@
public static void main(String[] args) throws Exception {
System.loadLibrary(args[0]);
+ // Feature only enabled for target SDK version Q and later.
+ setTargetSdkVersion(/* Q */ 29);
+
if (isDebuggable()) {
// Background verification is disabled in debuggable mode. This test makes
// no sense then.
@@ -60,6 +63,7 @@
}
private static native boolean isDebuggable();
+ private static native int setTargetSdkVersion(int version);
private static native void setProcessDataDir(String path);
private static native void waitForVerifier();
private static native boolean hasVdexFile(ClassLoader loader);
diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc
index 0ee3bcf..db70eec 100644
--- a/test/common/runtime_state.cc
+++ b/test/common/runtime_state.cc
@@ -375,4 +375,8 @@
return Runtime::Current()->IsJavaDebuggable() ? JNI_TRUE : JNI_FALSE;
}
+extern "C" JNIEXPORT void JNICALL Java_Main_setTargetSdkVersion(JNIEnv*, jclass, jint version) {
+ Runtime::Current()->SetTargetSdkVersion(static_cast<uint32_t>(version));
+}
+
} // namespace art