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:
lukai 2022-05-27 17:56:07 +08:00
parent 5e2c8ff9c8
commit 6eb0577699
20 changed files with 214 additions and 127 deletions

View 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

View File

@ -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";

View File

@ -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",

View File

@ -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"

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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()

View File

@ -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_;

View File

@ -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;

View File

@ -82,6 +82,7 @@ public:
private:
os::memory::Mutex lock_;
size_t minimumCapacity_;
};
class SnapshotSpace : public LinearSpace {

View File

@ -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);

View File

@ -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;
}

View File

@ -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();

View File

@ -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);

View File

@ -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();
}

View File

@ -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;

View File

@ -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

View File

@ -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()

View File

@ -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_);