diff options
author | 2023-10-06 14:24:54 +0100 | |
---|---|---|
committer | 2023-10-10 09:16:10 +0000 | |
commit | ed04dc23003dc5611a1e5b2ac2190b633dc6193e (patch) | |
tree | 0bb1da6dbb8d662cd523ee3a9e30eb6a046913c8 | |
parent | 30ec3a148e19fba2d54cdf482b16a9b82bec6da4 (diff) |
Speed-up Class.getSimpleName()
Bug: 303631821
Test: atest LibcoreBenchmarkTests:libcore.benchmark.ClassTest
Change-Id: I106aed4fe24b9138005c4928a7690d10c6df1d0a
-rw-r--r-- | runtime/mirror/string-inl.h | 14 | ||||
-rw-r--r-- | runtime/mirror/string.cc | 18 | ||||
-rw-r--r-- | runtime/mirror/string.h | 6 | ||||
-rw-r--r-- | runtime/native/java_lang_Class.cc | 39 |
4 files changed, 66 insertions, 11 deletions
diff --git a/runtime/mirror/string-inl.h b/runtime/mirror/string-inl.h index 66e0ef0bdb..0d18b78044 100644 --- a/runtime/mirror/string-inl.h +++ b/runtime/mirror/string-inl.h @@ -67,6 +67,20 @@ int32_t String::FastIndexOf(MemoryType* chars, int32_t ch, int32_t start) { return -1; } +template <typename MemoryType> +int32_t String::LastIndexOf(MemoryType* chars, int32_t ch, int32_t from_index) { + DCHECK_LT(from_index, GetLength()); + const MemoryType* start = chars; + const MemoryType* p = chars + from_index; + while (p >= start) { + if (*p == ch) { + return p - chars; + } + p--; + } + return -1; +} + inline int32_t String::ComputeHashCode() { uint32_t hash = IsCompressed() ? ComputeUtf16Hash(GetValueCompressed(), GetLength()) diff --git a/runtime/mirror/string.cc b/runtime/mirror/string.cc index 839e01a045..2a26d50d79 100644 --- a/runtime/mirror/string.cc +++ b/runtime/mirror/string.cc @@ -37,10 +37,10 @@ namespace mirror { int32_t String::FastIndexOf(int32_t ch, int32_t start) { int32_t count = GetLength(); - if (start < 0) { + if (start >= count) { + return -1; + } else if (start < 0) { start = 0; - } else if (start > count) { - start = count; } if (IsCompressed()) { return FastIndexOf<uint8_t>(GetValueCompressed(), ch, start); @@ -49,6 +49,18 @@ int32_t String::FastIndexOf(int32_t ch, int32_t start) { } } +int32_t String::LastIndexOf(int32_t ch) { + int32_t count = GetLength(); + if (count == 0) { + return -1; + } + if (IsCompressed()) { + return LastIndexOf<uint8_t>(GetValueCompressed(), ch, count - 1); + } else { + return LastIndexOf<uint16_t>(GetValue(), ch, count - 1); + } +} + int32_t String::ComputeAndSetHashCode() { int32_t new_hash_code = ComputeHashCode(); SetHashCode(new_hash_code); diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h index 90eb09211c..c0f9b39b1f 100644 --- a/runtime/mirror/string.h +++ b/runtime/mirror/string.h @@ -215,6 +215,12 @@ class MANAGED String final : public Object { int32_t FastIndexOf(MemoryType* chars, int32_t ch, int32_t start) REQUIRES_SHARED(Locks::mutator_lock_); + int32_t LastIndexOf(int32_t ch) REQUIRES_SHARED(Locks::mutator_lock_); + + template <typename MemoryType> + int32_t LastIndexOf(MemoryType* chars, int32_t ch, int32_t from_index) + REQUIRES_SHARED(Locks::mutator_lock_); + int32_t CompareTo(ObjPtr<String> other) REQUIRES_SHARED(Locks::mutator_lock_); static ObjPtr<CharArray> ToCharArray(Handle<String> h_this, Thread* self) 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<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis))); + MutableHandle<mirror::String> h_name(hs.NewHandle<mirror::String>(nullptr)); + MutableHandle<mirror::String> h_inner_name(hs.NewHandle<mirror::String>(nullptr)); if (klass->IsObsoleteObject()) { ThrowRuntimeException("Obsolete Object!"); return nullptr; } - if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) { - return nullptr; + if (!klass->IsProxyClass() && klass->GetDexCache() != nullptr) { + ObjPtr<mirror::String> 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<jstring>( + 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<jstring>(h_inner_name.Get()); + } + } } - ObjPtr<mirror::String> 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<jstring>(class_name); + int32_t dot_index = h_name->LastIndexOf('.'); + if (dot_index < 0) { + return soa.AddLocalReference<jstring>(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<jstring>( + 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"), |