mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2025-02-26 15:28:33 +00:00
fix conflict and move fields in JSThread into context
Signed-off-by: xiongluo <xiongluo@huawei.com> Change-Id: Id3eceac5f2b6a515ee946b8d9d806a04326863a6
This commit is contained in:
parent
f14ab3c325
commit
a07240968b
1
BUILD.gn
1
BUILD.gn
@ -604,6 +604,7 @@ ecma_source = [
|
||||
"ecmascript/dfx/vm_thread_control.cpp",
|
||||
"ecmascript/dump.cpp",
|
||||
"ecmascript/ecma_context.cpp",
|
||||
"ecmascript/ecma_handle_scope.cpp",
|
||||
"ecmascript/ecma_string.cpp",
|
||||
"ecmascript/ecma_string_table.cpp",
|
||||
"ecmascript/ecma_vm.cpp",
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "ecmascript/ecma_context.h"
|
||||
|
||||
#include "ecmascript/base/path_helper.h"
|
||||
#include "ecmascript/builtins/builtins.h"
|
||||
#include "ecmascript/builtins/builtins_global.h"
|
||||
#include "ecmascript/compiler/common_stubs.h"
|
||||
@ -29,10 +30,16 @@
|
||||
#include "ecmascript/jspandafile/js_pandafile_manager.h"
|
||||
#include "ecmascript/compiler/aot_file/an_file_data_manager.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/require/js_cjs_module_cache.h"
|
||||
#include "ecmascript/require/js_require_manager.h"
|
||||
#include "ecmascript/snapshot/mem/snapshot.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
using PathHelper = base::PathHelper;
|
||||
|
||||
EcmaContext::EcmaContext(JSThread *thread)
|
||||
: thread_(thread),
|
||||
vm_(thread->GetEcmaVM()),
|
||||
@ -71,6 +78,7 @@ bool EcmaContext::Initialize()
|
||||
LOG_ECMA(INFO) << "EcmaContext::Initialize";
|
||||
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "EcmaContext::Initialize");
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
propertiesCache_ = new PropertiesCache();
|
||||
regExpParserCache_ = new RegExpParserCache();
|
||||
auto globalConst = const_cast<GlobalEnvConstants *>(thread_->GlobalConstants());
|
||||
if (!vm_->GetJSOptions().EnableSnapshotDeserialize()) {
|
||||
@ -167,6 +175,13 @@ EcmaContext::~EcmaContext()
|
||||
if (runtimeStat_ != nullptr && runtimeStat_->IsRuntimeStatEnabled()) {
|
||||
runtimeStat_->Print();
|
||||
}
|
||||
for (auto n : handleStorageNodes_) {
|
||||
delete n;
|
||||
}
|
||||
handleStorageNodes_.clear();
|
||||
currentHandleStorageIndex_ = -1;
|
||||
handleScopeCount_ = 0;
|
||||
handleScopeStorageNext_ = handleScopeStorageEnd_ = nullptr;
|
||||
ClearBufferData();
|
||||
// clear c_address: c++ pointer delete
|
||||
if (!vm_->IsBundlePack()) {
|
||||
@ -206,16 +221,21 @@ EcmaContext::~EcmaContext()
|
||||
delete aotFileManager_;
|
||||
aotFileManager_ = nullptr;
|
||||
}
|
||||
if (propertiesCache_ != nullptr) {
|
||||
delete propertiesCache_;
|
||||
propertiesCache_ = nullptr;
|
||||
}
|
||||
}
|
||||
JSTaggedValue EcmaContext::InvokeEcmaAotEntrypoint(JSHandle<JSFunction> mainFunc, JSHandle<JSTaggedValue> &thisArg,
|
||||
const JSPandaFile *jsPandaFile, std::string_view entryPoint)
|
||||
const JSPandaFile *jsPandaFile, std::string_view entryPoint,
|
||||
CJSInfo* cjsInfo)
|
||||
{
|
||||
aotFileManager_->SetAOTMainFuncEntry(mainFunc, jsPandaFile, entryPoint);
|
||||
return JSFunction::InvokeOptimizedEntrypoint(thread_, mainFunc, thisArg, entryPoint);
|
||||
return JSFunction::InvokeOptimizedEntrypoint(thread_, mainFunc, thisArg, entryPoint, cjsInfo);
|
||||
}
|
||||
|
||||
JSTaggedValue EcmaContext::ExecuteAot(size_t actualNumArgs, JSTaggedType *args, const JSTaggedType *prevFp,
|
||||
OptimizedEntryFrame::CallType callType)
|
||||
JSTaggedValue EcmaContext::ExecuteAot(size_t actualNumArgs, JSTaggedType *args,
|
||||
const JSTaggedType *prevFp, bool needPushUndefined)
|
||||
{
|
||||
INTERPRETER_TRACE(thread_, ExecuteAot);
|
||||
auto entry = thread_->GetRTInterface(kungfu::RuntimeStubCSigns::ID_JSFunctionEntry);
|
||||
@ -238,7 +258,8 @@ Expected<JSTaggedValue, bool> EcmaContext::InvokeEcmaEntrypoint(const JSPandaFil
|
||||
return Unexpected(false);
|
||||
}
|
||||
// for debugger
|
||||
debuggerManager_->GetNotificationManager()->LoadModuleEvent(jsPandaFile->GetJSPandaFileDesc(), entryPoint);
|
||||
vm_->GetJsDebuggerManager()->GetNotificationManager()->LoadModuleEvent(
|
||||
jsPandaFile->GetJSPandaFileDesc(), entryPoint);
|
||||
|
||||
JSHandle<JSFunction> func(thread_, program->GetMainFunction());
|
||||
JSHandle<JSTaggedValue> global = GlobalEnv::Cast(globalEnv_.GetTaggedObject())->GetJSGlobalObject();
|
||||
@ -262,16 +283,16 @@ Expected<JSTaggedValue, bool> EcmaContext::InvokeEcmaEntrypoint(const JSPandaFil
|
||||
JSTaggedValue result;
|
||||
if (jsPandaFile->IsCjs(thread_, entryPoint.data())) {
|
||||
if (!thread_->HasPendingException()) {
|
||||
vm_->CJSExecution(func, global, jsPandaFile, entryPoint);
|
||||
CJSExecution(func, global, jsPandaFile, entryPoint);
|
||||
}
|
||||
} else {
|
||||
if (aotFileManager_->IsLoadMain(jsPandaFile, entryPoint.data())) {
|
||||
EcmaRuntimeStatScope runtimeStatScope(this);
|
||||
EcmaRuntimeStatScope runtimeStatScope(vm_);
|
||||
result = InvokeEcmaAotEntrypoint(func, global, jsPandaFile, entryPoint);
|
||||
} else {
|
||||
EcmaRuntimeCallInfo *info =
|
||||
EcmaInterpreter::NewRuntimeCallInfo(thread_, JSHandle<JSTaggedValue>(func), global, undefined, 0);
|
||||
EcmaRuntimeStatScope runtimeStatScope(this);
|
||||
EcmaRuntimeStatScope runtimeStatScope(vm_);
|
||||
EcmaInterpreter::Execute(info);
|
||||
}
|
||||
}
|
||||
@ -286,6 +307,57 @@ Expected<JSTaggedValue, bool> EcmaContext::InvokeEcmaEntrypoint(const JSPandaFil
|
||||
return result;
|
||||
}
|
||||
|
||||
void EcmaContext::CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValue> &thisArg,
|
||||
const JSPandaFile *jsPandaFile, std::string_view entryPoint)
|
||||
{
|
||||
// create "module", "exports", "require", "filename", "dirname"
|
||||
JSHandle<CjsModule> module = factory_->NewCjsModule();
|
||||
JSHandle<JSTaggedValue> require = GetGlobalEnv()->GetCjsRequireFunction();
|
||||
JSHandle<CjsExports> exports = factory_->NewCjsExports();
|
||||
JSMutableHandle<JSTaggedValue> filename(thread_, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> dirname(thread_, JSTaggedValue::Undefined());
|
||||
if (jsPandaFile->IsBundlePack()) {
|
||||
PathHelper::ResolveCurrentPath(thread_, dirname, filename, jsPandaFile);
|
||||
} else {
|
||||
filename.Update(func->GetModule());
|
||||
ASSERT(filename->IsString());
|
||||
dirname.Update(PathHelper::ResolveDirPath(thread_, filename));
|
||||
}
|
||||
CJSInfo cjsInfo(module, require, exports, filename, dirname);
|
||||
RequireManager::InitializeCommonJS(thread_, cjsInfo);
|
||||
if (aotFileManager_->IsLoadMain(jsPandaFile, entryPoint.data())) {
|
||||
EcmaRuntimeStatScope runtimeStateScope(vm_);
|
||||
InvokeEcmaAotEntrypoint(func, thisArg, jsPandaFile, entryPoint, &cjsInfo);
|
||||
} else {
|
||||
// Execute main function
|
||||
JSHandle<JSTaggedValue> undefined = thread_->GlobalConstants()->GetHandledUndefined();
|
||||
EcmaRuntimeCallInfo *info =
|
||||
EcmaInterpreter::NewRuntimeCallInfo(thread_,
|
||||
JSHandle<JSTaggedValue>(func),
|
||||
thisArg, undefined, 5); // 5 : argument numbers
|
||||
RETURN_IF_ABRUPT_COMPLETION(thread_);
|
||||
if (info == nullptr) {
|
||||
LOG_ECMA(ERROR) << "CJSExecution Stack overflow!";
|
||||
return;
|
||||
}
|
||||
info->SetCallArg(cjsInfo.exportsHdl.GetTaggedValue(),
|
||||
cjsInfo.requireHdl.GetTaggedValue(),
|
||||
cjsInfo.moduleHdl.GetTaggedValue(),
|
||||
cjsInfo.filenameHdl.GetTaggedValue(),
|
||||
cjsInfo.dirnameHdl.GetTaggedValue());
|
||||
EcmaRuntimeStatScope runtimeStatScope(this);
|
||||
EcmaInterpreter::Execute(info);
|
||||
}
|
||||
if (!thread_->HasPendingException()) {
|
||||
job::MicroJobQueue::ExecutePendingJob(thread_, thread_->GetCurrentEcmaContext()->GetMicroJobQueue());
|
||||
}
|
||||
|
||||
if (!thread_->HasPendingException()) {
|
||||
// Collecting module.exports : exports ---> module.exports --->Module._cache
|
||||
RequireManager::CollectExecutedExp(thread_, cjsInfo);
|
||||
}
|
||||
}
|
||||
|
||||
bool EcmaContext::HasCachedConstpool(const JSPandaFile *jsPandaFile) const
|
||||
{
|
||||
return cachedConstpools_.find(jsPandaFile) != cachedConstpools_.end();
|
||||
@ -534,20 +606,101 @@ void EcmaContext::UnmountContext(JSThread *thread)
|
||||
Destroy(context);
|
||||
}
|
||||
|
||||
|
||||
void EcmaContext::Iterate(const RootVisitor &v, [[maybe_unused]] const RootRangeVisitor &rv)
|
||||
void EcmaContext::SetupRegExpResultCache()
|
||||
{
|
||||
regexpCache_ = builtins::RegExpExecResultCache::CreateCacheTable(thread_);
|
||||
}
|
||||
|
||||
void EcmaContext::Iterate(const RootVisitor &v, const RootRangeVisitor &rv)
|
||||
{
|
||||
if (propertiesCache_ != nullptr) {
|
||||
propertiesCache_->Clear();
|
||||
}
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(®expCache_)));
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&globalEnv_)));
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(µJobQueue_)));
|
||||
moduleManager_->Iterate(v);
|
||||
tsManager_->Iterate(v);
|
||||
aotFileManager_->Iterate(v);
|
||||
if (vm_->GetJSOptions().EnableGlobalLeakCheck()) {
|
||||
IterateHandle(rv);
|
||||
} else {
|
||||
if (currentHandleStorageIndex_ != -1) {
|
||||
int32_t nid = currentHandleStorageIndex_;
|
||||
for (int32_t i = 0; i <= nid; ++i) {
|
||||
auto node = handleStorageNodes_.at(i);
|
||||
auto start = node->data();
|
||||
auto end = (i != nid) ? &(node->data()[NODE_BLOCK_SIZE]) : handleScopeStorageNext_;
|
||||
rv(ecmascript::Root::ROOT_HANDLE, ObjectSlot(ToUintPtr(start)), ObjectSlot(ToUintPtr(end)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EcmaContext::SetupRegExpResultCache()
|
||||
size_t EcmaContext::IterateHandle(const RootRangeVisitor &rangeVisitor)
|
||||
{
|
||||
regexpCache_ = builtins::RegExpExecResultCache::CreateCacheTable(thread_);
|
||||
size_t handleCount = 0;
|
||||
if (currentHandleStorageIndex_ != -1) {
|
||||
int32_t nid = currentHandleStorageIndex_;
|
||||
for (int32_t i = 0; i <= nid; ++i) {
|
||||
auto node = handleStorageNodes_.at(i);
|
||||
auto start = node->data();
|
||||
auto end = (i != nid) ? &(node->data()[NODE_BLOCK_SIZE]) : handleScopeStorageNext_;
|
||||
rangeVisitor(ecmascript::Root::ROOT_HANDLE, ObjectSlot(ToUintPtr(start)), ObjectSlot(ToUintPtr(end)));
|
||||
handleCount += (ToUintPtr(end) - ToUintPtr(start)) / sizeof(JSTaggedType);
|
||||
}
|
||||
}
|
||||
return handleCount;
|
||||
}
|
||||
|
||||
uintptr_t *EcmaContext::ExpandHandleStorage()
|
||||
{
|
||||
uintptr_t *result = nullptr;
|
||||
int32_t lastIndex = static_cast<int32_t>(handleStorageNodes_.size() - 1);
|
||||
if (currentHandleStorageIndex_ == lastIndex) {
|
||||
auto n = new std::array<JSTaggedType, NODE_BLOCK_SIZE>();
|
||||
handleStorageNodes_.push_back(n);
|
||||
currentHandleStorageIndex_++;
|
||||
result = reinterpret_cast<uintptr_t *>(&n->data()[0]);
|
||||
handleScopeStorageEnd_ = &n->data()[NODE_BLOCK_SIZE];
|
||||
} else {
|
||||
currentHandleStorageIndex_++;
|
||||
auto lastNode = handleStorageNodes_[currentHandleStorageIndex_];
|
||||
result = reinterpret_cast<uintptr_t *>(&lastNode->data()[0]);
|
||||
handleScopeStorageEnd_ = &lastNode->data()[NODE_BLOCK_SIZE];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void EcmaContext::ShrinkHandleStorage(int prevIndex)
|
||||
{
|
||||
currentHandleStorageIndex_ = prevIndex;
|
||||
int32_t lastIndex = static_cast<int32_t>(handleStorageNodes_.size() - 1);
|
||||
#if ECMASCRIPT_ENABLE_ZAP_MEM
|
||||
uintptr_t size = ToUintPtr(handleScopeStorageEnd_) - ToUintPtr(handleScopeStorageNext_);
|
||||
if (memset_s(handleScopeStorageNext_, size, 0, size) != EOK) {
|
||||
LOG_FULL(FATAL) << "memset_s failed";
|
||||
UNREACHABLE();
|
||||
}
|
||||
for (int32_t i = currentHandleStorageIndex_ + 1; i < lastIndex; i++) {
|
||||
if (memset_s(handleStorageNodes_[i],
|
||||
NODE_BLOCK_SIZE * sizeof(JSTaggedType), 0,
|
||||
NODE_BLOCK_SIZE * sizeof(JSTaggedType)) !=
|
||||
EOK) {
|
||||
LOG_FULL(FATAL) << "memset_s failed";
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (lastIndex > MIN_HANDLE_STORAGE_SIZE && currentHandleStorageIndex_ < MIN_HANDLE_STORAGE_SIZE) {
|
||||
for (int i = MIN_HANDLE_STORAGE_SIZE; i < lastIndex; i++) {
|
||||
auto node = handleStorageNodes_.back();
|
||||
delete node;
|
||||
handleStorageNodes_.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
void EcmaContext::LoadStubFile()
|
||||
{
|
||||
@ -577,4 +730,5 @@ void EcmaContext::DumpAOTInfo() const
|
||||
{
|
||||
aotFileManager_->DumpAOTInfo();
|
||||
}
|
||||
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -60,6 +60,7 @@ class TSManager;
|
||||
class AOTFileManager;
|
||||
class QuickFixManager;
|
||||
class OptCodeProfiler;
|
||||
struct CJSInfo;
|
||||
|
||||
namespace job {
|
||||
class MicroJobQueue;
|
||||
@ -92,15 +93,6 @@ public:
|
||||
EcmaContext(JSThread *thread);
|
||||
~EcmaContext();
|
||||
|
||||
void SetLoop(void *loop)
|
||||
{
|
||||
loop_ = loop;
|
||||
}
|
||||
|
||||
void *GetLoop() const
|
||||
{
|
||||
return loop_;
|
||||
}
|
||||
EcmaVM *GetEcmaVM() const
|
||||
{
|
||||
return vm_;
|
||||
@ -274,13 +266,91 @@ public:
|
||||
void InitializeEcmaScriptRunStat();
|
||||
void DumpAOTInfo() const DUMP_API_ATTR;
|
||||
|
||||
JSTaggedValue ExecuteAot(size_t actualNumArgs, JSTaggedType *args, const JSTaggedType *prevFp,
|
||||
OptimizedEntryFrame::CallType callType);
|
||||
JSTaggedValue ExecuteAot(size_t actualNumArgs, JSTaggedType *args,
|
||||
const JSTaggedType *prevFp, bool needPushUndefined);
|
||||
void LoadStubFile();
|
||||
|
||||
JSTaggedType *GetHandleScopeStorageNext() const
|
||||
{
|
||||
return handleScopeStorageNext_;
|
||||
}
|
||||
|
||||
void SetHandleScopeStorageNext(JSTaggedType *value)
|
||||
{
|
||||
handleScopeStorageNext_ = value;
|
||||
}
|
||||
|
||||
JSTaggedType *GetHandleScopeStorageEnd() const
|
||||
{
|
||||
return handleScopeStorageEnd_;
|
||||
}
|
||||
|
||||
void SetHandleScopeStorageEnd(JSTaggedType *value)
|
||||
{
|
||||
handleScopeStorageEnd_ = value;
|
||||
}
|
||||
|
||||
int GetCurrentHandleStorageIndex() const
|
||||
{
|
||||
return currentHandleStorageIndex_;
|
||||
}
|
||||
|
||||
void HandleScopeCountAdd()
|
||||
{
|
||||
handleScopeCount_++;
|
||||
}
|
||||
|
||||
void HandleScopeCountDec()
|
||||
{
|
||||
handleScopeCount_--;
|
||||
}
|
||||
|
||||
void SetLastHandleScope(EcmaHandleScope *scope)
|
||||
{
|
||||
lastHandleScope_ = scope;
|
||||
}
|
||||
|
||||
EcmaHandleScope *GetLastHandleScope() const
|
||||
{
|
||||
return lastHandleScope_;
|
||||
}
|
||||
size_t IterateHandle(const RootRangeVisitor &rangeVisitor);
|
||||
uintptr_t *ExpandHandleStorage();
|
||||
void ShrinkHandleStorage(int prevIndex);
|
||||
JSTaggedType *GetCurrentFrame() const
|
||||
{
|
||||
return currentFrame_;
|
||||
}
|
||||
|
||||
JSTaggedType *GetLeaveFrame() const
|
||||
{
|
||||
return leaveFrame_;
|
||||
}
|
||||
|
||||
JSTaggedType *GetLastFp() const
|
||||
{
|
||||
return lastFp_;
|
||||
}
|
||||
|
||||
void SetFramePointers(JSTaggedType *currentFrame, JSTaggedType *leaveFrame, JSTaggedType *lastFp)
|
||||
{
|
||||
currentFrame_ = currentFrame;
|
||||
leaveFrame_ = leaveFrame;
|
||||
lastFp_ = lastFp;
|
||||
}
|
||||
|
||||
PropertiesCache *GetPropertiesCache() const
|
||||
{
|
||||
return propertiesCache_;
|
||||
}
|
||||
void ClearBufferData();
|
||||
|
||||
private:
|
||||
void CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValue> &thisArg,
|
||||
const JSPandaFile *jsPandaFile, std::string_view entryPoint);
|
||||
JSTaggedValue InvokeEcmaAotEntrypoint(JSHandle<JSFunction> mainFunc, JSHandle<JSTaggedValue> &thisArg,
|
||||
const JSPandaFile *jsPandaFile, std::string_view entryPoint);
|
||||
const JSPandaFile *jsPandaFile, std::string_view entryPoint,
|
||||
CJSInfo* cjsInfo = nullptr);
|
||||
Expected<JSTaggedValue, bool> InvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile, std::string_view entryPoint,
|
||||
bool excuteFromJob = false);
|
||||
bool LoadAOTFiles(const std::string& aotFileName);
|
||||
@ -333,7 +403,6 @@ private:
|
||||
: locale(locale), icuObj(icuObj), deleteEntry(deleteEntry) {}
|
||||
};
|
||||
std::unordered_map<IcuFormatterType, IcuFormatter> icuObjCache_;
|
||||
void *loop_ {nullptr};
|
||||
|
||||
static const uint32_t NODE_BLOCK_SIZE_LOG2 = 10;
|
||||
static const uint32_t NODE_BLOCK_SIZE = 1U << NODE_BLOCK_SIZE_LOG2;
|
||||
|
87
ecmascript/ecma_handle_scope.cpp
Normal file
87
ecmascript/ecma_handle_scope.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_HANDLE_SCOPE_INL_H
|
||||
#define ECMASCRIPT_HANDLE_SCOPE_INL_H
|
||||
|
||||
#include "ecmascript/ecma_handle_scope.h"
|
||||
|
||||
#include "ecmascript/ecma_context.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
EcmaHandleScope::EcmaHandleScope(JSThread *thread) :
|
||||
thread_(thread)
|
||||
{
|
||||
auto context = thread_->GetCurrentEcmaContext();
|
||||
prevNext_ = context->handleScopeStorageNext_;
|
||||
prevEnd_ = context->handleScopeStorageEnd_;
|
||||
prevHandleStorageIndex_ = context->currentHandleStorageIndex_;
|
||||
#ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK
|
||||
thread_->HandleScopeCountAdd();
|
||||
prevHandleScope_ = thread->GetLastHandleScope();
|
||||
thread_->SetLastHandleScope(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
EcmaHandleScope::~EcmaHandleScope()
|
||||
{
|
||||
auto context = thread_->GetCurrentEcmaContext();
|
||||
#ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK
|
||||
context->HandleScopeCountDec();
|
||||
context->SetLastHandleScope(prevHandleScope_);
|
||||
prevHandleScope_ = nullptr;
|
||||
#endif
|
||||
context->handleScopeStorageNext_ = prevNext_;
|
||||
if (context->handleScopeStorageEnd_ != prevEnd_) {
|
||||
context->handleScopeStorageEnd_ = prevEnd_;
|
||||
context->ShrinkHandleStorage(prevHandleStorageIndex_);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
uintptr_t EcmaHandleScope::NewHandle(JSThread *thread, JSTaggedType value)
|
||||
{
|
||||
auto context = thread->GetCurrentEcmaContext();
|
||||
#ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK
|
||||
// Each Handle must be managed by HandleScope, otherwise it may cause Handle leakage.
|
||||
if (context->handleScopeCount_ <= 0) {
|
||||
LOG_ECMA(ERROR) << "New handle must be in handlescope" << context->handleScopeCount_;
|
||||
}
|
||||
static const long MAYBE_HANDLE_LEAK_TIME_MS = 5000;
|
||||
if (context->GetLastHandleScope() != nullptr) {
|
||||
float totalSpentTime = context->GetLastHandleScope()->scope_.TotalSpentTime();
|
||||
if (totalSpentTime >= MAYBE_HANDLE_LEAK_TIME_MS) {
|
||||
LOG_ECMA(INFO) << "New handle in scope count:" << context->handleScopeCount_
|
||||
<< ", time:" << totalSpentTime << "ms";
|
||||
std::ostringstream stack;
|
||||
Backtrace(stack, true);
|
||||
LOG_ECMA(INFO) << stack.str();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if ECMASCRIPT_ENABLE_NEW_HANDLE_CHECK
|
||||
thread->CheckJSTaggedType(value);
|
||||
#endif
|
||||
auto result = context->handleScopeStorageNext_;
|
||||
if (result == context->handleScopeStorageEnd_) {
|
||||
result = reinterpret_cast<JSTaggedType *>(context->ExpandHandleStorage());
|
||||
}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
context->handleScopeStorageNext_ = result + 1;
|
||||
*result = value;
|
||||
return reinterpret_cast<uintptr_t>(result);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
#endif
|
@ -29,64 +29,13 @@ namespace panda::ecmascript {
|
||||
* Handles are only valid within a HandleScope. When a handle is created for an object a cell is allocated in the
|
||||
* current HandleScope.
|
||||
*/
|
||||
class JSThread;
|
||||
class EcmaHandleScope {
|
||||
public:
|
||||
inline explicit EcmaHandleScope(JSThread *thread) :
|
||||
thread_(thread), prevNext_(thread->handleScopeStorageNext_), prevEnd_(thread->handleScopeStorageEnd_),
|
||||
prevHandleStorageIndex_(thread->currentHandleStorageIndex_)
|
||||
{
|
||||
#ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK
|
||||
thread_->HandleScopeCountAdd();
|
||||
prevHandleScope_ = thread->GetLastHandleScope();
|
||||
thread_->SetLastHandleScope(this);
|
||||
#endif
|
||||
}
|
||||
explicit EcmaHandleScope(JSThread *thread);
|
||||
|
||||
inline ~EcmaHandleScope()
|
||||
{
|
||||
#ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK
|
||||
thread_->HandleScopeCountDec();
|
||||
thread_->SetLastHandleScope(prevHandleScope_);
|
||||
prevHandleScope_ = nullptr;
|
||||
#endif
|
||||
thread_->handleScopeStorageNext_ = prevNext_;
|
||||
if (thread_->handleScopeStorageEnd_ != prevEnd_) {
|
||||
thread_->handleScopeStorageEnd_ = prevEnd_;
|
||||
thread_->ShrinkHandleStorage(prevHandleStorageIndex_);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uintptr_t PUBLIC_API NewHandle(JSThread *thread, JSTaggedType value)
|
||||
{
|
||||
#ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK
|
||||
// Each Handle must be managed by HandleScope, otherwise it may cause Handle leakage.
|
||||
if (thread->handleScopeCount_ <= 0) {
|
||||
LOG_ECMA(ERROR) << "New handle must be in handlescope" << thread->handleScopeCount_;
|
||||
}
|
||||
static const long MAYBE_HANDLE_LEAK_TIME_MS = 5000;
|
||||
if (thread->GetLastHandleScope() != nullptr) {
|
||||
float totalSpentTime = thread->GetLastHandleScope()->scope_.TotalSpentTime();
|
||||
if (totalSpentTime >= MAYBE_HANDLE_LEAK_TIME_MS) {
|
||||
LOG_ECMA(INFO) << "New handle in scope count:" << thread->handleScopeCount_
|
||||
<< ", time:" << totalSpentTime << "ms";
|
||||
std::ostringstream stack;
|
||||
Backtrace(stack, true);
|
||||
LOG_ECMA(INFO) << stack.str();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if ECMASCRIPT_ENABLE_NEW_HANDLE_CHECK
|
||||
thread->CheckJSTaggedType(value);
|
||||
#endif
|
||||
auto result = thread->handleScopeStorageNext_;
|
||||
if (result == thread->handleScopeStorageEnd_) {
|
||||
result = reinterpret_cast<JSTaggedType *>(thread->ExpandHandleStorage());
|
||||
}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
thread->handleScopeStorageNext_ = result + 1;
|
||||
*result = value;
|
||||
return reinterpret_cast<uintptr_t>(result);
|
||||
}
|
||||
~EcmaHandleScope();
|
||||
static uintptr_t PUBLIC_API NewHandle(JSThread *thread, JSTaggedType value);
|
||||
|
||||
JSThread *GetThread() const
|
||||
{
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
|
||||
#include "ecmascript/base/path_helper.h"
|
||||
#include "ecmascript/base/string_helper.h"
|
||||
#include "ecmascript/builtins/builtins.h"
|
||||
#include "ecmascript/builtins/builtins_ark_tools.h"
|
||||
@ -78,8 +77,6 @@
|
||||
#include "ecmascript/patch/quick_fix_manager.h"
|
||||
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
|
||||
#include "ecmascript/regexp/regexp_parser_cache.h"
|
||||
#include "ecmascript/require/js_cjs_module_cache.h"
|
||||
#include "ecmascript/require/js_require_manager.h"
|
||||
#include "ecmascript/runtime_call_id.h"
|
||||
#include "ecmascript/snapshot/mem/snapshot.h"
|
||||
#include "ecmascript/snapshot/mem/snapshot_env.h"
|
||||
@ -93,7 +90,6 @@
|
||||
#include "ecmascript/ts_types/ts_manager.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
using PathHelper = base::PathHelper;
|
||||
using RandomGenerator = base::RandomGenerator;
|
||||
AOTFileManager *JsStackInfo::loader = nullptr;
|
||||
/* static */
|
||||
@ -242,13 +238,10 @@ EcmaVM::~EcmaVM()
|
||||
pgoProfiler_ = nullptr;
|
||||
}
|
||||
|
||||
if (runtimeStat_ != nullptr && runtimeStat_->IsRuntimeStatEnabled()) {
|
||||
runtimeStat_->Print();
|
||||
}
|
||||
|
||||
#if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER
|
||||
DumpCallTimeInfo();
|
||||
#endif
|
||||
|
||||
// clear c_address: c++ pointer delete
|
||||
ClearBufferData();
|
||||
if (!isBundlePack_) {
|
||||
@ -336,57 +329,6 @@ void EcmaVM::CheckStartCpuProfiler()
|
||||
#endif
|
||||
}
|
||||
|
||||
void EcmaVM::CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValue> &thisArg,
|
||||
const JSPandaFile *jsPandaFile, std::string_view entryPoint)
|
||||
{
|
||||
// create "module", "exports", "require", "filename", "dirname"
|
||||
JSHandle<CjsModule> module = factory_->NewCjsModule();
|
||||
JSHandle<JSTaggedValue> require = GetGlobalEnv()->GetCjsRequireFunction();
|
||||
JSHandle<CjsExports> exports = factory_->NewCjsExports();
|
||||
JSMutableHandle<JSTaggedValue> filename(thread_, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> dirname(thread_, JSTaggedValue::Undefined());
|
||||
if (jsPandaFile->IsBundlePack()) {
|
||||
PathHelper::ResolveCurrentPath(thread_, dirname, filename, jsPandaFile);
|
||||
} else {
|
||||
filename.Update(func->GetModule());
|
||||
ASSERT(filename->IsString());
|
||||
dirname.Update(PathHelper::ResolveDirPath(thread_, filename));
|
||||
}
|
||||
CJSInfo cjsInfo(module, require, exports, filename, dirname);
|
||||
RequireManager::InitializeCommonJS(thread_, cjsInfo);
|
||||
if (aotFileManager_->IsLoadMain(jsPandaFile, entryPoint.data())) {
|
||||
EcmaRuntimeStatScope runtimeStateScope(this);
|
||||
InvokeEcmaAotEntrypoint(func, thisArg, jsPandaFile, entryPoint, &cjsInfo);
|
||||
} else {
|
||||
// Execute main function
|
||||
JSHandle<JSTaggedValue> undefined = thread_->GlobalConstants()->GetHandledUndefined();
|
||||
EcmaRuntimeCallInfo *info =
|
||||
EcmaInterpreter::NewRuntimeCallInfo(thread_,
|
||||
JSHandle<JSTaggedValue>(func),
|
||||
thisArg, undefined, 5); // 5 : argument numbers
|
||||
RETURN_IF_ABRUPT_COMPLETION(thread_);
|
||||
if (info == nullptr) {
|
||||
LOG_ECMA(ERROR) << "CJSExecution Stack overflow!";
|
||||
return;
|
||||
}
|
||||
info->SetCallArg(cjsInfo.exportsHdl.GetTaggedValue(),
|
||||
cjsInfo.requireHdl.GetTaggedValue(),
|
||||
cjsInfo.moduleHdl.GetTaggedValue(),
|
||||
cjsInfo.filenameHdl.GetTaggedValue(),
|
||||
cjsInfo.dirnameHdl.GetTaggedValue());
|
||||
EcmaRuntimeStatScope runtimeStatScope(this);
|
||||
EcmaInterpreter::Execute(info);
|
||||
}
|
||||
if (!thread_->HasPendingException()) {
|
||||
job::MicroJobQueue::ExecutePendingJob(thread_, thread_->GetCurrentEcmaContext()->GetMicroJobQueue());
|
||||
}
|
||||
|
||||
if (!thread_->HasPendingException()) {
|
||||
// Collecting module.exports : exports ---> module.exports --->Module._cache
|
||||
RequireManager::CollectExecutedExp(thread_, cjsInfo);
|
||||
}
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> EcmaVM::GetAndClearEcmaUncaughtException() const
|
||||
{
|
||||
JSHandle<JSTaggedValue> exceptionHandle = GetEcmaUncaughtException();
|
||||
@ -510,9 +452,6 @@ void EcmaVM::Iterate(const RootVisitor &v, const RootRangeVisitor &rv)
|
||||
if (pgoProfiler_ != nullptr) {
|
||||
pgoProfiler_->Iterate(v);
|
||||
}
|
||||
for (EcmaContext *context : contexts_) {
|
||||
context->Iterate(v, rv);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(ECMASCRIPT_SUPPORT_HEAPPROFILER)
|
||||
|
@ -75,13 +75,8 @@ class JSFunction;
|
||||
class Program;
|
||||
class TSManager;
|
||||
class AOTFileManager;
|
||||
class CjsModule;
|
||||
class CjsExports;
|
||||
class CjsRequire;
|
||||
class CjsModuleCache;
|
||||
class SlowRuntimeStub;
|
||||
class RequireManager;
|
||||
struct CJSInfo;
|
||||
class QuickFixManager;
|
||||
class ConstantPool;
|
||||
class FunctionCallTimer;
|
||||
@ -103,6 +98,16 @@ public:
|
||||
|
||||
~EcmaVM();
|
||||
|
||||
void SetLoop(void *loop)
|
||||
{
|
||||
loop_ = loop;
|
||||
}
|
||||
|
||||
void *GetLoop() const
|
||||
{
|
||||
return loop_;
|
||||
}
|
||||
|
||||
bool IsInitialized() const
|
||||
{
|
||||
return initialized_;
|
||||
@ -402,14 +407,12 @@ public:
|
||||
|
||||
|
||||
void SetGlobalEnv(GlobalEnv *global);
|
||||
|
||||
protected:
|
||||
|
||||
void PrintJSErrorInfo(const JSHandle<JSTaggedValue> &exceptionInfo) const;
|
||||
|
||||
private:
|
||||
void CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValue> &thisArg,
|
||||
const JSPandaFile *jsPandaFile, std::string_view entryPoint);
|
||||
|
||||
void ClearBufferData();
|
||||
void CheckStartCpuProfiler();
|
||||
|
||||
@ -450,6 +453,7 @@ private:
|
||||
CString moduleName_;
|
||||
// Registered Callbacks
|
||||
NativePtrGetter nativePtrGetter_ {nullptr};
|
||||
void *loop_ {nullptr};
|
||||
|
||||
// CJS resolve path Callbacks
|
||||
ResolvePathCallback resolvePathCallback_ {nullptr};
|
||||
|
@ -82,7 +82,7 @@ private:
|
||||
|
||||
std::array<PropertyKey, CACHE_LENGTH> keys_{};
|
||||
|
||||
friend class JSThread;
|
||||
friend class EcmaContext;
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_IC_PROPERTIES_CACHE_H
|
||||
|
@ -75,17 +75,17 @@ class NameDictionary;
|
||||
template <typename T>
|
||||
class JSHandle {
|
||||
public:
|
||||
inline JSHandle() : address_(reinterpret_cast<uintptr_t>(nullptr)) {}
|
||||
PUBLIC_API inline JSHandle() : address_(reinterpret_cast<uintptr_t>(nullptr)) {}
|
||||
~JSHandle() = default;
|
||||
DEFAULT_NOEXCEPT_MOVE_SEMANTIC(JSHandle);
|
||||
DEFAULT_COPY_SEMANTIC(JSHandle);
|
||||
|
||||
JSHandle(const JSThread *thread, JSTaggedValue value)
|
||||
PUBLIC_API JSHandle(const JSThread *thread, JSTaggedValue value)
|
||||
{
|
||||
address_ = EcmaHandleScope::NewHandle(const_cast<JSThread *>(thread), value.GetRawData());
|
||||
}
|
||||
|
||||
JSHandle(const JSThread *thread, const TaggedObject *value)
|
||||
PUBLIC_API JSHandle(const JSThread *thread, const TaggedObject *value)
|
||||
{
|
||||
address_ = EcmaHandleScope::NewHandle(const_cast<JSThread *>(thread), JSTaggedValue(value).GetRawData());
|
||||
}
|
||||
|
@ -85,20 +85,12 @@ JSThread::JSThread(EcmaVM *vm) : id_(os::thread::GetCurrentThreadId()), vm_(vm)
|
||||
clearWeak_ = std::bind(&EcmaGlobalStorage<DebugNode>::ClearWeak, globalDebugStorage_, std::placeholders::_1);
|
||||
isWeak_ = std::bind(&EcmaGlobalStorage<DebugNode>::IsWeak, globalDebugStorage_, std::placeholders::_1);
|
||||
}
|
||||
propertiesCache_ = new PropertiesCache();
|
||||
vmThreadControl_ = new VmThreadControl(this);
|
||||
SetBCStubStatus(BCStubStatus::NORMAL_BC_STUB);
|
||||
}
|
||||
|
||||
JSThread::~JSThread()
|
||||
{
|
||||
for (auto n : handleStorageNodes_) {
|
||||
delete n;
|
||||
}
|
||||
handleStorageNodes_.clear();
|
||||
currentHandleStorageIndex_ = -1;
|
||||
handleScopeCount_ = 0;
|
||||
handleScopeStorageNext_ = handleScopeStorageEnd_ = nullptr;
|
||||
if (globalStorage_ != nullptr) {
|
||||
GetEcmaVM()->GetChunk()->Delete(globalStorage_);
|
||||
globalStorage_ = nullptr;
|
||||
@ -113,10 +105,6 @@ JSThread::~JSThread()
|
||||
glueData_.frameBase_ = nullptr;
|
||||
nativeAreaAllocator_ = nullptr;
|
||||
heapRegionAllocator_ = nullptr;
|
||||
if (propertiesCache_ != nullptr) {
|
||||
delete propertiesCache_;
|
||||
propertiesCache_ = nullptr;
|
||||
}
|
||||
if (vmThreadControl_ != nullptr) {
|
||||
delete vmThreadControl_;
|
||||
vmThreadControl_ = nullptr;
|
||||
@ -219,10 +207,6 @@ void JSThread::CloseStackTraceFd()
|
||||
void JSThread::Iterate(const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor,
|
||||
const RootBaseAndDerivedVisitor &derivedVisitor)
|
||||
{
|
||||
if (propertiesCache_ != nullptr) {
|
||||
propertiesCache_->Clear();
|
||||
}
|
||||
|
||||
if (!glueData_.exception_.IsHole()) {
|
||||
visitor(Root::ROOT_VM, ObjectSlot(ToUintPtr(&glueData_.exception_)));
|
||||
}
|
||||
@ -235,16 +219,6 @@ void JSThread::Iterate(const RootVisitor &visitor, const RootRangeVisitor &range
|
||||
if (vm_->GetJSOptions().EnableGlobalLeakCheck()) {
|
||||
IterateHandleWithCheck(visitor, rangeVisitor);
|
||||
} else {
|
||||
if (currentHandleStorageIndex_ != -1) {
|
||||
int32_t nid = currentHandleStorageIndex_;
|
||||
for (int32_t i = 0; i <= nid; ++i) {
|
||||
auto node = handleStorageNodes_.at(i);
|
||||
auto start = node->data();
|
||||
auto end = (i != nid) ? &(node->data()[NODE_BLOCK_SIZE]) : handleScopeStorageNext_;
|
||||
rangeVisitor(ecmascript::Root::ROOT_HANDLE, ObjectSlot(ToUintPtr(start)), ObjectSlot(ToUintPtr(end)));
|
||||
}
|
||||
}
|
||||
|
||||
globalStorage_->IterateUsageGlobal([visitor](Node *node) {
|
||||
JSTaggedValue value(node->GetObject());
|
||||
if (value.IsHeapObject()) {
|
||||
@ -261,15 +235,8 @@ void JSThread::Iterate(const RootVisitor &visitor, const RootRangeVisitor &range
|
||||
void JSThread::IterateHandleWithCheck(const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor)
|
||||
{
|
||||
size_t handleCount = 0;
|
||||
if (currentHandleStorageIndex_ != -1) {
|
||||
int32_t nid = currentHandleStorageIndex_;
|
||||
for (int32_t i = 0; i <= nid; ++i) {
|
||||
auto node = handleStorageNodes_.at(i);
|
||||
auto start = node->data();
|
||||
auto end = (i != nid) ? &(node->data()[NODE_BLOCK_SIZE]) : handleScopeStorageNext_;
|
||||
rangeVisitor(ecmascript::Root::ROOT_HANDLE, ObjectSlot(ToUintPtr(start)), ObjectSlot(ToUintPtr(end)));
|
||||
handleCount += (ToUintPtr(end) - ToUintPtr(start)) / sizeof(JSTaggedType);
|
||||
}
|
||||
for (EcmaContext *context : contexts_) {
|
||||
handleCount += context->IterateHandle(rangeVisitor);
|
||||
}
|
||||
|
||||
size_t globalCount = 0;
|
||||
@ -380,52 +347,12 @@ bool JSThread::DoStackOverflowCheck(const JSTaggedType *sp)
|
||||
|
||||
uintptr_t *JSThread::ExpandHandleStorage()
|
||||
{
|
||||
uintptr_t *result = nullptr;
|
||||
int32_t lastIndex = static_cast<int32_t>(handleStorageNodes_.size() - 1);
|
||||
if (currentHandleStorageIndex_ == lastIndex) {
|
||||
auto n = new std::array<JSTaggedType, NODE_BLOCK_SIZE>();
|
||||
handleStorageNodes_.push_back(n);
|
||||
currentHandleStorageIndex_++;
|
||||
result = reinterpret_cast<uintptr_t *>(&n->data()[0]);
|
||||
handleScopeStorageEnd_ = &n->data()[NODE_BLOCK_SIZE];
|
||||
} else {
|
||||
currentHandleStorageIndex_++;
|
||||
auto lastNode = handleStorageNodes_[currentHandleStorageIndex_];
|
||||
result = reinterpret_cast<uintptr_t *>(&lastNode->data()[0]);
|
||||
handleScopeStorageEnd_ = &lastNode->data()[NODE_BLOCK_SIZE];
|
||||
}
|
||||
|
||||
return result;
|
||||
return GetCurrentEcmaContext()->ExpandHandleStorage();
|
||||
}
|
||||
|
||||
void JSThread::ShrinkHandleStorage(int prevIndex)
|
||||
{
|
||||
currentHandleStorageIndex_ = prevIndex;
|
||||
int32_t lastIndex = static_cast<int32_t>(handleStorageNodes_.size() - 1);
|
||||
#if ECMASCRIPT_ENABLE_ZAP_MEM
|
||||
uintptr_t size = ToUintPtr(handleScopeStorageEnd_) - ToUintPtr(handleScopeStorageNext_);
|
||||
if (memset_s(handleScopeStorageNext_, size, 0, size) != EOK) {
|
||||
LOG_FULL(FATAL) << "memset_s failed";
|
||||
UNREACHABLE();
|
||||
}
|
||||
for (int32_t i = currentHandleStorageIndex_ + 1; i < lastIndex; i++) {
|
||||
if (memset_s(handleStorageNodes_[i],
|
||||
NODE_BLOCK_SIZE * sizeof(JSTaggedType), 0,
|
||||
NODE_BLOCK_SIZE * sizeof(JSTaggedType)) !=
|
||||
EOK) {
|
||||
LOG_FULL(FATAL) << "memset_s failed";
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (lastIndex > MIN_HANDLE_STORAGE_SIZE && currentHandleStorageIndex_ < MIN_HANDLE_STORAGE_SIZE) {
|
||||
for (int i = MIN_HANDLE_STORAGE_SIZE; i < lastIndex; i++) {
|
||||
auto node = handleStorageNodes_.back();
|
||||
delete node;
|
||||
handleStorageNodes_.pop_back();
|
||||
}
|
||||
}
|
||||
GetCurrentEcmaContext()->ShrinkHandleStorage(prevIndex);
|
||||
}
|
||||
|
||||
void JSThread::NotifyStableArrayElementsGuardians(JSHandle<JSObject> receiver)
|
||||
@ -629,10 +556,34 @@ bool JSThread::IsMainThread()
|
||||
void JSThread::PushContext(EcmaContext *context)
|
||||
{
|
||||
contexts_.emplace_back(context);
|
||||
currentContext_ = context;
|
||||
}
|
||||
|
||||
void JSThread::PopContext()
|
||||
{
|
||||
contexts_.pop_back();
|
||||
}
|
||||
|
||||
void JSThread::SwitchCurrentContext(EcmaContext *currentContext)
|
||||
{
|
||||
ASSERT(std::count(contexts_.begin(), contexts_.end(), currentContext));
|
||||
|
||||
currentContext_->SetFramePointers(const_cast<JSTaggedType *>(GetCurrentSPFrame()),
|
||||
const_cast<JSTaggedType *>(GetLastLeaveFrame()),
|
||||
const_cast<JSTaggedType *>(GetLastFp()));
|
||||
currentContext_->SetGlobalEnv(GetGlueGlobalEnv());
|
||||
|
||||
SetCurrentSPFrame(currentContext->GetCurrentFrame());
|
||||
SetLastLeaveFrame(currentContext->GetLeaveFrame());
|
||||
SetLastFp(currentContext->GetLastFp());
|
||||
SetGlueGlobalEnv(*currentContext->GetGlobalEnv());
|
||||
SetGlobalObject(currentContext->GetGlobalEnv()->GetGlobalObject());
|
||||
|
||||
currentContext_ = currentContext;
|
||||
}
|
||||
|
||||
PropertiesCache *JSThread::GetPropertiesCache() const
|
||||
{
|
||||
return currentContext_->GetPropertiesCache();
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -30,9 +30,9 @@
|
||||
#include "ecmascript/mem/visitor.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
class EcmaHandleScope;
|
||||
class EcmaVM;
|
||||
class EcmaContext;
|
||||
class EcmaHandleScope;
|
||||
class HeapRegionAllocator;
|
||||
class PropertiesCache;
|
||||
template<typename T>
|
||||
@ -223,6 +223,11 @@ public:
|
||||
glueData_.lastFp_ = fp;
|
||||
}
|
||||
|
||||
const JSTaggedType *GetLastFp()const
|
||||
{
|
||||
return glueData_.lastFp_;
|
||||
}
|
||||
|
||||
const JSTaggedType *GetCurrentSPFrame() const
|
||||
{
|
||||
return glueData_.currentFrame_;
|
||||
@ -282,56 +287,11 @@ public:
|
||||
void PUBLIC_API CheckJSTaggedType(JSTaggedType value) const;
|
||||
bool PUBLIC_API CpuProfilerCheckJSTaggedType(JSTaggedType value) const;
|
||||
|
||||
JSTaggedType *GetHandleScopeStorageNext() const
|
||||
{
|
||||
return handleScopeStorageNext_;
|
||||
}
|
||||
|
||||
void SetHandleScopeStorageNext(JSTaggedType *value)
|
||||
{
|
||||
handleScopeStorageNext_ = value;
|
||||
}
|
||||
|
||||
JSTaggedType *GetHandleScopeStorageEnd() const
|
||||
{
|
||||
return handleScopeStorageEnd_;
|
||||
}
|
||||
|
||||
std::vector<std::pair<WeakClearCallback, void *>> *GetWeakNodeNativeFinalizeCallbacks()
|
||||
{
|
||||
return &weakNodeNativeFinalizeCallbacks_;
|
||||
}
|
||||
|
||||
void SetHandleScopeStorageEnd(JSTaggedType *value)
|
||||
{
|
||||
handleScopeStorageEnd_ = value;
|
||||
}
|
||||
|
||||
int GetCurrentHandleStorageIndex() const
|
||||
{
|
||||
return currentHandleStorageIndex_;
|
||||
}
|
||||
|
||||
void HandleScopeCountAdd()
|
||||
{
|
||||
handleScopeCount_++;
|
||||
}
|
||||
|
||||
void HandleScopeCountDec()
|
||||
{
|
||||
handleScopeCount_--;
|
||||
}
|
||||
|
||||
void SetLastHandleScope(EcmaHandleScope *scope)
|
||||
{
|
||||
lastHandleScope_ = scope;
|
||||
}
|
||||
|
||||
EcmaHandleScope *GetLastHandleScope() const
|
||||
{
|
||||
return lastHandleScope_;
|
||||
}
|
||||
|
||||
void SetException(JSTaggedValue exception);
|
||||
|
||||
JSTaggedValue GetException() const
|
||||
@ -439,10 +399,7 @@ public:
|
||||
|
||||
void IterateWeakEcmaGlobalStorage(const WeakRootVisitor &visitor);
|
||||
|
||||
PropertiesCache *GetPropertiesCache() const
|
||||
{
|
||||
return propertiesCache_;
|
||||
}
|
||||
PropertiesCache *GetPropertiesCache() const;
|
||||
|
||||
void SetMarkStatus(MarkStatus status)
|
||||
{
|
||||
@ -867,10 +824,11 @@ public:
|
||||
void PushContext(EcmaContext *context);
|
||||
void PopContext();
|
||||
|
||||
EcmaContext *GetCurrentEcmaContext() {
|
||||
EcmaContext *GetCurrentEcmaContext() const
|
||||
{
|
||||
return contexts_.back();
|
||||
}
|
||||
|
||||
void SwitchCurrentContext(EcmaContext *currentContext);
|
||||
private:
|
||||
NO_COPY_SEMANTIC(JSThread);
|
||||
NO_MOVE_SEMANTIC(JSThread);
|
||||
@ -885,10 +843,13 @@ private:
|
||||
return contexts_;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
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;
|
||||
static constexpr size_t DEFAULT_MAX_SYSTEM_STACK_SIZE = 8_MB;
|
||||
=======
|
||||
>>>>>>> fix conflict and move fields in JSThread into context
|
||||
GlueData glueData_;
|
||||
std::atomic<ThreadId> id_;
|
||||
EcmaVM *vm_ {nullptr};
|
||||
@ -897,15 +858,8 @@ private:
|
||||
int nestedLevel_ = 0;
|
||||
NativeAreaAllocator *nativeAreaAllocator_ {nullptr};
|
||||
HeapRegionAllocator *heapRegionAllocator_ {nullptr};
|
||||
JSTaggedType *handleScopeStorageNext_ {nullptr};
|
||||
JSTaggedType *handleScopeStorageEnd_ {nullptr};
|
||||
std::vector<std::array<JSTaggedType, NODE_BLOCK_SIZE> *> handleStorageNodes_ {};
|
||||
int32_t currentHandleStorageIndex_ {-1};
|
||||
int32_t handleScopeCount_ {0};
|
||||
EcmaHandleScope *lastHandleScope_ {nullptr};
|
||||
std::vector<std::pair<WeakClearCallback, void *>> weakNodeNativeFinalizeCallbacks_ {};
|
||||
|
||||
PropertiesCache *propertiesCache_ {nullptr};
|
||||
EcmaGlobalStorage<Node> *globalStorage_ {nullptr};
|
||||
EcmaGlobalStorage<DebugNode> *globalDebugStorage_ {nullptr};
|
||||
int32_t stackTraceFd_ {-1};
|
||||
@ -929,8 +883,7 @@ private:
|
||||
bool finalizationCheckState_ {false};
|
||||
|
||||
CVector<EcmaContext *> contexts_;
|
||||
|
||||
friend class EcmaHandleScope;
|
||||
EcmaContext *currentContext_ {nullptr};
|
||||
friend class GlobalHandleCollection;
|
||||
friend class EcmaVM;
|
||||
};
|
||||
|
@ -208,7 +208,7 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::Execute(JSThread *thread, con
|
||||
// For Ark application startup
|
||||
EcmaContext *context = thread->GetCurrentEcmaContext();
|
||||
|
||||
QuickFixManager *quickFixManager = vm->GetQuickFixManager();
|
||||
QuickFixManager *quickFixManager = thread->GetEcmaVM()->GetQuickFixManager();
|
||||
quickFixManager->LoadPatchIfNeeded(thread, jsPandaFile);
|
||||
|
||||
Expected<JSTaggedValue, bool> result = context->InvokeEcmaEntrypoint(jsPandaFile, entryPoint, excuteFromJob);
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include "ecmascript/ecma_runtime_call_info.h"
|
||||
#include "ecmascript/ecma_string.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/ecma_context.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/interpreter/fast_runtime_stub-inl.h"
|
||||
#include "ecmascript/jobs/micro_job_queue.h"
|
||||
@ -963,31 +962,31 @@ void JSNApi::DestroyAnDataManager()
|
||||
// ----------------------------------- HandleScope -------------------------------------
|
||||
LocalScope::LocalScope(const EcmaVM *vm) : thread_(vm->GetJSThread())
|
||||
{
|
||||
auto thread = reinterpret_cast<JSThread *>(thread_);
|
||||
prevNext_ = thread->GetHandleScopeStorageNext();
|
||||
prevEnd_ = thread->GetHandleScopeStorageEnd();
|
||||
prevHandleStorageIndex_ = thread->GetCurrentHandleStorageIndex();
|
||||
thread->HandleScopeCountAdd();
|
||||
auto context = reinterpret_cast<JSThread *>(thread_)->GetCurrentEcmaContext();
|
||||
prevNext_ = context->GetHandleScopeStorageNext();
|
||||
prevEnd_ = context->GetHandleScopeStorageEnd();
|
||||
prevHandleStorageIndex_ = context->GetCurrentHandleStorageIndex();
|
||||
context->HandleScopeCountAdd();
|
||||
}
|
||||
|
||||
LocalScope::LocalScope(const EcmaVM *vm, JSTaggedType value) : thread_(vm->GetJSThread())
|
||||
{
|
||||
auto thread = reinterpret_cast<JSThread *>(thread_);
|
||||
ecmascript::EcmaHandleScope::NewHandle(thread, value);
|
||||
prevNext_ = thread->GetHandleScopeStorageNext();
|
||||
prevEnd_ = thread->GetHandleScopeStorageEnd();
|
||||
prevHandleStorageIndex_ = thread->GetCurrentHandleStorageIndex();
|
||||
thread->HandleScopeCountAdd();
|
||||
auto context = reinterpret_cast<JSThread *>(thread_)->GetCurrentEcmaContext();
|
||||
ecmascript::EcmaHandleScope::NewHandle(reinterpret_cast<JSThread *>(thread_), value);
|
||||
prevNext_ = context->GetHandleScopeStorageNext();
|
||||
prevEnd_ = context->GetHandleScopeStorageEnd();
|
||||
prevHandleStorageIndex_ = context->GetCurrentHandleStorageIndex();
|
||||
context->HandleScopeCountAdd();
|
||||
}
|
||||
|
||||
LocalScope::~LocalScope()
|
||||
{
|
||||
auto thread = reinterpret_cast<JSThread *>(thread_);
|
||||
thread->HandleScopeCountDec();
|
||||
thread->SetHandleScopeStorageNext(static_cast<JSTaggedType *>(prevNext_));
|
||||
if (thread->GetHandleScopeStorageEnd() != prevEnd_) {
|
||||
thread->SetHandleScopeStorageEnd(static_cast<JSTaggedType *>(prevEnd_));
|
||||
thread->ShrinkHandleStorage(prevHandleStorageIndex_);
|
||||
auto context = reinterpret_cast<JSThread *>(thread_)->GetCurrentEcmaContext();
|
||||
context->HandleScopeCountDec();
|
||||
context->SetHandleScopeStorageNext(static_cast<JSTaggedType *>(prevNext_));
|
||||
if (context->GetHandleScopeStorageEnd() != prevEnd_) {
|
||||
context->SetHandleScopeStorageEnd(static_cast<JSTaggedType *>(prevEnd_));
|
||||
context->ShrinkHandleStorage(prevHandleStorageIndex_);
|
||||
}
|
||||
}
|
||||
|
||||
@ -996,7 +995,7 @@ EscapeLocalScope::EscapeLocalScope(const EcmaVM *vm) : LocalScope(vm, JSTaggedVa
|
||||
{
|
||||
auto thread = vm->GetJSThread();
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
escapeHandle_ = ToUintPtr(thread->GetHandleScopeStorageNext() - 1);
|
||||
escapeHandle_ = ToUintPtr(thread->GetCurrentEcmaContext()->GetHandleScopeStorageNext() - 1);
|
||||
}
|
||||
|
||||
// ----------------------------------- PritimitiveRef ---------------------------------------
|
||||
@ -3186,7 +3185,7 @@ void JSNApi::SetAssetPath(EcmaVM *vm, const std::string &assetPath)
|
||||
|
||||
void JSNApi::SetLoop(EcmaVM *vm, void *loop)
|
||||
{
|
||||
vm->GetJSThread()->GetCurrentEcmaContext()->SetLoop(loop);
|
||||
vm->SetLoop(loop);
|
||||
}
|
||||
|
||||
std::string JSNApi::GetAssetPath(EcmaVM *vm)
|
||||
@ -3226,36 +3225,12 @@ bool JSNApi::InitForConcurrentFunction(EcmaVM *vm, Local<JSValueRef> function, v
|
||||
auto *notificationMgr = vm->GetJsDebuggerManager()->GetNotificationManager();
|
||||
notificationMgr->LoadModuleEvent(moduleName, recordName);
|
||||
|
||||
<<<<<<< HEAD
|
||||
// check ESM or CJS
|
||||
if (!jsPandaFile->IsModule(thread, recordName)) {
|
||||
LOG_ECMA(DEBUG) << "Current function is not from ES Module's file.";
|
||||
=======
|
||||
bool isModule = jsPandaFile->IsModule(thread, recordName);
|
||||
if (isModule) {
|
||||
ecmascript::ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
|
||||
JSHandle<ecmascript::JSTaggedValue> moduleRecord;
|
||||
if (jsPandaFile->IsBundlePack()) {
|
||||
moduleRecord = moduleManager->HostResolveImportedModule(moduleName);
|
||||
} else {
|
||||
moduleRecord = moduleManager->HostResolveImportedModuleWithMerge(moduleName, recordName);
|
||||
if (ecmascript::AnFileDataManager::GetInstance()->IsEnable()) {
|
||||
vm->GetJSThread()->GetCurrentEcmaContext()->GetAOTFileManager()->LoadAiFile(jsPandaFile);
|
||||
}
|
||||
}
|
||||
ecmascript::SourceTextModule::Instantiate(thread, moduleRecord);
|
||||
if (thread->HasPendingException()) {
|
||||
vm->GetJSThread()->GetCurrentEcmaContext()->HandleUncaughtException(thread->GetException());
|
||||
return false;
|
||||
}
|
||||
JSHandle<ecmascript::SourceTextModule> module = JSHandle<ecmascript::SourceTextModule>::Cast(moduleRecord);
|
||||
module->SetStatus(ecmascript::ModuleStatus::INSTANTIATED);
|
||||
ecmascript::SourceTextModule::EvaluateForConcurrent(thread, module);
|
||||
transFunc->SetModule(thread, module);
|
||||
>>>>>>> add cachedconstpools from vm to context
|
||||
return true;
|
||||
}
|
||||
ecmascript::ModuleManager *moduleManager = vm->GetModuleManager();
|
||||
ecmascript::ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
|
||||
JSHandle<ecmascript::JSTaggedValue> moduleRecord;
|
||||
// check compileMode
|
||||
if (jsPandaFile->IsBundlePack()) {
|
||||
@ -3265,7 +3240,7 @@ bool JSNApi::InitForConcurrentFunction(EcmaVM *vm, Local<JSValueRef> function, v
|
||||
LOG_ECMA(DEBUG) << "compileMode is esmodule";
|
||||
moduleRecord = moduleManager->HostResolveImportedModuleWithMerge(moduleName, recordName);
|
||||
if (ecmascript::AnFileDataManager::GetInstance()->IsEnable()) {
|
||||
vm->GetAOTFileManager()->LoadAiFile(jsPandaFile);
|
||||
thread->GetCurrentEcmaContext()->GetAOTFileManager()->LoadAiFile(jsPandaFile);
|
||||
}
|
||||
}
|
||||
ecmascript::SourceTextModule::Instantiate(thread, moduleRecord);
|
||||
@ -3310,7 +3285,8 @@ void JSNApi::SynchronizVMInfo(EcmaVM *vm, const EcmaVM *hostVM)
|
||||
vm->SetModuleName(hostVM->GetModuleName());
|
||||
vm->SetAssetPath(hostVM->GetAssetPath());
|
||||
vm->SetIsBundlePack(hostVM->IsBundlePack());
|
||||
vm->GetModuleManager()->SetExecuteMode(hostVM->GetModuleManager()->GetCurrentMode());
|
||||
vm->GetJSThread()->GetCurrentEcmaContext()->GetModuleManager()->SetExecuteMode(
|
||||
hostVM->GetJSThread()->GetCurrentEcmaContext()->GetModuleManager()->GetCurrentMode());
|
||||
vm->SetResolveBufferCallback(hostVM->GetResolveBufferCallback());
|
||||
}
|
||||
|
||||
|
@ -1304,7 +1304,7 @@ HWTEST_F_L0(JSNApiTests, JSNApi_SetAssetPath_GetAssetPath)
|
||||
ASSERT_EQ(str, res);
|
||||
void *data = reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeInvokeSelf);
|
||||
JSNApi::SetLoop(vm_, data);
|
||||
void* res1 = vm_->GetJSThread()->GetCurrentEcmaContext()->GetLoop();
|
||||
void* res1 = vm_->GetLoop();
|
||||
ASSERT_EQ(res1, data);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user