mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
support memory parameters configuration
1. heap configuration including heapSize and space capaticity 2. other parameters such as gcThreadNum, longPauseTime. issue:https://gitee.com/openharmony/ark_js_runtime/issues/I59HYO?from=project-issue Signed-off-by: lukai <lukai25@huawei.com> Change-Id: If3bfe7338ae0712809d9750fef3bbbb14017223f
This commit is contained in:
parent
5e2c8ff9c8
commit
6eb0577699
35
ecmascript/ecma_param_configuration.h
Normal file
35
ecmascript/ecma_param_configuration.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 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.
|
||||
*/
|
||||
|
||||
#ifndef ECMASCRIPT_ECMA_PARAM_CONFIGURATION_H
|
||||
#define ECMASCRIPT_ECMA_PARAM_CONFIGURATION_H
|
||||
|
||||
#include "libpandabase/mem/mem.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
// MEMEORY SIZE SHOULD ROUND UP TO 256KB
|
||||
static constexpr size_t MAX_HEAP_SIZE = 256_MB; // Recommended range: 128-256MB
|
||||
static constexpr size_t DEFAULT_SEMI_SPACE_SIZE = 2_MB; // Recommended range: 2-4MB
|
||||
static constexpr size_t MAX_SEMI_SPACE_SIZE = 16_MB; // Recommended range: 2-16MB
|
||||
static constexpr size_t DEFAULT_NONMOVABLE_SPACE_SIZE = 4_MB; // Recommended range: 4-8MB
|
||||
static constexpr size_t DEFAULT_SNAPSHOT_SPACE_SIZE = 256_KB;
|
||||
static constexpr size_t MAX_SNAPSHOT_SPACE_SIZE = 8_MB;
|
||||
static constexpr size_t DEFAULT_MACHINECODE_SPACE_SIZE = 8_MB;
|
||||
|
||||
static constexpr size_t MIN_AllOC_LIMIT_GROWING_STEP = 8_MB;
|
||||
static constexpr uint32_t MAX_STACK_SIZE = 512_KB;
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
#endif // ECMASCRIPT_ECMA_PARAM_CONFIGURATION_H
|
@ -133,7 +133,7 @@ bool EcmaVM::Initialize()
|
||||
regExpParserCache_ = new RegExpParserCache();
|
||||
heap_ = new Heap(this);
|
||||
heap_->Initialize();
|
||||
gcStats_ = chunk_.New<GCStats>(heap_);
|
||||
gcStats_ = chunk_.New<GCStats>(heap_, options_.GetLongPauseTime());
|
||||
factory_ = chunk_.New<ObjectFactory>(thread_, heap_, &chunk_);
|
||||
if (UNLIKELY(factory_ == nullptr)) {
|
||||
LOG_ECMA(FATAL) << "alloc factory_ failed";
|
||||
|
@ -205,6 +205,26 @@ public:
|
||||
enableTSAot_.SetValue(value);
|
||||
}
|
||||
|
||||
void SetGcThreadNum(size_t num)
|
||||
{
|
||||
gcThreadNum_.SetValue(num);
|
||||
}
|
||||
|
||||
size_t GetGcThreadNum() const
|
||||
{
|
||||
return gcThreadNum_.GetValue();
|
||||
}
|
||||
|
||||
void SetLongPauseTime(size_t time)
|
||||
{
|
||||
longPauseTime_.SetValue(time);
|
||||
}
|
||||
|
||||
size_t GetLongPauseTime() const
|
||||
{
|
||||
return longPauseTime_.GetValue();
|
||||
}
|
||||
|
||||
void SetArkProperties(int prop)
|
||||
{
|
||||
if (prop != ArkProperties::DEFAULT) {
|
||||
@ -252,14 +272,9 @@ public:
|
||||
return (static_cast<uint32_t>(arkProperties_.GetValue()) & ArkProperties::THREAD_CHECK) != 0;
|
||||
}
|
||||
|
||||
size_t MaxSemiSpaceCapacity() const
|
||||
bool WasSetMaxNonmovableSpaceCapacity() const
|
||||
{
|
||||
return maxSemiSpaceCapacity_.GetValue();
|
||||
}
|
||||
|
||||
size_t MaxOldSpaceCapacity() const
|
||||
{
|
||||
return maxOldSpaceCapacity_.GetValue();
|
||||
return maxNonmovableSpaceCapacity_.WasSet();
|
||||
}
|
||||
|
||||
size_t MaxNonmovableSpaceCapacity() const
|
||||
@ -267,26 +282,6 @@ public:
|
||||
return maxNonmovableSpaceCapacity_.GetValue();
|
||||
}
|
||||
|
||||
size_t MaxMachineCodeSpaceCapacity() const
|
||||
{
|
||||
return maxMachineCodeSpaceCapacity_.GetValue();
|
||||
}
|
||||
|
||||
size_t MaxSnapshotSpaceCapacity() const
|
||||
{
|
||||
return maxSnapshotSpaceCapacity_.GetValue();
|
||||
}
|
||||
|
||||
size_t DefaultSemiSpaceCapacity() const
|
||||
{
|
||||
return defaultSemiSpaceCapacity_.GetValue();
|
||||
}
|
||||
|
||||
size_t DefaultSnapshotSpaceCapacity() const
|
||||
{
|
||||
return defaultSnapshotSpaceCapacity_.GetValue();
|
||||
}
|
||||
|
||||
void SetEnableAsmInterpreter(bool value)
|
||||
{
|
||||
enableAsmInterpreter_.SetValue(value);
|
||||
@ -496,6 +491,8 @@ private:
|
||||
true,
|
||||
R"(if true trigger full gc, else trigger semi and old gc)"};
|
||||
PandArg<int> arkProperties_ {"ark-properties", GetDefaultProperties(), R"(set ark properties)"};
|
||||
PandArg<size_t> gcThreadNum_ {"gcThreadNum", 7, R"(set gcThreadNum. Default: 7)"};
|
||||
PandArg<size_t> longPauseTime_ {"longPauseTime", 40, R"(set longPauseTime. Default: 40ms)"};
|
||||
PandArg<std::string> aotOutputFile_ {"aot-output-file",
|
||||
R"(aot_output_file.m)",
|
||||
R"(Path to AOT output file. Default: "aot_output_file.m")"};
|
||||
@ -505,27 +502,9 @@ private:
|
||||
Default: "x86_64-unknown-linux-gnu")"};
|
||||
PandArg<uint32_t> asmOptLevel_ {"opt-level", 3,
|
||||
R"(Optimization level configuration on llvm back end. Default: "3")"};
|
||||
PandArg<uint32_t> maxSemiSpaceCapacity_ {"maxSemiSpaceCapacity",
|
||||
16 * 1024 * 1024,
|
||||
R"(set max semi space capacity)"};
|
||||
PandArg<uint32_t> maxOldSpaceCapacity_ {"maxOldSpaceCapacity",
|
||||
256 * 1024 * 1024,
|
||||
R"(set max old space capacity)"};
|
||||
PandArg<uint32_t> maxNonmovableSpaceCapacity_ {"maxNonmovableSpaceCapacity",
|
||||
4 * 1024 * 1024,
|
||||
R"(set max nonmovable space capacity)"};
|
||||
PandArg<uint32_t> maxMachineCodeSpaceCapacity_ {"maxMachineCodeSpaceCapacity",
|
||||
8 * 1024 * 1024,
|
||||
R"(set max machine code space capacity)"};
|
||||
PandArg<uint32_t> maxSnapshotSpaceCapacity_ {"maxSnapshotSpaceCapacity",
|
||||
8 * 1024 * 1024,
|
||||
R"(set max snapshot space capacity)"};
|
||||
PandArg<uint32_t> defaultSemiSpaceCapacity_ {"defaultSemiSpaceCapacity",
|
||||
2 * 1024 * 1024,
|
||||
R"(set default semi space capacity)"};
|
||||
PandArg<uint32_t> defaultSnapshotSpaceCapacity_ {"defaultSnapshotSpaceCapacity",
|
||||
256 * 1024,
|
||||
R"(set default snapshot space capacity)"};
|
||||
PandArg<bool> enableAsmInterpreter_ {"asm-interpreter", false,
|
||||
R"(Enable asm interpreter. Default: false)"};
|
||||
PandArg<std::string> asmOpcodeDisableRange_ {"asm-opcode-disable-range",
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/compiler/llvm/llvm_stackmap_parser.h"
|
||||
#include "ecmascript/ecma_param_configuration.h"
|
||||
#include "ecmascript/global_env_constants-inl.h"
|
||||
#include "ecmascript/ic/properties_cache.h"
|
||||
#include "ecmascript/interpreter/interpreter-inl.h"
|
||||
|
@ -574,7 +574,6 @@ private:
|
||||
|
||||
void DumpStack() DUMP_API_ATTR;
|
||||
|
||||
static constexpr uint32_t MAX_STACK_SIZE = 512 * 1024;
|
||||
static const uint32_t NODE_BLOCK_SIZE_LOG2 = 10;
|
||||
static const uint32_t NODE_BLOCK_SIZE = 1U << NODE_BLOCK_SIZE_LOG2;
|
||||
static constexpr int32_t MIN_HANDLE_STORAGE_SIZE = 2;
|
||||
|
@ -123,15 +123,15 @@ void GCStats::PrintHeapStatisticResult(bool force)
|
||||
NativeAreaAllocator *nativeAreaAllocator = heap_->GetNativeAreaAllocator();
|
||||
HeapRegionAllocator *heapRegionAllocator = heap_->GetHeapRegionAllocator();
|
||||
LOG(INFO, RUNTIME) << "/******************* Memory statistic: *******************/";
|
||||
LOG(INFO, RUNTIME) << " Anno memory usage size:" << sizeToMB(heapRegionAllocator->GetAnnoMemoryUsage())
|
||||
LOG(INFO, RUNTIME) << " Anno memory usage size: " << sizeToMB(heapRegionAllocator->GetAnnoMemoryUsage())
|
||||
<< "MB"
|
||||
<< " anno memory max usage size:" << sizeToMB(heapRegionAllocator->GetMaxAnnoMemoryUsage())
|
||||
<< " anno memory max usage size: " << sizeToMB(heapRegionAllocator->GetMaxAnnoMemoryUsage())
|
||||
<< "MB"
|
||||
<< " native memory usage size:" << sizeToMB(nativeAreaAllocator->GetNativeMemoryUsage())
|
||||
<< " native memory usage size: " << sizeToMB(nativeAreaAllocator->GetNativeMemoryUsage())
|
||||
<< "MB"
|
||||
<< " native memory max usage size:"
|
||||
<< " native memory max usage size: "
|
||||
<< sizeToMB(nativeAreaAllocator->GetMaxNativeMemoryUsage()) << "MB";
|
||||
LOG(INFO, RUNTIME) << " Semi space commit size" << sizeToMB(heap_->GetNewSpace()->GetCommittedSize()) << "MB"
|
||||
LOG(INFO, RUNTIME) << " Semi space commit size: " << sizeToMB(heap_->GetNewSpace()->GetCommittedSize()) << "MB"
|
||||
<< " semi space heap object size: " << sizeToMB(heap_->GetNewSpace()->GetHeapObjectSize())
|
||||
<< "MB"
|
||||
<< " old space commit size: "
|
||||
@ -160,6 +160,8 @@ void GCStats::StatisticSTWYoungGC(Duration time, size_t aliveSize, size_t promot
|
||||
semiTotalCommitSize_ += commitSize;
|
||||
semiTotalPromoteSize_ += promotedSize;
|
||||
semiGCCount_++;
|
||||
currentGcType_ = "STWYoungGC";
|
||||
currentPauseTime_ = timeInMS / THOUSAND;
|
||||
}
|
||||
|
||||
void GCStats::StatisticPartialGC(bool concurrentMark, Duration time, size_t freeSize)
|
||||
@ -191,6 +193,8 @@ void GCStats::StatisticPartialGC(bool concurrentMark, Duration time, size_t free
|
||||
partialOldSpaceFreeSize_ = freeSize;
|
||||
partialGCCount_++;
|
||||
}
|
||||
currentGcType_ = "PartialGC";
|
||||
currentPauseTime_ = timeInMS / THOUSAND;
|
||||
}
|
||||
|
||||
void GCStats::StatisticFullGC(Duration time, size_t youngAndOldAliveSize, size_t youngCommitSize,
|
||||
@ -212,6 +216,21 @@ void GCStats::StatisticFullGC(Duration time, size_t youngAndOldAliveSize, size_t
|
||||
compressNonMoveTotalFreeSize_ += nonMoveSpaceFreeSize;
|
||||
compressNonMoveTotalCommitSize_ += nonMoveSpaceCommitSize;
|
||||
fullGCCount_++;
|
||||
currentGcType_ = "FullGC";
|
||||
currentPauseTime_ = timeInMS / THOUSAND;
|
||||
}
|
||||
|
||||
void GCStats::CheckIfLongTimePause()
|
||||
{
|
||||
if (currentPauseTime_ > longPauseTime_) {
|
||||
LOG(INFO, RUNTIME) << "Has checked a long time gc; gc type = " << currentGcType_ << "; pause time = "
|
||||
<< currentPauseTime_ << "ms";
|
||||
LOG(INFO, RUNTIME) << "/******************* GCStats statistic: *******************/";
|
||||
PrintSemiStatisticResult(true);
|
||||
PrintPartialStatisticResult(true);
|
||||
PrintCompressStatisticResult(true);
|
||||
PrintHeapStatisticResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
void GCStats::StatisticConcurrentMark(Duration time)
|
||||
|
@ -27,6 +27,8 @@ class GCStats {
|
||||
|
||||
public:
|
||||
explicit GCStats(const Heap *heap) : heap_(heap) {}
|
||||
explicit GCStats(const Heap *heap, size_t longPuaseTime) : heap_(heap),
|
||||
longPauseTime_(longPuaseTime) {}
|
||||
~GCStats() = default;
|
||||
|
||||
void PrintStatisticResult(bool force = false);
|
||||
@ -41,6 +43,7 @@ public:
|
||||
void StatisticConcurrentRemark(Duration time);
|
||||
void StatisticConcurrentEvacuate(Duration time);
|
||||
|
||||
void CheckIfLongTimePause();
|
||||
private:
|
||||
void PrintSemiStatisticResult(bool force);
|
||||
void PrintPartialStatisticResult(bool force);
|
||||
@ -101,6 +104,9 @@ private:
|
||||
size_t compressNonMoveTotalCommitSize_ = 0;
|
||||
|
||||
const Heap *heap_;
|
||||
std::string currentGcType_ = "";
|
||||
size_t currentPauseTime_ = 0;
|
||||
size_t longPauseTime_ = 0;
|
||||
|
||||
static constexpr uint32_t THOUSAND = 1000;
|
||||
static constexpr uint32_t MB = 1 * 1024 * 1024;
|
||||
|
@ -50,30 +50,51 @@ void Heap::Initialize()
|
||||
{
|
||||
memController_ = new MemController(this);
|
||||
|
||||
size_t defaultSemiSpaceCapacity = ecmaVm_->GetJSOptions().DefaultSemiSpaceCapacity();
|
||||
activeSemiSpace_ = new SemiSpace(this, defaultSemiSpaceCapacity, defaultSemiSpaceCapacity);
|
||||
size_t minSemiSpaceCapacity = std::max(DEFAULT_SEMI_SPACE_SIZE, CONSTRAINT_MIN_SEMI_SPACE_SIZE);
|
||||
size_t maxSemiSpaceCapacity = std::min(MAX_SEMI_SPACE_SIZE, CONSTRAINT_MAX_SEMI_SPACE_SIZE);
|
||||
activeSemiSpace_ = new SemiSpace(this, minSemiSpaceCapacity, maxSemiSpaceCapacity);
|
||||
activeSemiSpace_->Restart();
|
||||
activeSemiSpace_->SetWaterLine();
|
||||
auto topAddress = activeSemiSpace_->GetAllocationTopAddress();
|
||||
auto endAddress = activeSemiSpace_->GetAllocationEndAddress();
|
||||
thread_->ReSetNewSpaceAllocationAddress(topAddress, endAddress);
|
||||
inactiveSemiSpace_ = new SemiSpace(this, defaultSemiSpaceCapacity, defaultSemiSpaceCapacity);
|
||||
|
||||
inactiveSemiSpace_ = new SemiSpace(this, minSemiSpaceCapacity, maxSemiSpaceCapacity);
|
||||
// not set up from space
|
||||
size_t maxOldSpaceCapacity = ecmaVm_->GetJSOptions().MaxOldSpaceCapacity();
|
||||
oldSpace_ = new OldSpace(this, OLD_SPACE_LIMIT_BEGIN, maxOldSpaceCapacity);
|
||||
compressSpace_ = new OldSpace(this, OLD_SPACE_LIMIT_BEGIN, maxOldSpaceCapacity);
|
||||
oldSpace_->Initialize();
|
||||
size_t maxNonmovableSpaceCapacity = ecmaVm_->GetJSOptions().MaxNonmovableSpaceCapacity();
|
||||
nonMovableSpace_ = new NonMovableSpace(this, maxNonmovableSpaceCapacity, maxNonmovableSpaceCapacity);
|
||||
|
||||
size_t nonmovableSpaceCapacity = std::max(DEFAULT_NONMOVABLE_SPACE_SIZE, CONSTRAINT_MIN_NONMOVABLE_SPACE_SIZE);
|
||||
if (ecmaVm_->GetJSOptions().WasSetMaxNonmovableSpaceCapacity()) {
|
||||
nonmovableSpaceCapacity = ecmaVm_->GetJSOptions().MaxNonmovableSpaceCapacity();
|
||||
}
|
||||
nonMovableSpace_ = new NonMovableSpace(this, nonmovableSpaceCapacity, nonmovableSpaceCapacity);
|
||||
nonMovableSpace_->Initialize();
|
||||
size_t defaultSnapshotSpaceCapacity = ecmaVm_->GetJSOptions().DefaultSnapshotSpaceCapacity();
|
||||
size_t maxSnapshotSpaceCapacity = ecmaVm_->GetJSOptions().MaxSnapshotSpaceCapacity();
|
||||
snapshotSpace_ = new SnapshotSpace(this, defaultSnapshotSpaceCapacity, maxSnapshotSpaceCapacity);
|
||||
size_t maxMachineCodeSpaceCapacity = ecmaVm_->GetJSOptions().MaxMachineCodeSpaceCapacity();
|
||||
machineCodeSpace_ = new MachineCodeSpace(this, maxMachineCodeSpaceCapacity, maxMachineCodeSpaceCapacity);
|
||||
size_t snapshotSpaceCapacity = std::max(DEFAULT_SNAPSHOT_SPACE_SIZE, CONSTRAINT_MIN_SNAPSHOT_SPACE_SIZE);
|
||||
snapshotSpace_ = new SnapshotSpace(this, snapshotSpaceCapacity, MAX_SNAPSHOT_SPACE_SIZE);
|
||||
size_t machineCodeSpaceCapacity = std::max(DEFAULT_MACHINECODE_SPACE_SIZE, CONSTRAINT_MIN_MACHINECODE_SPACE_SIZE);
|
||||
machineCodeSpace_ = new MachineCodeSpace(this, machineCodeSpaceCapacity, machineCodeSpaceCapacity);
|
||||
machineCodeSpace_->Initialize();
|
||||
hugeObjectSpace_ = new HugeObjectSpace(heapRegionAllocator_);
|
||||
|
||||
size_t capacities = minSemiSpaceCapacity * 2 + nonmovableSpaceCapacity + snapshotSpaceCapacity +
|
||||
machineCodeSpaceCapacity;
|
||||
if (MAX_HEAP_SIZE < capacities || MAX_HEAP_SIZE - capacities < MIN_OLD_SPACE_LIMIT) {
|
||||
LOG_ECMA_MEM(FATAL) << "HeapSize is too small to initialize oldspace, heapSize = " << MAX_HEAP_SIZE;
|
||||
}
|
||||
size_t oldSpaceCapacity = MAX_HEAP_SIZE - capacities;
|
||||
globalSpaceAllocLimit_ = MAX_HEAP_SIZE - minSemiSpaceCapacity;
|
||||
|
||||
oldSpace_ = new OldSpace(this, oldSpaceCapacity, oldSpaceCapacity);
|
||||
compressSpace_ = new OldSpace(this, oldSpaceCapacity, oldSpaceCapacity);
|
||||
oldSpace_->Initialize();
|
||||
hugeObjectSpace_ = new HugeObjectSpace(heapRegionAllocator_, oldSpaceCapacity, oldSpaceCapacity);
|
||||
maxTaskCount_ = std::min<size_t>(ecmaVm_->GetJSOptions().GetGcThreadNum(),
|
||||
(Taskpool::GetCurrentTaskpool()->GetTotalThreadNum()) - 1);
|
||||
LOG(INFO, RUNTIME) << "heap initialize: heap size = " << MAX_HEAP_SIZE
|
||||
<< ", semispace capacity = " << minSemiSpaceCapacity
|
||||
<< ", nonmovablespace capacity = " << nonmovableSpaceCapacity
|
||||
<< ", snapshotspace capacity = " << snapshotSpaceCapacity
|
||||
<< ", machinecodespace capacity = " << machineCodeSpaceCapacity
|
||||
<< ", oldspace capacity = " << oldSpaceCapacity
|
||||
<< ", globallimit = " << globalSpaceAllocLimit_
|
||||
<< ", gcThreadNum = " << maxTaskCount_;
|
||||
parallelGC_ = ecmaVm_->GetJSOptions().EnableParallelGC();
|
||||
concurrentMarkingEnabled_ = ecmaVm_->GetJSOptions().EnableConcurrentMark();
|
||||
markType_ = MarkType::MARK_YOUNG;
|
||||
@ -207,7 +228,11 @@ void Heap::Resume(TriggerGCType gcType)
|
||||
oldSpace_ = oldSpace;
|
||||
}
|
||||
if (activeSemiSpace_->AdjustCapacity(inactiveSemiSpace_->GetAllocatedSizeSinceGC())) {
|
||||
inactiveSemiSpace_->SetMaximumCapacity(activeSemiSpace_->GetMaximumCapacity());
|
||||
// if activeSpace capacity changes, oldSpace maximumCapacity should change, too.
|
||||
int delta = activeSemiSpace_->GetInitialCapacity() - inactiveSemiSpace_->GetInitialCapacity();
|
||||
size_t oldSpaceMaxLimit = static_cast<int>(oldSpace_->GetMaximumCapacity()) - delta * 2;
|
||||
oldSpace_->SetMaximumCapacity(oldSpaceMaxLimit);
|
||||
inactiveSemiSpace_->SetInitialCapacity(activeSemiSpace_->GetInitialCapacity());
|
||||
}
|
||||
|
||||
activeSemiSpace_->SetWaterLine();
|
||||
@ -260,8 +285,8 @@ void Heap::CollectGarbage(TriggerGCType gcType)
|
||||
size_t originalNewSpaceSize = activeSemiSpace_->GetHeapObjectSize();
|
||||
memController_->StartCalculationBeforeGC();
|
||||
OPTIONAL_LOG(ecmaVm_, ERROR, ECMASCRIPT) << "Heap::CollectGarbage, gcType = " << gcType
|
||||
<< " global CommittedSize" << GetCommittedSize()
|
||||
<< " global limit" << globalSpaceAllocLimit_;
|
||||
<< " global CommittedSize " << GetCommittedSize()
|
||||
<< " global limit " << globalSpaceAllocLimit_;
|
||||
switch (gcType) {
|
||||
case TriggerGCType::YOUNG_GC:
|
||||
// Use partial GC for young generation.
|
||||
@ -309,11 +334,11 @@ void Heap::CollectGarbage(TriggerGCType gcType)
|
||||
// the limits of old space and global space can be recomputed.
|
||||
RecomputeLimits();
|
||||
OPTIONAL_LOG(ecmaVm_, ERROR, ECMASCRIPT) << " GC after: is full mark" << IsFullMark()
|
||||
<< " global CommittedSize" << GetCommittedSize()
|
||||
<< " global limit" << globalSpaceAllocLimit_;
|
||||
<< " global CommittedSize " << GetCommittedSize()
|
||||
<< " global limit " << globalSpaceAllocLimit_;
|
||||
markType_ = MarkType::MARK_YOUNG;
|
||||
}
|
||||
|
||||
ecmaVm_->GetEcmaGCStats()->CheckIfLongTimePause();
|
||||
# if ECMASCRIPT_ENABLE_GC_LOG
|
||||
ecmaVm_->GetEcmaGCStats()->PrintStatisticResult();
|
||||
#endif
|
||||
@ -398,14 +423,15 @@ void Heap::RecomputeLimits()
|
||||
double gcSpeed = memController_->CalculateMarkCompactSpeedPerMS();
|
||||
double mutatorSpeed = memController_->GetCurrentOldSpaceAllocationThroughputPerMS();
|
||||
size_t oldSpaceSize = oldSpace_->GetHeapObjectSize() + hugeObjectSpace_->GetHeapObjectSize();
|
||||
size_t newSpaceCapacity = activeSemiSpace_->GetMaximumCapacity();
|
||||
size_t newSpaceCapacity = activeSemiSpace_->GetInitialCapacity();
|
||||
|
||||
double growingFactor = memController_->CalculateGrowingFactor(gcSpeed, mutatorSpeed);
|
||||
size_t maxOldSpaceCapacity = GetEcmaVM()->GetJSOptions().MaxOldSpaceCapacity();
|
||||
size_t maxOldSpaceCapacity = oldSpace_->GetMaximumCapacity();
|
||||
auto newOldSpaceLimit = memController_->CalculateAllocLimit(oldSpaceSize, MIN_OLD_SPACE_LIMIT, maxOldSpaceCapacity,
|
||||
newSpaceCapacity, growingFactor);
|
||||
size_t maxGlobalSize = MAX_HEAP_SIZE - newSpaceCapacity;
|
||||
auto newGlobalSpaceLimit = memController_->CalculateAllocLimit(GetHeapObjectSize(), DEFAULT_HEAP_SIZE,
|
||||
MAX_HEAP_SIZE, newSpaceCapacity, growingFactor);
|
||||
maxGlobalSize, newSpaceCapacity, growingFactor);
|
||||
globalSpaceAllocLimit_ = newGlobalSpaceLimit;
|
||||
oldSpace_->SetInitialCapacity(newOldSpaceLimit);
|
||||
OPTIONAL_LOG(ecmaVm_, ERROR, ECMASCRIPT) << "RecomputeLimits oldSpaceAllocLimit_" << newOldSpaceLimit
|
||||
@ -489,8 +515,8 @@ void Heap::TryTriggerConcurrentMarking()
|
||||
}
|
||||
return;
|
||||
}
|
||||
newSpaceAllocToLimitDuration = (activeSemiSpace_->GetMaximumCapacity() - activeSemiSpace_->GetCommittedSize())
|
||||
/ newSpaceAllocSpeed;
|
||||
newSpaceAllocToLimitDuration = (activeSemiSpace_->GetInitialCapacity() - activeSemiSpace_->GetCommittedSize())
|
||||
/ newSpaceAllocSpeed;
|
||||
newSpaceMarkDuration = activeSemiSpace_->GetHeapObjectSize() / newSpaceConcurrentMarkSpeed;
|
||||
// newSpaceRemainSize means the predicted size which can be allocated after the semi concurrent mark.
|
||||
newSpaceRemainSize = (newSpaceAllocToLimitDuration - newSpaceMarkDuration) * newSpaceAllocSpeed;
|
||||
@ -585,7 +611,7 @@ void Heap::IncreaseTaskCount()
|
||||
bool Heap::CheckCanDistributeTask()
|
||||
{
|
||||
os::memory::LockHolder holder(waitTaskFinishedMutex_);
|
||||
return (runningTaskCount_ < Taskpool::GetCurrentTaskpool()->GetTotalThreadNum() - 1);
|
||||
return runningTaskCount_ < maxTaskCount_;
|
||||
}
|
||||
|
||||
void Heap::ReduceTaskCount()
|
||||
|
@ -482,7 +482,7 @@ private:
|
||||
bool concurrentMarkingEnabled_ {true};
|
||||
bool fullGCRequested_ {false};
|
||||
|
||||
size_t globalSpaceAllocLimit_ {GLOBAL_SPACE_LIMIT_BEGIN};
|
||||
size_t globalSpaceAllocLimit_ {0};
|
||||
bool oldSpaceLimitAdjusted_ {false};
|
||||
size_t promotedSize_ {0};
|
||||
size_t semiSpaceCopiedSize_ {0};
|
||||
@ -491,6 +491,7 @@ private:
|
||||
os::memory::Mutex waitClearTaskFinishedMutex_;
|
||||
os::memory::ConditionVariable waitClearTaskFinishedCV_;
|
||||
uint32_t runningTaskCount_ {0};
|
||||
uint32_t maxTaskCount_ {0};
|
||||
os::memory::Mutex waitTaskFinishedMutex_;
|
||||
os::memory::ConditionVariable waitTaskFinishedCV_;
|
||||
|
||||
|
@ -52,7 +52,7 @@ uintptr_t LinearSpace::Allocate(size_t size, bool isPromoted)
|
||||
|
||||
bool LinearSpace::Expand(bool isPromoted)
|
||||
{
|
||||
if (committedSize_ >= maximumCapacity_ + overShootSize_) {
|
||||
if (committedSize_ >= initialCapacity_ + overShootSize_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -125,7 +125,8 @@ void LinearSpace::IterateOverObjects(const std::function<void(TaggedObject *obje
|
||||
}
|
||||
|
||||
SemiSpace::SemiSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity)
|
||||
: LinearSpace(heap, MemSpaceType::SEMI_SPACE, initialCapacity, maximumCapacity) {}
|
||||
: LinearSpace(heap, MemSpaceType::SEMI_SPACE, initialCapacity, maximumCapacity),
|
||||
minimumCapacity_(initialCapacity) {}
|
||||
|
||||
void SemiSpace::Initialize()
|
||||
{
|
||||
@ -203,24 +204,23 @@ bool SemiSpace::AdjustCapacity(size_t allocatedSizeSinceGC)
|
||||
static constexpr double growObjectSurvivalRate = 0.8;
|
||||
static constexpr double shrinkObjectSurvivalRate = 0.2;
|
||||
static constexpr int growingFactor = 2;
|
||||
if (allocatedSizeSinceGC <= maximumCapacity_ * growObjectSurvivalRate / growingFactor) {
|
||||
if (allocatedSizeSinceGC <= initialCapacity_ * growObjectSurvivalRate / growingFactor) {
|
||||
return false;
|
||||
}
|
||||
double curObjectSurvivalRate = static_cast<double>(survivalObjectSize_) / allocatedSizeSinceGC;
|
||||
if (curObjectSurvivalRate > growObjectSurvivalRate) {
|
||||
size_t maxCapacity = heap_->GetEcmaVM()->GetJSOptions().MaxSemiSpaceCapacity();
|
||||
if (GetMaximumCapacity() >= maxCapacity) {
|
||||
if (initialCapacity_ >= maximumCapacity_) {
|
||||
return false;
|
||||
}
|
||||
size_t newCapacity = GetMaximumCapacity() * growingFactor;
|
||||
SetMaximumCapacity(std::min(newCapacity, maxCapacity));
|
||||
size_t newCapacity = initialCapacity_ * growingFactor;
|
||||
SetInitialCapacity(std::min(newCapacity, maximumCapacity_));
|
||||
return true;
|
||||
} else if (curObjectSurvivalRate < shrinkObjectSurvivalRate) {
|
||||
if (GetMaximumCapacity() <= initialCapacity_) {
|
||||
if (initialCapacity_ <= minimumCapacity_) {
|
||||
return false;
|
||||
}
|
||||
size_t newCapacity = GetMaximumCapacity() / growingFactor;
|
||||
SetMaximumCapacity(std::max(newCapacity, initialCapacity_));
|
||||
size_t newCapacity = initialCapacity_ / growingFactor;
|
||||
SetInitialCapacity(std::max(newCapacity, minimumCapacity_));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -82,6 +82,7 @@ public:
|
||||
|
||||
private:
|
||||
os::memory::Mutex lock_;
|
||||
size_t minimumCapacity_;
|
||||
};
|
||||
|
||||
class SnapshotSpace : public LinearSpace {
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "ecmascript/ecma_param_configuration.h"
|
||||
#include "ecmascript/mem/tagged_object.h"
|
||||
#include "libpandabase/mem/mem.h"
|
||||
#include "libpandabase/utils/logger.h"
|
||||
@ -36,25 +37,26 @@ enum class MemAlignmentLog2 : uint8_t {
|
||||
MEM_ALIGN_REGION_LOG2 = 4,
|
||||
};
|
||||
|
||||
static constexpr size_t SEMI_SPACE_TRIGGER_CONCURRENT_MARK = 1.5 * 1024 * 1024;
|
||||
static constexpr size_t SEMI_SPACE_OVERSHOOT_SIZE = 2 * 1024 * 1024;
|
||||
static constexpr size_t SEMI_SPACE_TRIGGER_CONCURRENT_MARK = 1.5_MB;
|
||||
static constexpr size_t SEMI_SPACE_OVERSHOOT_SIZE = 2_MB;
|
||||
|
||||
static constexpr size_t MIN_OLD_SPACE_LIMIT = 2 * 1024 * 1024;
|
||||
static constexpr size_t OLD_SPACE_LIMIT_BEGIN = 256 * 1024 * 1024;
|
||||
static constexpr size_t GLOBAL_SPACE_LIMIT_BEGIN = 256 * 1024 * 1024;
|
||||
static constexpr size_t MIN_GROWING_STEP = 16 * 1024 * 1024;
|
||||
static constexpr size_t MIN_AllOC_LIMIT_GROWING_STEP = 8 * 1024 * 1024;
|
||||
static constexpr size_t CONSTRAINT_MIN_SEMI_SPACE_SIZE = 1_MB;
|
||||
static constexpr size_t CONSTRAINT_MAX_SEMI_SPACE_SIZE = 16_MB;
|
||||
static constexpr size_t CONSTRAINT_MIN_NONMOVABLE_SPACE_SIZE = 1_MB;
|
||||
static constexpr size_t CONSTRAINT_MIN_SNAPSHOT_SPACE_SIZE = 256_KB;
|
||||
static constexpr size_t CONSTRAINT_MIN_MACHINECODE_SPACE_SIZE = 4_MB;
|
||||
|
||||
static constexpr size_t MIN_OLD_SPACE_LIMIT = 2_MB;
|
||||
static constexpr size_t MIN_GROWING_STEP = 16_MB;
|
||||
|
||||
static constexpr size_t REGION_SIZE_LOG2 = 18U;
|
||||
|
||||
static constexpr size_t MAX_HEAP_SIZE = 512 * 1024 * 1024;
|
||||
static constexpr size_t HALF_MAX_HEAP_SIZE = MAX_HEAP_SIZE / 2;
|
||||
static constexpr size_t DEFAULT_HEAP_SIZE = 5 * 1024 * 1024;
|
||||
static constexpr size_t DEFAULT_HEAP_SIZE = 5_MB;
|
||||
|
||||
static constexpr size_t DEFAULT_REGION_SIZE = 1U << REGION_SIZE_LOG2;
|
||||
static constexpr size_t DEFAULT_REGION_MASK = DEFAULT_REGION_SIZE - 1;
|
||||
|
||||
static constexpr size_t DEFAULT_MARK_STACK_SIZE = 4 * 1024;
|
||||
static constexpr size_t DEFAULT_MARK_STACK_SIZE = 4_KB;
|
||||
|
||||
static constexpr double MIN_OBJECT_SURVIVAL_RATE = 0.75;
|
||||
|
||||
@ -62,15 +64,13 @@ static constexpr double MIN_OBJECT_SURVIVAL_RATE = 0.75;
|
||||
// Regular objects will be allocated on regular regions and migrated on spaces.
|
||||
// They will never be moved to huge object space. So we take half of a regular
|
||||
// region as the border of regular objects.
|
||||
static constexpr size_t MAX_32BIT_OBJECT_SPACE_SIZE = 1 * 1024 * 1024 * 1024;
|
||||
static constexpr size_t MAX_32BIT_OBJECT_SPACE_SIZE = 1_GB;
|
||||
static constexpr size_t MAX_REGULAR_HEAP_OBJECT_SIZE = DEFAULT_REGION_SIZE * 2 / 3;
|
||||
static constexpr size_t MAX_HUGE_OBJECT_SIZE = 256 * 1024 * 1024;
|
||||
static constexpr size_t MAX_HUGE_OBJECT_SPACE_SIZE = 256 * 1024 * 1024;
|
||||
// internal allocator
|
||||
static constexpr size_t CHUNK_ALIGN_SIZE = 4 * 1024;
|
||||
static constexpr size_t MIN_CHUNK_AREA_SIZE = 4 * 1024;
|
||||
static constexpr size_t MAX_CACHED_CHUNK_AREA_SIZE = 16 * 1024;
|
||||
static constexpr size_t MAX_CHUNK_AREA_SIZE = 1 * 1024 * 1024;
|
||||
static constexpr size_t CHUNK_ALIGN_SIZE = 4_KB;
|
||||
static constexpr size_t MIN_CHUNK_AREA_SIZE = 4_KB;
|
||||
static constexpr size_t MAX_CACHED_CHUNK_AREA_SIZE = 16_KB;
|
||||
static constexpr size_t MAX_CHUNK_AREA_SIZE = 1 * 1024_KB;
|
||||
|
||||
using TaggedType = uint64_t;
|
||||
static constexpr uint32_t TAGGED_TYPE_SIZE = sizeof(TaggedType);
|
||||
|
@ -33,7 +33,7 @@ double MemController::CalculateAllocLimit(size_t currentSize, size_t minSize, si
|
||||
const uint64_t halfToMaxSize = (static_cast<uint64_t>(currentSize) + maxSize) / 2;
|
||||
auto result = static_cast<size_t>(std::min(limitAboveMinSize, halfToMaxSize));
|
||||
// Avoid the limit is larger than maxSize - newSpaceCapacity. It may cause old space merge OOM.
|
||||
result = static_cast<size_t>(std::min(result, maxSize - newSpaceCapacity));
|
||||
result = static_cast<size_t>(std::min(result, maxSize));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -83,10 +83,6 @@ uintptr_t HugeObjectSpace::Allocate(size_t objectSize, JSThread *thread)
|
||||
}
|
||||
|
||||
size_t alignedSize = AlignUp(objectSize + sizeof(Region), PANDA_POOL_ALIGNMENT_IN_BYTES);
|
||||
if (UNLIKELY(alignedSize > MAX_HUGE_OBJECT_SIZE)) {
|
||||
LOG_ECMA_MEM(FATAL) << "The size is too big for this allocator. Return nullptr.";
|
||||
return 0;
|
||||
}
|
||||
Region *region = heapRegionAllocator_->AllocateAlignedRegion(this, alignedSize, thread);
|
||||
AddRegion(region);
|
||||
return region->GetBegin();
|
||||
|
@ -192,8 +192,7 @@ protected:
|
||||
|
||||
class HugeObjectSpace : public Space {
|
||||
public:
|
||||
explicit HugeObjectSpace(HeapRegionAllocator *regionAllocator, size_t initialCapacity = MAX_HUGE_OBJECT_SPACE_SIZE,
|
||||
size_t maximumCapacity = MAX_HUGE_OBJECT_SPACE_SIZE);
|
||||
explicit HugeObjectSpace(HeapRegionAllocator *regionAllocator, size_t initialCapacity, size_t maximumCapacity);
|
||||
~HugeObjectSpace() override = default;
|
||||
NO_COPY_SEMANTIC(HugeObjectSpace);
|
||||
NO_MOVE_SEMANTIC(HugeObjectSpace);
|
||||
|
@ -28,7 +28,7 @@ static constexpr size_t SMALL_OBJECT_SIZE = 8 * 1024;
|
||||
TlabAllocator::TlabAllocator(Heap *heap)
|
||||
: heap_(heap), enableExpandYoung_(true)
|
||||
{
|
||||
size_t maxOldSpaceCapacity = heap->GetEcmaVM()->GetJSOptions().MaxOldSpaceCapacity();
|
||||
size_t maxOldSpaceCapacity = heap->GetOldSpace()->GetMaximumCapacity();
|
||||
localSpace_ = new LocalSpace(heap, maxOldSpaceCapacity, maxOldSpaceCapacity);
|
||||
youngAllocator_.Reset();
|
||||
}
|
||||
|
@ -58,6 +58,8 @@ using JSThread = ecmascript::JSThread;
|
||||
using JSTaggedType = uint64_t;
|
||||
|
||||
static constexpr uint32_t DEFAULT_GC_POOL_SIZE = 256 * 1024 * 1024;
|
||||
static constexpr size_t DEFAULT_GC_THREAD_NUM = 7;
|
||||
static constexpr size_t DEFAULT_LONG_PAUSE_TIME = 40;
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define ECMA_DISALLOW_COPY(className) \
|
||||
@ -790,6 +792,16 @@ public:
|
||||
arkProperties_ = prop;
|
||||
}
|
||||
|
||||
void SetGcThreadNum(size_t num)
|
||||
{
|
||||
gcThreadNum_ = num;
|
||||
}
|
||||
|
||||
void SetLongPauseTime(size_t time)
|
||||
{
|
||||
longPauseTime_ = time;
|
||||
}
|
||||
|
||||
void SetEnableAsmInterpreter(bool value)
|
||||
{
|
||||
enableAsmInterpreter_ = value;
|
||||
@ -875,6 +887,16 @@ private:
|
||||
return arkProperties_;
|
||||
}
|
||||
|
||||
size_t GetGcThreadNum() const
|
||||
{
|
||||
return gcThreadNum_;
|
||||
}
|
||||
|
||||
size_t GetLongPauseTime() const
|
||||
{
|
||||
return longPauseTime_;
|
||||
}
|
||||
|
||||
bool GetEnableAsmInterpreter() const
|
||||
{
|
||||
return enableAsmInterpreter_;
|
||||
@ -895,6 +917,8 @@ private:
|
||||
bool enableCpuprofiler_ {false};
|
||||
#endif
|
||||
int arkProperties_ {-1};
|
||||
size_t gcThreadNum_ {DEFAULT_GC_THREAD_NUM};
|
||||
size_t longPauseTime_ {DEFAULT_LONG_PAUSE_TIME};
|
||||
bool enableAsmInterpreter_ {false};
|
||||
std::string asmOpcodeDisableRange_ {""};
|
||||
friend JSNApi;
|
||||
|
@ -127,6 +127,8 @@ EcmaVM *JSNApi::CreateJSVM(const RuntimeOption &option)
|
||||
{
|
||||
JSRuntimeOptions runtimeOptions;
|
||||
runtimeOptions.SetArkProperties(option.GetArkProperties());
|
||||
runtimeOptions.SetLongPauseTime(option.GetLongPauseTime());
|
||||
runtimeOptions.SetGcThreadNum(option.GetGcThreadNum());
|
||||
// Mem
|
||||
runtimeOptions.SetHeapSizeLimit(option.GetGcPoolSize());
|
||||
// asmInterpreter
|
||||
|
@ -745,15 +745,14 @@ static uintptr_t g_nativeTable[] = {
|
||||
void SnapshotProcessor::Initialize()
|
||||
{
|
||||
auto heap = const_cast<Heap *>(vm_->GetHeap());
|
||||
size_t maxOldSpaceCapacity = vm_->GetJSOptions().MaxOldSpaceCapacity();
|
||||
oldLocalSpace_ = new LocalSpace(heap, maxOldSpaceCapacity, maxOldSpaceCapacity);
|
||||
size_t maxNonMovableCapacity = vm_->GetJSOptions().MaxNonmovableSpaceCapacity();
|
||||
nonMovableLocalSpace_ = new LocalSpace(heap, maxNonMovableCapacity, maxNonMovableCapacity);
|
||||
size_t maxMachineCodeCapacity = vm_->GetJSOptions().MaxMachineCodeSpaceCapacity();
|
||||
machineCodeLocalSpace_ = new LocalSpace(heap, maxMachineCodeCapacity, maxMachineCodeCapacity);
|
||||
size_t defaultSnapshotSpaceCapacity = vm_->GetJSOptions().DefaultSnapshotSpaceCapacity();
|
||||
size_t maxSnapshotSpaceCapacity = vm_->GetJSOptions().MaxSnapshotSpaceCapacity();
|
||||
snapshotLocalSpace_ = new SnapshotSpace(heap, defaultSnapshotSpaceCapacity, maxSnapshotSpaceCapacity);
|
||||
size_t oldSpaceCapacity = heap->GetOldSpace()->GetInitialCapacity();
|
||||
oldLocalSpace_ = new LocalSpace(heap, oldSpaceCapacity, oldSpaceCapacity);
|
||||
size_t nonMovableCapacity = heap->GetNonMovableSpace()->GetInitialCapacity();
|
||||
nonMovableLocalSpace_ = new LocalSpace(heap, nonMovableCapacity, nonMovableCapacity);
|
||||
size_t machineCodeCapacity = heap->GetMachineCodeSpace()->GetInitialCapacity();
|
||||
machineCodeLocalSpace_ = new LocalSpace(heap, machineCodeCapacity, machineCodeCapacity);
|
||||
size_t snapshotSpaceCapacity = heap->GetSnapshotSpace()->GetMaximumCapacity();
|
||||
snapshotLocalSpace_ = new SnapshotSpace(heap, snapshotSpaceCapacity, snapshotSpaceCapacity);
|
||||
}
|
||||
|
||||
void SnapshotProcessor::StopAllocate()
|
||||
|
@ -76,7 +76,7 @@ void JSPtHooks::LoadModule(std::string_view pandaFileName)
|
||||
|
||||
void JSPtHooks::PendingJobEntry()
|
||||
{
|
||||
LOG(INFO, DEBUGGER) << "JSPtHooks: PendingJobEntry";
|
||||
LOG(DEBUG, DEBUGGER) << "JSPtHooks: PendingJobEntry";
|
||||
|
||||
[[maybe_unused]] LocalScope scope(backend_->ecmaVm_);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user