Modify option source of stub compiler.

Using options in js runtime option list and delete stub compiler option.

Add path check for stub compiler generation phase.

Load stub file before loading of aot file.

Add runtime option for optimization level configuration.

Issue: https://gitee.com/openharmony/ark_js_runtime/issues/I557Q2
Signed-off-by: luochuhao <luochuhao@huawei.com>
Change-Id: Ifbaa7a2dc4333310c62f1f8e230eefb7a2136ca5
This commit is contained in:
luochuhao 2022-04-25 20:08:55 +08:00
parent f83919d735
commit 33e7b89cac
16 changed files with 92 additions and 229 deletions

View File

@ -186,13 +186,6 @@ ohos_shared_library("libark_jsoptimizer_test") {
subsystem_name = "test"
}
ark_gen_file("stub_aot_options_gen_h") {
template_file = "options.h.erb"
data_file = "stub_aot_options.yaml"
requires = [ "$ark_root/templates/common.rb" ]
output_file = "$target_gen_dir/generated/stub_aot_options_gen.h"
}
source_set("ark_stub_compiler_static") {
sources = [ "stub_compiler.cpp" ]
include_dirs = [ "$target_gen_dir" ]
@ -204,7 +197,6 @@ source_set("ark_stub_compiler_static") {
]
deps = [
":stub_aot_options_gen_h",
"$ark_root/libpandabase:libarkbase",
"//ark/js_runtime:libark_jsruntime",
"//ark/js_runtime/ecmascript/compiler:libark_jsoptimizer",

View File

@ -63,7 +63,7 @@ int Main(const int argc, const char **argv)
base_options::Options baseOptions(sp[0]);
panda::PandArg<bool> help("help", false, "Print this message and exit");
panda::PandArg<bool> options("options", false, "Print compiler and runtime options");
panda::PandArg<bool> options("options", false, "Print options");
// tail arguments
panda::PandArg<arg_list_t> files("files", {""}, "path to pandafiles", ":");
panda::PandArg<std::string> entrypoint("entrypoint", "init::func_main_0",
@ -114,8 +114,9 @@ int Main(const int argc, const char **argv)
arg_list_t pandaFileNames = files.GetValue();
PassManager passManager(vm, entry);
std::string triple = runtimeOptions.GetAotTargetTriple();
std::string triple = runtimeOptions.GetTargetTriple();
std::string outputFileName = runtimeOptions.GetAOTOutputFile();
size_t optLevel = runtimeOptions.GetOptLevel();
BytecodeStubCSigns::Initialize();
CommonStubCSigns::Initialize();
RuntimeStubCSigns::Initialize();
@ -124,7 +125,7 @@ int Main(const int argc, const char **argv)
AotLog log(logMethods);
for (const auto &fileName : pandaFileNames) {
COMPILER_LOG(INFO) << "AOT start to execute ark file: " << fileName;
if (passManager.Compile(fileName, triple, outputFileName, log) == false) {
if (passManager.Compile(fileName, triple, outputFileName, log, optLevel) == false) {
ret = false;
break;
}

View File

@ -24,8 +24,10 @@
namespace panda::ecmascript::kungfu {
class AotFileManager {
public:
AotFileManager(LLVMModule *llvmModule, const CompilerLog *log, bool genFp = true) : llvmModule_(llvmModule),
assembler_(llvmModule->GetModule(), genFp), log_(log) {};
AotFileManager(LLVMModule *llvmModule, const CompilerLog *log,
LOptions option = LOptions()) : llvmModule_(llvmModule),
assembler_(llvmModule->GetModule(), option),
log_(log) {};
~AotFileManager() = default;
// save function funcs for aot files containing stubs
void SaveStubFile(const std::string &filename);

View File

@ -166,9 +166,9 @@ void LLVMAssembler::BuildAndRunPasses()
LLVMDisposePassManager(modPass1);
}
LLVMAssembler::LLVMAssembler(LLVMModuleRef module, bool genFp) : module_(module)
LLVMAssembler::LLVMAssembler(LLVMModuleRef module, LOptions option) : module_(module)
{
Initialize(genFp);
Initialize(option);
}
LLVMAssembler::~LLVMAssembler()
@ -204,7 +204,7 @@ void LLVMAssembler::Run()
LLVMPrintModuleToFile(module_, optName.c_str(), &error);
}
void LLVMAssembler::Initialize(bool genFp)
void LLVMAssembler::Initialize(LOptions option)
{
std::string triple(LLVMGetTarget(module_));
if (triple.compare("x86_64-unknown-linux-gnu") == 0) {
@ -234,9 +234,9 @@ void LLVMAssembler::Initialize(bool genFp)
}
llvm::linkAllBuiltinGCs();
LLVMInitializeMCJITCompilerOptions(&options_, sizeof(options_));
options_.OptLevel = 3; // opt level 3
options_.OptLevel = option.optLevel;
// NOTE: Just ensure that this field still exists for PIC option
options_.NoFramePointerElim = genFp;
options_.NoFramePointerElim = option.genFp;
options_.CodeModel = LLVMCodeModelSmall;
}

View File

@ -162,9 +162,16 @@ private:
size_t stackMapsSize_ {0};
};
struct LOptions {
uint32_t optLevel : 2; // 2 bit for optimized level 0-4
uint32_t genFp : 1; // 1 bit for whether to generated frame pointer or not
LOptions() : optLevel(3), genFp(1) {}; // 3: default optLevel, 1: generating fp
LOptions(size_t level, bool genFp) : optLevel(level), genFp(genFp) {};
};
class LLVMAssembler {
public:
explicit LLVMAssembler(LLVMModuleRef module, bool genFp = true);
explicit LLVMAssembler(LLVMModuleRef module, LOptions option = LOptions());
virtual ~LLVMAssembler();
void Run();
const LLVMExecutionEngineRef &GetEngine()
@ -206,7 +213,7 @@ private:
void UseRoundTripSectionMemoryManager();
bool BuildMCJITEngine();
void BuildAndRunPasses();
void Initialize(bool genFp);
void Initialize(LOptions option);
LLVMMCJITCompilerOptions options_ {};
LLVMModuleRef module_;

View File

@ -1,118 +0,0 @@
/*
* 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.
*/
// Autogenerated file -- DO NOT EDIT!
#ifndef PANDA_<%= Common::module.name.upcase %>_OPTIONS_GEN_H_
#define PANDA_<%= Common::module.name.upcase %>_OPTIONS_GEN_H_
#include "utils/pandargs.h"
#include <optional>
#include <string>
#include <unordered_set>
#include <vector>
namespace <%= Common::module.namespace %> {
class <%= Common::module.name %>_Options {
public:
class Error {
public:
explicit Error(std::string msg) : msg_(std::move(msg)) {}
std::string GetMessage() {
return msg_;
}
private:
std::string msg_;
};
explicit <%= Common::module.name %>_Options(const std::string &exe_path) : exe_dir_(GetExeDir(exe_path)) {}
void AddOptions(PandArgParser *parser) {
% Common::options.each do |op|
parser->Add(&<%= op.field_name %>);
% end
}
% Common::options.each do |op|
<%= op.type %> <%= op.getter_name %>() const {
return <%= op.field_name %>.GetValue();
}
void <%= op.setter_name %>(<%= op.type %> value) {
<%= op.field_name %>.SetValue(<%= op.type == 'std::string' || op.type == 'arg_list_t' ? 'std::move(value)' : 'value' %>);
}
bool WasSet<%= op.name.split(Regexp.union(['-','.'])).map(&:capitalize).join %>() const {
return <%= op.field_name %>.WasSet();
}
% end
// NOLINTNEXTLINE(readability-function-size)
std::optional<Error> Validate() const {
% Common::options.each do |op|
% next unless defined? op.possible_values
% is_string = op.type == 'std::string' || op.type == 'arg_list_t'
% possible_values = op.possible_values.map { |e| is_string ? Common::to_raw(e) : e }.join(', ')
{
std::unordered_set<<%= is_string ? "std::string" : op.type %>> possible_values{<%= possible_values %>};
% if op.type != 'arg_list_t'
std::vector<<%= op.type %>> values{<%= op.field_name %>.GetValue()};
% else
const auto &values = <%= op.field_name %>.GetValue();
% end
for (const auto &value : values) {
if (possible_values.find(value) == possible_values.cend()) {
return Error("argument --<%= op.name %>: invalid value: '" + <%= is_string ? "value" : "std::to_string(value)" %> + \
R"('. Possible values: <%= op.possible_values %>)");
}
}
}
% end
return {};
}
private:
static std::string GetExeDir(const std::string &exe_path) {
auto pos = exe_path.find_last_of('/');
return exe_path.substr(0, pos);
}
% Common::options.each do |op|
% next unless op.need_default_constant
static constexpr <%= op.type %> <%= op.default_constant_name %> = <%= op.default %>;
% end
std::string exe_dir_;
% Common::options.each do |op|
% if defined? op.delimiter
PandArg<<%= op.type %>> <%= op.field_name %>{"<%= op.name %>", <%= op.default_value %>, <%= op.full_description %>, "<%= op.delimiter %>"};
% elsif defined? op.range
% min, max = op.range.match('(\d+)\D*(\d+)').captures;
% if op.default.to_i > max.to_i || op.default.to_i < min.to_i
% abort "FAILED: Default value of argument " + op.name + " has out of range default parameter"
% end
PandArg<<%= op.type %>> <%= op.field_name %>{"<%= op.name %>", <%= op.default_value %>, <%= op.full_description %>, <%= min.to_i %>, <%= max.to_i %>};
% else
PandArg<<%= op.type %>> <%= op.field_name %>{"<%= op.name %>", <%= op.default_value %>, <%= op.full_description %>};
% end
% end
};
} // namespace <%= Common::module.namespace %>
#endif // PANDA_<%= Common::module.name.upcase %>_OPTIONS_GEN_H_

View File

@ -25,7 +25,7 @@
namespace panda::ecmascript::kungfu {
bool PassManager::Compile(const std::string &fileName, const std::string &triple,
const std::string &outputFileName, const AotLog &log)
const std::string &outputFileName, const AotLog &log, size_t optLevel)
{
BytecodeTranslationInfo translationInfo;
[[maybe_unused]] EcmaHandleScope handleScope(vm_->GetJSThread());
@ -61,7 +61,7 @@ bool PassManager::Compile(const std::string &fileName, const std::string &triple
pipeline.RunPass<LLVMIRGenPass>(&aotModule, method);
}
AotFileManager manager(&aotModule, &log);
AotFileManager manager(&aotModule, &log, LOptions(optLevel, true));
manager.SaveAOTFile(outputFileName);
TSLoader *tsLoader = vm_->GetTSLoader();
SnapShot snapShot(vm_);

View File

@ -28,7 +28,7 @@ public:
bool CollectInfoOfPandaFile(const std::string &filename, std::string_view entryPoint,
BytecodeTranslationInfo *translateInfo);
bool Compile(const std::string &fileName, const std::string &triple, const std::string &outputFileName,
const AotLog &log);
const AotLog &log, size_t optLevel);
private:
EcmaVM* vm_;

View File

@ -1,45 +0,0 @@
# 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.
module:
name: Stub_Aot
namespace: panda
options:
- name: com-stub-out
type: std::string
default: com_stub.m
description: name of stub compiler output file, which includes common stubs
- name: bc-stub-out
type: std::string
default: bc_stub.m
description: name of stub compiler output file, which includes bytecode handler stubs
- name: target-triple
type: std::string
default: x86_64-unknown-linux-gnu
possible_values:
- x86_64-unknown-linux-gnu
- arm-unknown-linux-gnu
- aarch64-unknown-linux-gnu
description: stub aot compiler target triple
- name: compiled-stubs
type: std::string
default: All
description: generated assembly for stubs in the list
# e.g:
# using default value: xxx/ark_stub_compiler ..
# specify single stub: xxx/ark_stub_compiler --compiled-stubs=FastAdd
# specify multiple stubs: xxx/ark_stub_compiler --compiled-stubs=FastAddFastSubFastMulFastDiv

View File

@ -27,7 +27,6 @@
#include "ecmascript/napi/include/jsnapi.h"
#include "interpreter_stub-inl.h"
#include "generated/base_options.h"
#include "generated/stub_aot_options_gen.h"
#include "libpandabase/utils/pandargs.h"
#include "libpandabase/utils/span.h"
#include "llvm_codegen.h"
@ -124,7 +123,7 @@ void StubCompiler::RunPipeline(LLVMModule &module)
}
bool StubCompiler::BuildStubModuleAndSave(const std::string &triple, const std::string &commonStubFile,
const std::string &bcHandlerStubFile)
const std::string &bcHandlerStubFile, size_t optLevel)
{
BytecodeStubCSigns::Initialize();
CommonStubCSigns::Initialize();
@ -136,7 +135,7 @@ bool StubCompiler::BuildStubModuleAndSave(const std::string &triple, const std::
LLVMModule commonStubModule("com_stub", triple);
commonStubModule.SetUpForCommonStubs();
RunPipeline(commonStubModule);
AotFileManager manager(&commonStubModule, log);
AotFileManager manager(&commonStubModule, log, LOptions(optLevel, true));
manager.SaveStubFile(commonStubFile);
res++;
}
@ -146,7 +145,7 @@ bool StubCompiler::BuildStubModuleAndSave(const std::string &triple, const std::
LLVMModule bcHandlerStubModule("bc_stub", triple);
bcHandlerStubModule.SetUpForBytecodeHandlerStubs();
RunPipeline(bcHandlerStubModule);
AotFileManager manager(&bcHandlerStubModule, log, false);
AotFileManager manager(&bcHandlerStubModule, log, LOptions(optLevel, false));
manager.SaveStubFile(bcHandlerStubFile);
res++;
}
@ -157,14 +156,12 @@ bool StubCompiler::BuildStubModuleAndSave(const std::string &triple, const std::
int main(const int argc, const char **argv)
{
panda::Span<const char *> sp(argv, argc);
panda::Stub_Aot_Options stubOptions(sp[0]);
panda::ecmascript::JSRuntimeOptions runtimeOptions;
panda::base_options::Options baseOptions(sp[0]);
panda::PandArg<bool> help("help", false, "Print this message and exit");
panda::PandArg<bool> options("options", false, "Print compiler options");
panda::PandArg<bool> options("options", false, "Print options");
panda::PandArgParser paParser;
stubOptions.AddOptions(&paParser);
runtimeOptions.AddOptions(&paParser);
baseOptions.AddOptions(&paParser);
@ -186,21 +183,21 @@ int main(const int argc, const char **argv)
panda::Logger::ResetComponentMask(); // disable all Component
panda::Logger::EnableComponent(panda::Logger::Component::ECMASCRIPT); // enable ECMASCRIPT
std::string tripleString = stubOptions.GetTargetTriple();
std::string commonStubFile = stubOptions.WasSetComStubOut() ? stubOptions.GetComStubOut() : "";
std::string bcHandlerFile = stubOptions.WasSetBcStubOut() ? stubOptions.GetBcStubOut() : "";
std::string compiledStubList = stubOptions.GetCompiledStubs();
panda::ecmascript::EcmaVM *vm = panda::JSNApi::CreateEcmaVM(runtimeOptions);
if (vm == nullptr) {
COMPILER_LOG(INFO) << "Cann't Create EcmaVM";
return -1;
}
std::string tripleString = runtimeOptions.GetTargetTriple();
std::string commonStubFile = runtimeOptions.WasComStubFileSet() ? runtimeOptions.GetComStubFile() : "";
std::string bcHandlerFile = runtimeOptions.WasBcStubFileSet() ? runtimeOptions.GetBcStubFile() : "";
std::string logMethods = vm->GetJSOptions().GetlogCompiledMethods();
size_t optLevel = runtimeOptions.GetOptLevel();
panda::ecmascript::kungfu::CompilerLog log(logMethods);
panda::ecmascript::kungfu::StubCompiler compiler(&log);
bool res = compiler.BuildStubModuleAndSave(tripleString, commonStubFile, bcHandlerFile);
bool res = compiler.BuildStubModuleAndSave(tripleString, commonStubFile, bcHandlerFile, optLevel);
COMPILER_LOG(INFO) << "stub compiler run finish, result condition(T/F):" << std::boolalpha << res;
panda::JSNApi::DestroyJSVM(vm);
return 0;
}

View File

@ -30,7 +30,7 @@ public:
~StubCompiler() = default;
bool BuildStubModuleAndSave(const std::string &triple, const std::string &commonStubFile,
const std::string &bcHandlerStubFile);
const std::string &bcHandlerStubFile, size_t optLevel);
const CompilerLog *GetLog() const
{

View File

@ -157,6 +157,9 @@ bool EcmaVM::Initialize()
tsLoader_ = new TSLoader(this);
snapshotEnv_ = new SnapShotEnv(this);
aotInfo_ = new AotCodeInfo();
if (options_.IsEnableStubAot()) {
LoadStubs();
}
if (options_.EnableTSAot()) {
TryLoadSnapshotFile();
std::string file = options_.GetAOTOutputFile();
@ -166,9 +169,6 @@ bool EcmaVM::Initialize()
JSHandle<GlobalEnv> globalEnv = factory_->NewGlobalEnv(*globalEnvClass);
globalEnv->Init(thread_);
globalEnv_ = globalEnv.GetTaggedValue();
if (options_.IsEnableStubAot()) {
LoadStubs();
}
SetupRegExpResultCache();
microJobQueue_ = factory_->NewMicroJobQueue().GetTaggedValue();
Builtins builtins;

View File

@ -58,7 +58,8 @@ public:
parser->Add(&maxNonmovableSpaceCapacity_);
parser->Add(&asmInter_);
parser->Add(&aotOutputFile_);
parser->Add(&aotTargetTriple_);
parser->Add(&targetTriple_);
parser->Add(&asmOptLevel_);
parser->Add(&logCompiledMethods);
parser->Add(&internal_memory_size_limit_);
parser->Add(&heap_size_limit_);
@ -115,7 +116,7 @@ public:
comStubFile_.SetValue(std::move(value));
}
bool WasSetComStubFile() const
bool WasComStubFileSet() const
{
return comStubFile_.WasSet();
}
@ -130,7 +131,7 @@ public:
bcStubFile_.SetValue(std::move(value));
}
bool WasBcComStubFile() const
bool WasBcStubFileSet() const
{
return bcStubFile_.WasSet();
}
@ -145,14 +146,24 @@ public:
aotOutputFile_.SetValue(std::move(value));
}
std::string GetAotTargetTriple() const
std::string GetTargetTriple() const
{
return aotTargetTriple_.GetValue();
return targetTriple_.GetValue();
}
void SetAotTargetTriple(std::string value)
void SetTargetTriple(std::string value)
{
aotTargetTriple_.SetValue(std::move(value));
targetTriple_.SetValue(std::move(value));
}
size_t GetOptLevel() const
{
return asmOptLevel_.GetValue();
}
void SetOptLevel(size_t value)
{
asmOptLevel_.SetValue(value);
}
bool IsEnableForceGC() const
@ -535,11 +546,13 @@ private:
PandArg<bool> enableArkTools_ {"enable-ark-tools", false, R"(Enable ark tools to debug. Default: false)"};
PandArg<bool> enableCpuprofiler_ {"enable-cpuprofiler", false,
R"(Enable cpuprofiler to sample call stack and output to json file. Default: false)"};
PandArg<bool> enableStubAot_ {"enable-stub-aot", false, R"(enable aot of fast stub. Default: false)"};
PandArg<std::string> comStubFile_ {"com-stub-file",
PandArg<bool> enableStubAot_ {"enable-stub-aot", false,
R"(enable aot of common stub and bc handler stub. Default: false)"};
PandArg<bool> enableTSAot_ {"enable-ts-aot", false, R"(enable aot. Default: false)"};
PandArg<std::string> comStubFile_ {"com-stub-out",
R"(com_stub.m)",
R"(Path of file includes common stubs module compiled by stub compiler. Default: "com_stub.m")"};
PandArg<std::string> bcStubFile_ {"bc-stub-file",
PandArg<std::string> bcStubFile_ {"bc-stub-out",
R"(bc_stub.m)",
R"(Path of file includes bytecode handler stubs module compiled by stub compiler. Default: "bc_stub.m")"};
PandArg<bool> enableForceGc_ {"enable-force-gc", true, R"(enable force gc when allocating object)"};
@ -547,14 +560,15 @@ private:
true,
R"(if true trigger full gc, else trigger semi and old gc)"};
PandArg<int> arkProperties_ {"ark-properties", GetDefaultProperties(), R"(set ark properties)"};
PandArg<bool> enableTSAot_ {"enable-ts-aot", false, R"(enable aot of fast stub. Default: false)"};
PandArg<std::string> aotOutputFile_ {"aot-output-file",
R"(aot_output_file.m)",
R"(Path to AOT output file. Default: "aot_output_file.m")"};
PandArg<std::string> aotTargetTriple_ {"aot-target-triple", R"(x86_64-unknown-linux-gnu)",
R"(stub aot compiler target triple.
PandArg<std::string> targetTriple_ {"target-triple", R"(x86_64-unknown-linux-gnu)",
R"(target triple for aot compiler or stub compiler.
Possible values: ["x86_64-unknown-linux-gnu", "arm-unknown-linux-gnu", "aarch64-unknown-linux-gnu"].
Default: "x86_64-unknown-linux-gnu")"};
PandArg<size_t> asmOptLevel_ {"opt-level", 3,
R"(Optimization level configuration on llvm back end. Default: "3")"};
PandArg<size_t> totalSpaceCapacity_ {"totalSpaceCapacity",
512 * 1024 * 1024,
R"(set total space capacity)"};
@ -612,4 +626,4 @@ private:
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_JS_RUNTIME_OPTIONS_H_
#endif // ECMASCRIPT_JS_RUNTIME_OPTIONS_H_

View File

@ -278,7 +278,7 @@ void JSThread::LoadStubsFromFile(std::string &fileName)
bool enableCompilerLog = GetEcmaVM()->GetJSOptions().WasSetlogCompiledMethods();
kungfu::LLVMStackMapParser::GetInstance(enableCompilerLog).Print();
#endif
stubCode_ = aotInfo.GetCode();
stubCode_ = aotInfo.GetCode().GetTaggedValue();
}
void JSThread::CheckSwitchDebuggerBCStub()

View File

@ -21,6 +21,9 @@
namespace panda::ecmascript {
void AotCodeInfo::SerializeForStub(const std::string &filename)
{
if (!VerifyFilePath(filename, true)) {
return;
}
std::ofstream modulefile(filename.c_str(), std::ofstream::binary);
SetStubNum(stubEntries_.size());
/* write stub entries offset */
@ -43,7 +46,7 @@ bool AotCodeInfo::DeserializeForStub(JSThread *thread, const std::string &filena
// by calling NewMachineCodeObject.
// then MachineCode will support movable, code is saved to MachineCode and stackmap is saved
// to different heap which will be freed when stackmap is parsed by EcmaVM is started.
if (!VerifyFilePath(filename.c_str())) {
if (!VerifyFilePath(filename)) {
return false;
}
std::ifstream modulefile(filename.c_str(), std::ofstream::binary);
@ -61,7 +64,7 @@ bool AotCodeInfo::DeserializeForStub(JSThread *thread, const std::string &filena
auto factory = thread->GetEcmaVM()->GetFactory();
auto codeHandle = factory->NewMachineCodeObject(codeSize, nullptr);
modulefile.read(reinterpret_cast<char *>(codeHandle->GetDataOffsetAddress()), codeSize);
SetCode(*codeHandle);
SetCode(codeHandle);
SetDeviceCodeSectionAddr(codeHandle->GetDataOffsetAddress());
/* read stackmap */
uint32_t stackmapSize;
@ -83,6 +86,9 @@ bool AotCodeInfo::DeserializeForStub(JSThread *thread, const std::string &filena
void AotCodeInfo::Serialize(const std::string &filename)
{
if (!VerifyFilePath(filename, true)) {
return;
}
std::ofstream moduleFile(filename.c_str(), std::ofstream::binary);
uint32_t funcNum = aotFuncEntryOffsets_.size();
moduleFile.write(reinterpret_cast<char *>(&funcNum), sizeof(funcNum));
@ -108,7 +114,7 @@ void AotCodeInfo::Serialize(const std::string &filename)
bool AotCodeInfo::Deserialize(EcmaVM *vm, const std::string &filename)
{
if (!VerifyFilePath(filename.c_str())) {
if (!VerifyFilePath(filename)) {
return false;
}
std::ifstream moduleFile(filename.c_str(), std::ofstream::binary);
@ -134,10 +140,11 @@ bool AotCodeInfo::Deserialize(EcmaVM *vm, const std::string &filename)
moduleFile.read(reinterpret_cast<char *>(&hostCodeSectionAddr_), sizeof(hostCodeSectionAddr_));
uint32_t codeSize = 0;
moduleFile.read(reinterpret_cast<char *>(&codeSize), sizeof(codeSize));
[[maybe_unused]] EcmaHandleScope handleScope(vm->GetAssociatedJSThread());
auto factory = vm->GetFactory();
auto codeHandle = factory->NewMachineCodeObject(codeSize, nullptr);
moduleFile.read(reinterpret_cast<char *>(codeHandle->GetDataOffsetAddress()), codeSize);
SetCode(*codeHandle);
SetCode(codeHandle);
SetDeviceCodeSectionAddr(codeHandle->GetDataOffsetAddress());
/* read stackmap */
int stackmapSize;
@ -162,15 +169,19 @@ void AotCodeInfo::Iterate(const RootVisitor &v)
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&code_)));
}
bool AotCodeInfo::VerifyFilePath([[maybe_unused]] const CString &filePath) const
bool AotCodeInfo::VerifyFilePath([[maybe_unused]] const std::string &filePath,
[[maybe_unused]] bool toGenerate) const
{
#ifndef PANDA_TARGET_WINDOWS
if (filePath.size() > PATH_MAX) {
return false;
}
CVector<char> resolvedPath(PATH_MAX);
std::vector<char> resolvedPath(PATH_MAX);
auto result = realpath(filePath.c_str(), resolvedPath.data());
if (toGenerate && errno == ENOENT) {
return true;
}
if (result == nullptr) {
return false;
}

View File

@ -16,6 +16,7 @@
#define PANDA_RUNTIME_ECMASCRIPT_MEM_MACHINE_CODE_H
#include "ecmascript/ecma_macros.h"
#include "ecmascript/js_handle.h"
#include "ecmascript/js_tagged_value.h"
#include "ecmascript/js_thread.h"
#include "ecmascript/mem/tagged_object.h"
@ -85,7 +86,8 @@ public:
void Serialize(const std::string &filename);
bool DeserializeForStub(JSThread *thread, const std::string &filename);
bool Deserialize(EcmaVM *vm, const std::string &filename);
bool VerifyFilePath(const CString &filePath) const;
bool VerifyFilePath([[maybe_unused]] const std::string &filePath,
[[maybe_unused]] bool toGenerate = false) const;
struct StubDes {
uint64_t codeAddr_;
@ -126,14 +128,14 @@ public:
void Iterate(const RootVisitor &v);
void SetCode(MachineCode *code)
void SetCode(JSHandle<MachineCode> code)
{
code_ = JSTaggedValue(code);
code_ = code.GetTaggedValue();
}
JSTaggedValue GetCode()
JSHandle<MachineCode> GetCode()
{
return code_;
return JSHandle<MachineCode>(reinterpret_cast<uintptr_t>(&code_));
}
void SetCodePtr(uintptr_t codePtr)