mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
!1596 adjust pool size and related vm-memory according to physical memory
Merge pull request !1596 from lukai/master
This commit is contained in:
commit
a1474669ab
@ -19,17 +19,146 @@
|
||||
#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 DEFAULT_HEAP_SIZE = 256_MB; // Recommended range: 128-256MB
|
||||
static constexpr size_t DEFAULT_WORKER_HEAP_SIZE = 64_MB; // Recommended range: 64_MB
|
||||
|
||||
static constexpr size_t MIN_AllOC_LIMIT_GROWING_STEP = 8_MB;
|
||||
static constexpr uint32_t MAX_STACK_SIZE = 512_KB;
|
||||
class EcmaParamConfiguration {
|
||||
public:
|
||||
EcmaParamConfiguration(bool isWorker, size_t poolSize)
|
||||
{
|
||||
if (isWorker) {
|
||||
maxHeapSize_ = DEFAULT_WORKER_HEAP_SIZE;
|
||||
} else {
|
||||
if (poolSize >= DEFAULT_HEAP_SIZE) {
|
||||
maxHeapSize_ = DEFAULT_HEAP_SIZE;
|
||||
} else {
|
||||
maxHeapSize_ = poolSize; // pool is too small, no memory left for worker
|
||||
}
|
||||
}
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
if (maxHeapSize_ < LOW_MEMORY) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
if (maxHeapSize_ < MEDIUM_MEMORY) { // 64_MB ~ 128_MB
|
||||
minSemiSpaceSize_ = 2_MB;
|
||||
maxSemiSpaceSize_ = 4_MB;
|
||||
defaultNonMovableSpaceSize_ = 2_MB;
|
||||
defaultSnapshotSpaceSize_ = 512_KB;
|
||||
defaultMachineCodeSpaceSize_ = 2_MB;
|
||||
semiSpaceTriggerConcurrentMark_ = 1_MB;
|
||||
semiSpaceOvershootSize_ = 2_MB;
|
||||
minAllocLimitGrowingStep_ = 2_MB;
|
||||
minGrowingStep_ = 4_MB;
|
||||
maxStackSize_ = 512_KB;
|
||||
} else if (maxHeapSize_ < HIGH_MEMORY) { // 128_MB ~ 256_MB
|
||||
minSemiSpaceSize_ = 2_MB;
|
||||
maxSemiSpaceSize_ = 8_MB;
|
||||
defaultNonMovableSpaceSize_ = 4_MB;
|
||||
defaultSnapshotSpaceSize_ = 512_KB;
|
||||
defaultMachineCodeSpaceSize_ = 2_MB;
|
||||
semiSpaceTriggerConcurrentMark_ = 1.5_MB;
|
||||
semiSpaceOvershootSize_ = 2_MB;
|
||||
minAllocLimitGrowingStep_ = 4_MB;
|
||||
minGrowingStep_ = 8_MB;
|
||||
maxStackSize_ = 512_KB;
|
||||
} else { // 256_MB
|
||||
minSemiSpaceSize_ = 2_MB;
|
||||
maxSemiSpaceSize_ = 16_MB;
|
||||
defaultNonMovableSpaceSize_ = 4_MB;
|
||||
defaultSnapshotSpaceSize_ = 4_MB;
|
||||
defaultMachineCodeSpaceSize_ = 8_MB;
|
||||
semiSpaceTriggerConcurrentMark_ = 1.5_MB;
|
||||
semiSpaceOvershootSize_ = 2_MB;
|
||||
minAllocLimitGrowingStep_ = 8_MB;
|
||||
minGrowingStep_ = 16_MB;
|
||||
maxStackSize_ = 512_KB;
|
||||
}
|
||||
size_t half = 2;
|
||||
defaultHugeObjectSpaceSize_ = maxHeapSize_ / half;
|
||||
}
|
||||
|
||||
size_t GetMaxHeapSize() const
|
||||
{
|
||||
return maxHeapSize_;
|
||||
}
|
||||
|
||||
size_t GetMinSemiSpaceSize() const
|
||||
{
|
||||
return minSemiSpaceSize_;
|
||||
}
|
||||
|
||||
size_t GetMaxSemiSpaceSize() const
|
||||
{
|
||||
return maxSemiSpaceSize_;
|
||||
}
|
||||
|
||||
size_t GetDefaultNonMovableSpaceSize() const
|
||||
{
|
||||
return defaultNonMovableSpaceSize_;
|
||||
}
|
||||
|
||||
size_t GetDefaultSnapshotSpaceSize() const
|
||||
{
|
||||
return defaultSnapshotSpaceSize_;
|
||||
}
|
||||
|
||||
size_t GetDefaultMachineCodeSpaceSize() const
|
||||
{
|
||||
return defaultMachineCodeSpaceSize_;
|
||||
}
|
||||
|
||||
size_t GetSemiSpaceTriggerConcurrentMark() const
|
||||
{
|
||||
return semiSpaceTriggerConcurrentMark_;
|
||||
}
|
||||
|
||||
size_t GetSemiSpaceOvershootSize() const
|
||||
{
|
||||
return semiSpaceOvershootSize_;
|
||||
}
|
||||
|
||||
size_t GetDefaultHugeObjectSpaceSize() const
|
||||
{
|
||||
return defaultHugeObjectSpaceSize_;
|
||||
}
|
||||
|
||||
size_t GetMinAllocLimitGrowingStep() const
|
||||
{
|
||||
return minAllocLimitGrowingStep_;
|
||||
}
|
||||
|
||||
size_t GetMinGrowingStep() const
|
||||
{
|
||||
return minGrowingStep_;
|
||||
}
|
||||
|
||||
uint32_t GetMaxStackSize() const
|
||||
{
|
||||
return maxStackSize_;
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr size_t LOW_MEMORY = 64_MB;
|
||||
static constexpr size_t MEDIUM_MEMORY = 128_MB;
|
||||
static constexpr size_t HIGH_MEMORY = 256_MB;
|
||||
|
||||
size_t maxHeapSize_ {0};
|
||||
size_t minSemiSpaceSize_ {0};
|
||||
size_t maxSemiSpaceSize_ {0};
|
||||
size_t defaultNonMovableSpaceSize_ {0};
|
||||
size_t defaultSnapshotSpaceSize_ {0};
|
||||
size_t defaultMachineCodeSpaceSize_ {0};
|
||||
size_t defaultHugeObjectSpaceSize_ {0};
|
||||
size_t semiSpaceTriggerConcurrentMark_ {0};
|
||||
size_t semiSpaceOvershootSize_ {0};
|
||||
size_t minAllocLimitGrowingStep_ {0};
|
||||
size_t minGrowingStep_ {0};
|
||||
uint32_t maxStackSize_ {0};
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
#endif // ECMASCRIPT_ECMA_PARAM_CONFIGURATION_H
|
||||
|
@ -77,9 +77,9 @@
|
||||
|
||||
namespace panda::ecmascript {
|
||||
/* static */
|
||||
EcmaVM *EcmaVM::Create(const JSRuntimeOptions &options)
|
||||
EcmaVM *EcmaVM::Create(const JSRuntimeOptions &options, EcmaParamConfiguration &config)
|
||||
{
|
||||
auto vm = new EcmaVM(options);
|
||||
auto vm = new EcmaVM(options, config);
|
||||
if (UNLIKELY(vm == nullptr)) {
|
||||
LOG_ECMA(ERROR) << "Failed to create jsvm";
|
||||
return nullptr;
|
||||
@ -101,12 +101,13 @@ bool EcmaVM::Destroy(EcmaVM *vm)
|
||||
return false;
|
||||
}
|
||||
|
||||
EcmaVM::EcmaVM(JSRuntimeOptions options)
|
||||
EcmaVM::EcmaVM(JSRuntimeOptions options, EcmaParamConfiguration config)
|
||||
: stringTable_(new EcmaStringTable(this)),
|
||||
nativeAreaAllocator_(std::make_unique<NativeAreaAllocator>()),
|
||||
heapRegionAllocator_(std::make_unique<HeapRegionAllocator>()),
|
||||
chunk_(nativeAreaAllocator_.get()),
|
||||
nativePointerList_(&chunk_)
|
||||
nativePointerList_(&chunk_),
|
||||
ecmaParamConfiguration_(std::move(config))
|
||||
{
|
||||
options_ = std::move(options);
|
||||
icEnabled_ = options_.EnableIC();
|
||||
|
@ -87,11 +87,11 @@ using ResolvePathCallback = std::function<std::string(std::string dirPath, std::
|
||||
|
||||
class EcmaVM {
|
||||
public:
|
||||
static EcmaVM *Create(const JSRuntimeOptions &options);
|
||||
static EcmaVM *Create(const JSRuntimeOptions &options, EcmaParamConfiguration &config);
|
||||
|
||||
static bool Destroy(EcmaVM *vm);
|
||||
|
||||
explicit EcmaVM(JSRuntimeOptions options);
|
||||
explicit EcmaVM(JSRuntimeOptions options, EcmaParamConfiguration config);
|
||||
|
||||
EcmaVM();
|
||||
|
||||
@ -131,6 +131,11 @@ public:
|
||||
return options_;
|
||||
}
|
||||
|
||||
const EcmaParamConfiguration &GetEcmaParamConfiguration() const
|
||||
{
|
||||
return ecmaParamConfiguration_;
|
||||
}
|
||||
|
||||
JSHandle<GlobalEnv> GetGlobalEnv() const;
|
||||
|
||||
JSHandle<job::MicroJobQueue> GetMicroJobQueue() const;
|
||||
@ -441,6 +446,9 @@ private:
|
||||
// CJS resolve path Callbacks
|
||||
ResolvePathCallback resolvePathCallback_ {nullptr};
|
||||
|
||||
// vm parameter configurations
|
||||
EcmaParamConfiguration ecmaParamConfiguration_;
|
||||
|
||||
friend class Snapshot;
|
||||
friend class SnapshotProcessor;
|
||||
friend class ObjectFactory;
|
||||
|
@ -354,6 +354,16 @@ public:
|
||||
return heap_size_limit_.WasSet();
|
||||
}
|
||||
|
||||
void SetIsWorker(bool isWorker)
|
||||
{
|
||||
isWorker_.SetValue(isWorker);
|
||||
}
|
||||
|
||||
bool IsWorker() const
|
||||
{
|
||||
return isWorker_.GetValue();
|
||||
}
|
||||
|
||||
bool EnableIC() const
|
||||
{
|
||||
return enableIC_.GetValue();
|
||||
@ -508,6 +518,8 @@ private:
|
||||
R"(enable statistics of runtime state. Default: false)"};
|
||||
PandArg<bool> logTypeInfer_ {"log-Type-Infer", false,
|
||||
R"(print aot type infer log. Default: false)"};
|
||||
PandArg<bool> isWorker_ {"IsWorker", false,
|
||||
R"(whether is worker vm)"};
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
|
@ -34,9 +34,10 @@ JSThread *JSThread::Create(EcmaVM *vm)
|
||||
jsThread->nativeAreaAllocator_ = vm->GetNativeAreaAllocator();
|
||||
jsThread->heapRegionAllocator_ = vm->GetHeapRegionAllocator();
|
||||
// algin with 16
|
||||
size_t maxStackSize = vm->GetEcmaParamConfiguration().GetMaxStackSize();
|
||||
jsThread->glueData_.frameBase_ = static_cast<JSTaggedType *>(
|
||||
vm->GetNativeAreaAllocator()->Allocate(sizeof(JSTaggedType) * MAX_STACK_SIZE));
|
||||
jsThread->glueData_.currentFrame_ = jsThread->glueData_.frameBase_ + MAX_STACK_SIZE;
|
||||
vm->GetNativeAreaAllocator()->Allocate(sizeof(JSTaggedType) * maxStackSize));
|
||||
jsThread->glueData_.currentFrame_ = jsThread->glueData_.frameBase_ + maxStackSize;
|
||||
EcmaInterpreter::InitStackFrame(jsThread);
|
||||
return jsThread;
|
||||
}
|
||||
@ -60,7 +61,8 @@ JSThread::~JSThread()
|
||||
handleScopeStorageNext_ = handleScopeStorageEnd_ = nullptr;
|
||||
GetEcmaVM()->GetChunk()->Delete(globalStorage_);
|
||||
|
||||
GetNativeAreaAllocator()->Free(glueData_.frameBase_, sizeof(JSTaggedType) * MAX_STACK_SIZE);
|
||||
GetNativeAreaAllocator()->Free(glueData_.frameBase_, sizeof(JSTaggedType) *
|
||||
vm_->GetEcmaParamConfiguration().GetMaxStackSize());
|
||||
glueData_.frameBase_ = nullptr;
|
||||
nativeAreaAllocator_ = nullptr;
|
||||
heapRegionAllocator_ = nullptr;
|
||||
|
@ -51,9 +51,10 @@ Heap::Heap(EcmaVM *ecmaVm) : ecmaVm_(ecmaVm), thread_(ecmaVm->GetJSThread()),
|
||||
void Heap::Initialize()
|
||||
{
|
||||
memController_ = new MemController(this);
|
||||
|
||||
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);
|
||||
auto &config = ecmaVm_->GetEcmaParamConfiguration();
|
||||
size_t maxHeapSize = config.GetMaxHeapSize();
|
||||
size_t minSemiSpaceCapacity = config.GetMinSemiSpaceSize();
|
||||
size_t maxSemiSpaceCapacity = config.GetMaxSemiSpaceSize();
|
||||
activeSemiSpace_ = new SemiSpace(this, minSemiSpaceCapacity, maxSemiSpaceCapacity);
|
||||
activeSemiSpace_->Restart();
|
||||
activeSemiSpace_->SetWaterLine();
|
||||
@ -63,35 +64,37 @@ void Heap::Initialize()
|
||||
inactiveSemiSpace_ = new SemiSpace(this, minSemiSpaceCapacity, maxSemiSpaceCapacity);
|
||||
// not set up from space
|
||||
|
||||
size_t nonmovableSpaceCapacity = std::max(DEFAULT_NONMOVABLE_SPACE_SIZE, CONSTRAINT_MIN_NONMOVABLE_SPACE_SIZE);
|
||||
size_t nonmovableSpaceCapacity = config.GetDefaultNonMovableSpaceSize();
|
||||
if (ecmaVm_->GetJSOptions().WasSetMaxNonmovableSpaceCapacity()) {
|
||||
nonmovableSpaceCapacity = ecmaVm_->GetJSOptions().MaxNonmovableSpaceCapacity();
|
||||
}
|
||||
nonMovableSpace_ = new NonMovableSpace(this, nonmovableSpaceCapacity, nonmovableSpaceCapacity);
|
||||
nonMovableSpace_->Initialize();
|
||||
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);
|
||||
size_t snapshotSpaceCapacity = config.GetDefaultSnapshotSpaceSize();
|
||||
snapshotSpace_ = new SnapshotSpace(this, snapshotSpaceCapacity, snapshotSpaceCapacity);
|
||||
size_t machineCodeSpaceCapacity = config.GetDefaultMachineCodeSpaceSize();
|
||||
machineCodeSpace_ = new MachineCodeSpace(this, machineCodeSpaceCapacity, machineCodeSpaceCapacity);
|
||||
machineCodeSpace_->Initialize();
|
||||
|
||||
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;
|
||||
if (maxHeapSize < capacities || maxHeapSize - capacities < MIN_OLD_SPACE_LIMIT) {
|
||||
LOG_ECMA_MEM(FATAL) << "HeapSize is too small to initialize oldspace, heapSize = " << maxHeapSize;
|
||||
}
|
||||
size_t oldSpaceCapacity = MAX_HEAP_SIZE - capacities;
|
||||
globalSpaceAllocLimit_ = MAX_HEAP_SIZE - minSemiSpaceCapacity;
|
||||
size_t oldSpaceCapacity = maxHeapSize - capacities;
|
||||
globalSpaceAllocLimit_ = maxHeapSize - minSemiSpaceCapacity;
|
||||
|
||||
oldSpace_ = new OldSpace(this, oldSpaceCapacity, oldSpaceCapacity);
|
||||
compressSpace_ = new OldSpace(this, oldSpaceCapacity, oldSpaceCapacity);
|
||||
oldSpace_->Initialize();
|
||||
hugeObjectSpace_ = new HugeObjectSpace(heapRegionAllocator_, oldSpaceCapacity, oldSpaceCapacity);
|
||||
|
||||
size_t hugeObjectSpaceCapacity = config.GetDefaultHugeObjectSpaceSize();
|
||||
hugeObjectSpace_ = new HugeObjectSpace(heapRegionAllocator_, hugeObjectSpaceCapacity, hugeObjectSpaceCapacity);
|
||||
maxEvacuateTaskCount_ = Taskpool::GetCurrentTaskpool()->GetTotalThreadNum();
|
||||
maxMarkTaskCount_ = std::min<size_t>(ecmaVm_->GetJSOptions().GetGcThreadNum(),
|
||||
maxEvacuateTaskCount_ - 1);
|
||||
|
||||
LOG(INFO, RUNTIME) << "heap initialize: heap size = " << MAX_HEAP_SIZE
|
||||
LOG(INFO, RUNTIME) << "heap initialize: heap size = " << maxHeapSize
|
||||
<< ", semispace capacity = " << minSemiSpaceCapacity
|
||||
<< ", nonmovablespace capacity = " << nonmovableSpaceCapacity
|
||||
<< ", snapshotspace capacity = " << snapshotSpaceCapacity
|
||||
@ -414,8 +417,9 @@ void Heap::AdjustOldSpaceLimit()
|
||||
if (oldSpaceLimitAdjusted_) {
|
||||
return;
|
||||
}
|
||||
size_t minGrowingStep = ecmaVm_->GetEcmaParamConfiguration().GetMinGrowingStep();
|
||||
size_t oldSpaceAllocLimit = GetOldSpace()->GetInitialCapacity();
|
||||
size_t newOldSpaceAllocLimit = std::max(oldSpace_->GetHeapObjectSize() + MIN_GROWING_STEP,
|
||||
size_t newOldSpaceAllocLimit = std::max(oldSpace_->GetHeapObjectSize() + minGrowingStep,
|
||||
static_cast<size_t>(oldSpaceAllocLimit * memController_->GetAverageSurvivalRate()));
|
||||
if (newOldSpaceAllocLimit <= oldSpaceAllocLimit) {
|
||||
GetOldSpace()->SetInitialCapacity(newOldSpaceAllocLimit);
|
||||
@ -423,7 +427,7 @@ void Heap::AdjustOldSpaceLimit()
|
||||
oldSpaceLimitAdjusted_ = true;
|
||||
}
|
||||
|
||||
size_t newGlobalSpaceAllocLimit = std::max(GetHeapObjectSize() + MIN_GROWING_STEP,
|
||||
size_t newGlobalSpaceAllocLimit = std::max(GetHeapObjectSize() + minGrowingStep,
|
||||
static_cast<size_t>(globalSpaceAllocLimit_ * memController_->GetAverageSurvivalRate()));
|
||||
if (newGlobalSpaceAllocLimit < globalSpaceAllocLimit_) {
|
||||
globalSpaceAllocLimit_ = newGlobalSpaceAllocLimit;
|
||||
@ -459,11 +463,12 @@ void Heap::RecomputeLimits()
|
||||
size_t newSpaceCapacity = activeSemiSpace_->GetInitialCapacity();
|
||||
|
||||
double growingFactor = memController_->CalculateGrowingFactor(gcSpeed, mutatorSpeed);
|
||||
size_t maxOldSpaceCapacity = oldSpace_->GetMaximumCapacity();
|
||||
// newOldSpaceLimit should consider committedSize of hugeObjectSpace
|
||||
size_t maxOldSpaceCapacity = oldSpace_->GetMaximumCapacity() - hugeObjectSpace_->GetCommittedSize();
|
||||
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,
|
||||
size_t maxGlobalSize = ecmaVm_->GetEcmaParamConfiguration().GetMaxHeapSize() - newSpaceCapacity;
|
||||
auto newGlobalSpaceLimit = memController_->CalculateAllocLimit(GetHeapObjectSize(), MIN_HEAP_SIZE,
|
||||
maxGlobalSize, newSpaceCapacity, growingFactor);
|
||||
globalSpaceAllocLimit_ = newGlobalSpaceLimit;
|
||||
oldSpace_->SetInitialCapacity(newOldSpaceLimit);
|
||||
@ -541,7 +546,8 @@ void Heap::TryTriggerConcurrentMarking()
|
||||
double newSpaceConcurrentMarkSpeed = memController_->GetNewSpaceConcurrentMarkSpeedPerMS();
|
||||
|
||||
if (newSpaceConcurrentMarkSpeed == 0 || newSpaceAllocSpeed == 0) {
|
||||
if (activeSemiSpace_->GetCommittedSize() >= SEMI_SPACE_TRIGGER_CONCURRENT_MARK) {
|
||||
auto &config = ecmaVm_->GetEcmaParamConfiguration();
|
||||
if (activeSemiSpace_->GetCommittedSize() >= config.GetSemiSpaceTriggerConcurrentMark()) {
|
||||
markType_ = MarkType::MARK_YOUNG;
|
||||
TriggerConcurrentMarking();
|
||||
OPTIONAL_LOG(ecmaVm_, ERROR, ECMASCRIPT) << "Trigger the first semi mark" << fullGCRequested_;
|
||||
|
@ -41,7 +41,7 @@ uintptr_t LinearSpace::Allocate(size_t size, bool isPromoted)
|
||||
object = allocator_.Allocate(size);
|
||||
} else if (heap_->GetJSThread()->IsMarking()) {
|
||||
// Temporary adjust semi space capacity
|
||||
overShootSize_ = SEMI_SPACE_OVERSHOOT_SIZE;
|
||||
overShootSize_ = heap_->GetEcmaVM()->GetEcmaParamConfiguration().GetSemiSpaceOvershootSize();
|
||||
if (Expand(isPromoted)) {
|
||||
object = allocator_.Allocate(size);
|
||||
}
|
||||
|
@ -41,24 +41,19 @@ enum class MemAlignmentLog2 : uint8_t {
|
||||
MEM_ALIGN_REGION_LOG2 = 4,
|
||||
};
|
||||
|
||||
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 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_MEM_POOL_CAPACITY = 32_MB;
|
||||
static constexpr size_t LARGE_POOL_SIZE = 480_MB;
|
||||
static constexpr size_t MEDIUM_POOL_SIZE = 256_MB;
|
||||
static constexpr size_t LOW_POOL_SIZE = 64_MB;
|
||||
static constexpr size_t MIN_MEM_POOL_CAPACITY = 64_MB;
|
||||
static constexpr size_t PHY_SIZE_MULTIPLE = 4;
|
||||
static constexpr size_t WORKER_NUM = 7;
|
||||
static constexpr size_t STANDARD_POOL_SIZE = WORKER_NUM * DEFAULT_WORKER_HEAP_SIZE + DEFAULT_HEAP_SIZE;
|
||||
|
||||
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 DEFAULT_HEAP_SIZE = 5_MB;
|
||||
static constexpr size_t MIN_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;
|
||||
|
@ -20,19 +20,21 @@
|
||||
#include "ecmascript/mem/parallel_evacuator.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
MemController::MemController(Heap *heap) : heap_(heap), allocTimeMs_(GetSystemTimeInMs()) {}
|
||||
MemController::MemController(Heap *heap) : heap_(heap), allocTimeMs_(GetSystemTimeInMs())
|
||||
{
|
||||
minAllocLimitGrowingStep_ = heap->GetEcmaVM()->GetEcmaParamConfiguration().GetMinAllocLimitGrowingStep();
|
||||
}
|
||||
|
||||
double MemController::CalculateAllocLimit(size_t currentSize, size_t minSize, size_t maxSize, size_t newSpaceCapacity,
|
||||
double factor) const
|
||||
{
|
||||
const uint64_t limit = std::max(static_cast<uint64_t>(currentSize * factor),
|
||||
static_cast<uint64_t>(currentSize) + MIN_AllOC_LIMIT_GROWING_STEP) +
|
||||
static_cast<uint64_t>(currentSize) + minAllocLimitGrowingStep_) +
|
||||
newSpaceCapacity;
|
||||
|
||||
const uint64_t limitAboveMinSize = std::max<uint64_t>(limit, minSize);
|
||||
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));
|
||||
return result;
|
||||
}
|
||||
|
@ -135,6 +135,7 @@ private:
|
||||
const BytesAndDuration &initial, const double timeMs);
|
||||
|
||||
Heap* heap_;
|
||||
size_t minAllocLimitGrowingStep_ {0};
|
||||
|
||||
double gcStartTime_ {0.0};
|
||||
double gcEndTime_ {0.0};
|
||||
|
@ -127,6 +127,13 @@ void MemMapAllocator::AdapterSuitablePoolCapacity()
|
||||
size_t physSize = pages * pageSize;
|
||||
#endif
|
||||
capacity_ = std::max<size_t>(physSize / PHY_SIZE_MULTIPLE, MIN_MEM_POOL_CAPACITY);
|
||||
LOG(INFO, RUNTIME) << "Auto adapter memory pool capacity:" << capacity_;
|
||||
if (capacity_ > LARGE_POOL_SIZE) {
|
||||
capacity_ = std::max<size_t>(capacity_, STANDARD_POOL_SIZE);
|
||||
} else if (capacity_ >= MEDIUM_POOL_SIZE) {
|
||||
capacity_ = std::min<size_t>(capacity_, STANDARD_POOL_SIZE);
|
||||
} else if (capacity_ >= LOW_POOL_SIZE) {
|
||||
capacity_ = std::max<size_t>(capacity_, 128_MB);
|
||||
}
|
||||
LOG(INFO, RUNTIME) << "Ark Auto adapter memory pool capacity:" << capacity_;
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -220,6 +220,27 @@ public:
|
||||
memMapPool_.Finalize();
|
||||
}
|
||||
|
||||
size_t GetCapacity()
|
||||
{
|
||||
return capacity_;
|
||||
}
|
||||
|
||||
void IncreaseAndCheckReserved(size_t size)
|
||||
{
|
||||
if (reserved_ + size > capacity_) {
|
||||
LOG(ERROR, RUNTIME) << "pool is empty, reserved = " << reserved_ << ", capacity_ = "
|
||||
<< capacity_ << ", size = " << size;
|
||||
}
|
||||
reserved_ += size;
|
||||
LOG(DEBUG, RUNTIME) << "Ark IncreaseAndCheckReserved reserved = " << reserved_ << ", capacity_ = " << capacity_;
|
||||
}
|
||||
|
||||
void DecreaseReserved(size_t size)
|
||||
{
|
||||
reserved_ -= size;
|
||||
LOG(DEBUG, RUNTIME) << "Ark DecreaseReserved reserved = " << reserved_ << ", capacity_ = " << capacity_;
|
||||
}
|
||||
|
||||
static MemMapAllocator *GetInstance()
|
||||
{
|
||||
static MemMapAllocator vmAllocator_;
|
||||
@ -259,6 +280,7 @@ private:
|
||||
MemMapFreeList memMapFreeList_;
|
||||
std::atomic_size_t memMapTotalSize_ {0};
|
||||
size_t capacity_ {0};
|
||||
size_t reserved_ {0};
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_MEM_MEM_MAP_ALLOCATOR_H
|
||||
|
@ -70,7 +70,7 @@ HugeObjectSpace::HugeObjectSpace(HeapRegionAllocator *heapRegionAllocator,
|
||||
|
||||
uintptr_t HugeObjectSpace::Allocate(size_t objectSize, JSThread *thread)
|
||||
{
|
||||
if (committedSize_ >= maximumCapacity_) {
|
||||
if (committedSize_ + objectSize >= maximumCapacity_) {
|
||||
LOG_ECMA_MEM(INFO) << "Committed size " << committedSize_ << " of huge object space is too big.";
|
||||
return 0;
|
||||
}
|
||||
|
@ -945,6 +945,16 @@ public:
|
||||
asmOpcodeDisableRange_ = value;
|
||||
}
|
||||
|
||||
void SetIsWorker()
|
||||
{
|
||||
isWorker_ = true;
|
||||
}
|
||||
|
||||
bool GetIsWorker() const
|
||||
{
|
||||
return isWorker_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string GetGcType() const
|
||||
{
|
||||
@ -1053,6 +1063,7 @@ private:
|
||||
size_t gcThreadNum_ {DEFAULT_GC_THREAD_NUM};
|
||||
size_t longPauseTime_ {DEFAULT_LONG_PAUSE_TIME};
|
||||
bool enableAsmInterpreter_ {false};
|
||||
bool isWorker_ {false};
|
||||
std::string asmOpcodeDisableRange_ {""};
|
||||
friend JSNApi;
|
||||
};
|
||||
|
@ -129,6 +129,7 @@ EcmaVM *JSNApi::CreateJSVM(const RuntimeOption &option)
|
||||
runtimeOptions.SetArkProperties(option.GetArkProperties());
|
||||
runtimeOptions.SetLongPauseTime(option.GetLongPauseTime());
|
||||
runtimeOptions.SetGcThreadNum(option.GetGcThreadNum());
|
||||
runtimeOptions.SetIsWorker(option.GetIsWorker());
|
||||
// Mem
|
||||
runtimeOptions.SetHeapSizeLimit(option.GetGcPoolSize());
|
||||
// asmInterpreter
|
||||
@ -145,7 +146,6 @@ EcmaVM *JSNApi::CreateJSVM(const RuntimeOption &option)
|
||||
if (option.GetLogBufPrint() != nullptr) {
|
||||
Logger::SetMobileLogPrintEntryPointByPtr(reinterpret_cast<void *>(option.GetLogBufPrint()));
|
||||
}
|
||||
|
||||
runtimeOptions.SetEnableArkTools(option.GetEnableArkTools());
|
||||
return CreateEcmaVM(runtimeOptions);
|
||||
}
|
||||
@ -160,7 +160,11 @@ EcmaVM *JSNApi::CreateEcmaVM(const JSRuntimeOptions &options)
|
||||
initialize_ = true;
|
||||
}
|
||||
}
|
||||
return EcmaVM::Create(options);
|
||||
auto config = ecmascript::EcmaParamConfiguration(options.IsWorker(),
|
||||
MemMapAllocator::GetInstance()->GetCapacity());
|
||||
LOG(INFO, RUNTIME) << "CreateEcmaVM: isWorker = " << options.IsWorker() << ", vmCount = " << vmCount_;
|
||||
MemMapAllocator::GetInstance()->IncreaseAndCheckReserved(config.GetMaxHeapSize());
|
||||
return EcmaVM::Create(options, config);
|
||||
}
|
||||
|
||||
void JSNApi::DestroyJSVM(EcmaVM *ecmaVm)
|
||||
@ -169,6 +173,8 @@ void JSNApi::DestroyJSVM(EcmaVM *ecmaVm)
|
||||
if (!initialize_) {
|
||||
return;
|
||||
}
|
||||
auto &config = ecmaVm->GetEcmaParamConfiguration();
|
||||
MemMapAllocator::GetInstance()->DecreaseReserved(config.GetMaxHeapSize());
|
||||
EcmaVM::Destroy(ecmaVm);
|
||||
vmCount_--;
|
||||
if (vmCount_ <= 0) {
|
||||
|
@ -253,13 +253,14 @@ HWTEST_F_L0(SnapshotTest, SerializeBuiltins)
|
||||
// generate builtins.snapshot file
|
||||
JSRuntimeOptions options1;
|
||||
options1.SetArkProperties(ArkProperties::ENABLE_SNAPSHOT_SERIALIZE);
|
||||
EcmaVM *ecmaVm1 = EcmaVM::Create(options1);
|
||||
auto config = ecmascript::EcmaParamConfiguration(false, MemMapAllocator::GetInstance()->GetCapacity());
|
||||
EcmaVM *ecmaVm1 = EcmaVM::Create(options1, config);
|
||||
EcmaVM::Destroy(ecmaVm1);
|
||||
|
||||
// create EcmaVM use builtins deserialzie
|
||||
JSRuntimeOptions options2;
|
||||
options2.SetArkProperties(ArkProperties::ENABLE_SNAPSHOT_DESERIALIZE);
|
||||
EcmaVM *ecmaVm2 = EcmaVM::Create(options2);
|
||||
EcmaVM *ecmaVm2 = EcmaVM::Create(options2, config);
|
||||
EXPECT_TRUE(ecmaVm2->GetGlobalEnv()->GetClass()->GetObjectType() == JSType::GLOBAL_ENV);
|
||||
auto globalConst = const_cast<GlobalEnvConstants *>(ecmaVm2->GetJSThread()->GlobalConstants());
|
||||
size_t hclassEndIndex = static_cast<size_t>(ConstantIndex::UNDEFINED_INDEX);
|
||||
|
@ -59,7 +59,8 @@ HWTEST_F_L0(EcmaVMTest, CreateEcmaVMInTwoWays)
|
||||
options2.SetEnableCpuprofiler(true);
|
||||
options2.SetArkProperties(ArkProperties::GC_STATS_PRINT);
|
||||
// A non-production gc strategy. Prohibit stw-gc 10 times.
|
||||
EcmaVM *ecmaVm2 = EcmaVM::Create(options2);
|
||||
auto config = ecmascript::EcmaParamConfiguration(false, MemMapAllocator::GetInstance()->GetCapacity());
|
||||
EcmaVM *ecmaVm2 = EcmaVM::Create(options2, config);
|
||||
|
||||
EXPECT_TRUE(ecmaVm1 != ecmaVm2);
|
||||
|
||||
|
@ -95,21 +95,21 @@ HWTEST_F_L0(HugeObjectTest, MultipleArrays)
|
||||
auto heap = ecmaVm->GetHeap();
|
||||
{
|
||||
[[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
|
||||
for (int i = 0; i <= 20; i++) {
|
||||
for (int i = 0; i <= 14; i++) {
|
||||
JSHandle<TaggedArray> array1(thread, LargeArrayTestCreate(thread));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
[[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
|
||||
for (int i = 0; i <= 20; i++) {
|
||||
for (int i = 0; i <= 14; i++) {
|
||||
JSHandle<TaggedArray> array2(thread, LargeArrayTestCreate(thread));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
[[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
|
||||
for (int i = 0; i <= 20; i++) {
|
||||
for (int i = 0; i <= 14; i++) {
|
||||
JSHandle<TaggedArray> array2(thread, LargeArrayTestCreate(thread));
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,8 @@ public:
|
||||
{
|
||||
JSRuntimeOptions options;
|
||||
options.SetEnableForceGC(true);
|
||||
ecmaVm = EcmaVM::Create(options);
|
||||
auto config = ecmascript::EcmaParamConfiguration(false, MemMapAllocator::GetInstance()->GetCapacity());
|
||||
ecmaVm = EcmaVM::Create(options, config);
|
||||
ecmaVm->SetEnableForceGC(true);
|
||||
EXPECT_TRUE(ecmaVm != nullptr) << "Cannot create Runtime";
|
||||
thread = ecmaVm->GetJSThread();
|
||||
|
Loading…
Reference in New Issue
Block a user