From b94ce6beec71d5454639982dfa424bd89c282ea5 Mon Sep 17 00:00:00 2001 From: ZhouGuangyuan Date: Thu, 14 Aug 2025 17:08:26 +0800 Subject: [PATCH] add concurrent verify for stub compiler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/ICSZW5 Signed-off-by: ZhouGuangyuan Change-Id: I06d2042231b958721d7196e9cc69eb2f5d286462 !249 一致性整改 Merge pull request !249 from zhangdd_ewan/cherry-240712 --- .../compiler/aot_file/aot_file_info.cpp | 3 + ecmascript/compiler/aot_file/aot_file_info.h | 69 +++++++++++++++++++ ecmascript/compiler/code_generator.h | 4 ++ .../compiler/codegen/llvm/llvm_codegen.cpp | 25 ++++++- ecmascript/compiler/file_generators.cpp | 12 +++- ecmascript/tests/machine_code_test.cpp | 25 +++++++ libark_jsruntime.map | 2 +- 7 files changed, 136 insertions(+), 4 deletions(-) diff --git a/ecmascript/compiler/aot_file/aot_file_info.cpp b/ecmascript/compiler/aot_file/aot_file_info.cpp index abf2929d11..a3a242023b 100644 --- a/ecmascript/compiler/aot_file/aot_file_info.cpp +++ b/ecmascript/compiler/aot_file/aot_file_info.cpp @@ -16,6 +16,9 @@ #include "ecmascript/compiler/aot_file/aot_file_info.h" namespace panda::ecmascript { + +ConcurrentMonitor ConcurrentMonitor::monitor_; + void AOTFileInfo::Destroy() { entryNum_ = 0; diff --git a/ecmascript/compiler/aot_file/aot_file_info.h b/ecmascript/compiler/aot_file/aot_file_info.h index e42fbc87b5..7ca2e26728 100644 --- a/ecmascript/compiler/aot_file/aot_file_info.h +++ b/ecmascript/compiler/aot_file/aot_file_info.h @@ -24,6 +24,75 @@ #include "ecmascript/stackmap/ark_stackmap.h" namespace panda::ecmascript { +class PUBLIC_API ConcurrentMonitor { +public: + void RegisterThread() + { +#ifndef NDEBUG + std::lock_guard lock(mtx_); + ++registeredThreads_; +#endif + } + + void UnregisterThread() + { +#ifndef NDEBUG + std::unique_lock lock(mtx_); + --registeredThreads_; + if (waitingThreads_ == registeredThreads_) + { + ++generation_; + waitingThreads_ = 0; + cv_.notify_all(); + } +#endif + } + + void ArriveAndWait() + { +#ifndef NDEBUG + std::unique_lock lock(mtx_); + if (registeredThreads_ == 0) { + return; + } + int gen = generation_; + ++waitingThreads_; + if (waitingThreads_ == registeredThreads_) { + ++generation_; + waitingThreads_ = 0; + cv_.notify_all(); + } else { + // 等待其他线程 + cv_.wait(lock, [&] { + return gen != generation_; + }); + } +#endif + } + static ConcurrentMonitor monitor_; + + class Scope { + public: + Scope() + { + monitor_.RegisterThread(); + } + + ~Scope() + { + monitor_.UnregisterThread(); + } + }; +private: +#ifndef NDEBUG + std::mutex mtx_; + std::condition_variable cv_; + int registeredThreads_ = 0; + int waitingThreads_ = 0; + int generation_ = 0; +#endif +}; + class PUBLIC_API AOTFileInfo { public: using FuncEntryDes = ecmascript::FuncEntryDes; diff --git a/ecmascript/compiler/code_generator.h b/ecmascript/compiler/code_generator.h index 5d871ee8ba..54cc0174b0 100644 --- a/ecmascript/compiler/code_generator.h +++ b/ecmascript/compiler/code_generator.h @@ -85,6 +85,8 @@ struct CodeInfo { uint8_t *AllocaCodeSectionOnDemand(uintptr_t size, const char *sectionName); + void VerifyAddress(uintptr_t addr, uintptr_t size, uintptr_t alignSize); + uint8_t *AllocaDataSectionImp(uintptr_t size, const char *sectionName, AllocaSectionCallback allocaInReqSecBuffer, AllocaSectionCallback allocaInNotReqSecBuffer); @@ -137,6 +139,8 @@ private: CodeSpaceOnDemand &codeSpaceOnDemand_; bool useOwnSpace_ {false}; std::unique_ptr ownCodeSpace_ {nullptr}; + uintptr_t lastAddr_ {0}; + uintptr_t lastSize_ {0}; }; class Assembler { diff --git a/ecmascript/compiler/codegen/llvm/llvm_codegen.cpp b/ecmascript/compiler/codegen/llvm/llvm_codegen.cpp index 7d478c4d40..aad204d1ce 100644 --- a/ecmascript/compiler/codegen/llvm/llvm_codegen.cpp +++ b/ecmascript/compiler/codegen/llvm/llvm_codegen.cpp @@ -105,7 +105,8 @@ CodeInfo::CodeSpace::~CodeSpace() uint8_t *CodeInfo::CodeSpace::Alloca(uintptr_t size, bool isReq, size_t alignSize) { - LockHolder lock(mutex_); + // Wait other threads arrived here, then allocate in same time. + ConcurrentMonitor::monitor_.ArriveAndWait(); uint8_t *addr = nullptr; auto bufBegin = isReq ? reqSecs_ : unreqSecs_; auto &curPos = isReq ? reqBufPos_ : unreqBufPos_; @@ -182,11 +183,14 @@ uint8_t *CodeInfo::AllocaCodeSectionImp(uintptr_t size, const char *sectionName, if (!alreadyPageAlign_) { addr = (this->*allocaInReqSecBuffer)(size, AOTFileInfo::PAGE_ALIGN); alreadyPageAlign_ = true; + VerifyAddress(reinterpret_cast(addr), size, AOTFileInfo::PAGE_ALIGN); } else { addr = (this->*allocaInReqSecBuffer)(size, AOTFileInfo::TEXT_SEC_ALIGN); + VerifyAddress(reinterpret_cast(addr), size, AOTFileInfo::TEXT_SEC_ALIGN); } } else { addr = (this->*allocaInReqSecBuffer)(size, 0); + VerifyAddress(reinterpret_cast(addr), size, 0); } codeInfo_.push_back({addr, size}); if (curSec.isValidAOTSec()) { @@ -205,6 +209,25 @@ uint8_t *CodeInfo::AllocaCodeSectionOnDemand(uintptr_t size, const char *section return AllocaCodeSectionImp(size, sectionName, &CodeInfo::AllocaOnDemand); } +void CodeInfo::VerifyAddress(uintptr_t addr, uintptr_t size, uintptr_t alignSize) +{ + if (lastAddr_ == 0) { + lastAddr_ = addr; + lastSize_ = size; + return; + } + uintptr_t expectAddr = lastAddr_ + lastSize_; + if (alignSize != 0 && !IsAligned(expectAddr, alignSize)) { + expectAddr = AlignUp(expectAddr, alignSize); + } + if (expectAddr != addr) { + LOG_COMPILER(FATAL) << "VerifyAddress failed: " << lastAddr_ << " " << lastSize_ << " " << alignSize << + ", addr: " << addr; + } + lastAddr_ = addr; + lastSize_ = size; +} + uint8_t *CodeInfo::AllocaDataSectionImp(uintptr_t size, const char *sectionName, AllocaSectionCallback allocaInReqSecBuffer, AllocaSectionCallback allocaInNotReqSecBuffer) diff --git a/ecmascript/compiler/file_generators.cpp b/ecmascript/compiler/file_generators.cpp index b67588743d..601ec98f44 100644 --- a/ecmascript/compiler/file_generators.cpp +++ b/ecmascript/compiler/file_generators.cpp @@ -377,10 +377,14 @@ void StubFileGenerator::CollectCodeInfo() std::vector threads; for (size_t i = 1; i < modulePackage_.size(); ++i) { threads.emplace_back([&, i]() { + ConcurrentMonitor::Scope concurrentScope; entryPoints[i] = modulePackage_[i].GetFuncEntryPoints(); }); } - entryPoints[0] = modulePackage_[0].GetFuncEntryPoints(); + { + ConcurrentMonitor::Scope concurrentScope; + entryPoints[0] = modulePackage_[0].GetFuncEntryPoints(); + } for (auto& t : threads) { if (t.joinable()) { t.join(); @@ -533,10 +537,14 @@ void StubFileGenerator::RunLLVMAssembler() for (size_t i = 1; i < modulePackage_.size(); ++i) { const CompilerLog &log = *(this->log_); threads.emplace_back([&, i] { + ConcurrentMonitor::Scope concurrentScope; modulePackage_[i].RunAssembler(log, false); }); } - modulePackage_[0].RunAssembler(*(this->log_), false); + { + ConcurrentMonitor::Scope concurrentScope; + modulePackage_[0].RunAssembler(*(this->log_), false); + } for (auto& t : threads) { if (t.joinable()) { t.join(); diff --git a/ecmascript/tests/machine_code_test.cpp b/ecmascript/tests/machine_code_test.cpp index fcbaa557f7..a6ec750bc8 100644 --- a/ecmascript/tests/machine_code_test.cpp +++ b/ecmascript/tests/machine_code_test.cpp @@ -22,7 +22,9 @@ #include "ecmascript/js_array.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/object_factory-inl.h" +#include "ecmascript/compiler/aot_file/aot_file_info.h" #include "ecmascript/tests/test_helper.h" +#include using namespace panda; using namespace panda::ecmascript; @@ -226,4 +228,27 @@ HWTEST_F_L0(MachineCodeTest, SetText003) Jit::GetInstance()->SetEnableAsyncCopyToFort(true); } +HWTEST_F_L0(MachineCodeTest, ConcurrentTest001) +{ + std::vector threads; + for (size_t i = 1; i < 10; ++i) { + threads.emplace_back([] { + ConcurrentMonitor::Scope concurrentScope; + sleep(1); + ConcurrentMonitor::monitor_.ArriveAndWait(); + sleep(1); + }); + } + { + ConcurrentMonitor::Scope concurrentScope; + sleep(1); + ConcurrentMonitor::monitor_.ArriveAndWait(); + sleep(1); + } + for (auto &t: threads) { + if (t.joinable()) { + t.join(); + } + } +} } diff --git a/libark_jsruntime.map b/libark_jsruntime.map index ff2b0e3c7a..667bb92949 100644 --- a/libark_jsruntime.map +++ b/libark_jsruntime.map @@ -19,7 +19,7 @@ panda::ecmascript::COMPILER_HELP_HEAD_MSG*; panda::ecmascript::g_isEnableCMCGC*; panda::ArkCrashHolder*; - + panda::ecmascript::ConcurrentMonitor::*; panda::ArrayBufferRef::*; panda::SendableArrayBufferRef::*; panda::BufferRef::*; -- Gitee