workerxts bugfix

1. jspandfile used after free
2. icupath multi-thread problems
3. mmappool used after free
4. condition variable has waiters when delete it
issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I5FVPB?from=project-issue

Signed-off-by: lukai <lukai25@huawei.com>
Change-Id: Iddb7fb85bce6b87e568591e3967509daa943dbb2
This commit is contained in:
lukai 2022-07-18 19:06:58 +08:00
parent a41eddc321
commit 9ff67e2925
10 changed files with 57 additions and 46 deletions

View File

@ -74,7 +74,6 @@
#include "ecmascript/builtins/builtins_weak_set.h"
#include "ecmascript/containers/containers_private.h"
#include "ecmascript/ecma_runtime_call_info.h"
#include "ecmascript/file_loader.h"
#include "ecmascript/js_array.h"
#include "ecmascript/js_arraybuffer.h"
#include "ecmascript/js_array_iterator.h"
@ -306,7 +305,6 @@ void Builtins::Initialize(const JSHandle<GlobalEnv> &env, JSThread *thread)
InitializePluralRules(env);
InitializeDisplayNames(env);
InitializeListFormat(env);
InitializeIcuData();
InitializeModuleNamespace(env, objFuncDynclass);
InitializeCjsModule(env);
@ -325,7 +323,6 @@ void Builtins::InitializeForSnapshot(JSThread *thread)
vm_ = thread->GetEcmaVM();
factory_ = vm_->GetFactory();
InitializeIcuData();
// Initialize ArkTools
if (vm_->GetJSOptions().EnableArkTools()) {
auto env = vm_->GetGlobalEnv();
@ -3398,21 +3395,4 @@ void Builtins::InitializeCjsRequire(const JSHandle<GlobalEnv> &env) const
env->SetCjsRequireFunction(thread_, cjsRequireFunction);
}
void Builtins::InitializeIcuData()
{
ASSERT(vm_ != nullptr);
JSRuntimeOptions options = vm_->GetJSOptions();
std::string icuPath = options.GetIcuDataPath();
if (icuPath == "default") {
if (!WIN_OR_MAC_PLATFORM) {
SetHwIcuDirectory();
}
} else {
std::string absPath;
if (FileLoader::GetAbsolutePath(icuPath, absPath)) {
u_setDataDirectory(absPath.c_str());
}
}
}
} // namespace panda::ecmascript

View File

@ -136,9 +136,6 @@ private:
void InitializeDisplayNames(const JSHandle<GlobalEnv> &env);
void InitializeListFormat(const JSHandle<GlobalEnv> &env);
// Initialize IcuData Path
void InitializeIcuData();
void GeneralUpdateError(ErrorParameter *error, EcmaEntrypoint constructor, EcmaEntrypoint method, const char *name,
JSType type) const;

View File

