!1970 Decouple the method of collecting MethodPc in the Compiler from the PandaFileTranslator class

Merge pull request !1970 from weng-xi/dev_remove_translator
This commit is contained in:
openharmony_ci 2022-08-05 07:14:47 +00:00 committed by Gitee
commit 50f5ed60a1
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
8 changed files with 569 additions and 126 deletions

View File

@ -52,6 +52,7 @@ source_set("libark_jsoptimizer_set") {
"builtins/builtins_call_signature.cpp",
"builtins/builtins_stubs.cpp",
"bytecode_circuit_builder.cpp",
"bytecode_info_collector.cpp",
"call_signature.cpp",
"circuit.cpp",
"circuit_builder.cpp",

View File

@ -22,35 +22,16 @@
namespace panda::ecmascript::kungfu {
void BytecodeCircuitBuilder::BytecodeToCircuit()
{
auto curPc = pcArray_.front();
auto prePc = curPc;
std::map<uint8_t *, uint8_t *> byteCodeCurPrePc;
std::vector<CfgInfo> bytecodeBlockInfos;
int32_t offsetIndex = 1;
auto startPc = curPc;
bytecodeBlockInfos.emplace_back(startPc, SplitKind::START, std::vector<uint8_t *>(1, startPc));
byteCodeCurPrePc[curPc] = prePc;
pcToBCOffset_[curPc]=offsetIndex++;
for (size_t i = 1; i < pcArray_.size() - 1; i++) {
curPc = pcArray_[i];
byteCodeCurPrePc[curPc] = prePc;
pcToBCOffset_[curPc]=offsetIndex++;
prePc = curPc;
CollectBytecodeBlockInfo(curPc, bytecodeBlockInfos);
}
// handle empty
uint8_t *emptyPc = pcArray_.back();
byteCodeCurPrePc[emptyPc] = prePc;
pcToBCOffset_[emptyPc] = offsetIndex++;
std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> exceptionInfo;
// collect try catch block info
auto exceptionInfo = CollectTryCatchBlockInfo(byteCodeCurPrePc, bytecodeBlockInfos);
CollectTryCatchBlockInfo(exceptionInfo);
// Complete bytecode block Information
CompleteBytecodeBlockInfo(byteCodeCurPrePc, bytecodeBlockInfos);
CompleteBytecodeBlockInfo();
// Building the basic block diagram of bytecode
BuildBasicBlocks(exceptionInfo, bytecodeBlockInfos, byteCodeCurPrePc);
BuildBasicBlocks(exceptionInfo);
}
void BytecodeCircuitBuilder::CollectBytecodeBlockInfo(uint8_t *pc, std::vector<CfgInfo> &bytecodeBlockInfos)
@ -152,14 +133,14 @@ void BytecodeCircuitBuilder::CollectBytecodeBlockInfo(uint8_t *pc, std::vector<C
}
}
std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> BytecodeCircuitBuilder::CollectTryCatchBlockInfo(
std::map<uint8_t *, uint8_t*> &byteCodeCurPrePc, std::vector<CfgInfo> &bytecodeBlockInfos)
void BytecodeCircuitBuilder::CollectTryCatchBlockInfo(std::map<std::pair<uint8_t *, uint8_t *>,
std::vector<uint8_t *>> &byteCodeException)
{
// try contains many catch
std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> byteCodeException;
panda_file::MethodDataAccessor mda(*pf_, method_->GetMethodId());
panda_file::CodeDataAccessor cda(*pf_, mda.GetCodeId().value());
cda.EnumerateTryBlocks([this, &byteCodeCurPrePc, &bytecodeBlockInfos, &byteCodeException](
cda.EnumerateTryBlocks([this, &byteCodeException](
panda_file::CodeDataAccessor::TryBlock &try_block) {
auto tryStartOffset = try_block.GetStartPc();
auto tryEndOffset = try_block.GetStartPc() + try_block.GetLength();
@ -177,32 +158,32 @@ std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> BytecodeCircui
// Check whether the previous block of the try block exists.
// If yes, add the current block; otherwise, create a new block.
bool flag = false;
for (size_t i = 0; i < bytecodeBlockInfos.size(); i++) {
if (bytecodeBlockInfos[i].splitKind == SplitKind::START) {
for (size_t i = 0; i < bytecodeBlockInfos_.size(); i++) {
if (bytecodeBlockInfos_[i].splitKind == SplitKind::START) {
continue;
}
if (bytecodeBlockInfos[i].pc == byteCodeCurPrePc[tryStartPc]) {
if (bytecodeBlockInfos_[i].pc == byteCodeCurPrePc_.at(tryStartPc)) {
flag = true;
break;
}
}
if (!flag) {
// pre block
bytecodeBlockInfos.emplace_back(byteCodeCurPrePc[tryStartPc], SplitKind::END,
std::vector<uint8_t *>(1, tryStartPc));
bytecodeBlockInfos_.emplace_back(byteCodeCurPrePc_.at(tryStartPc), SplitKind::END,
std::vector<uint8_t *>(1, tryStartPc));
}
// try block
bytecodeBlockInfos.emplace_back(tryStartPc, SplitKind::START, std::vector<uint8_t *>(1, tryStartPc));
bytecodeBlockInfos_.emplace_back(tryStartPc, SplitKind::START, std::vector<uint8_t *>(1, tryStartPc));
flag = false;
for (size_t i = 0; i < bytecodeBlockInfos.size(); i++) {
if (bytecodeBlockInfos[i].splitKind == SplitKind::START) {
for (size_t i = 0; i < bytecodeBlockInfos_.size(); i++) {
if (bytecodeBlockInfos_[i].splitKind == SplitKind::START) {
continue;
}
if (bytecodeBlockInfos[i].pc == byteCodeCurPrePc[tryEndPc]) {
auto &succs = bytecodeBlockInfos[i].succs;
auto iter = std::find(succs.cbegin(), succs.cend(), bytecodeBlockInfos[i].pc);
if (bytecodeBlockInfos_[i].pc == byteCodeCurPrePc_.at(tryEndPc)) {
auto &succs = bytecodeBlockInfos_[i].succs;
auto iter = std::find(succs.cbegin(), succs.cend(), bytecodeBlockInfos_[i].pc);
if (iter == succs.cend()) {
auto opcode = static_cast<EcmaOpcode>(*(bytecodeBlockInfos[i].pc));
auto opcode = static_cast<EcmaOpcode>(*(bytecodeBlockInfos_[i].pc));
switch (opcode) {
case EcmaOpcode::JMP_IMM8:
case EcmaOpcode::JMP_IMM16:
@ -227,47 +208,45 @@ std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> BytecodeCircui
}
}
if (!flag) {
bytecodeBlockInfos.emplace_back(byteCodeCurPrePc[tryEndPc], SplitKind::END,
std::vector<uint8_t *>(1, tryEndPc));
bytecodeBlockInfos_.emplace_back(byteCodeCurPrePc_.at(tryEndPc), SplitKind::END,
std::vector<uint8_t *>(1, tryEndPc));
}
bytecodeBlockInfos.emplace_back(tryEndPc, SplitKind::START, std::vector<uint8_t *>(1, tryEndPc)); // next block
bytecodeBlockInfos_.emplace_back(tryEndPc, SplitKind::START, std::vector<uint8_t *>(1, tryEndPc)); // next block
return true;
});
return byteCodeException;
}
void BytecodeCircuitBuilder::CompleteBytecodeBlockInfo(std::map<uint8_t *, uint8_t *> &byteCodeCurPrePc,
std::vector<CfgInfo> &bytecodeBlockInfos)
void BytecodeCircuitBuilder::CompleteBytecodeBlockInfo()
{
std::sort(bytecodeBlockInfos.begin(), bytecodeBlockInfos.end());
std::sort(bytecodeBlockInfos_.begin(), bytecodeBlockInfos_.end());
if (IsLogEnabled()) {
PrintCollectBlockInfo(bytecodeBlockInfos);
PrintCollectBlockInfo(bytecodeBlockInfos_);
}
// Deduplicate
auto deduplicateIndex = std::unique(bytecodeBlockInfos.begin(), bytecodeBlockInfos.end());
bytecodeBlockInfos.erase(deduplicateIndex, bytecodeBlockInfos.end());
auto deduplicateIndex = std::unique(bytecodeBlockInfos_.begin(), bytecodeBlockInfos_.end());
bytecodeBlockInfos_.erase(deduplicateIndex, bytecodeBlockInfos_.end());
// Supplementary block information
std::vector<uint8_t *> endBlockPc;
std::vector<uint8_t *> startBlockPc;
for (size_t i = 0; i < bytecodeBlockInfos.size() - 1; i++) {
if (bytecodeBlockInfos[i].splitKind == bytecodeBlockInfos[i + 1].splitKind &&
bytecodeBlockInfos[i].splitKind == SplitKind::START) {
auto prePc = byteCodeCurPrePc[bytecodeBlockInfos[i + 1].pc];
for (size_t i = 0; i < bytecodeBlockInfos_.size() - 1; i++) {
if (bytecodeBlockInfos_[i].splitKind == bytecodeBlockInfos_[i + 1].splitKind &&
bytecodeBlockInfos_[i].splitKind == SplitKind::START) {
auto prePc = byteCodeCurPrePc_.at(bytecodeBlockInfos_[i + 1].pc);
endBlockPc.emplace_back(prePc); // Previous instruction of current instruction
endBlockPc.emplace_back(bytecodeBlockInfos[i + 1].pc); // current instruction
endBlockPc.emplace_back(bytecodeBlockInfos_[i + 1].pc); // current instruction
continue;
}
if (bytecodeBlockInfos[i].splitKind == bytecodeBlockInfos[i + 1].splitKind &&
bytecodeBlockInfos[i].splitKind == SplitKind::END) {
auto tempPc = bytecodeBlockInfos[i].pc;
auto findItem = std::find_if(byteCodeCurPrePc.cbegin(), byteCodeCurPrePc.cend(),
if (bytecodeBlockInfos_[i].splitKind == bytecodeBlockInfos_[i + 1].splitKind &&
bytecodeBlockInfos_[i].splitKind == SplitKind::END) {
auto tempPc = bytecodeBlockInfos_[i].pc;
auto findItem = std::find_if(byteCodeCurPrePc_.cbegin(), byteCodeCurPrePc_.cend(),
[tempPc](const std::map<uint8_t *, uint8_t *>::value_type item) {
return item.second == tempPc;
});
if (findItem != byteCodeCurPrePc.cend()) {
if (findItem != byteCodeCurPrePc_.cend()) {
startBlockPc.emplace_back((*findItem).first);
}
}
@ -275,54 +254,52 @@ void BytecodeCircuitBuilder::CompleteBytecodeBlockInfo(std::map<uint8_t *, uint8
// Supplementary end block info
for (auto iter = endBlockPc.cbegin(); iter != endBlockPc.cend(); iter += 2) { // 2: index
bytecodeBlockInfos.emplace_back(*iter, SplitKind::END,
bytecodeBlockInfos_.emplace_back(*iter, SplitKind::END,
std::vector<uint8_t *>(1, *(iter + 1)));
}
// Supplementary start block info
for (auto iter = startBlockPc.cbegin(); iter != startBlockPc.cend(); iter++) {
bytecodeBlockInfos.emplace_back(*iter, SplitKind::START, std::vector<uint8_t *>(1, *iter));
bytecodeBlockInfos_.emplace_back(*iter, SplitKind::START, std::vector<uint8_t *>(1, *iter));
}
// Deduplicate successor
for (size_t i = 0; i < bytecodeBlockInfos.size(); i++) {
if (bytecodeBlockInfos[i].splitKind == SplitKind::END) {
std::set<uint8_t *> tempSet(bytecodeBlockInfos[i].succs.cbegin(),
bytecodeBlockInfos[i].succs.cend());
bytecodeBlockInfos[i].succs.assign(tempSet.cbegin(), tempSet.cend());
for (size_t i = 0; i < bytecodeBlockInfos_.size(); i++) {
if (bytecodeBlockInfos_[i].splitKind == SplitKind::END) {
std::set<uint8_t *> tempSet(bytecodeBlockInfos_[i].succs.cbegin(),
bytecodeBlockInfos_[i].succs.cend());
bytecodeBlockInfos_[i].succs.assign(tempSet.cbegin(), tempSet.cend());
}
}
std::sort(bytecodeBlockInfos.begin(), bytecodeBlockInfos.end());
std::sort(bytecodeBlockInfos_.begin(), bytecodeBlockInfos_.end());
// handling jumps to an empty block
auto endPc = bytecodeBlockInfos[bytecodeBlockInfos.size() - 1].pc;
auto iter = --byteCodeCurPrePc.cend();
auto endPc = bytecodeBlockInfos_[bytecodeBlockInfos_.size() - 1].pc;
auto iter = --byteCodeCurPrePc_.cend();
if (endPc == iter->first) {
bytecodeBlockInfos.emplace_back(endPc, SplitKind::END, std::vector<uint8_t *>(1, endPc));
bytecodeBlockInfos_.emplace_back(endPc, SplitKind::END, std::vector<uint8_t *>(1, endPc));
}
// Deduplicate
deduplicateIndex = std::unique(bytecodeBlockInfos.begin(), bytecodeBlockInfos.end());
bytecodeBlockInfos.erase(deduplicateIndex, bytecodeBlockInfos.end());
deduplicateIndex = std::unique(bytecodeBlockInfos_.begin(), bytecodeBlockInfos_.end());
bytecodeBlockInfos_.erase(deduplicateIndex, bytecodeBlockInfos_.end());
if (IsLogEnabled()) {
PrintCollectBlockInfo(bytecodeBlockInfos);
PrintCollectBlockInfo(bytecodeBlockInfos_);
}
}
void BytecodeCircuitBuilder::BuildBasicBlocks(std::map<std::pair<uint8_t *, uint8_t *>,
std::vector<uint8_t *>> &exception,
std::vector<CfgInfo> &bytecodeBlockInfo,
[[maybe_unused]] std::map<uint8_t *, uint8_t *> &byteCodeCurPrePc)
std::vector<uint8_t *>> &exception)
{
std::map<uint8_t *, BytecodeRegion *> startPcToBB; // [start, bb]
std::map<uint8_t *, BytecodeRegion *> endPcToBB; // [end, bb]
graph_.resize(bytecodeBlockInfo.size() / 2); // 2 : half size
graph_.resize(bytecodeBlockInfos_.size() / 2); // 2 : half size
// build basic block
int blockId = 0;
int index = 0;
for (size_t i = 0; i < bytecodeBlockInfo.size() - 1; i += 2) { // 2:index
auto startPc = bytecodeBlockInfo[i].pc;
auto endPc = bytecodeBlockInfo[i + 1].pc;
for (size_t i = 0; i < bytecodeBlockInfos_.size() - 1; i += 2) { // 2:index
auto startPc = bytecodeBlockInfos_[i].pc;
auto endPc = bytecodeBlockInfos_[i + 1].pc;
auto block = &graph_[index++];
block->id = blockId++;
block->start = startPc;
@ -334,12 +311,12 @@ void BytecodeCircuitBuilder::BuildBasicBlocks(std::map<std::pair<uint8_t *, uint
}
// add block associate
for (size_t i = 0; i < bytecodeBlockInfo.size(); i++) {
if (bytecodeBlockInfo[i].splitKind == SplitKind::START) {
for (size_t i = 0; i < bytecodeBlockInfos_.size(); i++) {
if (bytecodeBlockInfos_[i].splitKind == SplitKind::START) {
continue;
}
auto curPc = bytecodeBlockInfo[i].pc;
auto &successors = bytecodeBlockInfo[i].succs;
auto curPc = bytecodeBlockInfos_[i].pc;
auto &successors = bytecodeBlockInfos_[i].succs;
for (size_t j = 0; j < successors.size(); j++) {
if (successors[j] == curPc) {
continue;
@ -2614,7 +2591,7 @@ void BytecodeCircuitBuilder::AddBytecodeOffsetInfo(GateRef &gate, const Bytecode
{
if (info.IsCall()) {
auto bcOffset = circuit_.NewGate(OpCode(OpCode::CONSTANT), MachineType::I64,
pcToBCOffset_[pc],
pcToBCOffset_.at(pc),
{Circuit::GetCircuitRoot(OpCode(OpCode::CONSTANT_LIST))},
GateType::NJSValue());
gateAcc_.NewIn(gate, bcOffsetIndex, bcOffset);

View File

@ -25,6 +25,7 @@
#include "ecmascript/compiler/argument_accessor.h"
#include "ecmascript/compiler/circuit.h"
#include "ecmascript/compiler/type_recorder.h"
#include "ecmascript/compiler/bytecode_info_collector.h"
#include "ecmascript/interpreter/interpreter-inl.h"
#include "ecmascript/js_method.h"
#include "ecmascript/jspandafile/js_pandafile.h"
@ -443,21 +444,22 @@ enum BytecodeOffset {
class BytecodeCircuitBuilder {
public:
explicit BytecodeCircuitBuilder(const BytecodeTranslationInfo &translationInfo, size_t index,
explicit BytecodeCircuitBuilder(const JSPandaFile *jsPandaFile,
JSHandle<JSTaggedValue> &constantPool,
BytecodeInfoCollector::MethodPcInfo &methodPCInfo,
TSManager *tsManager, bool enableLog)
: tsManager_(tsManager), file_(translationInfo.jsPandaFile), pf_(translationInfo.jsPandaFile->GetPandaFile()),
method_(translationInfo.methodPcInfos[index].method),
pcArray_(translationInfo.methodPcInfos[index].pcArray),
constantPool_(translationInfo.constantPool),
gateAcc_(&circuit_), argAcc_(&circuit_, method_),
: tsManager_(tsManager), file_(jsPandaFile), pf_(jsPandaFile->GetPandaFile()),
method_(methodPCInfo.method), constantPool_(constantPool), gateAcc_(&circuit_), argAcc_(&circuit_, method_),
typeRecorder_(method_, tsManager), hasTypes_(file_->HasTSTypes()),
enableLog_(enableLog)
enableLog_(enableLog), pcToBCOffset_(methodPCInfo.pcToBCOffset),
byteCodeCurPrePc_(methodPCInfo.byteCodeCurPrePc), bytecodeBlockInfos_(methodPCInfo.bytecodeBlockInfos)
{
}
~BytecodeCircuitBuilder() = default;
NO_COPY_SEMANTIC(BytecodeCircuitBuilder);
NO_MOVE_SEMANTIC(BytecodeCircuitBuilder);
void PUBLIC_API BytecodeToCircuit();
static void PUBLIC_API CollectBytecodeBlockInfo(uint8_t *pc, std::vector<CfgInfo> &bytecodeBlockInfos);
[[nodiscard]] kungfu::Circuit* GetCircuit()
{
@ -534,17 +536,9 @@ public:
}
private:
void PUBLIC_API CollectBytecodeBlockInfo(uint8_t* pc, std::vector<CfgInfo> &bytecodeBlockInfos);
std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> CollectTryCatchBlockInfo(
std::map<uint8_t *, uint8_t*> &byteCodeCurPrePc, std::vector<CfgInfo> &bytecodeBlockInfos);
void CompleteBytecodeBlockInfo(std::map<uint8_t *, uint8_t*> &byteCodeCurPrePc,
std::vector<CfgInfo> &bytecodeBlockInfos);
void BuildBasicBlocks(std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> &exception,
std::vector<CfgInfo> &bytecodeBlockInfo,
std::map<uint8_t *, uint8_t*> &byteCodeCurPrePc);
void CollectTryCatchBlockInfo(std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> &Exception);
void CompleteBytecodeBlockInfo();
void BuildBasicBlocks(std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> &Exception);
void ComputeDominatorTree();
void BuildImmediateDominator(const std::vector<size_t> &immDom);
void ComputeDomFrontiers(const std::vector<size_t> &immDom);
@ -590,15 +584,16 @@ private:
const JSPandaFile *file_ {nullptr};
const panda_file::File *pf_ {nullptr};
const JSMethod *method_ {nullptr};
const std::vector<uint8_t *> pcArray_;
JSHandle<JSTaggedValue> constantPool_;
GateAccessor gateAcc_;
ArgumentAccessor argAcc_;
TypeRecorder typeRecorder_;
bool hasTypes_ {false};
bool enableLog_ {false};
std::map<const uint8_t *, int32_t> pcToBCOffset_;
std::vector<kungfu::GateRef> suspendAndResumeGates_ {};
const std::map<const uint8_t *, int32_t> &pcToBCOffset_;
const std::map<uint8_t *, uint8_t *> &byteCodeCurPrePc_;
std::vector<CfgInfo> &bytecodeBlockInfos_;
};
} // namespace panda::ecmascript::kungfu
#endif // ECMASCRIPT_CLASS_LINKER_BYTECODE_CIRCUIT_IR_BUILDER_H

View File

@ -0,0 +1,395 @@
/*
* Copyright (c) 2022 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.
*/
#include "ecmascript/compiler/bytecode_info_collector.h"
#include "ecmascript/jspandafile/js_pandafile_manager.h"
#include "ecmascript/compiler/bytecode_circuit_builder.h"
#include "libpandafile/class_data_accessor-inl.h"
namespace panda::ecmascript::kungfu {
const JSPandaFile *BytecodeInfoCollector::LoadInfoFromPf(const CString &filename, const std::string_view &entryPoint,
std::vector<MethodPcInfo>& methodPcInfos)
{
JSPandaFileManager *jsPandaFileManager = JSPandaFileManager::GetInstance();
JSPandaFile *jsPandaFile = jsPandaFileManager->OpenJSPandaFile(filename);
if (jsPandaFile == nullptr) {
LOG_ECMA(ERROR) << "open file " << filename << " error";
return nullptr;
}
CString methodName;
auto pos = entryPoint.find_last_of("::");
if (pos != std::string_view::npos) {
methodName = entryPoint.substr(pos + 1);
} else {
// default use func_main_0 as entryPoint
methodName = JSPandaFile::ENTRY_FUNCTION_NAME;
}
ProcessClasses(jsPandaFile, methodName, methodPcInfos);
return jsPandaFile;
}
void BytecodeInfoCollector::ProcessClasses(JSPandaFile *jsPandaFile, const CString &methodName,
std::vector<MethodPcInfo> &methodPcInfos)
{
ASSERT(jsPandaFile != nullptr && jsPandaFile->GetMethods() != nullptr);
JSMethod *methods = jsPandaFile->GetMethods();
const panda_file::File *pf = jsPandaFile->GetPandaFile();
size_t methodIdx = 0;
panda_file::File::StringData sd = {static_cast<uint32_t>(methodName.size()),
reinterpret_cast<const uint8_t *>(methodName.c_str())};
std::set<const uint8_t *> processedInsns;
Span<const uint32_t> classIndexes = jsPandaFile->GetClasses();
for (const uint32_t index : classIndexes) {
panda_file::File::EntityId classId(index);
if (pf->IsExternal(classId)) {
continue;
}
panda_file::ClassDataAccessor cda(*pf, classId);
cda.EnumerateMethods([methods, &methodIdx, pf, &processedInsns, jsPandaFile, &methodPcInfos, &sd]
(panda_file::MethodDataAccessor &mda) {
auto codeId = mda.GetCodeId();
ASSERT(codeId.has_value());
JSMethod *method = methods + (methodIdx++);
panda_file::CodeDataAccessor codeDataAccessor(*pf, codeId.value());
uint32_t codeSize = codeDataAccessor.GetCodeSize();
uint32_t mainMethodIndex = jsPandaFile->GetMainMethodIndex();
if (mainMethodIndex == 0 && pf->GetStringData(mda.GetNameId()) == sd) {
jsPandaFile->UpdateMainMethodIndex(mda.GetMethodId().GetOffset());
}
new (method) JSMethod(jsPandaFile, mda.GetMethodId());
method->SetHotnessCounter(EcmaInterpreter::METHOD_HOTNESS_THRESHOLD);
method->InitializeCallField(codeDataAccessor.GetNumVregs(), codeDataAccessor.GetNumArgs());
const uint8_t *insns = codeDataAccessor.GetInstructions();
if (processedInsns.find(insns) == processedInsns.end()) {
processedInsns.insert(insns);
CollectMethodPcs(jsPandaFile, codeSize, insns, method, methodPcInfos);
}
jsPandaFile->SetMethodToMap(method);
});
}
}
void BytecodeInfoCollector::FixOpcode(uint8_t *pc)
{
auto opcode = static_cast<BytecodeInstruction::Opcode>(*pc);
switch (opcode) {
case BytecodeInstruction::Opcode::MOV_V4_V4:
*pc = static_cast<uint8_t>(EcmaOpcode::MOV_V4_V4);
break;
case BytecodeInstruction::Opcode::MOV_DYN_V8_V8:
*pc = static_cast<uint8_t>(EcmaOpcode::MOV_DYN_V8_V8);
break;
case BytecodeInstruction::Opcode::MOV_DYN_V16_V16:
*pc = static_cast<uint8_t>(EcmaOpcode::MOV_DYN_V16_V16);
break;
case BytecodeInstruction::Opcode::LDA_STR_ID32:
*pc = static_cast<uint8_t>(EcmaOpcode::LDA_STR_ID32);
break;
case BytecodeInstruction::Opcode::JMP_IMM8:
*pc = static_cast<uint8_t>(EcmaOpcode::JMP_IMM8);
break;
case BytecodeInstruction::Opcode::JMP_IMM16:
*pc = static_cast<uint8_t>(EcmaOpcode::JMP_IMM16);
break;
case BytecodeInstruction::Opcode::JMP_IMM32:
*pc = static_cast<uint8_t>(EcmaOpcode::JMP_IMM32);
break;
case BytecodeInstruction::Opcode::JEQZ_IMM8:
*pc = static_cast<uint8_t>(EcmaOpcode::JEQZ_IMM8);
break;
case BytecodeInstruction::Opcode::JEQZ_IMM16:
*pc = static_cast<uint8_t>(EcmaOpcode::JEQZ_IMM16);
break;
case BytecodeInstruction::Opcode::JNEZ_IMM8:
*pc = static_cast<uint8_t>(EcmaOpcode::JNEZ_IMM8);
break;
case BytecodeInstruction::Opcode::JNEZ_IMM16:
*pc = static_cast<uint8_t>(EcmaOpcode::JNEZ_IMM16);
break;
case BytecodeInstruction::Opcode::LDA_DYN_V8:
*pc = static_cast<uint8_t>(EcmaOpcode::LDA_DYN_V8);
break;
case BytecodeInstruction::Opcode::STA_DYN_V8:
*pc = static_cast<uint8_t>(EcmaOpcode::STA_DYN_V8);
break;
case BytecodeInstruction::Opcode::LDAI_DYN_IMM32:
*pc = static_cast<uint8_t>(EcmaOpcode::LDAI_DYN_IMM32);
break;
case BytecodeInstruction::Opcode::FLDAI_DYN_IMM64:
*pc = static_cast<uint8_t>(EcmaOpcode::FLDAI_DYN_IMM64);
break;
case BytecodeInstruction::Opcode::RETURN_DYN:
*pc = static_cast<uint8_t>(EcmaOpcode::RETURN_DYN);
break;
default:
if (*pc != static_cast<uint8_t>(BytecodeInstruction::Opcode::ECMA_LDNAN_PREF_NONE)) {
LOG_FULL(FATAL) << "Is not an Ecma Opcode opcode: " << static_cast<uint16_t>(opcode);
UNREACHABLE();
}
*pc = *(pc + 1);
*(pc + 1) = 0xFF;
break;
}
}
void BytecodeInfoCollector::UpdateICOffset(JSMethod *method, uint8_t *pc)
{
uint8_t offset = JSMethod::MAX_SLOT_SIZE;
auto opcode = static_cast<EcmaOpcode>(*pc);
switch (opcode) {
case EcmaOpcode::TRYLDGLOBALBYNAME_PREF_ID32:
case EcmaOpcode::TRYSTGLOBALBYNAME_PREF_ID32:
case EcmaOpcode::LDGLOBALVAR_PREF_ID32:
case EcmaOpcode::STGLOBALVAR_PREF_ID32:
case EcmaOpcode::ADD2DYN_PREF_V8:
case EcmaOpcode::SUB2DYN_PREF_V8:
case EcmaOpcode::MUL2DYN_PREF_V8:
case EcmaOpcode::DIV2DYN_PREF_V8:
case EcmaOpcode::MOD2DYN_PREF_V8:
case EcmaOpcode::SHL2DYN_PREF_V8:
case EcmaOpcode::SHR2DYN_PREF_V8:
case EcmaOpcode::ASHR2DYN_PREF_V8:
case EcmaOpcode::AND2DYN_PREF_V8:
case EcmaOpcode::OR2DYN_PREF_V8:
case EcmaOpcode::XOR2DYN_PREF_V8:
case EcmaOpcode::EQDYN_PREF_V8:
case EcmaOpcode::NOTEQDYN_PREF_V8:
case EcmaOpcode::LESSDYN_PREF_V8:
case EcmaOpcode::LESSEQDYN_PREF_V8:
case EcmaOpcode::GREATERDYN_PREF_V8:
case EcmaOpcode::GREATEREQDYN_PREF_V8:
offset = method->UpdateSlotSize(1);
break;
case EcmaOpcode::LDOBJBYVALUE_PREF_V8_V8:
case EcmaOpcode::STOBJBYVALUE_PREF_V8_V8:
case EcmaOpcode::STOWNBYVALUE_PREF_V8_V8:
case EcmaOpcode::LDOBJBYNAME_PREF_ID32_V8:
case EcmaOpcode::STOBJBYNAME_PREF_ID32_V8:
case EcmaOpcode::STOWNBYNAME_PREF_ID32_V8:
case EcmaOpcode::LDOBJBYINDEX_PREF_V8_IMM32:
case EcmaOpcode::STOBJBYINDEX_PREF_V8_IMM32:
case EcmaOpcode::STOWNBYINDEX_PREF_V8_IMM32:
case EcmaOpcode::LDSUPERBYVALUE_PREF_V8_V8:
case EcmaOpcode::STSUPERBYVALUE_PREF_V8_V8:
case EcmaOpcode::LDSUPERBYNAME_PREF_ID32_V8:
case EcmaOpcode::STSUPERBYNAME_PREF_ID32_V8:
case EcmaOpcode::LDMODULEVAR_PREF_ID32_IMM8:
case EcmaOpcode::STMODULEVAR_PREF_ID32:
offset = method->UpdateSlotSize(2); // 2: occupy two ic slot
break;
default:
return;
}
*(pc + 1) = offset;
}
void BytecodeInfoCollector::FixInstructionId32(const BytecodeInstruction &inst, uint32_t index,
uint32_t fixOrder)
{
// NOLINTNEXTLINE(hicpp-use-auto)
auto pc = const_cast<uint8_t *>(inst.GetAddress());
switch (inst.GetFormat()) {
case BytecodeInstruction::Format::ID32: {
uint8_t size = sizeof(uint32_t);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
if (memcpy_s(pc + FixInsIndex::FIX_ONE, size, &index, size) != EOK) {
LOG_FULL(FATAL) << "memcpy_s failed";
UNREACHABLE();
}
break;
}
case BytecodeInstruction::Format::PREF_ID16_IMM16_V8: {
uint16_t u16Index = index;
uint8_t size = sizeof(uint16_t);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
if (memcpy_s(pc + FixInsIndex::FIX_TWO, size, &u16Index, size) != EOK) {
LOG_FULL(FATAL) << "memcpy_s failed";
UNREACHABLE();
}
break;
}
case BytecodeInstruction::Format::PREF_ID32:
case BytecodeInstruction::Format::PREF_ID32_V8:
case BytecodeInstruction::Format::PREF_ID32_IMM8: {
uint8_t size = sizeof(uint32_t);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
if (memcpy_s(pc + FixInsIndex::FIX_TWO, size, &index, size) != EOK) {
LOG_FULL(FATAL) << "memcpy_s failed";
UNREACHABLE();
}
break;
}
case BytecodeInstruction::Format::PREF_IMM16: {
ASSERT(static_cast<uint16_t>(index) == index);
uint16_t u16Index = index;
uint8_t size = sizeof(uint16_t);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
if (memcpy_s(pc + FixInsIndex::FIX_TWO, size, &u16Index, size) != EOK) {
LOG_FULL(FATAL) << "memcpy_s failed";
UNREACHABLE();
}
break;
}
case BytecodeInstruction::Format::PREF_ID16_IMM16_IMM16_V8_V8: {
// Usually, we fix one part of instruction one time. But as for instruction DefineClassWithBuffer,
// which use both method id and literal buffer id.Using fixOrder indicates fix Location.
if (fixOrder == 0) {
uint8_t size = sizeof(uint16_t);
ASSERT(static_cast<uint16_t>(index) == index);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
if (memcpy_s(pc + FixInsIndex::FIX_TWO, size, &index, size) != EOK) {
LOG_FULL(FATAL) << "memcpy_s failed";
UNREACHABLE();
}
break;
}
if (fixOrder == 1) {
ASSERT(static_cast<uint16_t>(index) == index);
uint16_t u16Index = index;
uint8_t size = sizeof(uint16_t);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
if (memcpy_s(pc + FixInsIndex::FIX_FOUR, size, &u16Index, size) != EOK) {
LOG_FULL(FATAL) << "memcpy_s failed";
UNREACHABLE();
}
break;
}
break;
}
default:
UNREACHABLE();
}
}
void BytecodeInfoCollector::TranslateBCIns(JSPandaFile *jsPandaFile, const panda::BytecodeInstruction &bcIns,
const JSMethod *method)
{
const panda_file::File *pf = jsPandaFile->GetPandaFile();
if (bcIns.HasFlag(BytecodeInstruction::Flags::STRING_ID) &&
BytecodeInstruction::HasId(bcIns.GetFormat(), 0)) {
auto index = jsPandaFile->GetOrInsertConstantPool(
ConstPoolType::STRING, bcIns.GetId().AsFileId().GetOffset());
FixInstructionId32(bcIns, index);
} else {
BytecodeInstruction::Opcode opcode = static_cast<BytecodeInstruction::Opcode>(bcIns.GetOpcode());
switch (opcode) {
uint32_t index;
uint32_t methodId;
case BytecodeInstruction::Opcode::ECMA_DEFINEFUNCDYN_PREF_ID16_IMM16_V8:
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId().AsIndex()).GetOffset();
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::BASE_FUNCTION, methodId);
FixInstructionId32(bcIns, index);
break;
case BytecodeInstruction::Opcode::ECMA_DEFINENCFUNCDYN_PREF_ID16_IMM16_V8:
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId().AsIndex()).GetOffset();
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::NC_FUNCTION, methodId);
FixInstructionId32(bcIns, index);
break;
case BytecodeInstruction::Opcode::ECMA_DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8:
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId().AsIndex()).GetOffset();
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::GENERATOR_FUNCTION, methodId);
FixInstructionId32(bcIns, index);
break;
case BytecodeInstruction::Opcode::ECMA_DEFINEASYNCFUNC_PREF_ID16_IMM16_V8:
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId().AsIndex()).GetOffset();
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::ASYNC_FUNCTION, methodId);
FixInstructionId32(bcIns, index);
break;
case BytecodeInstruction::Opcode::ECMA_DEFINEMETHOD_PREF_ID16_IMM16_V8:
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId().AsIndex()).GetOffset();
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::METHOD, methodId);
FixInstructionId32(bcIns, index);
break;
case BytecodeInstruction::Opcode::ECMA_CREATEOBJECTWITHBUFFER_PREF_IMM16:
case BytecodeInstruction::Opcode::ECMA_CREATEOBJECTHAVINGMETHOD_PREF_IMM16: {
auto imm = bcIns.GetImm<BytecodeInstruction::Format::PREF_IMM16>();
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::OBJECT_LITERAL,
static_cast<uint16_t>(imm));
FixInstructionId32(bcIns, index);
break;
}
case BytecodeInstruction::Opcode::ECMA_CREATEARRAYWITHBUFFER_PREF_IMM16: {
auto imm = bcIns.GetImm<BytecodeInstruction::Format::PREF_IMM16>();
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::ARRAY_LITERAL,
static_cast<uint16_t>(imm));
FixInstructionId32(bcIns, index);
break;
}
case BytecodeInstruction::Opcode::ECMA_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8: {
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId().AsIndex()).GetOffset();
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::CLASS_FUNCTION, methodId);
FixInstructionId32(bcIns, index);
auto imm = bcIns.GetImm<BytecodeInstruction::Format::PREF_ID16_IMM16_IMM16_V8_V8>();
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::CLASS_LITERAL,
static_cast<uint16_t>(imm));
FixInstructionId32(bcIns, index, 1);
break;
}
default:
break;
}
}
}
void BytecodeInfoCollector::CollectMethodPcs(JSPandaFile *jsPandaFile, const uint32_t insSz, const uint8_t *insArr,
const JSMethod *method, std::vector<MethodPcInfo> &methodPcInfos)
{
auto bcIns = BytecodeInstruction(insArr);
auto bcInsLast = bcIns.JumpTo(insSz);
methodPcInfos.emplace_back(MethodPcInfo { method, {}, {}, {} });
int32_t offsetIndex = 1;
uint8_t *curPc = nullptr;
uint8_t *prePc = nullptr;
while (bcIns.GetAddress() != bcInsLast.GetAddress()) {
TranslateBCIns(jsPandaFile, bcIns, method);
auto pc = const_cast<uint8_t *>(bcIns.GetAddress());
bcIns = bcIns.GetNext();
FixOpcode(pc);
UpdateICOffset(const_cast<JSMethod *>(method), pc);
auto &bytecodeBlockInfos = methodPcInfos.back().bytecodeBlockInfos;
auto &byteCodeCurPrePc = methodPcInfos.back().byteCodeCurPrePc;
auto &pcToBCOffset = methodPcInfos.back().pcToBCOffset;
if (offsetIndex == 1) {
curPc = prePc = pc;
bytecodeBlockInfos.emplace_back(curPc, SplitKind::START, std::vector<uint8_t *>(1, curPc));
byteCodeCurPrePc[curPc] = prePc;
pcToBCOffset[curPc] = offsetIndex++;
} else {
curPc = pc;
byteCodeCurPrePc[curPc] = prePc;
pcToBCOffset[curPc] = offsetIndex++;
prePc = curPc;
BytecodeCircuitBuilder::CollectBytecodeBlockInfo(curPc, bytecodeBlockInfos);
}
}
auto emptyPc = const_cast<uint8_t *>(bcInsLast.GetAddress());
methodPcInfos.back().byteCodeCurPrePc[emptyPc] = prePc;
methodPcInfos.back().pcToBCOffset[emptyPc] = offsetIndex++;
}
} // namespace panda::ecmascript::kungfu

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2022 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_COMPILER_BYTECODE_INFO_COLLECTOR_H
#define ECMASCRIPT_COMPILER_BYTECODE_INFO_COLLECTOR_H
#include "ecmascript/ecma_vm.h"
#include "libpandafile/bytecode_instruction-inl.h"
namespace panda::ecmascript::kungfu {
struct CfgInfo;
class BytecodeInfoCollector {
public:
// need to remove in the future
enum FixInsIndex : uint8_t { FIX_ONE = 1, FIX_TWO = 2, FIX_FOUR = 4 };
struct MethodPcInfo {
const JSMethod *method {nullptr};
std::map<uint8_t *, uint8_t *> byteCodeCurPrePc {};
std::vector<CfgInfo> bytecodeBlockInfos {};
std::map<const uint8_t *, int32_t> pcToBCOffset {};
};
struct BCInfo {
const JSPandaFile *jsPandaFile {nullptr};
JSHandle<JSTaggedValue> constantPool;
std::vector<MethodPcInfo> methodPcInfos {};
template <class Callback>
void EnumerateBCInfo(const Callback &cb)
{
for (size_t i = 0; i < methodPcInfos.size(); i++) {
cb(jsPandaFile, constantPool, methodPcInfos[i]);
}
}
};
static const JSPandaFile *LoadInfoFromPf(const CString &filename, const std::string_view& entryPoint,
std::vector<MethodPcInfo> &methodPcInfos);
private:
static void ProcessClasses(JSPandaFile *jsPandaFile, const CString &methodName,
std::vector<MethodPcInfo> &methodPcInfos);
// need to remove in the future
static void FixOpcode(uint8_t *pc);
// need to remove in the future
static void UpdateICOffset(JSMethod *method, uint8_t *pc);
// need to remove in the future
static void FixInstructionId32(const BytecodeInstruction &inst, uint32_t index, uint32_t fixOrder = 0);
// need to remove in the future
static void TranslateBCIns(JSPandaFile *jsPandaFile, const BytecodeInstruction &bcIns, const JSMethod *method);
static void CollectMethodPcs(JSPandaFile *jsPandaFile, const uint32_t insSz, const uint8_t *insArr,
const JSMethod *method, std::vector<MethodPcInfo> &methodPcInfos);
};
} // namespace panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_BYTECODE_INFO_COLLECTOR_H

View File

@ -16,6 +16,7 @@
#include "ecmascript/compiler/file_generators.h"
#include "ecmascript/compiler/pass.h"
#include "ecmascript/compiler/bytecode_info_collector.h"
#include "ecmascript/ecma_handle_scope.h"
#include "ecmascript/js_tagged_value.h"
#include "ecmascript/jspandafile/js_pandafile_manager.h"
@ -26,9 +27,9 @@
namespace panda::ecmascript::kungfu {
bool PassManager::Compile(const std::string &fileName, AOTFileGenerator &generator)
{
BytecodeTranslationInfo translationInfo;
BytecodeInfoCollector::BCInfo bytecodeInfo;
[[maybe_unused]] EcmaHandleScope handleScope(vm_->GetJSThread());
bool res = CollectInfoOfPandaFile(fileName, entry_, &translationInfo);
bool res = CollectBCInfo(fileName, &bytecodeInfo);
if (!res) {
LOG_COMPILER(ERROR) << "Cannot execute panda file '" << fileName << "'";
return false;
@ -41,19 +42,21 @@ bool PassManager::Compile(const std::string &fileName, AOTFileGenerator &generat
bool enableLog = !log_->NoneMethod();
for (size_t i = 0; i < translationInfo.methodPcInfos.size(); i++) {
const JSMethod *method = translationInfo.methodPcInfos[i].method;
const std::string methodName(method->GetMethodName());
bytecodeInfo.EnumerateBCInfo([this, &fileName, &enableLog, aotModule, &cmpCfg, tsManager]
(const JSPandaFile *jsPandaFile, JSHandle<JSTaggedValue> &constantPool,
BytecodeInfoCollector::MethodPcInfo &methodPCInfo) {
const std::string methodName(methodPCInfo.method->GetMethodName());
if (log_->CertainMethod()) {
enableLog = logList_->IncludesMethod(fileName, methodName);
}
if (enableLog) {
LOG_COMPILER(INFO) << "\033[34m" << "aot method [" << fileName << ":"
<< methodName << "] log:" << "\033[0m";
<< methodName << "] log:" << "\033[0m";
}
BytecodeCircuitBuilder builder(translationInfo, i, tsManager, enableLog && log_->OutputCIR());
BytecodeCircuitBuilder builder(jsPandaFile, constantPool, methodPCInfo, tsManager,
enableLog && log_->OutputCIR());
builder.BytecodeToCircuit();
PassData data(builder.GetCircuit());
PassRunner<PassData> pipeline(&data, enableLog && log_->OutputCIR());
@ -63,26 +66,25 @@ bool PassManager::Compile(const std::string &fileName, AOTFileGenerator &generat
pipeline.RunPass<SlowPathLoweringPass>(&builder, &cmpCfg);
pipeline.RunPass<VerifierPass>();
pipeline.RunPass<SchedulingPass>();
pipeline.RunPass<LLVMIRGenPass>(aotModule, method);
}
pipeline.RunPass<LLVMIRGenPass>(aotModule, methodPCInfo.method);
});
generator.AddModule(aotModule, aotModuleAssembler, translationInfo.jsPandaFile);
generator.AddModule(aotModule, aotModuleAssembler, bytecodeInfo.jsPandaFile);
return true;
}
bool PassManager::CollectInfoOfPandaFile(const std::string &fileName, std::string_view entryPoint,
BytecodeTranslationInfo *translateInfo)
bool PassManager::CollectBCInfo(const std::string &fileName, BytecodeInfoCollector::BCInfo *bytecodeInfo)
{
if (translateInfo == nullptr) {
if (bytecodeInfo == nullptr) {
return false;
}
const JSPandaFile *jsPandaFile =
JSPandaFileManager::GetInstance()->LoadAotInfoFromPf(fileName.c_str(), entryPoint,
&(translateInfo->methodPcInfos));
const JSPandaFile *jsPandaFile = BytecodeInfoCollector::LoadInfoFromPf(fileName.c_str(), entry_,
bytecodeInfo->methodPcInfos);
if (jsPandaFile == nullptr) {
return false;
}
translateInfo->jsPandaFile = jsPandaFile;
bytecodeInfo->jsPandaFile = jsPandaFile;
if (jsPandaFile->HasTSTypes()) {
TSManager *tsManager = vm_->GetTSManager();
@ -99,7 +101,7 @@ bool PassManager::CollectInfoOfPandaFile(const std::string &fileName, std::strin
auto program = PandaFileTranslator::GenerateProgram(vm_, jsPandaFile);
JSHandle<JSFunction> mainFunc(vm_->GetJSThread(), program->GetMainFunction());
JSHandle<JSTaggedValue> constPool(vm_->GetJSThread(), mainFunc->GetConstantPool());
translateInfo->constantPool = constPool;
bytecodeInfo->constantPool = constPool;
return true;
}
} // namespace panda::ecmascript::kungfu

View File

@ -30,8 +30,7 @@ public:
relocMode_(relocMode), log_(log), logList_(logList) {};
PassManager() = default;
~PassManager() = default;
bool CollectInfoOfPandaFile(const std::string &filename, std::string_view entryPoint,
BytecodeTranslationInfo *translateInfo);
bool CollectBCInfo(const std::string &filename, BytecodeInfoCollector::BCInfo *bytecodeInfo);
bool Compile(const std::string &fileName, AOTFileGenerator &generator);
void SaveSnapshotFile();

View File

@ -81,7 +81,7 @@ public:
return constpoolMap_;
}
uint32_t GetOrInsertConstantPool(ConstPoolType type, uint32_t offset);
uint32_t PUBLIC_API GetOrInsertConstantPool(ConstPoolType type, uint32_t offset);
void UpdateMainMethodIndex(uint32_t mainMethodIndex)
{