Modify TagggedHashTable grow strategy

Description:When delete holes are more than half of free entries, only rehash instead of grow
issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I615RY?from=project-issue

Signed-off-by: dingwen <dingwen6@huawei.com>
Change-Id: I676d4c7cabd7cf624ad0df01d6a42d02b4751db6
This commit is contained in:
dingwen 2022-11-16 10:25:25 +08:00
parent 49c347b9af
commit 68dcb05a99
6 changed files with 37 additions and 31 deletions

View File

@ -206,10 +206,11 @@ HWTEST_F_L0(PGOProfilerTest, PGOProfilerManagerSample)
{
RuntimeOption option;
option.SetEnableProfile(true);
char currentPath[PATH_MAX + 1];
if (memset_s(currentPath, PATH_MAX + 1, 1, PATH_MAX + 1) != EOK) {
char currentPath[PATH_MAX + 2];
if (memset_s(currentPath, PATH_MAX, 1, PATH_MAX) != EOK) {
ASSERT_TRUE(false);
}
currentPath[PATH_MAX + 1] = '\0';
option.SetProfileDir(currentPath);
vm_ = JSNApi::CreateJSVM(option);
ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";

View File

@ -26,7 +26,7 @@
#include "ecmascript/ecma_vm.h"
#include "ecmascript/js_runtime_options.h"
#include "ecmascript/jspandafile/js_pandafile.h"
#include "ecmascript/log.cpp"
#include "ecmascript/log.h"
#include "ecmascript/mem/mem_controller.h"
#include "ecmascript/napi/include/jsnapi.h"

View File

@ -1283,6 +1283,7 @@ void SnapshotProcessor::DeserializeHugeSpaceObject(uintptr_t beginAddr, HugeObje
size_t regionIndex = SnapshotHelper::GetHugeObjectRegionIndex(wasted);
regionIndexMap_.emplace(regionIndex, region);
ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast<void *>(region->packedData_.begin_), objSize);
if (memcpy_s(ToVoidPtr(region->packedData_.begin_),
objSize,
ToVoidPtr(copyFrom),

View File

@ -63,6 +63,15 @@ public:
int numOfAddedElements = 1)
{
if (!table->IsNeedGrowHashTable(numOfAddedElements)) {
// if deleted entries are more than half of the free entries, rehash to clear holes.
int freeSize = table->Size() - table->EntriesCount() - numOfAddedElements;
if (table->HoleEntriesCount() > freeSize / 2) { // 2: half
int copyLength = Derived::GetEntryIndex(table->Size());
JSHandle<Derived> copyTable(thread->GetEcmaVM()->GetFactory()->NewDictionaryArray(copyLength));
copyTable->SetHashTableSize(thread, table->Size());
table->Rehash(thread, *copyTable);
return copyTable;
}
return table;
}
int newSize = ComputeHashTableSize(table->Size() + numOfAddedElements);
@ -149,18 +158,13 @@ public:
bool IsNeedGrowHashTable(int numOfAddEntries)
{
int entriesCount = EntriesCount();
int numOfDelEntries = HoleEntriesCount();
int currentSize = Size();
int numberFilled = entriesCount + numOfAddEntries;
// needn't to grow table:
// 1. after adding number entries, table have half free entries.
// 2. deleted entries are less than half of the free entries.
// needn't to grow table: after adding number entries, table have half free entries.
const int halfFree = 2;
if ((numberFilled < currentSize) && ((numOfDelEntries <= (currentSize - numberFilled) / halfFree))) {
int neededFree = numberFilled / halfFree;
if (numberFilled + neededFree <= currentSize) {
return false;
}
int neededFree = numberFilled / halfFree;
if (numberFilled + neededFree <= currentSize) {
return false;
}
return true;
}

View File

@ -946,7 +946,7 @@ HWTEST_F_L0(ObjectOperatorTest, Property_Add_004)
EXPECT_FALSE(objectOperator.IsTransition());
}
HWTEST_F_L0(ObjectOperatorTest, Property_DeleteElement)
HWTEST_F_L0(ObjectOperatorTest, Property_DeleteElement1)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<JSTaggedValue> handleKey0(thread, JSTaggedValue(0));
@ -986,6 +986,24 @@ HWTEST_F_L0(ObjectOperatorTest, Property_DeleteElement)
EXPECT_TRUE(JSObject::GetProperty(thread, handleObject2, handleKey1).GetValue()->IsUndefined());
}
HWTEST_F_L0(ObjectOperatorTest, Property_DeleteElement2)
{
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
JSHandle<JSTaggedValue> globalObj = env->GetJSGlobalObject();
JSHandle<JSObject> handleGlobalObject(globalObj);
JSHandle<NumberDictionary> handleDict = NumberDictionary::Create(thread, 4);
handleGlobalObject->SetElements(thread, handleDict.GetTaggedValue());
handleGlobalObject->GetClass()->SetIsDictionaryElement(true);
for (int i = 0; i < 10000; i++) {
JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(i));
JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(i));
JSObject::SetProperty(thread, globalObj, handleKey, handleValue);
JSObject::DeleteProperty(thread, handleGlobalObject, handleKey);
}
auto resultDict = NumberDictionary::Cast(handleGlobalObject->GetElements().GetTaggedObject());
EXPECT_EQ(resultDict->Size(), 4);
}
HWTEST_F_L0(ObjectOperatorTest, Property_DeleteProperty)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();

View File

@ -200,12 +200,6 @@ HWTEST_F_L0(TemplateMapTest, IsNeedGrowHashTable)
}
EXPECT_FALSE(templateMap->IsNeedGrowHashTable(addEntriesCount));
EXPECT_TRUE(templateMap->IsNeedGrowHashTable(addEntriesCount + 1));
templateMap->IncreaseHoleEntriesCount(thread, intNumElementsTempMap - atLeastSize);
EXPECT_FALSE(templateMap->IsNeedGrowHashTable(addEntriesCount));
EXPECT_TRUE(templateMap->IsNeedGrowHashTable(addEntriesCount + 1));
templateMap->IncreaseHoleEntriesCount(thread, 1);
EXPECT_TRUE(templateMap->IsNeedGrowHashTable(addEntriesCount));
EXPECT_TRUE(templateMap->IsNeedGrowHashTable(addEntriesCount + 1));
// Test for the TemplateMap of which the size is 256
intNumElementsTempMap = 256;
JSHandle<TemplateMap> templateMap1 = TemplateMap::Create(thread, intNumElementsTempMap);
@ -218,18 +212,6 @@ HWTEST_F_L0(TemplateMapTest, IsNeedGrowHashTable)
EXPECT_FALSE(templateMap1->IsNeedGrowHashTable(addEntriesCount));
EXPECT_FALSE(templateMap1->IsNeedGrowHashTable(addEntriesCount + 1));
EXPECT_TRUE(templateMap1->IsNeedGrowHashTable(addEntriesCount + 2));
templateMap1->IncreaseHoleEntriesCount(thread, intNumElementsTempMap - atLeastSize - 1);
EXPECT_FALSE(templateMap1->IsNeedGrowHashTable(addEntriesCount));
EXPECT_FALSE(templateMap1->IsNeedGrowHashTable(addEntriesCount + 1));
EXPECT_TRUE(templateMap1->IsNeedGrowHashTable(addEntriesCount + 2));
templateMap1->IncreaseHoleEntriesCount(thread, 1);
EXPECT_FALSE(templateMap1->IsNeedGrowHashTable(addEntriesCount));
EXPECT_TRUE(templateMap1->IsNeedGrowHashTable(addEntriesCount + 1));
EXPECT_TRUE(templateMap1->IsNeedGrowHashTable(addEntriesCount + 2));
templateMap1->IncreaseHoleEntriesCount(thread, 1);
EXPECT_TRUE(templateMap1->IsNeedGrowHashTable(addEntriesCount));
EXPECT_TRUE(templateMap1->IsNeedGrowHashTable(addEntriesCount + 1));
EXPECT_TRUE(templateMap1->IsNeedGrowHashTable(addEntriesCount + 2));
}
/*