mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-24 02:30:03 +00:00
fix taskpools shared between parent and child process
should recreate taskpools for child process issue: https://gitee.com/openharmony/ark_js_runtime/issues/I5EG9W?from=project-issue Signed-off-by: lukai <lukai25@huawei.com> Change-Id: If98b0938af358a3949fb1f5f809467737761b792
This commit is contained in:
parent
de2b4a87f1
commit
3d956047cf
@ -106,6 +106,19 @@ bool EcmaVM::Destroy(EcmaVM *vm)
|
||||
return false;
|
||||
}
|
||||
|
||||
void EcmaVM::preFork()
|
||||
{
|
||||
heap_->CompactHeapBeforeFork();
|
||||
heap_->GetReadOnlySpace()->SetReadOnly();
|
||||
heap_->DisableParallelGC();
|
||||
}
|
||||
|
||||
void EcmaVM::postFork()
|
||||
{
|
||||
GetAssociatedJSThread()->SetThreadId();
|
||||
Taskpool::GetCurrentTaskpool()->Initialize();
|
||||
}
|
||||
|
||||
EcmaVM::EcmaVM(JSRuntimeOptions options, EcmaParamConfiguration config)
|
||||
: stringTable_(new EcmaStringTable(this)),
|
||||
nativeAreaAllocator_(std::make_unique<NativeAreaAllocator>()),
|
||||
@ -192,7 +205,6 @@ bool EcmaVM::Initialize()
|
||||
if (options_.GetEnableAsmInterpreter() && options_.WasAOTOutputFileSet()) {
|
||||
LoadAOTFiles();
|
||||
}
|
||||
heap_->GetReadOnlySpace()->SetReadOnly();
|
||||
InitializeFinish();
|
||||
return true;
|
||||
}
|
||||
@ -624,7 +636,7 @@ void EcmaVM::ClearBufferData()
|
||||
bool EcmaVM::ExecutePromisePendingJob()
|
||||
{
|
||||
if (isProcessingPendingJob_) {
|
||||
LOG_ECMA(ERROR) << "EcmaVM::ExecutePromisePendingJob can not reentrant";
|
||||
LOG_ECMA(DEBUG) << "EcmaVM::ExecutePromisePendingJob can not reentrant";
|
||||
return false;
|
||||
}
|
||||
if (!thread_->HasPendingException()) {
|
||||
|
@ -113,7 +113,6 @@ public:
|
||||
}
|
||||
|
||||
bool Initialize();
|
||||
|
||||
bool InitializeFinish();
|
||||
|
||||
GCStats *GetEcmaGCStats() const
|
||||
@ -348,6 +347,8 @@ public:
|
||||
exceptionBCList_.clear();
|
||||
}
|
||||
|
||||
void preFork();
|
||||
void postFork();
|
||||
protected:
|
||||
|
||||
void HandleUncaughtException(TaggedObject *exception);
|
||||
|
@ -393,6 +393,11 @@ public:
|
||||
return id_.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void SetThreadId()
|
||||
{
|
||||
id_.store(JSThread::GetCurrentThreadId(), std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
static ThreadId GetCurrentThreadId()
|
||||
{
|
||||
return os::thread::GetCurrentThreadId();
|
||||
|
@ -58,6 +58,12 @@ public:
|
||||
return enableMarkType_ == EnableConcurrentMarkType::DISABLE ||
|
||||
enableMarkType_ == EnableConcurrentMarkType::CONFIG_DISABLE;
|
||||
}
|
||||
|
||||
void DisableConcurrentMark()
|
||||
{
|
||||
enableMarkType_ = EnableConcurrentMarkType::CONFIG_DISABLE;
|
||||
}
|
||||
|
||||
bool IsRequestDisabled() const
|
||||
{
|
||||
return enableMarkType_ == EnableConcurrentMarkType::REQUEST_DISABLE;
|
||||
|
@ -65,6 +65,11 @@ public:
|
||||
return !IsDisabled();
|
||||
}
|
||||
|
||||
void DisableConcurrentSweep()
|
||||
{
|
||||
enableType_ = EnableConcurrentSweepType::CONFIG_DISABLE;
|
||||
}
|
||||
|
||||
bool IsDisabled() const
|
||||
{
|
||||
return enableType_ == EnableConcurrentSweepType::DISABLE ||
|
||||
|
@ -90,7 +90,10 @@ void FullGC::Sweep()
|
||||
{
|
||||
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "FullGC::Sweep");
|
||||
// process weak reference
|
||||
auto totalThreadCount = Taskpool::GetCurrentTaskpool()->GetTotalThreadNum() + 1; // gc thread and main thread
|
||||
uint32_t totalThreadCount = 1; // 1 : mainthread
|
||||
if (heap_->IsParallelGCEnabled()) {
|
||||
totalThreadCount += Taskpool::GetCurrentTaskpool()->GetTotalThreadNum();
|
||||
}
|
||||
for (uint32_t i = 0; i < totalThreadCount; i++) {
|
||||
ProcessQueue *queue = workManager_->GetWeakReferenceQueue(i);
|
||||
|
||||
|
@ -280,6 +280,18 @@ void Heap::CompactHeapBeforeFork()
|
||||
fullGC_->RunPhasesForAppSpawn();
|
||||
}
|
||||
|
||||
void Heap::DisableParallelGC()
|
||||
{
|
||||
Prepare();
|
||||
parallelGC_ = false;
|
||||
maxEvacuateTaskCount_ = 0;
|
||||
maxMarkTaskCount_ = 0;
|
||||
stwYoungGC_->DisableParallelGC();
|
||||
sweeper_->DisableConcurrentSweep();
|
||||
concurrentMarker_ ->DisableConcurrentMark();
|
||||
Taskpool::GetCurrentTaskpool()->Destroy();
|
||||
}
|
||||
|
||||
TriggerGCType Heap::SelectGCType() const
|
||||
{
|
||||
// If concurrent mark is enabled, the TryTriggerConcurrentMarking decide which GC to choose.
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
void Prepare();
|
||||
void Resume(TriggerGCType gcType);
|
||||
void CompactHeapBeforeFork();
|
||||
void DisableParallelGC();
|
||||
// fixme: Rename NewSpace to YoungSpace.
|
||||
// This is the active young generation space that the new objects are allocated in
|
||||
// or copied into (from the other semi space) during semi space GC.
|
||||
|
@ -40,6 +40,10 @@ public:
|
||||
NO_COPY_SEMANTIC(STWYoungGC);
|
||||
NO_MOVE_SEMANTIC(STWYoungGC);
|
||||
|
||||
void DisableParallelGC()
|
||||
{
|
||||
parallelGC_ = false;
|
||||
}
|
||||
virtual void RunPhases() override;
|
||||
|
||||
protected:
|
||||
|
@ -1146,6 +1146,8 @@ public:
|
||||
static void InitializeMemMapAllocator();
|
||||
static void DestroyMemMapAllocator();
|
||||
static EcmaVM* CreateEcmaVM(const ecmascript::JSRuntimeOptions &options);
|
||||
static void preFork(EcmaVM *vm);
|
||||
static void postFork(EcmaVM *vm);
|
||||
private:
|
||||
static int vmCount_;
|
||||
static bool initialize_;
|
||||
|
@ -292,6 +292,16 @@ bool JSNApi::Execute(EcmaVM *vm, const uint8_t *data, int32_t size,
|
||||
return true;
|
||||
}
|
||||
|
||||
void JSNApi::preFork(EcmaVM *vm)
|
||||
{
|
||||
vm->preFork();
|
||||
}
|
||||
|
||||
void JSNApi::postFork(EcmaVM *vm)
|
||||
{
|
||||
vm->postFork();
|
||||
}
|
||||
|
||||
Local<ObjectRef> JSNApi::GetUncaughtException(const EcmaVM *vm)
|
||||
{
|
||||
return JSNApiHelper::ToLocal<ObjectRef>(vm->GetEcmaUncaughtException());
|
||||
|
@ -95,6 +95,7 @@ public:
|
||||
HWTEST_F_L0(ReadOnlySpaceTest, ReadOnlyTest)
|
||||
{
|
||||
auto *heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
|
||||
heap->GetReadOnlySpace()->SetReadOnly();
|
||||
if (ReadOnlyTestManager::RegisterSignal() == -1) {
|
||||
perror("sigaction error");
|
||||
exit(1);
|
||||
@ -112,7 +113,6 @@ HWTEST_F_L0(ReadOnlySpaceTest, ReadOnlyTest)
|
||||
HWTEST_F_L0(ReadOnlySpaceTest, AllocateTest)
|
||||
{
|
||||
auto *heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
|
||||
heap->GetReadOnlySpace()->ClearReadOnly();
|
||||
auto *object = heap->AllocateReadOnlyOrHugeObject(
|
||||
JSHClass::Cast(thread->GlobalConstants()->GetBigIntClass().GetTaggedObject()));
|
||||
auto *region = Region::ObjectAddressToRange(object);
|
||||
@ -122,7 +122,6 @@ HWTEST_F_L0(ReadOnlySpaceTest, AllocateTest)
|
||||
HWTEST_F_L0(ReadOnlySpaceTest, CompactHeapBeforeForkTest)
|
||||
{
|
||||
auto *heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
|
||||
heap->GetReadOnlySpace()->ClearReadOnly();
|
||||
std::string rawStr = "test string";
|
||||
JSHandle<EcmaString> string = factory->NewFromStdString(rawStr);
|
||||
JSHandle<JSObject> obj = factory->NewEmptyJSObject();
|
||||
@ -140,7 +139,6 @@ HWTEST_F_L0(ReadOnlySpaceTest, CompactHeapBeforeForkTest)
|
||||
HWTEST_F_L0(ReadOnlySpaceTest, GCTest)
|
||||
{
|
||||
auto *heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
|
||||
heap->GetReadOnlySpace()->ClearReadOnly();
|
||||
auto *object = heap->AllocateReadOnlyOrHugeObject(
|
||||
JSHClass::Cast(thread->GlobalConstants()->GetBigIntClass().GetTaggedObject()));
|
||||
heap->CollectGarbage(TriggerGCType::YOUNG_GC);
|
||||
@ -149,4 +147,23 @@ HWTEST_F_L0(ReadOnlySpaceTest, GCTest)
|
||||
auto *region = Region::ObjectAddressToRange(object);
|
||||
EXPECT_TRUE(region->InReadOnlySpace());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(ReadOnlySpaceTest, ForkTest)
|
||||
{
|
||||
auto vm = thread->GetEcmaVM();
|
||||
auto *heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
|
||||
std::string rawStr = "fork string";
|
||||
JSHandle<EcmaString> string = factory->NewFromStdString(rawStr);
|
||||
JSNApi::preFork(vm);
|
||||
if (fork() != 0) {
|
||||
// test gc in parent process
|
||||
heap->CollectGarbage(TriggerGCType::OLD_GC);
|
||||
} else {
|
||||
JSNApi::postFork(vm);
|
||||
// test gc in child process
|
||||
heap->CollectGarbage(TriggerGCType::OLD_GC);
|
||||
auto *region = Region::ObjectAddressToRange(string.GetObject<TaggedObject>());
|
||||
EXPECT_TRUE(region->InReadOnlySpace());
|
||||
}
|
||||
}
|
||||
} // namespace panda::test
|
||||
|
Loading…
Reference in New Issue
Block a user