!8726 Adjust native size trigger gc strategy

Merge pull request !8726 from dingwen/stragery_br
This commit is contained in:
openharmony_ci 2024-08-24 03:51:38 +00:00 committed by Gitee
commit d89dfcbe62
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
10 changed files with 78 additions and 36 deletions

View File

@ -60,7 +60,7 @@ JSTaggedValue BuiltinsGc::RegisterNativeAllocation(EcmaRuntimeCallInfo *info)
THROW_RANGE_ERROR_AND_RETURN(thread, "The value must be non negative", JSTaggedValue::Exception());
}
heap->IncreaseNativeBindingSize(size);
heap->TryTriggerFullMarkByNativeSize();
heap->TryTriggerFullMarkOrGCByNativeSize();
if (heap->GetConcurrentMarker()->IsTriggeredConcurrentMark()) {
heap->WaitConcurrentMarkingFinished();
heap->GetConcurrentMarker()->HandleMarkingFinished();

View File

@ -97,8 +97,8 @@ public:
sharedHeapLimitGrowingFactor_ = 2; // 2: growing factor
sharedHeapLimitGrowingStep_ = 20_MB;
incObjSizeThresholdInSensitive_ = 40_MB;
incNativeSizeTriggerSharedCM_ = 256_MB;
incNativeSizeTriggerGC_ = 768_MB;
stepNativeSizeInc_ = 256_MB;
maxNativeSizeInc_ = 768_MB;
} else if (maxHeapSize_ < HIGH_MEMORY) { // 128_MB ~ 256_MB
minSemiSpaceSize_ = 2_MB;
maxSemiSpaceSize_ = 8_MB;
@ -120,8 +120,8 @@ public:
sharedHeapLimitGrowingFactor_ = 2; // 2: growing factor
sharedHeapLimitGrowingStep_ = 40_MB;
incObjSizeThresholdInSensitive_ = 40_MB;
incNativeSizeTriggerSharedCM_ = 256_MB;
incNativeSizeTriggerGC_ = 768_MB;
stepNativeSizeInc_ = 256_MB;
maxNativeSizeInc_ = 768_MB;
} else { // 256_MB ~ 384_MB
minSemiSpaceSize_ = 2_MB;
maxSemiSpaceSize_ = 16_MB;
@ -143,8 +143,8 @@ public:
sharedHeapLimitGrowingFactor_ = 4; // 4: growing factor
sharedHeapLimitGrowingStep_ = 80_MB;
incObjSizeThresholdInSensitive_ = 80_MB;
incNativeSizeTriggerSharedCM_ = 300_MB;
incNativeSizeTriggerGC_ = 1_GB;
stepNativeSizeInc_ = 300_MB;
maxNativeSizeInc_ = 1_GB;
}
}
@ -243,14 +243,14 @@ public:
return incObjSizeThresholdInSensitive_;
}
size_t GetIncNativeSizeTriggerSharedCM() const
size_t GetStepNativeSizeInc() const
{
return incNativeSizeTriggerSharedCM_;
return stepNativeSizeInc_;
}
size_t GetIncNativeSizeTriggerGC() const
size_t GetMaxNativeSizeInc() const
{
return incNativeSizeTriggerGC_;
return maxNativeSizeInc_;
}
uint32_t GetMaxStackSize() const
@ -305,8 +305,8 @@ private:
size_t sharedHeapLimitGrowingFactor_ {0};
size_t sharedHeapLimitGrowingStep_ {0};
size_t incObjSizeThresholdInSensitive_ {0};
size_t incNativeSizeTriggerSharedCM_ {0};
size_t incNativeSizeTriggerGC_ {0};
size_t stepNativeSizeInc_ {0};
size_t maxNativeSizeInc_ {0};
size_t maxJSSerializerSize_ {0};
uint32_t maxStackSize_ {0};
};

View File

