mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-06 23:54:03 +00:00
!9028 fix pandafile cannot get from shared pandafileManagerList
Merge pull request !9028 from yaochaonan/pandafile
This commit is contained in:
commit
3fc1d0b960
@ -23,13 +23,14 @@
|
||||
#include "ecmascript/jit/jit.h"
|
||||
#include "ecmascript/linked_hash_table.h"
|
||||
#include "ecmascript/module/module_logger.h"
|
||||
#include "ecmascript/jspandafile/abc_buffer_cache.h"
|
||||
#include "ecmascript/platform/aot_crash_info.h"
|
||||
#include "ecmascript/platform/log.h"
|
||||
#include "ecmascript/regexp/regexp_parser_cache.h"
|
||||
#include "ecmascript/require/js_require_manager.h"
|
||||
#include "ecmascript/runtime.h"
|
||||
#include "ecmascript/snapshot/mem/snapshot.h"
|
||||
#include "ecmascript/stubs/runtime_stubs.h"
|
||||
#include "ecmascript/platform/log.h"
|
||||
#include "ecmascript/sustaining_js_handle.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
@ -100,6 +101,7 @@ bool EcmaContext::Initialize()
|
||||
moduleManager_ = new ModuleManager(vm_);
|
||||
ptManager_ = new kungfu::PGOTypeManager(vm_);
|
||||
optCodeProfiler_ = new OptCodeProfiler();
|
||||
abcBufferCache_ = new AbcBufferCache();
|
||||
if (vm_->GetJSOptions().GetTypedOpProfiler()) {
|
||||
typedOpProfiler_ = new TypedOpProfiler();
|
||||
}
|
||||
@ -260,6 +262,10 @@ EcmaContext::~EcmaContext()
|
||||
delete functionProtoTransitionTable_;
|
||||
functionProtoTransitionTable_ = nullptr;
|
||||
}
|
||||
if (abcBufferCache_ != nullptr) {
|
||||
delete abcBufferCache_;
|
||||
abcBufferCache_ = nullptr;
|
||||
}
|
||||
// clear join stack
|
||||
joinStack_.clear();
|
||||
|
||||
|
@ -64,6 +64,7 @@ class AOTFileManager;
|
||||
class QuickFixManager;
|
||||
class OptCodeProfiler;
|
||||
class TypedOpProfiler;
|
||||
class AbcBufferCache;
|
||||
struct CJSInfo;
|
||||
class FunctionProtoTransitionTable;
|
||||
class ModuleLogger;
|
||||
@ -138,6 +139,11 @@ public:
|
||||
return moduleManager_;
|
||||
}
|
||||
|
||||
AbcBufferCache *GetAbcBufferCache() const
|
||||
{
|
||||
return abcBufferCache_;
|
||||
}
|
||||
|
||||
kungfu::PGOTypeManager *GetPTManager() const
|
||||
{
|
||||
return ptManager_;
|
||||
@ -696,6 +702,7 @@ private:
|
||||
ModuleManager *moduleManager_ {nullptr};
|
||||
kungfu::PGOTypeManager *ptManager_ {nullptr};
|
||||
AOTFileManager *aotFileManager_ {nullptr};
|
||||
AbcBufferCache *abcBufferCache_ {nullptr};
|
||||
|
||||
// for recording the transition of function prototype
|
||||
FunctionProtoTransitionTable *functionProtoTransitionTable_ {nullptr};
|
||||
|
98
ecmascript/jspandafile/abc_buffer_cache.h
Normal file
98
ecmascript/jspandafile/abc_buffer_cache.h
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ECMASCRIPT_JSPANDAFILE_ABC_BUFFER_CACHE_H
|
||||
#define ECMASCRIPT_JSPANDAFILE_ABC_BUFFER_CACHE_H
|
||||
|
||||
#include <string>
|
||||
#include "ecmascript/ecma_context.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
|
||||
enum AbcBufferType { NORMAL_BUFFER, SECURE_BUFFER };
|
||||
struct AbcBufferInfo {
|
||||
void *buffer_ ;
|
||||
size_t size_;
|
||||
AbcBufferType bufferType_;
|
||||
|
||||
AbcBufferInfo(void *buffer, size_t size, AbcBufferType bufferType)
|
||||
: buffer_(buffer), size_(size), bufferType_(bufferType) {}
|
||||
AbcBufferInfo()
|
||||
: buffer_(nullptr), size_(0), bufferType_(AbcBufferType::NORMAL_BUFFER) {}
|
||||
};
|
||||
|
||||
/*
|
||||
* If JSPandafileManager's loadedJSPandaFiles_ delete cache during sharedgc process,
|
||||
* buffer cannot get in later module LoadJsPandafile process, which will cause crash.
|
||||
* This map can help use buffer to get *pf again.
|
||||
*/
|
||||
class AbcBufferCache {
|
||||
public:
|
||||
AbcBufferCache() = default;
|
||||
~AbcBufferCache()
|
||||
{
|
||||
abcBufferMap_.clear();
|
||||
}
|
||||
|
||||
void AddAbcBufferToCache(const CString &fileName, const void *buffer, size_t size, AbcBufferType bufferType)
|
||||
{
|
||||
abcBufferMap_.emplace(fileName, AbcBufferInfo(const_cast<void *>(buffer), size, bufferType));
|
||||
}
|
||||
|
||||
void DeleteAbcBufferFromCache(const CString &fileName)
|
||||
{
|
||||
auto iter = abcBufferMap_.find(fileName);
|
||||
if (iter == abcBufferMap_.end()) {
|
||||
return;
|
||||
}
|
||||
abcBufferMap_.erase(iter);
|
||||
}
|
||||
|
||||
AbcBufferInfo FindJSPandaFileInAbcBufferCache(const CString &fileName) const
|
||||
{
|
||||
auto iter = abcBufferMap_.find(fileName);
|
||||
if (iter == abcBufferMap_.end()) {
|
||||
return AbcBufferInfo();
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<CString, AbcBufferInfo> abcBufferMap_;
|
||||
};
|
||||
|
||||
class AbcBufferCacheScope {
|
||||
public:
|
||||
AbcBufferCacheScope(JSThread *thread, const CString &filename, const void *buffer,
|
||||
size_t size, AbcBufferType bufferType): filename_(filename)
|
||||
{
|
||||
abcBufferCache_ = thread->GetCurrentEcmaContext()->GetAbcBufferCache();
|
||||
ASSERT(abcBufferCache_ != nullptr);
|
||||
abcBufferCache_->AddAbcBufferToCache(filename_, buffer, size, bufferType);
|
||||
}
|
||||
|
||||
~AbcBufferCacheScope()
|
||||
{
|
||||
ASSERT(abcBufferCache_ != nullptr);
|
||||
abcBufferCache_->DeleteAbcBufferFromCache(filename_);
|
||||
}
|
||||
|
||||
private:
|
||||
const CString filename_;
|
||||
AbcBufferCache *abcBufferCache_ {nullptr};
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_JSPANDAFILE_ABC_BUFFER_CACHE_H
|
@ -16,6 +16,7 @@
|
||||
#include "ecmascript/jspandafile/js_pandafile_executor.h"
|
||||
|
||||
#include "ecmascript/js_file_path.h"
|
||||
#include "ecmascript/jspandafile/abc_buffer_cache.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
#include "ecmascript/module/module_path_helper.h"
|
||||
#include "ecmascript/checkpoint/thread_state_transition.h"
|
||||
@ -155,6 +156,7 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteFromBuffer(JSThread *t
|
||||
LOG_FULL(FATAL) << "Load current file's panda file failed. Current file is " << normalName;
|
||||
#endif
|
||||
}
|
||||
AbcBufferCacheScope bufferScope(thread, normalName, buffer, size, AbcBufferType::NORMAL_BUFFER);
|
||||
auto vm = thread->GetEcmaVM();
|
||||
|
||||
CString entry = entryPoint.data();
|
||||
@ -205,7 +207,7 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteModuleBuffer(
|
||||
LOG_FULL(FATAL) << "Load current file's panda file failed. Current file is " << name;
|
||||
#endif
|
||||
}
|
||||
|
||||
AbcBufferCacheScope bufferScope(thread, name, buffer, size, AbcBufferType::NORMAL_BUFFER);
|
||||
bool isBundle = jsPandaFile->IsBundlePack();
|
||||
|
||||
// realEntry is used to record the original record, which is easy to throw when there are exceptions
|
||||
@ -332,6 +334,7 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteFromBufferSecure(JSThr
|
||||
LOG_FULL(FATAL) << "Load current file's panda file failed. Current file is " << normalName;
|
||||
#endif
|
||||
}
|
||||
AbcBufferCacheScope bufferScope(thread, normalName, buffer, size, AbcBufferType::SECURE_BUFFER);
|
||||
auto vm = thread->GetEcmaVM();
|
||||
|
||||
CString entry = entryPoint.data();
|
||||
@ -407,7 +410,7 @@ Expected<JSTaggedValue, bool> JSPandaFileExecutor::ExecuteModuleBufferSecure(JST
|
||||
LOG_FULL(FATAL) << "Load current file's panda file failed. Current file is " << name;
|
||||
#endif
|
||||
}
|
||||
|
||||
AbcBufferCacheScope bufferScope(thread, name, buffer, size, AbcBufferType::SECURE_BUFFER);
|
||||
// realEntry is used to record the original record, which is easy to throw when there are exceptions
|
||||
const CString realEntry = entry;
|
||||
if (vm->IsNormalizedOhmUrlPack()) {
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "ecmascript/jspandafile/js_pandafile_manager.h"
|
||||
|
||||
#include "ecmascript/checkpoint/thread_state_transition.h"
|
||||
#include "ecmascript/jspandafile/abc_buffer_cache.h"
|
||||
#include "ecmascript/jspandafile/js_pandafile_executor.h"
|
||||
#include "ecmascript/module/module_path_helper.h"
|
||||
#include "ecmascript/module/module_message_helper.h"
|
||||
@ -54,6 +55,9 @@ std::shared_ptr<JSPandaFile> JSPandaFileManager::LoadJSPandaFile(JSThread *threa
|
||||
jsPandaFile = FindJSPandaFileWithChecksum(filename, pf->GetHeader()->checksum);
|
||||
} else {
|
||||
jsPandaFile = FindJSPandaFileUnlocked(filename);
|
||||
if (jsPandaFile == nullptr) {
|
||||
jsPandaFile = GenerateJSPandafileFromBufferCache(thread, filename, entryPoint);
|
||||
}
|
||||
}
|
||||
if (jsPandaFile != nullptr) {
|
||||
return jsPandaFile;
|
||||
@ -592,6 +596,24 @@ bool JSPandaFileManager::CheckFilePath(JSThread *thread, const CString &fileName
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<JSPandaFile> JSPandaFileManager::GenerateJSPandafileFromBufferCache(
|
||||
JSThread *thread, const CString &filename, std::string_view entryPoint)
|
||||
{
|
||||
AbcBufferInfo bufferInfo =
|
||||
thread->GetCurrentEcmaContext()->GetAbcBufferCache()->FindJSPandaFileInAbcBufferCache(filename);
|
||||
if (bufferInfo.buffer_ == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
LOG_FULL(INFO) << "fileName was found in bufferFiles_.";
|
||||
JSPandaFileManager *jsPandaFileManager = JSPandaFileManager::GetInstance();
|
||||
if (bufferInfo.bufferType_ == AbcBufferType::SECURE_BUFFER) {
|
||||
return jsPandaFileManager->LoadJSPandaFileSecure(
|
||||
thread, filename, entryPoint, reinterpret_cast<uint8_t *>(bufferInfo.buffer_), bufferInfo.size_);
|
||||
}
|
||||
return jsPandaFileManager->LoadJSPandaFile(
|
||||
thread, filename, entryPoint, bufferInfo.buffer_, bufferInfo.size_);
|
||||
}
|
||||
|
||||
void *JSPandaFileManager::AllocateBuffer(size_t size)
|
||||
{
|
||||
return JSPandaFileAllocator::AllocateBuffer(size);
|
||||
|
@ -113,6 +113,9 @@ private:
|
||||
std::shared_ptr<JSPandaFile> GetJSPandaFile(const panda_file::File *pf);
|
||||
std::shared_ptr<JSPandaFile> FindJSPandaFileWithChecksum(const CString &filename, uint32_t checksum);
|
||||
std::shared_ptr<JSPandaFile> FindJSPandaFileUnlocked(const CString &filename);
|
||||
std::shared_ptr<JSPandaFile> GenerateJSPandafileFromBufferCache(JSThread *thread,
|
||||
const CString &filename,
|
||||
std::string_view entryPoint);
|
||||
void ObsoleteLoadedJSPandaFile(const CString &filename);
|
||||
|
||||
static void *AllocateBuffer(size_t size);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "libziparchive/zip_archive.h"
|
||||
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/jspandafile/abc_buffer_cache.h"
|
||||
#include "ecmascript/jspandafile/js_pandafile.h"
|
||||
#include "ecmascript/jspandafile/js_pandafile_manager.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
@ -362,4 +363,26 @@ HWTEST_F_L0(JSPandaFileManagerTest, CheckFilePath)
|
||||
EXPECT_TRUE(result);
|
||||
pfManager->RemoveJSPandaFile(pf.get());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(JSPandaFileManagerTest, GetJSPandaFileByBufferFiles)
|
||||
{
|
||||
JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
|
||||
const char *fileName = "__JSPandaFileManagerTest3.abc";
|
||||
const char *data = R"(
|
||||
.function void foo() {}
|
||||
)";
|
||||
Parser parser;
|
||||
auto res = parser.Parse(data);
|
||||
std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
|
||||
std::shared_ptr<JSPandaFile> pf = pfManager->NewJSPandaFile(pfPtr.release(), CString(fileName));
|
||||
std::shared_ptr<JSPandaFile> jsPandaFile;
|
||||
pfManager->AddJSPandaFile(pf);
|
||||
AbcBufferCache *abcBufferCache = thread->GetCurrentEcmaContext()->GetAbcBufferCache();
|
||||
abcBufferCache->AddAbcBufferToCache(CString(fileName), (void *)data, sizeof(data), AbcBufferType::NORMAL_BUFFER);
|
||||
AbcBufferInfo bufferInfo = abcBufferCache->FindJSPandaFileInAbcBufferCache(CString(fileName));
|
||||
EXPECT_TRUE(bufferInfo.buffer_ != nullptr);
|
||||
abcBufferCache->DeleteAbcBufferFromCache(CString(fileName));
|
||||
jsPandaFile = pfManager->LoadJSPandaFile(thread, CString(fileName), "");
|
||||
EXPECT_TRUE(jsPandaFile != nullptr);
|
||||
}
|
||||
} // namespace panda::test
|
||||
|
Loading…
Reference in New Issue
Block a user