!2708 Fix object allocation in tenured region

Merge pull request !2708 from Panferov Ivan/pinned-bug
This commit is contained in:
openharmony_ci 2024-11-02 09:19:28 +00:00 committed by Gitee
commit b8f67368ff
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 46 additions and 48 deletions

View File

@ -113,5 +113,6 @@ if (NOT CMAKE_CROSSCOMPILING)
endif()
add_ets_gc_test(FILE heap_info_test.sts OPTIONS MODE "INT")
add_ets_gc_test(FILE free_heap_size_test.sts OPTIONS "--gc-type=g1-gc" "--gc-trigger-type=debug" "--run-gc-in-place" "--gc-workers-count=1" MODE "INT")
add_ets_gc_test(FILE alloc_pinned.sts OPTIONS "--gc-type=g1-gc" "--heap-verifier=fail_on_verification:pre:into:before_g1_concurrent:post" MODE "INT")
# Running tests via API calls
add_ets_napi_gc_test(FILE pending_exception_gc_test.sts CPP_SOURCE pending_exception_test.cpp OPTIONS "--gc-type=g1-gc" "--gc-trigger-type=debug-never")

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2024 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 main() {
let size = 10;
let arr: boolean[] = [];
for (let iter = 0; iter < 1000; ++iter) {
try {
arr = GC.allocatePinnedBooleanArray(size);
} catch (e) {
console.log("Allocation exception")
}
}
}

View File

@ -138,6 +138,8 @@ template <RegionFlag REGION_TYPE>
void *RegionAllocator<AllocConfigT, LockConfigT>::AllocRegular(size_t alignSize)
{
static constexpr bool IS_ATOMIC = std::is_same_v<LockConfigT, RegionAllocatorLockConfig::CommonLock>;
static_assert((REGION_TYPE == RegionFlag::IS_EDEN) || (REGION_TYPE == RegionFlag::IS_OLD) ||
(REGION_TYPE == RegionFlag::IS_PINNED));
// NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon)
if constexpr (REGION_TYPE == RegionFlag::IS_EDEN) {
void *mem = GetCurrentRegion<IS_ATOMIC, REGION_TYPE>()->template Alloc<IS_ATOMIC>(alignSize);
@ -161,48 +163,17 @@ void *RegionAllocator<AllocConfigT, LockConfigT>::AllocRegular(size_t alignSize)
return mem;
}
// NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon)
if constexpr (REGION_TYPE == RegionFlag::IS_OLD) {
void *mem = nullptr;
Region *regionTo = PopFromRegionQueue<IS_ATOMIC, REGION_TYPE>();
if (regionTo != nullptr) {
// Here we need memory barrier to make the allocation visible
// in all threads before SetCurrentRegion
mem = regionTo->template Alloc<IS_ATOMIC>(alignSize);
if (mem != nullptr) {
PushToRegionQueue<IS_ATOMIC, REGION_TYPE>(regionTo);
return mem;
}
}
os::memory::LockHolder lock(this->regionLock_);
regionTo = this->template CreateAndSetUpNewRegion<AllocConfigT>(REGION_SIZE, REGION_TYPE);
if (LIKELY(regionTo != nullptr)) {
// Here we need memory barrier to make the allocation visible
// in all threads before SetCurrentRegion
mem = regionTo->template Alloc<IS_ATOMIC>(alignSize);
PushToRegionQueue<IS_ATOMIC, REGION_TYPE>(regionTo);
}
return mem;
}
UNREACHABLE();
return nullptr;
}
template <typename AllocConfigT, typename LockConfigT>
void *RegionAllocator<AllocConfigT, LockConfigT>::AllocRegularPinned(size_t alignSize)
{
static constexpr bool IS_ATOMIC = std::is_same_v<LockConfigT, RegionAllocatorLockConfig::CommonLock>;
void *mem = nullptr;
Region *regionTo = PopFromRegionQueue<IS_ATOMIC, RegionFlag::IS_PINNED>();
Region *regionTo = PopFromRegionQueue<IS_ATOMIC, REGION_TYPE>();
if (regionTo != nullptr) {
// Here we need memory barrier to make the allocation visible
// in all threads before SetCurrentRegion
mem = regionTo->template Alloc<IS_ATOMIC>(alignSize);
if (mem != nullptr) {
regionTo->PinObject();
PushToRegionQueue<IS_ATOMIC, RegionFlag::IS_PINNED>(regionTo);
if constexpr (REGION_TYPE == RegionFlag::IS_PINNED) {
regionTo->PinObject();
}
PushToRegionQueue<IS_ATOMIC, REGION_TYPE>(regionTo);
return mem;
}
}
@ -212,13 +183,12 @@ void *RegionAllocator<AllocConfigT, LockConfigT>::AllocRegularPinned(size_t alig
if (LIKELY(regionTo != nullptr)) {
// Here we need memory barrier to make the allocation visible
// in all threads before SetCurrentRegion
mem = regionTo->Alloc<IS_ATOMIC>(alignSize);
mem = regionTo->template Alloc<IS_ATOMIC>(alignSize);
if constexpr (REGION_TYPE == RegionFlag::IS_PINNED) {
regionTo->PinObject();
}
PushToRegionQueue<IS_ATOMIC, REGION_TYPE>(regionTo);
}
if (mem != nullptr) {
regionTo->PinObject();
PushToRegionQueue<IS_ATOMIC, RegionFlag::IS_PINNED>(regionTo);
}
return mem;
}
@ -233,11 +203,7 @@ void *RegionAllocator<AllocConfigT, LockConfigT>::Alloc(size_t size, Alignment a
// for nonmovable or large size object, allocate a seprate large region for it
if (this->GetSpaceType() != SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT &&
LIKELY(alignSize <= GetMaxRegularObjectSize())) {
if (pinned) {
mem = AllocRegularPinned(alignSize);
} else {
mem = AllocRegular<REGION_TYPE>(alignSize);
}
mem = pinned ? AllocRegular<IS_PINNED>(alignSize) : AllocRegular<REGION_TYPE>(alignSize);
} else {
os::memory::LockHolder lock(this->regionLock_);
Region *region = this->template CreateAndSetUpNewRegion<AllocConfigT>(
@ -252,6 +218,12 @@ void *RegionAllocator<AllocConfigT, LockConfigT>::Alloc(size_t size, Alignment a
AllocConfigT::OnAlloc(alignSize, this->spaceType_, this->memStats_);
AllocConfigT::MemoryInit(mem);
}
// Do it after memory init because we can reach this memory after setting live bitmap
if ((REGION_TYPE == RegionFlag::IS_OLD) || pinned) {
auto liveBitmap = this->GetRegion(reinterpret_cast<ObjectHeader *>(mem))->GetLiveBitmap();
ASSERT(liveBitmap != nullptr);
liveBitmap->AtomicTestAndSet(mem);
}
}
return mem;
}

View File

@ -503,7 +503,6 @@ private:
template <RegionFlag REGION_TYPE>
void *AllocRegular(size_t alignSize);
void *AllocRegularPinned(size_t alignSize);
TLAB *CreateTLABInRegion(Region *region, size_t size);
Region fullRegion_;