!9028 fix pandafile cannot get from shared pandafileManagerList

Merge pull request !9028 from yaochaonan/pandafile
This commit is contained in:
openharmony_ci 2024-09-07 12:10:48 +00:00 committed by Gitee
commit 3fc1d0b960
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
7 changed files with 165 additions and 3 deletions

View File

@ -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();

View File

@ -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};

View 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

View File

@ -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()) {

View File

@ -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);

View File

@ -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);

View File

@ -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