mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 10:09:54 +00:00
Optimize Map/Set.clear
Change-Id: Ide6559f8de763eb3b09d58d9b4fa8edd6f1c9b9a Signed-off-by: Artem Udovichenko <artem.udovichenko@huawei.com>
This commit is contained in:
parent
4ee8e5f33e
commit
ce2066a698
@ -373,13 +373,32 @@ GateRef LinkedHashTableStubBuilder<LinkedHashTableType, LinkedHashTableObject>::
|
||||
env->SubCfgEntry(&entry);
|
||||
Label exit(env);
|
||||
Label setLinked(env);
|
||||
DEFVARIABLE(result, VariableType::JS_ANY(), linkedTable);
|
||||
|
||||
GateRef newTable = Create(Int32(LinkedHashTableType::MIN_CAPACITY));
|
||||
Label reuseExistingTable(env);
|
||||
Label createNewTable(env);
|
||||
GateRef cap = GetCapacity(linkedTable);
|
||||
GateRef minCapacity = Int32(LinkedHashTableType::MIN_CAPACITY);
|
||||
BRANCH(Equal(cap, minCapacity), &reuseExistingTable, &createNewTable);
|
||||
|
||||
Bind(&reuseExistingTable);
|
||||
size_t length = LinkedHashTableType::GetLengthOfTable(LinkedHashTableType::MIN_CAPACITY);
|
||||
for (size_t i = LinkedHashTableType::ELEMENTS_START_INDEX; i < length; ++i) {
|
||||
SetValueToTaggedArray(VariableType::JS_NOT_POINTER(), glue_, linkedTable, Int32(i), Hole());
|
||||
}
|
||||
GateRef numberOfElements = GetNumberOfElements(linkedTable);
|
||||
GateRef numberOfDeletedElements = GetNumberOfDeletedElements(linkedTable);
|
||||
SetNumberOfElements(linkedTable, Int32(0));
|
||||
SetNumberOfDeletedElements(linkedTable, Int32Add(numberOfElements, numberOfDeletedElements));
|
||||
Jump(&exit);
|
||||
|
||||
Bind(&createNewTable);
|
||||
GateRef newTable = Create(minCapacity);
|
||||
result = newTable;
|
||||
Label noException(env);
|
||||
BRANCH(TaggedIsException(newTable), &exit, &noException);
|
||||
Bind(&noException);
|
||||
|
||||
GateRef cap = GetCapacity(linkedTable);
|
||||
Label capGreaterZero(env);
|
||||
BRANCH(Int32GreaterThan(cap, Int32(0)), &capGreaterZero, &exit);
|
||||
Bind(&capGreaterZero);
|
||||
@ -392,8 +411,9 @@ GateRef LinkedHashTableStubBuilder<LinkedHashTableType, LinkedHashTableObject>::
|
||||
}
|
||||
|
||||
Bind(&exit);
|
||||
GateRef res = *result;
|
||||
env->SubCfgExit();
|
||||
return newTable;
|
||||
return res;
|
||||
}
|
||||
|
||||
template GateRef LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject>::Clear(GateRef);
|
||||
|
@ -177,6 +177,13 @@ bool LinkedHashMap::Has(const JSThread *thread, JSTaggedValue key) const
|
||||
|
||||
JSHandle<LinkedHashMap> LinkedHashMap::Clear(const JSThread *thread, const JSHandle<LinkedHashMap> &table)
|
||||
{
|
||||
if (table->Capacity() == LinkedHashMap::MIN_CAPACITY) {
|
||||
table->FillRangeWithSpecialValue(JSTaggedValue::Hole(), LinkedHashMap::ELEMENTS_START_INDEX,
|
||||
table->GetLength());
|
||||
table->SetNumberOfDeletedElements(thread, table->NumberOfDeletedElements() + table->NumberOfElements());
|
||||
table->SetNumberOfElements(thread, 0);
|
||||
return table;
|
||||
}
|
||||
JSHandle<LinkedHashMap> newMap = LinkedHashMap::Create(thread, LinkedHashMap::MIN_CAPACITY,
|
||||
table.GetTaggedValue().IsInSharedHeap() ? MemSpaceKind::SHARED : MemSpaceKind::LOCAL);
|
||||
if (table->Capacity() > 0) {
|
||||
@ -224,6 +231,13 @@ bool LinkedHashSet::Has(const JSThread *thread, JSTaggedValue key) const
|
||||
|
||||
JSHandle<LinkedHashSet> LinkedHashSet::Clear(const JSThread *thread, const JSHandle<LinkedHashSet> &table)
|
||||
{
|
||||
if (table->Capacity() == LinkedHashSet::MIN_CAPACITY) {
|
||||
table->FillRangeWithSpecialValue(JSTaggedValue::Hole(), LinkedHashSet::ELEMENTS_START_INDEX,
|
||||
table->GetLength());
|
||||
table->SetNumberOfDeletedElements(thread, table->NumberOfDeletedElements() + table->NumberOfElements());
|
||||
table->SetNumberOfElements(thread, 0);
|
||||
return table;
|
||||
}
|
||||
JSHandle<LinkedHashSet> newSet = LinkedHashSet::Create(thread, LinkedHashSet::MIN_CAPACITY,
|
||||
table.GetTaggedValue().IsInSharedHeap() ? MemSpaceKind::SHARED : MemSpaceKind::LOCAL);
|
||||
if (table->Capacity() > 0) {
|
||||
|
@ -63,6 +63,11 @@ public:
|
||||
|
||||
static JSHandle<Derived> Shrink(const JSThread *thread, const JSHandle<Derived> &table, int additionalCapacity = 0);
|
||||
|
||||
static int GetLengthOfTable(int numberOfElements)
|
||||
{
|
||||
return ELEMENTS_START_INDEX + numberOfElements + numberOfElements * (HashObject::ENTRY_SIZE + 1);
|
||||
}
|
||||
|
||||
inline bool HasSufficientCapacity(int numOfAddElements) const
|
||||
{
|
||||
int numberOfElements = NumberOfElements();
|
||||
|
@ -141,10 +141,15 @@ inline bool TaggedArray::HasDuplicateEntry() const
|
||||
|
||||
void TaggedArray::InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t length, uint32_t extraLength)
|
||||
{
|
||||
ASSERT(initValue.IsSpecial());
|
||||
SetLength(length);
|
||||
SetExtraLength(extraLength);
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
FillRangeWithSpecialValue(initValue, 0, length);
|
||||
}
|
||||
|
||||
void TaggedArray::FillRangeWithSpecialValue(JSTaggedValue initValue, uint32_t start, uint32_t end)
|
||||
{
|
||||
ASSERT(initValue.IsSpecial());
|
||||
for (uint32_t i = start; i < end; i++) {
|
||||
size_t offset = JSTaggedValue::TaggedTypeSize() * i;
|
||||
Barriers::SetPrimitive<JSTaggedType>(GetData(), offset, initValue.GetRawData());
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ public:
|
||||
JSHandle<TaggedArray> &dstElements, uint32_t effectiveLength);
|
||||
|
||||
inline void InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t length, uint32_t extraLength = 0);
|
||||
inline void FillRangeWithSpecialValue(JSTaggedValue initValue, uint32_t start, uint32_t end);
|
||||
|
||||
static inline bool ShouldTrim(uint32_t oldLength, uint32_t newLength)
|
||||
{
|
||||
|
@ -225,3 +225,66 @@ try {
|
||||
} catch (error) {
|
||||
print("Caught an error: " + error);
|
||||
}
|
||||
|
||||
// Map.clear tests
|
||||
map = new Map();
|
||||
map.set(1, null);
|
||||
map.set(2, null);
|
||||
map.set(3, null);
|
||||
let beginNotTought = map.entries();
|
||||
let midNotTought = map.entries();
|
||||
midNotTought.next();
|
||||
let begin = map.entries(); // points to (1, null)
|
||||
let mid = map.entries(); // points to (2, null)
|
||||
mid.next();
|
||||
let last = map.entries(); // points to (3, null)
|
||||
last.next();
|
||||
last.next();
|
||||
let end = map.entries(); // points to the end
|
||||
while (end.next().done) {
|
||||
}
|
||||
map.clear();
|
||||
if (map.size != 0) {
|
||||
throw new Error("Map size must be 0");
|
||||
}
|
||||
if (!begin.next().done) {
|
||||
throw new Error("Invalid 'begin' iterator");
|
||||
}
|
||||
if (!mid.next().done) {
|
||||
throw new Error("Invalid 'mid' iterator");
|
||||
}
|
||||
if (!last.next().done) {
|
||||
throw new Error("Invalid 'last' iterator");
|
||||
}
|
||||
if (!end.next().done) {
|
||||
throw new Error("Invalid 'end' iterator");
|
||||
}
|
||||
map.set(-1, null);
|
||||
map.set(-2, null);
|
||||
map.set(-3, null);
|
||||
let v = beginNotTought.next();
|
||||
if (v.done) {
|
||||
throw new Error("Invalid 'beginNotTought' iterator");
|
||||
}
|
||||
if (v.value[0] != -1) {
|
||||
throw new Error("Invalid 'beginNotTought' iterator's value");
|
||||
}
|
||||
v = midNotTought.next();
|
||||
if (v.done) {
|
||||
throw new Error("Invalid 'midNotTought' iterator");
|
||||
}
|
||||
if (v.value[0] != -1) {
|
||||
throw new Error("Invalid 'midNotTought' iterator's value");
|
||||
}
|
||||
if (!begin.next().done) {
|
||||
throw new Error("Invalid 'begin' iterator");
|
||||
}
|
||||
if (!mid.next().done) {
|
||||
throw new Error("Invalid 'mid' iterator");
|
||||
}
|
||||
if (!last.next().done) {
|
||||
throw new Error("Invalid 'last' iterator");
|
||||
}
|
||||
if (!end.next().done) {
|
||||
throw new Error("Invalid 'end' iterator");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user