Fix some bugs at device when enable sendable patchs.

Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I94Q3I?from=project-issue
1. Add threadStateTranstion when call from native to js.
2. Some mutexes don't transition their state at safepoint
3. Updating localToShareRSet encounters data race.

Signed-off-by: lukai <lukai25@huawei.com>
Change-Id: I3955eafdc043a61f563ac342ac53852d6f842720
This commit is contained in:
lukai 2024-02-29 15:48:30 +08:00
parent cc31021d26
commit 718413114a
11 changed files with 54 additions and 5 deletions

View File

@ -256,8 +256,8 @@ EcmaString *EcmaStringTable::GetOrInternStringWithSpaceType(EcmaVM *vm, const ui
{
ASSERT(IsSMemSpace(type));
type = (type == MemSpaceType::SHARED_NON_MOVABLE) ? type : MemSpaceType::SHARED_OLD_SPACE;
EcmaString *str = EcmaStringAccessor::CreateUtf16StringFromUtf8(vm, utf8Data, utf16Len, type);
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
EcmaString *str = EcmaStringAccessor::CreateUtf16StringFromUtf8(vm, utf8Data, utf16Len, type);
EcmaString *result = GetStringThreadUnsafe(str);
if (result != nullptr) {
return result;

View File

@ -142,6 +142,7 @@ void EcmaVM::PreFork()
heap_->CompactHeapBeforeFork();
heap_->AdjustSpaceSizeForAppSpawn();
heap_->GetReadOnlySpace()->SetReadOnly();
SharedHeap::GetInstance()->DisableParallelGC();
heap_->DisableParallelGC();
}
@ -150,6 +151,8 @@ void EcmaVM::PostFork()
RandomGenerator::InitRandom();
heap_->SetHeapMode(HeapMode::SHARE);
GetAssociatedJSThread()->PostFork();
Taskpool::GetCurrentTaskpool()->Initialize();
SharedHeap::GetInstance()->EnableParallelGC(GetJSOptions());
heap_->EnableParallelGC();
std::string bundleName = PGOProfilerManager::GetInstance()->GetBundleName();
if (ohos::EnableAotListHelper::GetInstance()->IsDisableBlackList(bundleName)) {

View File

@ -191,6 +191,31 @@ void SharedHeap::ReclaimRegions()
}
}
void SharedHeap::DisableParallelGC()
{
Prepare();
parallelGC_ = false;
maxMarkTaskCount_ = 0;
sSweeper_->ConfigConcurrentSweep(false);
}
void SharedHeap::EnableParallelGC(JSRuntimeOptions &option)
{
uint32_t totalThreadNum = Taskpool::GetCurrentTaskpool()->GetTotalThreadNum();
maxMarkTaskCount_ = totalThreadNum - 1;
parallelGC_ = option.EnableParallelGC();
if (auto workThreadNum = sWorkManager_->GetTotalThreadNum();
workThreadNum != totalThreadNum + 1) {
LOG_ECMA_MEM(ERROR) << "TheadNum mismatch, totalThreadNum(sWorkerManager): " << workThreadNum << ", "
<< "totalThreadNum(taskpool): " << totalThreadNum + 1;
delete sWorkManager_;
sWorkManager_ = new SharedGCWorkManager(this, totalThreadNum + 1);
sharedGCMarker_->ResetWorkManager(sWorkManager_);
sharedGC_->ResetWorkManager(sWorkManager_);
}
sSweeper_->ConfigConcurrentSweep(option.EnableConcurrentSweep());
}
Heap::Heap(EcmaVM *ecmaVm)
: BaseHeap(ecmaVm->GetEcmaParamConfiguration()),
ecmaVm_(ecmaVm), thread_(ecmaVm->GetJSThread()) {}
@ -462,7 +487,6 @@ void Heap::DisableParallelGC()
void Heap::EnableParallelGC()
{
Taskpool::GetCurrentTaskpool()->Initialize();
parallelGC_ = ecmaVm_->GetJSOptions().EnableParallelGC();
maxEvacuateTaskCount_ = Taskpool::GetCurrentTaskpool()->GetTotalThreadNum();
if (auto totalThreadNum = workManager_->GetTotalThreadNum();

View File

@ -298,6 +298,8 @@ public:
void PostInitialization(const GlobalEnvConstants *globalEnvConstants, const JSRuntimeOptions &option);
void EnableParallelGC(JSRuntimeOptions &option);
void DisableParallelGC();
class ParallelMarkTask : public Task {
public:
ParallelMarkTask(int32_t id, SharedHeap *heap)

View File

@ -288,7 +288,7 @@ void MovableMarker::SetLocalToShareRSet(ObjectSlot slot, Region *region)
}
Region *valueRegion = Region::ObjectAddressToRange(value);
if (valueRegion->InSharedSweepableSpace()) {
region->InsertLocalToShareRSet(slot.SlotAddress());
region->AtomicInsertLocalToShareRSet(slot.SlotAddress());
}
}

View File

@ -70,8 +70,7 @@ void SharedGC::Sweep()
LOG_GC(ERROR) << "SharedGC updateWeakReference: region is nullptr, header is " << header;
return reinterpret_cast<TaggedObject *>(ToUintPtr(nullptr));
}
ASSERT(objectRegion->InSharedSweepableSpace());
if (objectRegion->Test(header)) {
if (!objectRegion->InSharedSweepableSpace() || objectRegion->Test(header)) {
return header;
}
return reinterpret_cast<TaggedObject *>(ToUintPtr(nullptr));
@ -119,4 +118,9 @@ void SharedGC::UpdateRecordWeakReference()
}
}
}
void SharedGC::ResetWorkManager(SharedGCWorkManager *workManager)
{
sWorkManager_ = workManager;
}
} // namespace panda::ecmascript

