mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-27 12:10:47 +00:00
[JIT] Fix cancel jit task and visit machinecode
Fixed bind jit task with thread id, may cancel failed when mutli jsthread bind one pthread Add lock in sweep machinecode space and iterate machinecode obj Disallow alloc string when across gc point Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IALVNG Change-Id: Ic857714ce92b5a9d504d85d869db537abe4f8bed Signed-off-by: xiaoweidong <xiaoweidong@huawei.com>
This commit is contained in:
parent
5be332038b
commit
847f22baa8
@ -105,7 +105,8 @@ panda_file::File::EntityId AOTCompilationEnv::GetIdFromCache(JSTaggedValue const
|
||||
return ConstantPool::GetIdFromCache(constpool, index);
|
||||
}
|
||||
|
||||
JSTaggedValue AOTCompilationEnv::GetStringFromConstantPool(const uint32_t methodOffset, const uint16_t cpIdx) const
|
||||
JSTaggedValue AOTCompilationEnv::GetStringFromConstantPool(const uint32_t methodOffset, const uint16_t cpIdx,
|
||||
[[maybe_unused]] bool allowAlloc) const
|
||||
{
|
||||
return ptManager_->GetStringFromConstantPool(methodOffset, cpIdx);
|
||||
}
|
||||
|
@ -56,7 +56,8 @@ public:
|
||||
// GlobalConstants
|
||||
const GlobalEnvConstants *GlobalConstants() const override;
|
||||
|
||||
JSTaggedValue GetStringFromConstantPool(const uint32_t methodOffset, const uint16_t cpIdx) const override;
|
||||
JSTaggedValue GetStringFromConstantPool(const uint32_t methodOffset, const uint16_t cpIdx,
|
||||
bool allowAlloc = true) const override;
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_COMPILER_AOT_COMPILATION_ENV_H
|
||||
|
@ -81,7 +81,8 @@ public:
|
||||
virtual JSTaggedValue GetObjectLiteralFromCache(JSTaggedValue constpool, uint32_t index, CString entry) const = 0;
|
||||
virtual JSTaggedValue GetMethodFromCache(JSTaggedValue constpool, uint32_t index) const = 0;
|
||||
virtual panda_file::File::EntityId GetIdFromCache(JSTaggedValue constpool, uint32_t index) const = 0;
|
||||
virtual JSTaggedValue GetStringFromConstantPool(const uint32_t methodOffset, const uint16_t cpIdx) const = 0;
|
||||
virtual JSTaggedValue GetStringFromConstantPool(const uint32_t methodOffset, const uint16_t cpIdx,
|
||||
bool allowAlloc = true) const = 0;
|
||||
|
||||
// GlobalEnv
|
||||
virtual JSHandle<GlobalEnv> GetGlobalEnv() const = 0;
|
||||
|
@ -170,13 +170,13 @@ const GlobalEnvConstants *JitCompilationEnv::GlobalConstants() const
|
||||
}
|
||||
|
||||
JSTaggedValue JitCompilationEnv::GetStringFromConstantPool([[maybe_unused]] const uint32_t methodOffset,
|
||||
const uint16_t cpIdx) const
|
||||
const uint16_t cpIdx, bool allowAlloc) const
|
||||
{
|
||||
JSTaggedValue constpool = GetConstantPoolByMethodOffset(methodOffset);
|
||||
if (constpool.IsUndefined()) {
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
return ConstantPool::GetStringFromCacheForJit(GetJSThread(), constpool, cpIdx);
|
||||
return ConstantPool::GetStringFromCacheForJit(GetJSThread(), constpool, cpIdx, allowAlloc);
|
||||
}
|
||||
|
||||
JSFunction *JitCompilationEnv::GetJsFunctionByMethodOffset(uint32_t methodOffset) const
|
||||
|
@ -58,7 +58,8 @@ public:
|
||||
// GlobalConstants
|
||||
const GlobalEnvConstants *GlobalConstants() const override;
|
||||
|
||||
JSTaggedValue GetStringFromConstantPool(const uint32_t methodOffset, const uint16_t cpIdx) const override;
|
||||
JSTaggedValue GetStringFromConstantPool(const uint32_t methodOffset, const uint16_t cpIdx,
|
||||
bool allowAlloc = true) const override;
|
||||
|
||||
JSThread *GetHostThread() const override
|
||||
{
|
||||
|
@ -98,7 +98,11 @@ GateRef TSHCROptPass::ConvertStringEqualToConst(GateRef left, GateRef right)
|
||||
auto leftMethodOffset = acc_.TryGetMethodOffset(left);
|
||||
auto rightMethodOffset = acc_.TryGetMethodOffset(right);
|
||||
JSTaggedValue leftStr = GetStringFromConstantPool(leftMethodOffset, leftId);
|
||||
JSTaggedValue rightStr = GetStringFromConstantPool(rightMethodOffset, rightId);
|
||||
// jit: disallow alloc jsstring, across gc point
|
||||
JSTaggedValue rightStr = GetStringFromConstantPool(rightMethodOffset, rightId, false);
|
||||
if (leftStr == JSTaggedValue::Undefined() || rightStr == JSTaggedValue::Undefined()) {
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
if (leftStr == rightStr) {
|
||||
return builder_.Boolean(true);
|
||||
}
|
||||
|
@ -63,9 +63,9 @@ private:
|
||||
return methodName_;
|
||||
}
|
||||
|
||||
JSTaggedValue GetStringFromConstantPool(uint32_t methodOffset, uint32_t cpIdx) const
|
||||
JSTaggedValue GetStringFromConstantPool(uint32_t methodOffset, uint32_t cpIdx, bool allowAlloc = true) const
|
||||
{
|
||||
return compilationEnv_->GetStringFromConstantPool(methodOffset, cpIdx);
|
||||
return compilationEnv_->GetStringFromConstantPool(methodOffset, cpIdx, allowAlloc);
|
||||
}
|
||||
|
||||
GateRef VisitTypedBinaryOp(GateRef gate);
|
||||
|
@ -471,7 +471,7 @@ void Jit::Compile(EcmaVM *vm, JSHandle<JSFunction> &jsFunction, CompilerTier tie
|
||||
void Jit::RequestInstallCode(std::shared_ptr<JitTask> jitTask)
|
||||
{
|
||||
LockHolder holder(threadTaskInfoLock_);
|
||||
ThreadTaskInfo &info = threadTaskInfo_[jitTask->GetTaskThreadId()];
|
||||
ThreadTaskInfo &info = threadTaskInfo_[jitTask->GetHostThread()];
|
||||
if (info.skipInstallTask_) {
|
||||
return;
|
||||
}
|
||||
@ -531,15 +531,15 @@ uint32_t Jit::GetRunningTaskCnt(EcmaVM *vm)
|
||||
}
|
||||
});
|
||||
LockHolder holder(threadTaskInfoLock_);
|
||||
ThreadTaskInfo &info = threadTaskInfo_[vm->GetJSThread()->GetThreadId()];
|
||||
ThreadTaskInfo &info = threadTaskInfo_[vm->GetJSThread()];
|
||||
auto &taskQueue = info.installJitTasks_;
|
||||
return taskQueue.size() + cnt;
|
||||
}
|
||||
|
||||
void Jit::InstallTasks(uint32_t threadId)
|
||||
void Jit::InstallTasks(JSThread *jsThread)
|
||||
{
|
||||
LockHolder holder(threadTaskInfoLock_);
|
||||
ThreadTaskInfo &info = threadTaskInfo_[threadId];
|
||||
ThreadTaskInfo &info = threadTaskInfo_[jsThread];
|
||||
auto &taskQueue = info.installJitTasks_;
|
||||
|
||||
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, ConvertToStdString("Jit::InstallTasks count:" + ToCString(taskQueue.size())));
|
||||
@ -608,7 +608,7 @@ void Jit::ClearTaskWithVm(EcmaVM *vm)
|
||||
|
||||
{
|
||||
LockHolder holder(threadTaskInfoLock_);
|
||||
ThreadTaskInfo &info = threadTaskInfo_[vm->GetJSThread()->GetThreadId()];
|
||||
ThreadTaskInfo &info = threadTaskInfo_[vm->GetJSThread()];
|
||||
info.skipInstallTask_ = true;
|
||||
auto &taskQueue = info.installJitTasks_;
|
||||
taskQueue.clear();
|
||||
@ -622,14 +622,14 @@ void Jit::ClearTaskWithVm(EcmaVM *vm)
|
||||
void Jit::IncJitTaskCnt(JSThread *thread)
|
||||
{
|
||||
LockHolder holder(threadTaskInfoLock_);
|
||||
ThreadTaskInfo &info = threadTaskInfo_[thread->GetThreadId()];
|
||||
ThreadTaskInfo &info = threadTaskInfo_[thread];
|
||||
info.jitTaskCnt_.fetch_add(1);
|
||||
}
|
||||
|
||||
void Jit::DecJitTaskCnt(JSThread *thread)
|
||||
{
|
||||
LockHolder holder(threadTaskInfoLock_);
|
||||
ThreadTaskInfo &info = threadTaskInfo_[thread->GetThreadId()];
|
||||
ThreadTaskInfo &info = threadTaskInfo_[thread];
|
||||
uint32_t old = info.jitTaskCnt_.fetch_sub(1);
|
||||
if (old == 1) {
|
||||
info.jitTaskCntCv_.Signal();
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
int JitVerifyAndCopy(void *codeSigner, void *jit_memory, void *tmpBuffer, int size);
|
||||
|
||||
void RequestInstallCode(std::shared_ptr<JitTask> jitTask);
|
||||
void InstallTasks(uint32_t threadId);
|
||||
void InstallTasks(JSThread *jsThread);
|
||||
void ClearTask(const std::function<bool(Task *task)> &checkClear);
|
||||
void ClearTask(EcmaContext *ecmaContext);
|
||||
void ClearTaskWithVm(EcmaVM *vm);
|
||||
@ -240,7 +240,7 @@ private:
|
||||
std::string bundleName_;
|
||||
bool isEnableAppPGO_ { true };
|
||||
|
||||
std::unordered_map<uint32_t, ThreadTaskInfo> threadTaskInfo_;
|
||||
std::unordered_map<JSThread*, ThreadTaskInfo> threadTaskInfo_;
|
||||
RecursiveMutex threadTaskInfoLock_;
|
||||
bool isEnableJitFort_ { true };
|
||||
bool isDisableCodeSign_ { true };
|
||||
|
@ -795,7 +795,7 @@ bool JSThread::CheckSafepoint()
|
||||
vmThreadControl_->SuspendVM();
|
||||
}
|
||||
if (HasInstallMachineCode()) {
|
||||
vm_->GetJit()->InstallTasks(GetThreadId());
|
||||
vm_->GetJit()->InstallTasks(this);
|
||||
SetInstallMachineCode(false);
|
||||
}
|
||||
|
||||
|
@ -72,10 +72,14 @@ JSHandle<TaggedArray> ConstantPool::GetFieldLiteral(JSThread *thread, JSHandle<C
|
||||
return literalArray;
|
||||
}
|
||||
|
||||
JSTaggedValue ConstantPool::GetStringFromCacheForJit(JSThread *thread, JSTaggedValue constpool, uint32_t index)
|
||||
JSTaggedValue ConstantPool::GetStringFromCacheForJit(JSThread *thread, JSTaggedValue constpool, uint32_t index,
|
||||
bool allowAlloc)
|
||||
{
|
||||
const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject());
|
||||
auto val = taggedPool->Get(index);
|
||||
if (!allowAlloc && val.IsHole()) {
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
if (val.IsHole()) {
|
||||
JSPandaFile *jsPandaFile = taggedPool->GetJSPandaFile();
|
||||
panda_file::File::EntityId id = taggedPool->GetEntityId(index);
|
||||
|
@ -668,7 +668,8 @@ public:
|
||||
return GetLiteralFromCache<type>(thread, constpool, index, entry);
|
||||
}
|
||||
|
||||
static JSTaggedValue PUBLIC_API GetStringFromCacheForJit(JSThread *thread, JSTaggedValue constpool, uint32_t index);
|
||||
static JSTaggedValue PUBLIC_API GetStringFromCacheForJit(JSThread *thread, JSTaggedValue constpool, uint32_t index,
|
||||
bool allowAlloc = true);
|
||||
|
||||
static JSTaggedValue PUBLIC_API GetStringFromCache(JSThread *thread, JSTaggedValue constpool, uint32_t index);
|
||||
|
||||
|
@ -654,7 +654,6 @@ uintptr_t MachineCodeSpace::JitFortAllocate(MachineCodeDesc *desc)
|
||||
// Record info on JitFort mem allocated to live MachineCode objects
|
||||
void MachineCodeSpace::FreeRegion(Region *current, bool isMain)
|
||||
{
|
||||
LockHolder holder(freeRegionMutex_);
|
||||
LOG_JIT(DEBUG) << "MachineCodeSpace FreeRegion: " << current << " isMain " << isMain;
|
||||
uintptr_t freeStart = current->GetBegin();
|
||||
current->IterateAllMarkedBits([this, ¤t, &freeStart, isMain](void *mem) {
|
||||
@ -679,6 +678,23 @@ void MachineCodeSpace::FreeRegion(Region *current, bool isMain)
|
||||
}
|
||||
}
|
||||
|
||||
void MachineCodeSpace::AsyncSweep(bool isMain)
|
||||
{
|
||||
LockHolder holder(asyncSweepMutex_);
|
||||
Region *current = GetSweepingRegionSafe();
|
||||
while (current != nullptr) {
|
||||
FreeRegion(current, isMain);
|
||||
// Main thread sweeping region is added;
|
||||
if (!isMain) {
|
||||
AddSweptRegionSafe(current);
|
||||
} else {
|
||||
current->MergeOldToNewRSetForCS();
|
||||
current->MergeLocalToShareRSetForCS();
|
||||
}
|
||||
current = GetSweepingRegionSafe();
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t MachineCodeSpace::Allocate(size_t size, bool allowGC)
|
||||
{
|
||||
return SparseSpace::Allocate(size, allowGC);
|
||||
@ -742,7 +758,7 @@ size_t MachineCodeSpace::CheckMachineCodeObject(uintptr_t curPtr, uintptr_t &mac
|
||||
uintptr_t MachineCodeSpace::GetMachineCodeObject(uintptr_t pc)
|
||||
{
|
||||
uintptr_t machineCode = 0;
|
||||
LockHolder holder(freeRegionMutex_);
|
||||
LockHolder holder(asyncSweepMutex_);
|
||||
allocator_->FillBumpPointer();
|
||||
|
||||
EnumerateRegions([&](Region *region) {
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
// For sweeping
|
||||
void PrepareSweeping();
|
||||
void Sweep();
|
||||
void AsyncSweep(bool isMain);
|
||||
virtual void AsyncSweep(bool isMain);
|
||||
|
||||
bool TryFillSweptRegion();
|
||||
// Ensure All region finished sweeping
|
||||
@ -273,6 +273,7 @@ public:
|
||||
NO_MOVE_SEMANTIC(MachineCodeSpace); // Note: Expand() left for define
|
||||
uintptr_t GetMachineCodeObject(uintptr_t pc);
|
||||
size_t CheckMachineCodeObject(uintptr_t curPtr, uintptr_t &machineCode, uintptr_t pc);
|
||||
void AsyncSweep(bool isMain) override;
|
||||
void FreeRegion(Region *current, bool isMain = true) override;
|
||||
uintptr_t Allocate(size_t size, bool allowGC = true);
|
||||
uintptr_t Allocate(size_t size, MachineCodeDesc *desc, bool allowGC = true);
|
||||
@ -306,7 +307,7 @@ public:
|
||||
|
||||
private:
|
||||
JitFort *jitFort_ {nullptr};
|
||||
Mutex freeRegionMutex_;
|
||||
Mutex asyncSweepMutex_;
|
||||
friend class Heap;
|
||||
friend class ConcurrentSweeper;
|
||||
};
|
||||
|
@ -30,6 +30,7 @@ group("ark_jit_ts_test") {
|
||||
"ts_inline",
|
||||
"proxy_fast_call",
|
||||
"fuzz_exception",
|
||||
"throw_error",
|
||||
]
|
||||
|
||||
deps = [ "pgo_roottype_test:pgo_roottype_test" ]
|
||||
|
18
test/jittest/throw_error/BUILD.gn
Normal file
18
test/jittest/throw_error/BUILD.gn
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2024 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.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_jit_test_action("throw_error") {
|
||||
deps = []
|
||||
}
|
14
test/jittest/throw_error/expect_output.txt
Normal file
14
test/jittest/throw_error/expect_output.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2024 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.
|
||||
|
||||
60
|
51
test/jittest/throw_error/throw_error.ts
Normal file
51
test/jittest/throw_error/throw_error.ts
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.
|
||||
*/
|
||||
let catchcnt = 0;
|
||||
function ThrowFunc() {
|
||||
try {
|
||||
throw new Error("error");
|
||||
} catch (e) {
|
||||
catchcnt++;
|
||||
}
|
||||
}
|
||||
|
||||
function CallThrowFunc() {
|
||||
ThrowFunc();
|
||||
let arr = [];
|
||||
for(var i = 0; i < 10; i++){
|
||||
arr.push('CallThrowFunc')
|
||||
}
|
||||
for(var i = 0; i < 10; i++){
|
||||
arr.push('push............')
|
||||
}
|
||||
ThrowFunc();
|
||||
}
|
||||
|
||||
function Test() {
|
||||
CallThrowFunc();
|
||||
}
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
Test();
|
||||
}
|
||||
ArkTools.jitCompileAsync(Test);
|
||||
|
||||
var ret = ArkTools.waitJitCompileFinish(Test);
|
||||
for (let i = 0; i < 20; i++) {
|
||||
Test();
|
||||
ArkTools.gc(0);
|
||||
}
|
||||
|
||||
print(catchcnt);
|
Loading…
Reference in New Issue
Block a user