mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-27 04:00:37 +00:00
Signed-off-by: linxiang8 <linxiang8@huawei.com>
Change-Id: I474a84db7d80ec0f5370a4f58df115963e21d90f Change-Id: I471252903083c4d2d15f389b23afbc6c5427f664
This commit is contained in:
parent
fa6dd8ea2f
commit
1fe4846e88
@ -71,7 +71,7 @@ int TransitionsDictionary::FindEntry(const JSTaggedValue &key, const JSTaggedVal
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (TransitionsDictionary::IsMatch(key, metaData, element, GetAttributes(entry))) {
|
||||
if (TransitionsDictionary::IsMatch(key, metaData, element, GetAttributes(entry).GetWeakRawValue())) {
|
||||
return static_cast<int>(entry);
|
||||
}
|
||||
}
|
||||
@ -95,27 +95,29 @@ JSHandle<TransitionsDictionary> TransitionsDictionary::Remove(const JSThread *th
|
||||
void TransitionsDictionary::Rehash(const JSThread *thread, TransitionsDictionary *newTable)
|
||||
{
|
||||
DISALLOW_GARBAGE_COLLECTION;
|
||||
if ((newTable == nullptr) || (newTable->Size() < EntriesCount())) {
|
||||
if (newTable == nullptr) {
|
||||
return;
|
||||
}
|
||||
int size = this->Size();
|
||||
// Rehash elements to new table
|
||||
int entryCount = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
int fromIndex = GetEntryIndex(i);
|
||||
JSTaggedValue k = this->GetKey(i);
|
||||
if (!IsKey(k)) {
|
||||
continue;
|
||||
}
|
||||
int hash = TransitionsDictionary::Hash(k, this->GetAttributes(i));
|
||||
int insertionIndex = GetEntryIndex(newTable->FindInsertIndex(hash));
|
||||
JSTaggedValue tv = Get(fromIndex);
|
||||
newTable->Set(thread, insertionIndex, tv);
|
||||
for (int j = 1; j < TransitionsDictionary::ENTRY_SIZE; j++) {
|
||||
tv = Get(fromIndex + j);
|
||||
newTable->Set(thread, insertionIndex + j, tv);
|
||||
JSTaggedValue v = this->GetValue(i);
|
||||
if (IsKey(k) && TransitionsDictionary::CheckWeakExist(v)) {
|
||||
int hash = TransitionsDictionary::Hash(k, this->GetAttributes(i));
|
||||
int insertionIndex = GetEntryIndex(newTable->FindInsertIndex(hash));
|
||||
JSTaggedValue tv = Get(fromIndex);
|
||||
newTable->Set(thread, insertionIndex, tv);
|
||||
for (int j = 1; j < TransitionsDictionary::ENTRY_SIZE; j++) {
|
||||
tv = Get(fromIndex + j);
|
||||
newTable->Set(thread, insertionIndex + j, tv);
|
||||
}
|
||||
entryCount++;
|
||||
}
|
||||
}
|
||||
newTable->SetEntriesCount(thread, EntriesCount());
|
||||
newTable->SetEntriesCount(thread, entryCount);
|
||||
newTable->SetHoleEntriesCount(thread, 0);
|
||||
}
|
||||
|
||||
|
@ -200,6 +200,14 @@ public:
|
||||
return JSTaggedValue(value_ | TAG_WEAK);
|
||||
}
|
||||
|
||||
inline JSTaggedValue GetWeakRawValue() const
|
||||
{
|
||||
if (IsHeapObject()) {
|
||||
return JSTaggedValue(value_ & (~TAG_WEAK));
|
||||
}
|
||||
return JSTaggedValue(value_);
|
||||
}
|
||||
|
||||
ARK_INLINE bool IsWeak() const
|
||||
{
|
||||
return ((value_ & TAG_WEAK_MASK) == TAG_WEAK);
|
||||
|
@ -132,6 +132,11 @@ public:
|
||||
const JSHandle<CjsModuleCache> &dictionary,
|
||||
const JSHandle<JSTaggedValue> &key,
|
||||
const JSHandle<JSTaggedValue> &value);
|
||||
static int ComputeCompactSize([[maybe_unused]] const JSHandle<CjsModuleCache> &table, int computeHashTableSize,
|
||||
[[maybe_unused]] int tableSize, [[maybe_unused]] int addedElements)
|
||||
{
|
||||
return computeHashTableSize;
|
||||
}
|
||||
static constexpr int ENTRY_KEY_INDEX = 0;
|
||||
static constexpr int ENTRY_VALUE_INDEX = 1;
|
||||
static constexpr int ENTRY_SIZE = 2;
|
||||
|
@ -100,6 +100,11 @@ public:
|
||||
}
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
static int ComputeCompactSize([[maybe_unused]] const JSHandle<SymbolTable> &table, int computeHashTableSize,
|
||||
[[maybe_unused]] int tableSize, [[maybe_unused]] int addedElements)
|
||||
{
|
||||
return computeHashTableSize;
|
||||
}
|
||||
static constexpr int ENTRY_KEY_INDEX = 0;
|
||||
static constexpr int ENTRY_VALUE_INDEX = 1;
|
||||
static constexpr int ENTRY_SIZE = 2;
|
||||
|
@ -74,7 +74,9 @@ public:
|
||||
}
|
||||
return table;
|
||||
}
|
||||
int newSize = ComputeHashTableSize(table->Size() + numOfAddedElements);
|
||||
int newSize = Derived::ComputeCompactSize(table, ComputeHashTableSize(table->Size() + numOfAddedElements),
|
||||
table->Size(), numOfAddedElements);
|
||||
newSize = std::max(newSize, MIN_SHRINK_SIZE);
|
||||
int length = Derived::GetEntryIndex(newSize);
|
||||
JSHandle<Derived> newTable(thread->GetEcmaVM()->GetFactory()->NewDictionaryArray(length));
|
||||
newTable->SetHashTableSize(thread, newSize);
|
||||
@ -488,6 +490,12 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
static int ComputeCompactSize([[maybe_unused]] const JSHandle<Derived> &table, int computeHashTableSize,
|
||||
[[maybe_unused]] int tableSize, [[maybe_unused]] int addedElements)
|
||||
{
|
||||
return computeHashTableSize;
|
||||
}
|
||||
|
||||
static const int NEXT_ENUMERATION_INDEX = HashTableT::SIZE_INDEX + 1;
|
||||
static const int DEFAULT_ELEMENTS_NUMBER = 128;
|
||||
static constexpr int TABLE_HEADER_SIZE = 4;
|
||||
|
@ -59,6 +59,11 @@ public:
|
||||
{
|
||||
return HashTable::Create(thread, numberOfElements);
|
||||
}
|
||||
static int ComputeCompactSize([[maybe_unused]] const JSHandle<TemplateMap> &table, int computeHashTableSize,
|
||||
[[maybe_unused]] int tableSize, [[maybe_unused]] int addedElements)
|
||||
{
|
||||
return computeHashTableSize;
|
||||
}
|
||||
static const int ENTRY_SIZE = 2;
|
||||
static const int ENTRY_KEY_INDEX = 0;
|
||||
static const int ENTRY_VALUE_INDEX = 1;
|
||||
|
@ -111,7 +111,12 @@ public:
|
||||
SetKey(thread, entry, key);
|
||||
JSTaggedValue weakValue = JSTaggedValue(value.CreateAndGetWeakRef());
|
||||
SetValue(thread, entry, weakValue);
|
||||
SetAttributes(thread, entry, metaData);
|
||||
if (!metaData.IsHeapObject()) {
|
||||
SetAttributes(thread, entry, metaData);
|
||||
return;
|
||||
}
|
||||
JSTaggedValue weakMetaData = JSTaggedValue(metaData.CreateAndGetWeakRef());
|
||||
SetAttributes(thread, entry, weakMetaData);
|
||||
}
|
||||
|
||||
inline void RemoveElement(const JSThread *thread, int entry)
|
||||
@ -132,10 +137,33 @@ public:
|
||||
const JSHandle<JSTaggedValue> &key, const JSTaggedValue &metaData);
|
||||
void Rehash(const JSThread *thread, TransitionsDictionary *newTable);
|
||||
|
||||
static bool CheckWeakExist(const JSTaggedValue &value)
|
||||
{
|
||||
if (value == JSTaggedValue::Undefined()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ComputeCompactSize(const JSHandle<TransitionsDictionary> &table, int computeHashTableSize,
|
||||
int tableSize, int addedElements)
|
||||
{
|
||||
int realEntryCount = 0;
|
||||
for (int i = 0; i < tableSize; i++) {
|
||||
// value is weak reference, if not use will be set undefined.
|
||||
if (TransitionsDictionary::CheckWeakExist(table->GetValue(i))) {
|
||||
realEntryCount++;
|
||||
}
|
||||
}
|
||||
return std::min(computeHashTableSize,
|
||||
static_cast<int>(helpers::math::GetPowerOfTwoValue32(realEntryCount + addedElements) * HASH_TABLE_BUFFER));
|
||||
}
|
||||
|
||||
static constexpr int ENTRY_SIZE = 3;
|
||||
static constexpr int ENTRY_KEY_INDEX = 0;
|
||||
static constexpr int ENTRY_VALUE_INDEX = 1;
|
||||
static constexpr int ENTRY_DETAILS_INDEX = 2;
|
||||
static constexpr int HASH_TABLE_BUFFER = 2;
|
||||
DECL_DUMP()
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -51,6 +51,7 @@ group("ark_js_moduletest") {
|
||||
"linkedhashtable:linkedhashtableAction",
|
||||
"loadicbyvalue:loadicbyvalueAction",
|
||||
"localelowercase:localelowercaseAction",
|
||||
"memleak/objectcreate:objectcreateAction",
|
||||
"merge:mergeAction",
|
||||
"module:moduleAction",
|
||||
"moduleImportJson:moduleImportJsonAction",
|
||||
|
18
test/moduletest/memleak/objectcreate/BUILD.gn
Normal file
18
test/moduletest/memleak/objectcreate/BUILD.gn
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_moduletest_action("objectcreate") {
|
||||
deps = []
|
||||
}
|
14
test/moduletest/memleak/objectcreate/expect_output.txt
Normal file
14
test/moduletest/memleak/objectcreate/expect_output.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
log test
|
35
test/moduletest/memleak/objectcreate/objectcreate.js
Normal file
35
test/moduletest/memleak/objectcreate/objectcreate.js
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
function foo() {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
var base = {
|
||||
extend() {
|
||||
return Object.create(this);
|
||||
},
|
||||
test() {
|
||||
print("log test");
|
||||
}
|
||||
}
|
||||
if (i == 0) {
|
||||
var instance = base.extend();
|
||||
base.test()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArkTools.forceFullGC();
|
||||
foo()
|
||||
ArkTools.forceFullGC();
|
Loading…
Reference in New Issue
Block a user