@ -269,6 +269,7 @@ EcmaVM::~EcmaVM()
{
LOG_ECMA(INFO) << "Destruct ecma_vm, vm address is: " << this;
vmInitialized_ = false;
heap_->WaitAllTasksFinished();
Taskpool::GetCurrentTaskpool()->Destroy();
if (runtimeStat_ != nullptr && runtimeStat_->IsRuntimeStatEnabled()) {

View File

@ -70,10 +70,13 @@ const JSPandaFile *JSPandaFileManager::LoadJSPandaFile(JSThread *thread, const C
std::string_view entryPoint)
{
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "JSPandaFileManager::LoadJSPandaFile");
const JSPandaFile *jsPandaFile = FindJSPandaFile(filename);
if (jsPandaFile != nullptr) {
IncreaseRefJSPandaFile(jsPandaFile);
return jsPandaFile;
{
os::memory::LockHolder lock(jsPandaFileLock_);
const JSPandaFile *jsPandaFile = FindJSPandaFileUnlocked(filename);
if (jsPandaFile != nullptr) {
IncreaseRefJSPandaFileUnlocked(jsPandaFile);
return jsPandaFile;
}
}
auto pf = panda_file::OpenPandaFileOrZip(filename, panda_file::File::READ_WRITE);
@ -82,7 +85,7 @@ const JSPandaFile *JSPandaFileManager::LoadJSPandaFile(JSThread *thread, const C
return nullptr;
}
jsPandaFile = GenerateJSPandaFile(thread, pf.release(), filename, entryPoint);
const JSPandaFile *jsPandaFile = GenerateJSPandaFile(thread, pf.release(), filename, entryPoint);
return jsPandaFile;
}
@ -92,11 +95,13 @@ const JSPandaFile *JSPandaFileManager::LoadJSPandaFile(JSThread *thread, const C
if (buffer == nullptr || size == 0) {
return nullptr;
}
const JSPandaFile *jsPandaFile = FindJSPandaFile(filename);
if (jsPandaFile != nullptr) {
IncreaseRefJSPandaFile(jsPandaFile);
return jsPandaFile;
{
os::memory::LockHolder lock(jsPandaFileLock_);
const JSPandaFile *jsPandaFile = FindJSPandaFileUnlocked(filename);
if (jsPandaFile != nullptr) {
IncreaseRefJSPandaFileUnlocked(jsPandaFile);
return jsPandaFile;
}
}
auto pf = panda_file::OpenPandaFileFromMemory(buffer, size);
@ -104,7 +109,7 @@ const JSPandaFile *JSPandaFileManager::LoadJSPandaFile(JSThread *thread, const C
LOG_ECMA(ERROR) << "open file " << filename << " error";
return nullptr;
}
jsPandaFile = GenerateJSPandaFile(thread, pf.release(), filename, entryPoint);
const JSPandaFile *jsPandaFile = GenerateJSPandaFile(thread, pf.release(), filename, entryPoint);
return jsPandaFile;
}
@ -117,12 +122,11 @@ JSHandle<Program> JSPandaFileManager::GenerateProgram(EcmaVM *vm, const JSPandaF
return program;
}
const JSPandaFile *JSPandaFileManager::FindJSPandaFile(const CString &filename)
const JSPandaFile *JSPandaFileManager::FindJSPandaFileUnlocked(const CString &filename)
{
if (filename.empty()) {
return nullptr;
}
os::memory::LockHolder lock(jsPandaFileLock_);
auto const iter = loadedJSPandaFiles_.find(filename);
if (iter == loadedJSPandaFiles_.end()) {
return nullptr;
@ -152,11 +156,10 @@ void JSPandaFileManager::InsertJSPandaFile(const JSPandaFile *jsPandaFile)
loadedJSPandaFiles_[filename] = pandaFileRecord;
}
void JSPandaFileManager::IncreaseRefJSPandaFile(const JSPandaFile *jsPandaFile)
void JSPandaFileManager::IncreaseRefJSPandaFileUnlocked(const JSPandaFile *jsPandaFile)
{
auto const filename = jsPandaFile->GetJSPandaFileDesc();
LOG_ECMA(DEBUG) << "IncreaseRefJSPandaFile " << filename;
os::memory::LockHolder lock(jsPandaFileLock_);
LOG_ECMA(DEBUG) << "IncreaseRefJSPandaFileUnlocked " << filename;
auto iter = loadedJSPandaFiles_.find(filename);
ASSERT(iter != loadedJSPandaFiles_.end());
iter->second.second++;
@ -247,9 +250,9 @@ const JSPandaFile *JSPandaFileManager::GenerateJSPandaFile(JSThread *thread, con
PandaFileTranslator::TranslateClasses(newJsPandaFile, methodName);
{
os::memory::LockHolder lock(jsPandaFileLock_);
const JSPandaFile *jsPandaFile = FindJSPandaFile(desc);
const JSPandaFile *jsPandaFile = FindJSPandaFileUnlocked(desc);
if (jsPandaFile != nullptr) {
IncreaseRefJSPandaFile(jsPandaFile);
IncreaseRefJSPandaFileUnlocked(jsPandaFile);
ReleaseJSPandaFile(newJsPandaFile);
return jsPandaFile;
}

View File

@ -76,9 +76,9 @@ private:
std::string_view entryPoint);
void ReleaseJSPandaFile(const JSPandaFile *jsPandaFile);
const JSPandaFile *GetJSPandaFile(const panda_file::File *pf);
const JSPandaFile *FindJSPandaFile(const CString &filename);
const JSPandaFile *FindJSPandaFileUnlocked(const CString &filename);
void InsertJSPandaFile(const JSPandaFile *jsPandaFile);
void IncreaseRefJSPandaFile(const JSPandaFile *jsPandaFile);
void IncreaseRefJSPandaFileUnlocked(const JSPandaFile *jsPandaFile);
void DecreaseRefJSPandaFile(const JSPandaFile *jsPandaFile);
static void *AllocateBuffer(size_t size);

View File

@ -130,7 +130,6 @@ void Heap::Initialize()
void Heap::Destroy()
{
Prepare();
if (workManager_ != nullptr) {
delete workManager_;
workManager_ = nullptr;
@ -281,7 +280,7 @@ void Heap::CompactHeapBeforeFork()
void Heap::DisableParallelGC()
{
Prepare();
WaitAllTasksFinished();
parallelGC_ = false;
maxEvacuateTaskCount_ = 0;
maxMarkTaskCount_ = 0;
@ -661,6 +660,16 @@ void Heap::WaitClearTaskFinished()
}
}
void Heap::WaitAllTasksFinished()
{
WaitRunningTaskFinished();
sweeper_->EnsureAllTaskFinished();
WaitClearTaskFinished();
if (concurrentMarker_->IsEnabled() && thread_->IsMarking()) {
concurrentMarker_->WaitMarkingFinished();
}
}
void Heap::WaitConcurrentMarkingFinished()
{
concurrentMarker_->WaitMarkingFinished();

View File

@ -317,6 +317,7 @@ public:
inline void ClearSlotsRange(Region *current, uintptr_t freeStart, uintptr_t freeEnd);
void WaitAllTasksFinished();
void WaitConcurrentMarkingFinished();
MemGrowingType GetMemGrowingType() const

View File

@ -176,9 +176,9 @@ public:
if (iterate == freeList_.end()) {
return MemMap();
}
freeList_.erase(iterate);
MemMap memMap = iterate->second;
size_t remainderSize = memMap.GetSize() - size;
freeList_.erase(iterate);
if (remainderSize >= DEFAULT_REGION_SIZE) {
auto next = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(memMap.GetMem()) + size);
freeList_.insert(std::pair<size_t, MemMap>(remainderSize, MemMap(next, remainderSize)));

View File

@ -1143,6 +1143,7 @@ public:
static void SetHostResolvePathTracker(EcmaVM *vm,
std::function<std::string(std::string dirPath, std::string requestPath)> cb);
static void SetHostEnqueueJob(const EcmaVM* vm, Local<JSValueRef> cb);
static void InitializeIcuData(const ecmascript::JSRuntimeOptions &options);
static void InitializeMemMapAllocator();
static void DestroyMemMapAllocator();
static EcmaVM* CreateEcmaVM(const ecmascript::JSRuntimeOptions &options);

View File

@ -30,6 +30,7 @@
#include "ecmascript/ecma_runtime_call_info.h"
#include "ecmascript/ecma_string.h"
#include "ecmascript/ecma_vm.h"
#include "ecmascript/file_loader.h"
#include "ecmascript/global_env.h"
#include "ecmascript/interpreter/fast_runtime_stub-inl.h"
#include "ecmascript/jobs/micro_job_queue.h"
@ -62,6 +63,7 @@
#include "ecmascript/tooling/interface/js_debugger_manager.h"
#include "generated/base_options.h"
#include "ohos/init_data.h"
#include "utils/pandargs.h"
#include "os/mutex.h"
@ -163,6 +165,7 @@ EcmaVM *JSNApi::CreateEcmaVM(const JSRuntimeOptions &options)
os::memory::LockHolder lock(mutex);
vmCount_++;
if (!initialize_) {
InitializeIcuData(options);
InitializeMemMapAllocator();
initialize_ = true;
}
@ -520,6 +523,22 @@ Local<ObjectRef> JSNApi::GetExportObjectFromBuffer(EcmaVM *vm, const std::string
return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
}
// Initialize IcuData Path
void JSNApi::InitializeIcuData(const JSRuntimeOptions &options)
{
std::string icuPath = options.GetIcuDataPath();
if (icuPath == "default") {
if (!WIN_OR_MAC_PLATFORM) {
SetHwIcuDirectory();
}
} else {
std::string absPath;
if (ecmascript::FileLoader::GetAbsolutePath(icuPath, absPath)) {
u_setDataDirectory(absPath.c_str());
}
}
}
void JSNApi::InitializeMemMapAllocator()
{
MemMapAllocator::GetInstance()->Initialize(ecmascript::DEFAULT_REGION_SIZE);