mirror of
https://gitee.com/openharmony/arkcompiler_runtime_core
synced 2024-11-23 14:50:51 +00:00
!2708 Fix object allocation in tenured region
Merge pull request !2708 from Panferov Ivan/pinned-bug
This commit is contained in:
commit
b8f67368ff
@ -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")
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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_;
|
||||
|
Loading…
Reference in New Issue
Block a user