View File

@ -33,6 +33,7 @@ public:
NO_MOVE_SEMANTIC(SharedGC);
void RunPhases() override;
void ResetWorkManager(SharedGCWorkManager *workManager);
protected:
void Initialize() override;
void Mark() override;

View File

@ -63,4 +63,9 @@ void SharedGCMarker::ProcessMarkStack(uint32_t threadId)
ObjectXRay::VisitObjectBody<VisitType::OLD_GC_VISIT>(obj, hclass, visitor);
}
}
void SharedGCMarker::ResetWorkManager(SharedGCWorkManager *workManager)
{
sWorkManager_ = workManager;
}
} // namespace panda::ecmascript

View File

@ -29,6 +29,7 @@ public:
explicit SharedGCMarker(SharedGCWorkManager *workManger) : sWorkManager_(workManger) {}
~SharedGCMarker() = default;
void ResetWorkManager(SharedGCWorkManager *workManager);
void MarkRoots(uint32_t threadId, EcmaVM *localVm);
void ProcessMarkStack(uint32_t threadId);
template <typename Callback>

View File

@ -16,6 +16,7 @@
#include "ecmascript/napi/include/dfx_jsnapi.h"
#include "ecmascript/builtins/builtins_ark_tools.h"
#include "ecmascript/checkpoint/thread_state_transition.h"
#include "ecmascript/dfx/hprof/heap_profiler.h"
#include "ecmascript/dfx/stackinfo/js_stackinfo.h"
#include "ecmascript/dfx/tracing/tracing.h"
@ -321,6 +322,7 @@ void DFXJSNApi::GetHeapPrepare(const EcmaVM *vm)
void DFXJSNApi::NotifyApplicationState(EcmaVM *vm, bool inBackground)
{
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
const_cast<ecmascript::Heap *>(vm->GetHeap())->ChangeGCParams(inBackground);
}
@ -331,6 +333,7 @@ void DFXJSNApi::NotifyIdleStatusControl(const EcmaVM *vm, std::function<void(boo
void DFXJSNApi::NotifyIdleTime(const EcmaVM *vm, int idleMicroSec)
{
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
const_cast<ecmascript::Heap *>(vm->GetHeap())->TriggerIdleCollection(idleMicroSec);
}
@ -341,6 +344,7 @@ void DFXJSNApi::NotifyMemoryPressure(EcmaVM *vm, bool inHighMemoryPressure)
void DFXJSNApi::NotifyFinishColdStart(EcmaVM *vm, bool isConvinced)
{
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
if (isConvinced) {
const_cast<ecmascript::Heap *>(vm->GetHeap())->NotifyFinishColdStart();
} else {

View File

@ -2261,6 +2261,7 @@ JSValueRef* FunctionRef::CallForNapi(const EcmaVM *vm, JSValueRef *thisObj,
FunctionCallScope callScope(EcmaVM::ConstCast(vm));
ASSERT(IsFunction()); // IsFunction check has been done in napi.
{
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
LocalScope scope(vm);
ecmascript::tooling::JsDebuggerManager *dm = vm->GetJsDebuggerManager();
if (dm->IsDebugApp()) {
@ -2551,6 +2552,7 @@ FunctionCallScope::~FunctionCallScope()
vm_->DecreaseCallDepth();
if (vm_->IsTopLevelCallDepth()) {
JSThread *thread = vm_->GetJSThread();
ecmascript::ThreadManagedScope managedScope(vm_->GetJSThread());
thread->GetCurrentEcmaContext()->ExecutePromisePendingJob();
}
}
@ -3473,6 +3475,7 @@ bool JSNApi::ExecuteModuleBufferSecure(EcmaVM *vm, uint8_t* data, int32_t size,
LOG_ECMA(ERROR) << "Secure memory check failed, please execute in srcure memory.";
return false;
}
ecmascript::ThreadManagedScope scope(vm->GetJSThread());
if (!ecmascript::JSPandaFileExecutor::ExecuteModuleBufferSecure(thread, data, size, filename.c_str(),
needUpdate)) {
if (thread->HasPendingException()) {
@ -3486,6 +3489,7 @@ bool JSNApi::ExecuteModuleBufferSecure(EcmaVM *vm, uint8_t* data, int32_t size,
void JSNApi::PreFork(EcmaVM *vm)
{
ecmascript::ThreadManagedScope scope(vm->GetJSThread());
vm->PreFork();
}
@ -3783,6 +3787,7 @@ void JSNApi::SetHostEnqueueJob(const EcmaVM *vm, Local<JSValueRef> cb)
bool JSNApi::ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
ecmascript::ThreadManagedScope scope(vm->GetJSThread());
if (!ecmascript::JSPandaFileExecutor::ExecuteFromBuffer(thread, data, size, ENTRY_POINTER, file.c_str())) {
std::cerr << "Cannot execute panda file from memory" << std::endl;
return false;