From 1cbafe57fe9b3b0d9e27ea26088504663792c9dc Mon Sep 17 00:00:00 2001 From: xing-yunhao-huawei Date: Thu, 3 Jul 2025 16:12:14 +0800 Subject: [PATCH] Optimize UpdateLayOutAndAddTransition 1. Remove redundent hash computation in TransitionDictionary::PutIfAbsent 2. Remove sp in ObjectFactory::CopyAndResort Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/ICJQKY?from=project-issue Change-Id: Ib84b5cfbeeaad45207b83151327266a9e4b7ad36 Signed-off-by: xing-yunhao-huawei --- ecmascript/js_hclass-inl.h | 4 ++-- ecmascript/js_hclass.cpp | 16 +++++++--------- ecmascript/object_factory.cpp | 5 +---- ecmascript/tests/transitions_dictionary_test.cpp | 10 ++++++---- ecmascript/transitions_dictionary.h | 2 +- 5 files changed, 17 insertions(+), 20 deletions(-) diff --git a/ecmascript/js_hclass-inl.h b/ecmascript/js_hclass-inl.h index 6846dc2eb5..e60804fae0 100644 --- a/ecmascript/js_hclass-inl.h +++ b/ecmascript/js_hclass-inl.h @@ -126,7 +126,7 @@ inline JSHClass *JSHClass::FindTransitions(const JSThread *thread, const JSTagge ASSERT(transitions.IsTaggedArray()); TransitionsDictionary *dict = TransitionsDictionary::Cast(transitions.GetTaggedObject()); - auto entry = dict->FindEntry(thread, key, metaData); + auto entry = std::get<0>(dict->FindEntryWithHash(thread, key, metaData)); if (entry == -1) { return nullptr; } @@ -150,7 +150,7 @@ inline JSHClass *JSHClass::FindProtoTransitions(const JSThread *thread, const JS } ASSERT(transitions.IsTaggedArray()); TransitionsDictionary *dict = TransitionsDictionary::Cast(transitions.GetTaggedObject()); - auto entry = dict->FindEntry(thread, key, proto); + auto entry = std::get<0>(dict->FindEntryWithHash(thread, key, proto)); if (entry == -1) { return nullptr; } diff --git a/ecmascript/js_hclass.cpp b/ecmascript/js_hclass.cpp index 8ce089384b..8c8156ca11 100644 --- a/ecmascript/js_hclass.cpp +++ b/ecmascript/js_hclass.cpp @@ -34,11 +34,8 @@ JSHandle TransitionsDictionary::PutIfAbsent(const JSThrea const JSHandle &value, const JSHandle &metaData) { - uint32_t hash = - static_cast(TransitionsDictionary::Hash(thread, key.GetTaggedValue(), metaData.GetTaggedValue())); - /* no need to add key if exist */ - int entry = dictionary->FindEntry(thread, key.GetTaggedValue(), metaData.GetTaggedValue()); + auto [entry, hash] = dictionary->FindEntryWithHash(thread, key.GetTaggedValue(), metaData.GetTaggedValue()); if (entry != -1) { if (dictionary->GetValue(thread, entry).IsUndefined()) { JSTaggedValue weakValue = JSTaggedValue(value->CreateAndGetWeakRef()); @@ -58,7 +55,8 @@ JSHandle TransitionsDictionary::PutIfAbsent(const JSThrea return newDictionary; } -int TransitionsDictionary::FindEntry(const JSThread *thread, const JSTaggedValue &key, const JSTaggedValue &metaData) +std::tuple TransitionsDictionary::FindEntryWithHash(const JSThread *thread, const JSTaggedValue &key, + const JSTaggedValue &metaData) { size_t size = static_cast(Size()); uint32_t count = 1; @@ -70,14 +68,14 @@ int TransitionsDictionary::FindEntry(const JSThread *thread, const JSTaggedValue continue; } if (element.IsUndefined()) { - return -1; + return std::make_tuple(-1, hash); } if (TransitionsDictionary::IsMatch(key, metaData, element, GetAttributes(thread, entry).GetWeakRawValue())) { - return static_cast(entry); + return std::make_tuple(static_cast(entry), hash); } } - return -1; + return std::make_tuple(-1, hash); } JSHandle TransitionsDictionary::Remove(const JSThread *thread, @@ -85,7 +83,7 @@ JSHandle TransitionsDictionary::Remove(const JSThread *th const JSHandle &key, const JSTaggedValue &metaData) { - int entry = table->FindEntry(thread, key.GetTaggedValue(), metaData); + int entry = std::get<0>(table->FindEntryWithHash(thread, key.GetTaggedValue(), metaData)); if (entry == -1) { return table; } diff --git a/ecmascript/object_factory.cpp b/ecmascript/object_factory.cpp index 49433f5e52..67c08a52cc 100644 --- a/ecmascript/object_factory.cpp +++ b/ecmascript/object_factory.cpp @@ -3369,7 +3369,6 @@ JSHandle ObjectFactory::CopyAndReSort(const JSHandle &ol { ASSERT(capacity >= end); JSHandle newArr = CreateLayoutInfo(capacity); - Span sp(old->GetProperties(), end); void *propertiesObj = reinterpret_cast(old->GetProperties()); size_t keyOffset = 0; size_t attrOffset = sizeof(JSTaggedType); @@ -3378,9 +3377,7 @@ JSHandle ObjectFactory::CopyAndReSort(const JSHandle &ol keyOffset)); JSTaggedValue propValue(Barriers::GetTaggedValue(thread_, ToUintPtr(propertiesObj) + i * sizeof(Properties) + attrOffset)); - sp[i].key_ = propKey; - sp[i].attr_ = propValue; - newArr->AddKey(thread_, i, sp[i].key_, PropertyAttributes(sp[i].attr_)); + newArr->AddKey(thread_, i, propKey, PropertyAttributes(propValue)); } return newArr; diff --git a/ecmascript/tests/transitions_dictionary_test.cpp b/ecmascript/tests/transitions_dictionary_test.cpp index 35f1db8950..53a1bb47d1 100644 --- a/ecmascript/tests/transitions_dictionary_test.cpp +++ b/ecmascript/tests/transitions_dictionary_test.cpp @@ -167,7 +167,8 @@ HWTEST_F_L0(TransitionsDictionaryTest, FindEntry) TestCommon(thread, numberOfElements, [&](JSThread *thread, int index, JSHandle &key, JSHandle &value) { transDic = TransitionsDictionary::PutIfAbsent(thread, transDic, key, value, metaData); - int foundEntry = transDic->FindEntry(thread, key.GetTaggedValue(), metaData.GetTaggedValue()); + int foundEntry = std::get<0>(transDic->FindEntryWithHash(thread, key.GetTaggedValue(), + metaData.GetTaggedValue())); EXPECT_EQ(index + 3, foundEntry); // 3 : table header size }); } @@ -183,12 +184,12 @@ HWTEST_F_L0(TransitionsDictionaryTest, RemoveElement) }); auto factory = thread->GetEcmaVM()->GetFactory(); JSHandle key7(factory->NewFromStdString("key7")); // test remove element by "key7" - int foundEntry = transDic->FindEntry(thread, key7.GetTaggedValue(), metaData.GetTaggedValue()); + int foundEntry = std::get<0>(transDic->FindEntryWithHash(thread, key7.GetTaggedValue(), metaData.GetTaggedValue())); EXPECT_EQ(foundEntry, 7 + 3); EXPECT_EQ(transDic->EntriesCount(), 8); transDic->RemoveElement(thread, foundEntry); - foundEntry = transDic->FindEntry(thread, key7.GetTaggedValue(), metaData.GetTaggedValue()); + foundEntry = std::get<0>(transDic->FindEntryWithHash(thread, key7.GetTaggedValue(), metaData.GetTaggedValue())); EXPECT_EQ(foundEntry, -1); // -1 : not found entry EXPECT_EQ(transDic->EntriesCount(), 7); } @@ -206,7 +207,8 @@ HWTEST_F_L0(TransitionsDictionaryTest, PutIfAbsent) JSHandle key(factory->NewFromStdString(keyStr)); JSHandle value(factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT)); transDic = TransitionsDictionary::PutIfAbsent(thread, transDic, key, value, metaData); - int foundEntry = transDic->FindEntry(thread, key.GetTaggedValue(), metaData.GetTaggedValue()); + int foundEntry = std::get<0>(transDic->FindEntryWithHash(thread, key.GetTaggedValue(), + metaData.GetTaggedValue())); EXPECT_EQ(foundEntry, index + 3); JSTaggedValue foundValue = transDic->GetValue(thread, foundEntry); diff --git a/ecmascript/transitions_dictionary.h b/ecmascript/transitions_dictionary.h index 0a1ac2875b..a2461efc95 100644 --- a/ecmascript/transitions_dictionary.h +++ b/ecmascript/transitions_dictionary.h @@ -128,7 +128,7 @@ public: IncreaseHoleEntriesCount(thread); } - int FindEntry(const JSThread *thread, const JSTaggedValue &key, const JSTaggedValue &metaData); + std::tuple FindEntryWithHash(const JSThread *thread, const JSTaggedValue &key, const JSTaggedValue &metaData); template void IterateEntryValue(const JSThread *thread, Callback callback) { -- Gitee