diff --git a/common_components/heap/allocator/alloc_buffer.h b/common_components/heap/allocator/alloc_buffer.h index 3d8a8f9af1f69ff411871e02ea19b4e46d145ab9..f8e7a794de3dec39d0a2526db45f05926f57f015 100755 --- a/common_components/heap/allocator/alloc_buffer.h +++ b/common_components/heap/allocator/alloc_buffer.h @@ -155,8 +155,8 @@ public: private: // slow path HeapAddress TryAllocateOnce(size_t totalSize, AllocType allocType); - HeapAddress AllocateImpl(size_t totalSize, AllocType allocType); - HeapAddress AllocateRawPointerObject(size_t totalSize); + HeapAddress AllocateImpl(size_t totalSize, AllocType allocType, bool isCopy = false); + HeapAddress AllocateRawPointerObject(size_t totalSize, bool isCopy = false); // tlRegion in AllocBuffer is a shortcut for fast allocation. // we should handle failure in RegionManager diff --git a/common_components/heap/allocator/memory_map.cpp b/common_components/heap/allocator/memory_map.cpp index 90420c26bf0ee0c8985de206ee929811910418d1..67e7c9964d2508d2c87e1a43a75dcdc0f3992504 100755 --- a/common_components/heap/allocator/memory_map.cpp +++ b/common_components/heap/allocator/memory_map.cpp @@ -81,7 +81,6 @@ MemoryMap* MemoryMap::MapMemory(size_t reqSize, size_t initSize, const Option& o MemoryMap* MemoryMap::MapMemoryAlignInner4G(uint64_t reqSize, uint64_t initSize, const Option& opt) { static constexpr uint64_t MAX_SUPPORT_CAPACITY = 4ULL * GB; - LOGF_CHECK(reqSize <= MAX_SUPPORT_CAPACITY) << "Max support capacity 4G"; void* mappedAddr = nullptr; reqSize = AllocUtilRndUp(reqSize, ALLOC_UTIL_PAGE_SIZE); diff --git a/common_components/heap/allocator/region_manager.cpp b/common_components/heap/allocator/region_manager.cpp index 24e7ea0be7d547cc2986a248cb0fa43881cd741a..0d8a6ddae836e0c737c11358e5d3a4bae05c0394 100755 --- a/common_components/heap/allocator/region_manager.cpp +++ b/common_components/heap/allocator/region_manager.cpp @@ -551,7 +551,8 @@ void RegionManager::ForEachAwaitingJitFortUnsafe(const std::function totalHeapSize) { + if (!isCopy) { + (void)inactiveZone_.fetch_sub(size); + return nullptr; + } else { + Heap::GetHeap().SetForceThrowOOM(true); + } + } + if (addr < regionHeapEnd_ - size) { region = RegionDesc::InitRegionAt(addr, num, type); size_t idx = region->GetUnitIdx(); diff --git a/common_components/heap/allocator/region_manager.h b/common_components/heap/allocator/region_manager.h index 7c8025df616c1e11835fac83ff016afef4c7c91d..28a391209a601dbbd20ce249a648ea02227ae009 100755 --- a/common_components/heap/allocator/region_manager.h +++ b/common_components/heap/allocator/region_manager.h @@ -138,11 +138,12 @@ public: } } // take a region with *num* units for allocation - RegionDesc* TakeRegion(size_t num, RegionDesc::UnitRole, bool expectPhysicalMem = false, bool allowgc = true); + RegionDesc* TakeRegion(size_t num, RegionDesc::UnitRole, bool expectPhysicalMem = false, bool allowgc = true, + bool isCopy = false); - RegionDesc* TakeRegion(bool expectPhysicalMem, bool allowgc) + RegionDesc* TakeRegion(bool expectPhysicalMem, bool allowgc, bool isCopy = false) { - return TakeRegion(1, RegionDesc::UnitRole::SMALL_SIZED_UNITS, expectPhysicalMem, allowgc); + return TakeRegion(1, RegionDesc::UnitRole::SMALL_SIZED_UNITS, expectPhysicalMem, allowgc, isCopy); } void AddRecentPinnedRegion(RegionDesc* region) @@ -352,6 +353,7 @@ public: size_t GetDirtyUnitCount() const { return freeRegionManager_.GetDirtyUnitCount(); } size_t GetInactiveUnitCount() const { return (regionHeapEnd_ - inactiveZone_) / RegionDesc::UNIT_SIZE; } + size_t GetActiveSize() const { return inactiveZone_ - regionHeapStart_; } inline size_t GetLargeObjectSize() const { diff --git a/common_components/heap/allocator/region_space.cpp b/common_components/heap/allocator/region_space.cpp index 7b45c57dfa717c34f5f17730f98f80fc38d7bd1e..f941d132305a1952d00d631aa1950e8d3d0e4101 100755 --- a/common_components/heap/allocator/region_space.cpp +++ b/common_components/heap/allocator/region_space.cpp @@ -25,11 +25,10 @@ #include "common_components/heap/heap.h" namespace common { - template -RegionDesc* RegionSpace::AllocateThreadLocalRegion(bool expectPhysicalMem) +RegionDesc* RegionSpace::AllocateThreadLocalRegion(bool expectPhysicalMem, bool isCopy) { - RegionDesc* region = regionManager_.TakeRegion(expectPhysicalMem, true); + RegionDesc* region = regionManager_.TakeRegion(expectPhysicalMem, true, isCopy); if constexpr (type == AllocBufferType::TO) { if (region != nullptr) { toSpace_.AddThreadLocalRegion(region); @@ -271,6 +270,13 @@ void RegionSpace::Init(const RuntimeParam& param) MemoryMap::Option opt = MemoryMap::DEFAULT_OPTIONS; opt.tag = "region_heap"; size_t heapSize = param.heapParam.heapSize * KB; + +#if defined(PANDA_TARGET_64) + static constexpr uint64_t MAX_SUPPORT_CAPACITY = 4ULL * GB; + // 2: double heap size + LOGF_CHECK((heapSize / 2)<= MAX_SUPPORT_CAPACITY) << "Max support capacity 4G"; +#endif + size_t totalSize = RegionManager::GetHeapMemorySize(heapSize); size_t regionNum = RegionManager::GetHeapUnitCount(heapSize); #if defined(COMMON_ASAN_SUPPORT) @@ -369,7 +375,7 @@ HeapAddress AllocationBuffer::ToSpaceAllocate(size_t totalSize) heapSpace.HandleFullThreadLocalRegion(tlToRegion_); tlToRegion_ = RegionDesc::NullRegion(); - RegionDesc* r = heapSpace.AllocateThreadLocalRegion(false); + RegionDesc* r = heapSpace.AllocateThreadLocalRegion(false, true); if (UNLIKELY_CC(r == nullptr)) { return 0; } @@ -412,7 +418,7 @@ HeapAddress AllocationBuffer::Allocate(size_t totalSize, AllocType allocType) } // try an allocation but do not handle failure -HeapAddress AllocationBuffer::AllocateImpl(size_t totalSize, AllocType allocType) +HeapAddress AllocationBuffer::AllocateImpl(size_t totalSize, AllocType allocType, bool isCopy) { RegionSpace& heapSpace = reinterpret_cast(Heap::GetHeap().GetAllocator()); @@ -421,7 +427,7 @@ HeapAddress AllocationBuffer::AllocateImpl(size_t totalSize, AllocType allocType heapSpace.HandleFullThreadLocalRegion(tlRegion_); tlRegion_ = RegionDesc::NullRegion(); - RegionDesc* r = heapSpace.AllocateThreadLocalRegion(false); + RegionDesc* r = heapSpace.AllocateThreadLocalRegion(false, isCopy); if (UNLIKELY_CC(r == nullptr)) { return 0; } @@ -443,7 +449,7 @@ HeapAddress AllocationBuffer::AllocateImpl(size_t totalSize, AllocType allocType UNREACHABLE(); } -HeapAddress AllocationBuffer::AllocateRawPointerObject(size_t totalSize) +HeapAddress AllocationBuffer::AllocateRawPointerObject(size_t totalSize, bool isCopy) { RegionDesc* region = tlRawPointerRegions_.GetHeadRegion(); if (region != nullptr) { @@ -456,7 +462,7 @@ HeapAddress AllocationBuffer::AllocateRawPointerObject(size_t totalSize) size_t needRegionNum = totalSize / RegionDesc::UNIT_SIZE + 1; // region should have at least 2 unit needRegionNum = (needRegionNum == 1) ? 2 : needRegionNum; - region = manager.TakeRegion(needRegionNum, RegionDesc::UnitRole::SMALL_SIZED_UNITS); + region = manager.TakeRegion(needRegionNum, RegionDesc::UnitRole::SMALL_SIZED_UNITS, isCopy); if (region == nullptr) { return 0; } diff --git a/common_components/heap/allocator/region_space.h b/common_components/heap/allocator/region_space.h index e250cc2000984abc8674d7169ade985449022698..be4c1e9ad70dd83ba9f08e70836400cb086255d4 100755 --- a/common_components/heap/allocator/region_space.h +++ b/common_components/heap/allocator/region_space.h @@ -74,7 +74,7 @@ public: void Init(const RuntimeParam ¶m) override; template - RegionDesc* AllocateThreadLocalRegion(bool expectPhysicalMem = false); + RegionDesc* AllocateThreadLocalRegion(bool expectPhysicalMem = false, bool isCopy = false); template void HandleFullThreadLocalRegion(RegionDesc* region) noexcept @@ -376,7 +376,7 @@ public: private: enum class TryAllocationThreshold { RESCHEDULE = 3, - TRIGGER_OOM = 5, + TRIGGER_OOM = 3, }; HeapAddress TryAllocateOnce(size_t allocSize, AllocType allocType); bool ShouldRetryAllocation(size_t& tryTimes) const; diff --git a/common_components/heap/collector/heuristic_gc_policy.cpp b/common_components/heap/collector/heuristic_gc_policy.cpp index 5ddf98f95c62ce68dd0a8afaffcc0bf3ee6839a2..ad900667fff1d3f00678fe015a58246fc40cec8c 100644 --- a/common_components/heap/collector/heuristic_gc_policy.cpp +++ b/common_components/heap/collector/heuristic_gc_policy.cpp @@ -34,6 +34,8 @@ void HeuristicGCPolicy::Init() { HeapParam &heapParam = BaseRuntime::GetInstance()->GetHeapParam(); heapSize_ = heapParam.heapSize * KB; + // 2: only half heapSize used allocate + heapSize_ = heapSize_ / 2; } bool HeuristicGCPolicy::ShouldRestrainGCOnStartup() diff --git a/common_components/heap/collector/trace_collector.cpp b/common_components/heap/collector/trace_collector.cpp index fb9d1122d56ffe08321b079b66884895ce1ddb75..4af62919f028e67810c24e3978f9f3b2809cd82a 100755 --- a/common_components/heap/collector/trace_collector.cpp +++ b/common_components/heap/collector/trace_collector.cpp @@ -752,6 +752,10 @@ void TraceCollector::RunGarbageCollection(uint64_t gcIndex, GCReason reason, GCT } UpdateGCStats(); + + if (Heap::GetHeap().GetForceThrowOOM()) { + Heap::throwOOM(); + } } void TraceCollector::CopyFromSpace() diff --git a/common_components/heap/heap.cpp b/common_components/heap/heap.cpp index 1f2342399e52df180a0320a1fac9af90c98d5483..2c89b2e1122721d372ab6eef046f3f85081af3da 100644 --- a/common_components/heap/heap.cpp +++ b/common_components/heap/heap.cpp @@ -91,6 +91,8 @@ public: RegionDesc *region = RegionDesc::GetRegionDescAt(reinterpret_cast(addr)); return region->IsInRecentSpace(); } + bool GetForceThrowOOM() const override { return isForceThrowOOM_; }; + void SetForceThrowOOM(bool val) override { isForceThrowOOM_ = val; }; HeapAddress Allocate(size_t size, AllocType allocType, bool allowGC = true) override; @@ -154,6 +156,7 @@ private: std::atomic isGCEnabled_ = { true }; GCReason gcReason_ = GCReason::GC_REASON_INVALID; + bool isForceThrowOOM_ = { false }; }; // end class HeapImpl static ImmortalWrapper g_heapInstance; diff --git a/common_components/heap/heap.h b/common_components/heap/heap.h index 58d69eab3335cd8a3edadbccd263b3ef461a5c6d..b44867883364b12dbe3f500322a52ccd9ec92e36 100755 --- a/common_components/heap/heap.h +++ b/common_components/heap/heap.h @@ -182,6 +182,8 @@ public: virtual void SetGCReason(GCReason reason) = 0; virtual bool InRecentSpace(const void *addr) = 0; + virtual bool GetForceThrowOOM() const = 0; + virtual void SetForceThrowOOM(bool val) = 0; static void OnHeapCreated(HeapAddress startAddr) { diff --git a/common_components/heap/w_collector/w_collector.cpp b/common_components/heap/w_collector/w_collector.cpp index d1206c13018cfe058b24cda1e384535a025a51f9..afdc50c558b4f6a4335668c2f5d056e3f6fb1478 100755 --- a/common_components/heap/w_collector/w_collector.cpp +++ b/common_components/heap/w_collector/w_collector.cpp @@ -299,7 +299,6 @@ public: if (collector_->IsFromObject(oldObj)) { BaseObject* toVersion = collector_->TryForwardObject(oldObj); if (toVersion == nullptr) { - Heap::throwOOM(); return; } HeapProfilerListener::GetInstance().OnMoveEvent(reinterpret_cast(oldObj), @@ -963,7 +962,6 @@ BaseObject* WCollector::CopyObjectAfterExclusive(BaseObject* obj) } BaseObject* toObj = fwdTable_.RouteObject(obj, size); if (toObj == nullptr) { - Heap::throwOOM(); // ConcurrentGC obj->UnlockExclusive(BaseStateWord::ForwardState::NORMAL); return toObj; diff --git a/ecmascript/mem/mem_map_allocator.cpp b/ecmascript/mem/mem_map_allocator.cpp index 6951f26fa1310d7a0ac2b87082752e6e5d5096f3..a1aac74197ff4caad65e57152f7fdbcff6407ff7 100644 --- a/ecmascript/mem/mem_map_allocator.cpp +++ b/ecmascript/mem/mem_map_allocator.cpp @@ -343,7 +343,15 @@ void MemMapAllocator::AdapterSuitablePoolCapacity(bool isLargeHeap) } else { poolSize = GetPoolSize(MAX_MEM_POOL_CAPACITY); } - capacity_ = std::min(physicalSize * DEFAULT_CAPACITY_RATE, poolSize); + if (g_isEnableCMCGC) { + constexpr double capacityRate = 0.4; + capacity_ = std::min(physicalSize * capacityRate, poolSize); + // 2: double size, for cmc copy + capacity_ *= 2; + } else { + capacity_ = std::min(physicalSize * DEFAULT_CAPACITY_RATE, poolSize); + } + LOG_GC(INFO) << "Ark Auto adapter memory pool capacity:" << capacity_; }