From ed04dc23003dc5611a1e5b2ac2190b633dc6193e Mon Sep 17 00:00:00 2001 From: Victor Chang Date: Fri, 6 Oct 2023 14:24:54 +0100 Subject: Speed-up Class.getSimpleName() Bug: 303631821 Test: atest LibcoreBenchmarkTests:libcore.benchmark.ClassTest Change-Id: I106aed4fe24b9138005c4928a7690d10c6df1d0a --- runtime/native/java_lang_Class.cc | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'runtime/native/java_lang_Class.cc') diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc index 5e54f85b9d..83736668bb 100644 --- a/runtime/native/java_lang_Class.cc +++ b/runtime/native/java_lang_Class.cc @@ -681,22 +681,45 @@ static jint Class_getInnerClassFlags(JNIEnv* env, jobject javaThis, jint default return mirror::Class::GetInnerClassFlags(klass, defaultValue); } -static jstring Class_getInnerClassName(JNIEnv* env, jobject javaThis) { +static jstring Class_getSimpleNameNative(JNIEnv* env, jobject javaThis) { ScopedFastNativeObjectAccess soa(env); - StackHandleScope<1> hs(soa.Self()); + StackHandleScope<3> hs(soa.Self()); Handle klass(hs.NewHandle(DecodeClass(soa, javaThis))); + MutableHandle h_name(hs.NewHandle(nullptr)); + MutableHandle h_inner_name(hs.NewHandle(nullptr)); if (klass->IsObsoleteObject()) { ThrowRuntimeException("Obsolete Object!"); return nullptr; } - if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) { - return nullptr; + if (!klass->IsProxyClass() && klass->GetDexCache() != nullptr) { + ObjPtr class_name = nullptr; + if (annotations::GetInnerClass(klass, &class_name)) { + if (class_name == nullptr) { // Anonymous class + gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); + return soa.AddLocalReference( + mirror::String::AllocEmptyString(soa.Self(), allocator_type)); + } + h_inner_name.Assign(class_name); + if (annotations::GetDeclaringClass(klass) != nullptr || // member class + annotations::GetEnclosingMethod(klass) != nullptr) { // local class + return soa.AddLocalReference(h_inner_name.Get()); + } + } } - ObjPtr class_name = nullptr; - if (!annotations::GetInnerClass(klass, &class_name)) { + + h_name.Assign(mirror::Class::ComputeName(klass)); + if (h_name == nullptr) { return nullptr; } - return soa.AddLocalReference(class_name); + int32_t dot_index = h_name->LastIndexOf('.'); + if (dot_index < 0) { + return soa.AddLocalReference(h_name.Get()); + } + int32_t start_index = dot_index + 1; + int32_t length = h_name->GetLength() - start_index; + gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); + return soa.AddLocalReference( + mirror::String::AllocFromString(soa.Self(), length, h_name, start_index, allocator_type)); } static jobjectArray Class_getSignatureAnnotation(JNIEnv* env, jobject javaThis) { @@ -971,7 +994,6 @@ static JNINativeMethod gMethods[] = { FAST_NATIVE_METHOD(Class, getEnclosingConstructorNative, "()Ljava/lang/reflect/Constructor;"), FAST_NATIVE_METHOD(Class, getEnclosingMethodNative, "()Ljava/lang/reflect/Method;"), FAST_NATIVE_METHOD(Class, getInnerClassFlags, "(I)I"), - FAST_NATIVE_METHOD(Class, getInnerClassName, "()Ljava/lang/String;"), FAST_NATIVE_METHOD(Class, getInterfacesInternal, "()[Ljava/lang/Class;"), FAST_NATIVE_METHOD(Class, getPrimitiveClass, "(Ljava/lang/String;)Ljava/lang/Class;"), FAST_NATIVE_METHOD(Class, getNameNative, "()Ljava/lang/String;"), @@ -981,6 +1003,7 @@ static JNINativeMethod gMethods[] = { FAST_NATIVE_METHOD(Class, getPublicDeclaredFields, "()[Ljava/lang/reflect/Field;"), FAST_NATIVE_METHOD(Class, getRecordAnnotationElement, "(Ljava/lang/String;Ljava/lang/Class;)[Ljava/lang/Object;"), FAST_NATIVE_METHOD(Class, getSignatureAnnotation, "()[Ljava/lang/String;"), + FAST_NATIVE_METHOD(Class, getSimpleNameNative, "()Ljava/lang/String;"), FAST_NATIVE_METHOD(Class, isAnonymousClass, "()Z"), FAST_NATIVE_METHOD(Class, isDeclaredAnnotationPresent, "(Ljava/lang/Class;)Z"), FAST_NATIVE_METHOD(Class, isRecord0, "()Z"), -- cgit v1.2.3-59-g8ed1b