Allow late lookup for @CriticalNative methods.
Test: Add and enable tests in 178-app-image-native-method
Test: Add and enable tests in jni_compiler_test
Test: Manually step through the new stub in GDB and check
that backtrace works at various points.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: aosp_taimen-userdebug boots.
Test: run-gtests.sh
Test: testrunner.py --target --optimizing
Bug: 112189621
Change-Id: If094e5062acbb99eefa88f2afb4815f93730cb82
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc
index fb9704a..405c9ec 100644
--- a/compiler/jni/jni_compiler_test.cc
+++ b/compiler/jni/jni_compiler_test.cc
@@ -45,10 +45,25 @@
return count + 1;
}
+// Note: JNI name mangling "_" -> "_1".
+extern "C" JNIEXPORT jint JNICALL Java_MyClassNatives_bar_1Fast(JNIEnv*, jobject, jint count) {
+ return count + 1;
+}
+
extern "C" JNIEXPORT jint JNICALL Java_MyClassNatives_sbar(JNIEnv*, jclass, jint count) {
return count + 1;
}
+// Note: JNI name mangling "_" -> "_1".
+extern "C" JNIEXPORT jint JNICALL Java_MyClassNatives_sbar_1Fast(JNIEnv*, jclass, jint count) {
+ return count + 1;
+}
+
+// Note: JNI name mangling "_" -> "_1".
+extern "C" JNIEXPORT jint JNICALL Java_MyClassNatives_sbar_1Critical(jint count) {
+ return count + 1;
+}
+
// TODO: In the Baker read barrier configuration, add checks to ensure
// the Marking Register's value is correct.
@@ -71,6 +86,11 @@
return gCurrentJni == static_cast<uint32_t>(JniKind::kCritical);
}
+// Is the current native method under test @FastNative?
+static bool IsCurrentJniFast() {
+ return gCurrentJni == static_cast<uint32_t>(JniKind::kFast);
+}
+
// Is the current native method a plain-old non-annotated native?
static bool IsCurrentJniNormal() {
return gCurrentJni == static_cast<uint32_t>(JniKind::kNormal);
@@ -352,6 +372,7 @@
void MaxParamNumberImpl();
void WithoutImplementationImpl();
void WithoutImplementationRefReturnImpl();
+ void StaticWithoutImplementationImpl();
void StackArgsIntsFirstImpl();
void StackArgsFloatsFirstImpl();
void StackArgsMixedImpl();
@@ -373,9 +394,7 @@
// Test the normal compiler and normal generic JNI only.
// The following features are unsupported in @FastNative:
-// 1) JNI stubs (lookup via dlsym) when methods aren't explicitly registered
-// 2) synchronized keyword
-// -- TODO: We can support (1) if we remove the mutator lock assert during stub lookup.
+// 1) synchronized keyword
# define JNI_TEST_NORMAL_ONLY(TestName) \
TEST_F(JniCompilerTest, TestName ## NormalCompiler) { \
ScopedCheckHandleScope top_handle_scope_check; \
@@ -612,8 +631,8 @@
#define NORMAL_JNI_ONLY_NOWRAP(func) \
({ ASSERT_TRUE(IsCurrentJniNormal()); reinterpret_cast<void*>(&(func)); })
// Same as above, but with nullptr. When we want to test the stub functionality.
-#define NORMAL_JNI_ONLY_NULLPTR \
- ({ ASSERT_TRUE(IsCurrentJniNormal()); nullptr; })
+#define NORMAL_OR_FAST_JNI_ONLY_NULLPTR \
+ ({ ASSERT_TRUE(IsCurrentJniNormal() || IsCurrentJniFast()); nullptr; })
int gJava_MyClassNatives_foo_calls[kJniKindCount] = {};
@@ -636,8 +655,8 @@
JNI_TEST(CompileAndRunNoArgMethod)
void JniCompilerTest::CompileAndRunIntMethodThroughStubImpl() {
- SetUpForTest(false, "bar", "(I)I", NORMAL_JNI_ONLY_NULLPTR);
- // calling through stub will link with &Java_MyClassNatives_bar
+ SetUpForTest(false, "bar", "(I)I", NORMAL_OR_FAST_JNI_ONLY_NULLPTR);
+ // calling through stub will link with &Java_MyClassNatives_bar{,_1Fast}
std::string reason;
ASSERT_TRUE(Runtime::Current()->GetJavaVM()->
@@ -648,12 +667,12 @@
EXPECT_EQ(25, result);
}
-// TODO: Support @FastNative and @CriticalNative through stubs.
-JNI_TEST_NORMAL_ONLY(CompileAndRunIntMethodThroughStub)
+// Note: @CriticalNative is only for static methods.
+JNI_TEST(CompileAndRunIntMethodThroughStub)
void JniCompilerTest::CompileAndRunStaticIntMethodThroughStubImpl() {
- SetUpForTest(true, "sbar", "(I)I", NORMAL_JNI_ONLY_NULLPTR);
- // calling through stub will link with &Java_MyClassNatives_sbar
+ SetUpForTest(true, "sbar", "(I)I", nullptr);
+ // calling through stub will link with &Java_MyClassNatives_sbar{,_1Fast,_1Critical}
std::string reason;
ASSERT_TRUE(Runtime::Current()->GetJavaVM()->
@@ -664,8 +683,7 @@
EXPECT_EQ(43, result);
}
-// TODO: Support @FastNative and @CriticalNative through stubs.
-JNI_TEST_NORMAL_ONLY(CompileAndRunStaticIntMethodThroughStub)
+JNI_TEST_CRITICAL(CompileAndRunStaticIntMethodThroughStub)
int gJava_MyClassNatives_fooI_calls[kJniKindCount] = {};
jint Java_MyClassNatives_fooI(JNIEnv*, jobject, jint x) {
@@ -1894,7 +1912,7 @@
// This will lead to error messages in the log.
ScopedLogSeverity sls(LogSeverity::FATAL);
- SetUpForTest(false, "withoutImplementation", "()V", NORMAL_JNI_ONLY_NULLPTR);
+ SetUpForTest(false, "withoutImplementation", "()V", NORMAL_OR_FAST_JNI_ONLY_NULLPTR);
env_->CallVoidMethod(jobj_, jmethod_);
@@ -1902,9 +1920,7 @@
EXPECT_TRUE(env_->ExceptionCheck() == JNI_TRUE);
}
-// TODO: Don't test @FastNative here since it goes through a stub lookup (unsupported) which would
-// normally fail with an exception, but fails with an assert.
-JNI_TEST_NORMAL_ONLY(WithoutImplementation)
+JNI_TEST(WithoutImplementation)
void JniCompilerTest::WithoutImplementationRefReturnImpl() {
// This will lead to error messages in the log.
@@ -1913,7 +1929,7 @@
SetUpForTest(false,
"withoutImplementationRefReturn",
"()Ljava/lang/Object;",
- NORMAL_JNI_ONLY_NULLPTR);
+ NORMAL_OR_FAST_JNI_ONLY_NULLPTR);
env_->CallObjectMethod(jobj_, jmethod_);
@@ -1921,8 +1937,21 @@
EXPECT_TRUE(env_->ExceptionCheck() == JNI_TRUE);
}
-// TODO: Should work for @FastNative too.
-JNI_TEST_NORMAL_ONLY(WithoutImplementationRefReturn)
+JNI_TEST(WithoutImplementationRefReturn)
+
+void JniCompilerTest::StaticWithoutImplementationImpl() {
+ // This will lead to error messages in the log.
+ ScopedLogSeverity sls(LogSeverity::FATAL);
+
+ SetUpForTest(true, "staticWithoutImplementation", "()V", nullptr);
+
+ env_->CallStaticVoidMethod(jklass_, jmethod_);
+
+ EXPECT_TRUE(Thread::Current()->IsExceptionPending());
+ EXPECT_TRUE(env_->ExceptionCheck() == JNI_TRUE);
+}
+
+JNI_TEST_CRITICAL(StaticWithoutImplementation)
void Java_MyClassNatives_stackArgsIntsFirst(JNIEnv*, jclass, jint i1, jint i2, jint i3,
jint i4, jint i5, jint i6, jint i7, jint i8, jint i9,