@ -222,8 +222,8 @@ void SharedHeap::Initialize(NativeAreaAllocator *nativeAreaAllocator, HeapRegion
sAppSpawnSpace_ = new SharedAppSpawnSpace(this, oldSpaceCapacity);
growingFactor_ = config_.GetSharedHeapLimitGrowingFactor();
growingStep_ = config_.GetSharedHeapLimitGrowingStep();
incNativeSizeTriggerSharedCM_= config_.GetIncNativeSizeTriggerSharedCM();
incNativeSizeTriggerSharedGC_ = config_.GetIncNativeSizeTriggerGC();
incNativeSizeTriggerSharedCM_= config_.GetStepNativeSizeInc();
incNativeSizeTriggerSharedGC_ = config_.GetMaxNativeSizeInc();
dThread_ = dThread;
}
@ -790,7 +790,8 @@ void Heap::Initialize()
evacuator_ = new ParallelEvacuator(this);
incrementalMarker_ = new IncrementalMarker(this);
gcListeners_.reserve(16U);
incNativeSizeTriggerLocalGC_ = config_.GetIncNativeSizeTriggerGC();
nativeSizeTriggerGCThreshold_ = config_.GetMaxNativeSizeInc();
incNativeSizeTriggerGC_ = config_.GetStepNativeSizeInc();
}
void Heap::ResetTlab()
@ -1226,6 +1227,7 @@ void Heap::CollectGarbage(TriggerGCType gcType, GCReason reason)
// Only when the gc type is not semiGC and after the old space sweeping has been finished,
// the limits of old space and global space can be recomputed.
RecomputeLimits();
ResetNativeSizeAfterLastGC();
OPTIONAL_LOG(ecmaVm_, INFO) << " GC after: is full mark" << IsConcurrentFullMark()
<< " global object size " << GetHeapObjectSize()
<< " global committed size " << GetCommittedSize()
@ -2119,12 +2121,13 @@ void Heap::TryTriggerConcurrentMarking()
}
}
void Heap::TryTriggerFullMarkByNativeSize()
void Heap::TryTriggerFullMarkOrGCByNativeSize()
{
if (GlobalNativeSizeLargerThanLimit()) {
if (GetGlobalNativeSize() > incNativeSizeTriggerLocalGC_) {
CollectGarbage(TriggerGCType::OLD_GC, GCReason::ALLOCATION_FAILED);
} else if (concurrentMarker_->IsEnabled()) {
// In high sensitive scene and native size larger than limit, trigger old gc directly
if (InSensitiveStatus() && GlobalNativeSizeLargerToTriggerGC()) {
CollectGarbage(TriggerGCType::OLD_GC, GCReason::ALLOCATION_FAILED);
} else if (GlobalNativeSizeLargerThanLimit()) {
if (concurrentMarker_->IsEnabled()) {
SetFullMarkRequestedState(true);
TryTriggerConcurrentMarking();
} else {

View File

@ -654,19 +654,19 @@ public:
return result;
}
void ResetNativeSizeAfterGC()
void ResetNativeSizeAfterLastGC()
{
nativeSizeAfterGC_ = 0;
nativeSizeAfterLastGC_.store(0, std::memory_order_relaxed);
}
void IncNativeSizeAfterGC(size_t size)
void IncNativeSizeAfterLastGC(size_t size)
{
nativeSizeAfterGC_ += size;
nativeSizeAfterLastGC_.fetch_add(size, std::memory_order_relaxed);
}
size_t GetNativeSizeAfterGC() const
size_t GetNativeSizeAfterLastGC() const
{
return nativeSizeAfterGC_;
return nativeSizeAfterLastGC_.load(std::memory_order_relaxed);
}
size_t GetNativeSizeTriggerSharedGC() const
@ -853,7 +853,7 @@ private:
size_t growingStep_ {0};
size_t incNativeSizeTriggerSharedCM_ {0};
size_t incNativeSizeTriggerSharedGC_ {0};
std::atomic<size_t> nativeSizeAfterGC_ {0};
std::atomic<size_t> nativeSizeAfterLastGC_ {0};
};
class Heap : public BaseHeap {
@ -1420,6 +1420,25 @@ public:
return GetNativeBindingSize() + nativeAreaAllocator_->GetNativeMemoryUsage();
}
void ResetNativeSizeAfterLastGC()
{
nativeSizeAfterLastGC_ = 0;
nativeBindingSizeAfterLastGC_= nativeBindingSize_;
}
void IncNativeSizeAfterLastGC(size_t size)
{
nativeSizeAfterLastGC_ += size;
}
bool GlobalNativeSizeLargerToTriggerGC() const
{
auto incNativeBindingSizeAfterLastGC = nativeBindingSize_ > nativeBindingSizeAfterLastGC_ ?
nativeBindingSize_ - nativeBindingSizeAfterLastGC_ : 0;
return GetGlobalNativeSize() > nativeSizeTriggerGCThreshold_ &&
nativeSizeAfterLastGC_ + incNativeBindingSizeAfterLastGC > incNativeSizeTriggerGC_;
}
bool GlobalNativeSizeLargerThanLimit() const
{
return GetGlobalNativeSize() >= globalSpaceNativeLimit_;
@ -1431,7 +1450,7 @@ public:
IDLE_SPACE_SIZE_LIMIT_RATE);
}
void TryTriggerFullMarkByNativeSize();
void TryTriggerFullMarkOrGCByNativeSize();
void TryTriggerFullMarkBySharedSize(size_t size);
@ -1680,7 +1699,10 @@ private:
size_t semiSpaceCopiedSize_ {0};
size_t nativeBindingSize_{0};
size_t globalSpaceNativeLimit_ {0};
size_t incNativeSizeTriggerLocalGC_ {0};
size_t nativeSizeTriggerGCThreshold_ {0};
size_t incNativeSizeTriggerGC_ {0};
size_t nativeSizeAfterLastGC_ {0};
size_t nativeBindingSizeAfterLastGC_ {0};
size_t newAllocatedSharedObjectSize_ {0};
// Record heap object size before enter sensitive status
size_t recordObjSizeBeforeSensitive_ {0};

View File

@ -61,7 +61,7 @@ void SharedGC::RunPhases()
}
Finish();
sHeap_->NotifyHeapAliveSizeAfterGC(sHeap_->GetHeapObjectSize());
sHeap_->ResetNativeSizeAfterGC();
sHeap_->ResetNativeSizeAfterLastGC();
}
void SharedGC::Initialize()

