mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-27 04:00:37 +00:00
!8726 Adjust native size trigger gc strategy
Merge pull request !8726 from dingwen/stragery_br
This commit is contained in:
commit
d89dfcbe62
@ -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();
|
||||
|
@ -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};
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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};
|
||||
|
@ -61,7 +61,7 @@ void SharedGC::RunPhases()
|
||||
}
|
||||
Finish();
|
||||
sHeap_->NotifyHeapAliveSizeAfterGC(sHeap_->GetHeapObjectSize());
|
||||
sHeap_->ResetNativeSizeAfterGC();
|
||||
sHeap_->ResetNativeSizeAfterLastGC();
|
||||
}
|
||||
|
||||
void SharedGC::Initialize()
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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> ®exp, 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();
|
||||
|
@ -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;
|
||||
|
@ -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_);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user