summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mythri Alle <mythria@google.com> 2024-12-31 15:30:27 +0000
committer Mythri Alle <mythria@google.com> 2025-01-05 19:41:46 -0800
commit26040bb0286ca351158c675dcedd32bc85dd6dd1 (patch)
treed4d81884db6a38d2311478ca5f8c6510532d2992
parent8842f9debe16fd1251cd6dbe16fd8c168098c61d (diff)
Add a test to check AOT code is used when method tracing is stopped
Adds a test to check that AOT code is restored when available when method tracing is stopped. Also updates isAotCompiled to work with more methods. Bug: 303686344 Test: art/test.py -t 2286 Change-Id: I4b7abdeef4aa2bddb85e9cf86f3d844974b69dba
-rw-r--r--test/2286-method-tracing-aot-code/expected-stderr.txt0
-rw-r--r--test/2286-method-tracing-aot-code/expected-stdout.txt1
-rw-r--r--test/2286-method-tracing-aot-code/info.txt1
-rw-r--r--test/2286-method-tracing-aot-code/src/Main.java124
-rw-r--r--test/common/runtime_state.cc29
5 files changed, 140 insertions, 15 deletions
diff --git a/test/2286-method-tracing-aot-code/expected-stderr.txt b/test/2286-method-tracing-aot-code/expected-stderr.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/2286-method-tracing-aot-code/expected-stderr.txt
diff --git a/test/2286-method-tracing-aot-code/expected-stdout.txt b/test/2286-method-tracing-aot-code/expected-stdout.txt
new file mode 100644
index 0000000000..6a5618ebc6
--- /dev/null
+++ b/test/2286-method-tracing-aot-code/expected-stdout.txt
@@ -0,0 +1 @@
+JNI_OnLoad called
diff --git a/test/2286-method-tracing-aot-code/info.txt b/test/2286-method-tracing-aot-code/info.txt
new file mode 100644
index 0000000000..2c5b5a42f7
--- /dev/null
+++ b/test/2286-method-tracing-aot-code/info.txt
@@ -0,0 +1 @@
+Tests that AOT code is used if available after tracing has stopped.
diff --git a/test/2286-method-tracing-aot-code/src/Main.java b/test/2286-method-tracing-aot-code/src/Main.java
new file mode 100644
index 0000000000..138f6fd11c
--- /dev/null
+++ b/test/2286-method-tracing-aot-code/src/Main.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+public class Main {
+ private static final String TEMP_FILE_NAME_PREFIX = "test";
+ private static final String TEMP_FILE_NAME_SUFFIX = ".trace";
+ private static File file;
+
+ public static void main(String[] args) throws Exception {
+ System.loadLibrary(args[0]);
+ String name = System.getProperty("java.vm.name");
+ if (!"Dalvik".equals(name)) {
+ System.out.println("This test is not supported on " + name);
+ return;
+ }
+
+ if (VMDebug.getMethodTracingMode() != 0) {
+ VMDebug.$noinline$stopMethodTracing();
+ }
+
+ Main m = new Main();
+ boolean isAot_main_before = isAotCompiled(Main.class, "main");
+ boolean isAot_callOuter_before = isAotCompiled(Main.class, "callOuterFunction");
+
+ file = createTempFile();
+ FileOutputStream out_file = new FileOutputStream(file);
+ VMDebug.startMethodTracing(file.getPath(), out_file.getFD(), /*buffer_size=*/0, /*flags=*/0,
+ /*sampling=*/false, /*sampling_interval*/ 0, /*streaming=*/true);
+ m.$noinline$doSomeWork();
+
+ VMDebug.$noinline$stopMethodTracing();
+ out_file.close();
+ file.delete();
+
+ boolean isAot_main_after = isAotCompiled(Main.class, "main");
+ boolean isAot_callOuter_after = isAotCompiled(Main.class, "callOuterFunction");
+ if (isAot_main_before != isAot_main_after) {
+ throw new Exception("AOT code for main not restored after method tracing? "
+ + isAot_main_before + " " + isAot_main_after);
+ }
+
+ if (isAot_callOuter_before != isAot_callOuter_after) {
+ throw new Exception("AOT code for callOuter not restored after method tracing? "
+ + isAot_callOuter_before + " " + isAot_callOuter_after);
+ }
+ }
+
+ private static File createTempFile() throws Exception {
+ try {
+ return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
+ } catch (IOException e) {
+ System.setProperty("java.io.tmpdir", "/data/local/tmp");
+ try {
+ return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
+ } catch (IOException e2) {
+ System.setProperty("java.io.tmpdir", "/sdcard");
+ return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
+ }
+ }
+ }
+
+ public void callOuterFunction() {
+ callLeafFunction();
+ }
+
+ public void callLeafFunction() {}
+
+ public void $noinline$doSomeWork() {
+ callOuterFunction();
+ callLeafFunction();
+ }
+
+ private static class VMDebug {
+ private static final Method startMethodTracingMethod;
+ private static final Method stopMethodTracingMethod;
+ private static final Method getMethodTracingModeMethod;
+ static {
+ try {
+ Class<?> c = Class.forName("dalvik.system.VMDebug");
+ startMethodTracingMethod = c.getDeclaredMethod("startMethodTracing", String.class,
+ FileDescriptor.class, Integer.TYPE, Integer.TYPE, Boolean.TYPE,
+ Integer.TYPE, Boolean.TYPE);
+ stopMethodTracingMethod = c.getDeclaredMethod("stopMethodTracing");
+ getMethodTracingModeMethod = c.getDeclaredMethod("getMethodTracingMode");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void startMethodTracing(String filename, FileDescriptor fd, int bufferSize,
+ int flags, boolean samplingEnabled, int intervalUs, boolean streaming)
+ throws Exception {
+ startMethodTracingMethod.invoke(
+ null, filename, fd, bufferSize, flags, samplingEnabled, intervalUs, streaming);
+ }
+ public static void $noinline$stopMethodTracing() throws Exception {
+ stopMethodTracingMethod.invoke(null);
+ }
+ public static int getMethodTracingMode() throws Exception {
+ return (int) getMethodTracingModeMethod.invoke(null);
+ }
+ }
+
+ private native static boolean isAotCompiled(Class<?> cls, String methodName);
+}
diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc
index c046e26755..6ff27f98f4 100644
--- a/test/common/runtime_state.cc
+++ b/test/common/runtime_state.cc
@@ -164,6 +164,19 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_compiledWithOptimizing(JNIEnv* e
return JNI_TRUE;
}
+static ArtMethod* GetMethod(ScopedObjectAccess& soa, jclass cls, const ScopedUtfChars& chars)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ CHECK(chars.c_str() != nullptr);
+ ArtMethod* method = soa.Decode<mirror::Class>(cls)->FindDeclaredDirectMethodByName(
+ chars.c_str(), kRuntimePointerSize);
+ if (method == nullptr) {
+ method = soa.Decode<mirror::Class>(cls)->FindDeclaredVirtualMethodByName(chars.c_str(),
+ kRuntimePointerSize);
+ }
+ DCHECK(method != nullptr) << "Unable to find method called " << chars.c_str();
+ return method;
+}
+
extern "C" JNIEXPORT jboolean JNICALL Java_Main_isAotCompiled(JNIEnv* env,
jclass,
jclass cls,
@@ -172,8 +185,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_isAotCompiled(JNIEnv* env,
ScopedObjectAccess soa(self);
ScopedUtfChars chars(env, method_name);
CHECK(chars.c_str() != nullptr);
- ArtMethod* method = soa.Decode<mirror::Class>(cls)->FindDeclaredDirectMethodByName(
- chars.c_str(), kRuntimePointerSize);
+ ArtMethod* method = GetMethod(soa, cls, chars);
const void* oat_code = method->GetOatMethodQuickCode(kRuntimePointerSize);
if (oat_code == nullptr) {
return false;
@@ -182,19 +194,6 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_isAotCompiled(JNIEnv* env,
return actual_code == oat_code;
}
-static ArtMethod* GetMethod(ScopedObjectAccess& soa, jclass cls, const ScopedUtfChars& chars)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- CHECK(chars.c_str() != nullptr);
- ArtMethod* method = soa.Decode<mirror::Class>(cls)->FindDeclaredDirectMethodByName(
- chars.c_str(), kRuntimePointerSize);
- if (method == nullptr) {
- method = soa.Decode<mirror::Class>(cls)->FindDeclaredVirtualMethodByName(
- chars.c_str(), kRuntimePointerSize);
- }
- DCHECK(method != nullptr) << "Unable to find method called " << chars.c_str();
- return method;
-}
-
extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasJitCompiledEntrypoint(JNIEnv* env,
jclass,
jclass cls,