View File

@ -121,7 +121,7 @@ JSHandle<JSNativePointer> ObjectFactory::NewJSNativePointer(void *externalPointe
vm_->PushToNativePointerList(static_cast<JSNativePointer *>(header), isConcurrent);
// In some cases, the size of JS/TS object is too small and the native binding size is too large.
// Check and try trigger concurrent mark here.
heap_->TryTriggerFullMarkByNativeSize();
heap_->TryTriggerFullMarkOrGCByNativeSize();
}
return obj;
}

View File

@ -221,6 +221,7 @@ void ObjectFactory::NewJSArrayBufferData(const JSHandle<JSArrayBuffer> &array, i
if (!data.IsUndefined()) {
auto *pointer = JSNativePointer::Cast(data.GetTaggedObject());
auto newData = vm_->GetNativeAreaAllocator()->AllocateBuffer(size);
heap_->IncNativeSizeAfterLastGC(size);
if (memset_s(newData, length, 0, length) != EOK) {
LOG_FULL(FATAL) << "memset_s failed";
UNREACHABLE();
@ -232,6 +233,7 @@ void ObjectFactory::NewJSArrayBufferData(const JSHandle<JSArrayBuffer> &array, i
}
auto newData = vm_->GetNativeAreaAllocator()->AllocateBuffer(size);
heap_->IncNativeSizeAfterLastGC(size);
if (memset_s(newData, length, 0, length) != EOK) {
LOG_FULL(FATAL) << "memset_s failed";
UNREACHABLE();
@ -346,6 +348,7 @@ JSHandle<JSArrayBuffer> ObjectFactory::NewJSArrayBuffer(int32_t length)
arrayBuffer->SetArrayBufferByteLength(length);
if (length > 0) {
auto newData = vm_->GetNativeAreaAllocator()->AllocateBuffer(length);
heap_->IncNativeSizeAfterLastGC(length);
if (memset_s(newData, length, 0, length) != EOK) {
LOG_FULL(FATAL) << "memset_s failed";
UNREACHABLE();
@ -436,6 +439,7 @@ void ObjectFactory::NewJSRegExpByteCodeData(const JSHandle<JSRegExp> &regexp, vo
}
auto newBuffer = vm_->GetNativeAreaAllocator()->AllocateBuffer(size);
heap_->IncNativeSizeAfterLastGC(size);
if (memcpy_s(newBuffer, size, buffer, size) != EOK) {
LOG_FULL(FATAL) << "memcpy_s failed";
UNREACHABLE();

View File

@ -321,6 +321,7 @@ size_t BaseDeserializer::ReadSingleEncodeData(uint8_t encodeFlag, uintptr_t objA
size_t bufferLength = data_->ReadUint32(position_);
auto nativeAreaAllocator = thread_->GetEcmaVM()->GetNativeAreaAllocator();
bufferPointer_ = nativeAreaAllocator->AllocateBuffer(bufferLength);
heap_->IncNativeSizeAfterLastGC(bufferLength);
data_->ReadRawData(ToUintPtr(bufferPointer_), bufferLength, position_);
heap_->IncreaseNativeBindingSize(bufferLength);
handledFieldSize = 0;

View File

@ -485,15 +485,15 @@ JSHandle<JSNativePointer> ObjectFactory::NewSJSNativePointer(void *externalPoint
obj->SetNativeFlag(flag);
if (callBack != nullptr) {
sHeap_->IncNativeSizeAfterGC(nativeBindingsize);
sHeap_->IncNativeSizeAfterLastGC(nativeBindingsize);
vm_->PushToSharedNativePointerList(static_cast<JSNativePointer *>(header));
// In some cases, the size of JS/TS object is too small and the native binding size is too large.
// Check and try trigger concurrent mark here.
size_t nativeSizeAfterGC = sHeap_->GetNativeSizeAfterGC();
if (nativeSizeAfterGC > sHeap_->GetNativeSizeTriggerSharedGC()) {
size_t nativeSizeAfterLastGC = sHeap_->GetNativeSizeAfterLastGC();
if (nativeSizeAfterLastGC > sHeap_->GetNativeSizeTriggerSharedGC()) {
sHeap_->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::ALLOCATION_FAILED>(thread_);
} else if (sHeap_->CheckCanTriggerConcurrentMarking(thread_) &&
nativeSizeAfterGC > sHeap_->GetNativeSizeTriggerSharedCM()) {
nativeSizeAfterLastGC > sHeap_->GetNativeSizeTriggerSharedCM()) {
sHeap_->TriggerConcurrentMarking<TriggerGCType::SHARED_GC, GCReason::ALLOCATION_LIMIT>(thread_);
}
}

View File

@ -305,4 +305,16 @@ HWTEST_F_L0(GCTest, AdjustCapacity)
EXPECT_TRUE(space->AdjustCapacity(size, thread));
#endif
}
HWTEST_F_L0(GCTest, NativeMemAllocInSensitive)
{
auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
heap->NotifyHighSensitive(true);
for (size_t i = 0; i < 20; i++) {
[[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread);
factory->NewJSArrayBuffer(300 * 1024 * 1024); // 300MB
}
EXPECT_TRUE(heap->GetGlobalNativeSize() < 1 * 1024 * 1024* 1024); // 1GB
}
} // namespace panda::test