jni: Add @CriticalNative optimization to speed up JNI transitions
Change-Id: I963059ac3a72dd8e6a867596c356d7062deb6da7
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index f9bc249..1392399 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -335,20 +335,30 @@
}
bool ArtMethod::IsAnnotatedWithFastNative() {
+ return IsAnnotatedWith(WellKnownClasses::dalvik_annotation_optimization_FastNative,
+ DexFile::kDexVisibilityBuild);
+}
+
+bool ArtMethod::IsAnnotatedWithCriticalNative() {
+ return IsAnnotatedWith(WellKnownClasses::dalvik_annotation_optimization_CriticalNative,
+ DexFile::kDexVisibilityBuild);
+}
+
+bool ArtMethod::IsAnnotatedWith(jclass klass, uint32_t visibility) {
Thread* self = Thread::Current();
ScopedObjectAccess soa(self);
StackHandleScope<1> shs(self);
const DexFile& dex_file = GetDeclaringClass()->GetDexFile();
- mirror::Class* fast_native_annotation =
- soa.Decode<mirror::Class*>(WellKnownClasses::dalvik_annotation_optimization_FastNative);
- Handle<mirror::Class> fast_native_handle(shs.NewHandle(fast_native_annotation));
+ mirror::Class* annotation = soa.Decode<mirror::Class*>(klass);
+ DCHECK(annotation->IsAnnotation());
+ Handle<mirror::Class> annotation_handle(shs.NewHandle(annotation));
// Note: Resolves any method annotations' classes as a side-effect.
// -- This seems allowed by the spec since it says we can preload any classes
// referenced by another classes's constant pool table.
- return dex_file.IsMethodAnnotationPresent(this, fast_native_handle, DexFile::kDexVisibilityBuild);
+ return dex_file.IsMethodAnnotationPresent(this, annotation_handle, visibility);
}
bool ArtMethod::EqualParameters(Handle<mirror::ObjectArray<mirror::Class>> params) {
diff --git a/runtime/art_method.h b/runtime/art_method.h
index b25087c..8051a1f 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -378,6 +378,10 @@
// -- Independent of kAccFastNative access flags.
bool IsAnnotatedWithFastNative();
+ // Checks to see if the method was annotated with @dalvik.annotation.optimization.CriticalNative
+ // -- Unrelated to the GC notion of "critical".
+ bool IsAnnotatedWithCriticalNative();
+
// Returns true if this method could be overridden by a default method.
bool IsOverridableByDefaultMethod() REQUIRES_SHARED(Locks::mutator_lock_);
@@ -776,6 +780,8 @@
} ptr_sized_fields_;
private:
+ bool IsAnnotatedWith(jclass klass, uint32_t visibility);
+
static constexpr size_t PtrSizedFieldsOffset(PointerSize pointer_size) {
// Round up to pointer size for padding field. Tested in art_method.cc.
return RoundUp(offsetof(ArtMethod, hotness_count_) + sizeof(hotness_count_),
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index 741b682..dba0a81 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -608,6 +608,10 @@
EXPECT_TRUE(actual_.empty()) << actual_;
}
+void CheckJniAbortCatcher::Check(const std::string& expected_text) {
+ Check(expected_text.c_str());
+}
+
void CheckJniAbortCatcher::Check(const char* expected_text) {
EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
<< "Expected to find: " << expected_text << "\n"
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index 00394e9..b2090b7 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -184,6 +184,7 @@
~CheckJniAbortCatcher();
+ void Check(const std::string& expected_text);
void Check(const char* expected_text);
private:
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 2c99275..5f5fbc8 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -30,6 +30,7 @@
namespace art {
jclass WellKnownClasses::com_android_dex_Dex;
+jclass WellKnownClasses::dalvik_annotation_optimization_CriticalNative;
jclass WellKnownClasses::dalvik_annotation_optimization_FastNative;
jclass WellKnownClasses::dalvik_system_DexFile;
jclass WellKnownClasses::dalvik_system_DexPathList;
@@ -216,6 +217,8 @@
void WellKnownClasses::Init(JNIEnv* env) {
com_android_dex_Dex = CacheClass(env, "com/android/dex/Dex");
+ dalvik_annotation_optimization_CriticalNative =
+ CacheClass(env, "dalvik/annotation/optimization/CriticalNative");
dalvik_annotation_optimization_FastNative = CacheClass(env, "dalvik/annotation/optimization/FastNative");
dalvik_system_DexFile = CacheClass(env, "dalvik/system/DexFile");
dalvik_system_DexPathList = CacheClass(env, "dalvik/system/DexPathList");
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index 25c9424..ce710ff 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -41,6 +41,7 @@
REQUIRES_SHARED(Locks::mutator_lock_);
static jclass com_android_dex_Dex;
+ static jclass dalvik_annotation_optimization_CriticalNative;
static jclass dalvik_annotation_optimization_FastNative;
static jclass dalvik_system_DexFile;
static jclass dalvik_system_DexPathList;