Huge object memap bigaddr

Description:Huge object memap bigaddr
Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I9787J?from=project-issue

Signed-off-by: dingwen <dingwen6@huawei.com>
Change-Id: I8b77791411e534281580ce5191d3716b50e7359c
This commit is contained in:
dingwen 2024-03-10 16:52:08 +08:00
parent a751be4b1d
commit ffdb6bfe09
3 changed files with 64 additions and 21 deletions

View File

@ -1600,9 +1600,6 @@ bool Heap::NeedStopCollection()
return true;
}
LOG_GC(INFO) << "SmartGC: force expand will cause OOM, have to trigger gc";
GetNewSpace()->SetOverShootSize(
GetNewSpace()->GetCommittedSize() - GetNewSpace()->GetInitialCapacity() +
config_.GetOldSpaceOvershootSize());
return false;
}

View File

@ -25,6 +25,58 @@ MemMapAllocator *MemMapAllocator::GetInstance()
return vmAllocator_;
}
void MemMapAllocator::InitializeRegularRegionMap([[maybe_unused]] size_t alignment)
{
#if defined(PANDA_TARGET_64) && !WIN_OR_MAC_OR_IOS_PLATFORM
size_t initialRegularObjectCapacity = std::min(capacity_ / 2, INITIAL_REGULAR_OBJECT_CAPACITY);
size_t i = 0;
while (i < MEM_MAP_RETRY_NUM) {
void *addr = reinterpret_cast<void *>(ToUintPtr(RandomGenerateBigAddr(REGULAR_OBJECT_MEM_MAP_BEGIN_ADDR)) +
i * STEP_INCREASE_MEM_MAP_ADDR);
MemMap memMap = PageMap(initialRegularObjectCapacity, PAGE_PROT_NONE, alignment, addr);
if (ToUintPtr(memMap.GetMem()) >= ToUintPtr(addr)) {
PageTag(memMap.GetMem(), memMap.GetSize(), PageTagType::MEMPOOL_CACHE);
PageRelease(memMap.GetMem(), memMap.GetSize());
memMapPool_.InsertMemMap(memMap);
memMapPool_.SplitMemMapToCache(memMap);
break;
} else {
PageUnmap(memMap);
LOG_ECMA(ERROR) << "Regular object mem map big addr fail: " << errno;
}
i++;
}
#endif
}
void MemMapAllocator::InitializeHugeRegionMap(size_t alignment)
{
size_t initialHugeObjectCapacity = std::min(capacity_ / 2, INITIAL_HUGE_OBJECT_CAPACITY);
#if defined(PANDA_TARGET_64) && !WIN_OR_MAC_OR_IOS_PLATFORM
size_t i = 0;
while (i <= MEM_MAP_RETRY_NUM) {
void *addr = reinterpret_cast<void *>(ToUintPtr(RandomGenerateBigAddr(HUGE_OBJECT_MEM_MAP_BEGIN_ADDR)) +
i * STEP_INCREASE_MEM_MAP_ADDR);
MemMap memMap = PageMap(initialHugeObjectCapacity, PAGE_PROT_NONE, alignment, addr);
if (ToUintPtr(memMap.GetMem()) >= ToUintPtr(addr) || i == MEM_MAP_RETRY_NUM) {
PageTag(memMap.GetMem(), memMap.GetSize(), PageTagType::MEMPOOL_CACHE);
PageRelease(memMap.GetMem(), memMap.GetSize());
memMapFreeList_.Initialize(memMap, capacity_);
break;
} else {
PageUnmap(memMap);
LOG_ECMA(ERROR) << "Huge object mem map big addr fail: " << errno;
}
i++;
}
#else
MemMap hugeMemMap = PageMap(initialHugeObjectCapacity, PAGE_PROT_NONE, alignment);
PageTag(hugeMemMap.GetMem(), hugeMemMap.GetSize(), PageTagType::MEMPOOL_CACHE);
PageRelease(hugeMemMap.GetMem(), hugeMemMap.GetSize());
memMapFreeList_.Initialize(hugeMemMap, capacity_);
#endif
}
MemMap MemMapAllocator::Allocate(const uint32_t threadId, size_t size, size_t alignment,
const std::string &spaceName, bool regular, bool isMachineCode)
{

View File

@ -252,19 +252,8 @@ public:
{
AdapterSuitablePoolCapacity();
memMapTotalSize_ = 0;
size_t initialHugeObjectCapacity = std::min(capacity_ / 2, INITIAL_HUGE_OBJECT_CAPACITY);
MemMap hugeMemMap = PageMap(initialHugeObjectCapacity, PAGE_PROT_NONE, alignment);
PageTag(hugeMemMap.GetMem(), hugeMemMap.GetSize(), PageTagType::MEMPOOL_CACHE);
PageRelease(hugeMemMap.GetMem(), hugeMemMap.GetSize());
memMapFreeList_.Initialize(hugeMemMap, capacity_);
#if defined(PANDA_TARGET_64) && !WIN_OR_MAC_OR_IOS_PLATFORM
size_t initialRegularObjectCapacity = std::min(capacity_ / 2, INITIAL_REGULAR_OBJECT_CAPACITY);
MemMap memMap = PageMap(initialRegularObjectCapacity, PAGE_PROT_NONE, alignment, RandomGenerateBigAddr());
PageTag(memMap.GetMem(), memMap.GetSize(), PageTagType::MEMPOOL_CACHE);
PageRelease(memMap.GetMem(), memMap.GetSize());
memMapPool_.InsertMemMap(memMap);
memMapPool_.SplitMemMapToCache(memMap);
#endif
InitializeHugeRegionMap(alignment);
InitializeRegularRegionMap(alignment);
}
void Finalize()
@ -304,8 +293,10 @@ public:
void CacheOrFree(void *mem, size_t size, bool isRegular, size_t cachedSize);
private:
void InitializeRegularRegionMap(size_t alignment);
void InitializeHugeRegionMap(size_t alignment);
// Random generate big mem map addr to avoid js heap is written by others
void *RandomGenerateBigAddr()
void *RandomGenerateBigAddr(uint64_t addr)
{
// Use the current time as the seed
unsigned seed = static_cast<unsigned>(std::chrono::system_clock::now().time_since_epoch().count());
@ -315,14 +306,17 @@ private:
std::uniform_int_distribution<uint64_t> distribution(0, RANDOM_NUM_MAX);
uint64_t randomNum = distribution(generator);
// Big addr random change in 0x10000000000 ~ 0x1FF00000000
return reinterpret_cast<void *>(BIG_MEM_MAP_BEGIN_ADDR + (randomNum << UINT32_BIT));
// Big addr random change in 0x2000000000 ~ 0x2FF0000000
return reinterpret_cast<void *>(addr + (randomNum << RANDOM_SHIFT_BIT));
}
static constexpr size_t REGULAR_REGION_MMAP_SIZE = 4_MB;
static constexpr uint64_t BIG_MEM_MAP_BEGIN_ADDR = 0x10000000000;
static constexpr uint64_t HUGE_OBJECT_MEM_MAP_BEGIN_ADDR = 0x1000000000;
static constexpr uint64_t REGULAR_OBJECT_MEM_MAP_BEGIN_ADDR = 0x2000000000;
static constexpr uint64_t STEP_INCREASE_MEM_MAP_ADDR = 0x1000000000;
static constexpr size_t RANDOM_NUM_MAX = 0xFF;
static constexpr size_t UINT32_BIT = 32;
static constexpr size_t RANDOM_SHIFT_BIT = 28;
static constexpr size_t MEM_MAP_RETRY_NUM = 10;
void AdapterSuitablePoolCapacity();
void Free(void *mem, size_t size, bool isRegular);