Signed-off-by: wanyanglan <wanyanglan1@huawei.com>
Change-Id: I332794482e4ef0375c94f8e840f26a01f5a5da59
This commit is contained in:
wanyanglan 2022-09-15 21:09:37 +08:00
parent 3533e67aaf
commit c4831ab009
6 changed files with 157 additions and 46 deletions

View File

@ -189,7 +189,7 @@ source_set("ark_aot_compiler_set") {
sources = [
"aot_compiler.cpp",
"pass_manager.cpp",
# "slowpath_lowering.cpp",
"slowpath_lowering.cpp",
# "ts_type_lowering.cpp",
# "type_lowering.cpp",
]

View File

@ -606,6 +606,10 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
auto opcode = inst.GetOpcode();
info.offset = BytecodeInstruction::Size(opcode);
info.opcode = opcode;
if (opcode == panda::ecmascript::EcmaOpcode::LDGLOBALVAR_IMM16_ID16)
{
std::cout << "WYL ==================== " << std::endl;
}
info.accIn = inst.HasFlag(BytecodeInstruction::Flags::ACC_READ);
info.accOut = inst.HasFlag(BytecodeInstruction::Flags::ACC_WRITE);
switch (opcode) {
@ -674,13 +678,14 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
case EcmaOpcode::CALLARG1_IMM8_V8: {
uint32_t a0 = READ_INST_8_1();
info.inputs.emplace_back(VirtualRegister(a0));
info.accIn = true;
break;
}
case EcmaOpcode::DEPRECATED_CALLARG1_PREF_V8_V8: {
uint32_t startReg = READ_INST_8_1();
uint32_t a0 = READ_INST_8_2();
info.inputs.emplace_back(VirtualRegister(startReg));
info.inputs.emplace_back(VirtualRegister(a0));
info.inputs.emplace_back(VirtualRegister(startReg));
break;
}
case EcmaOpcode::CALLARGS2_IMM8_V8_V8: {
@ -818,8 +823,10 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
}
break;
}
case EcmaOpcode::RETURN:
case EcmaOpcode::RETURNUNDEFINED:
info.accIn = true;
break;
case EcmaOpcode::RETURN:
case EcmaOpcode::LDNAN:
case EcmaOpcode::LDINFINITY:
case EcmaOpcode::LDNEWTARGET:
@ -2749,6 +2756,9 @@ void BytecodeCircuitBuilder::BuildCircuit()
auto bytecodeInfo = GetBytecodeInfo(pc);
[[maybe_unused]] size_t numValueInputs = bytecodeInfo.ComputeTotalValueCount();
[[maybe_unused]] size_t numValueOutputs = bytecodeInfo.ComputeOutCount() + bytecodeInfo.vregOut.size();
gateAcc_.Print(gate);
std::cout << "WYL ========== EcmaOpcode: " << GetEcmaOpcodeStr(bytecodeInfo.opcode) << std::endl;
std::cout << "WYL ========== numValueInputs: " << numValueInputs << " valueCount: "<< valueCount << std::endl;
ASSERT(numValueInputs == valueCount);
ASSERT(numValueOutputs <= 1);
auto stateCount = gateAcc_.GetStateCount(gate);

View File

@ -22,6 +22,12 @@
#include "libpandafile/class_data_accessor-inl.h"
namespace panda::ecmascript::kungfu {
template<class T, class... Args>
static T *InitializeMemory(T *mem, Args... args)
{
return new (mem) T(std::forward<Args>(args)...);
}
const CString BytecodeInfoCollector::GetEntryFunName(const std::string_view &entryPoint) const
{
CString methodName;
@ -55,6 +61,7 @@ void BytecodeInfoCollector::ProcessClasses(const CString &methodName)
cda.EnumerateMethods([this, methods, &methodIdx, pf, &processedInsns, &sd, methodName]
(panda_file::MethodDataAccessor &mda) {
auto codeId = mda.GetCodeId();
auto methodId = mda.GetMethodId();
ASSERT(codeId.has_value());
MethodLiteral *methodLiteral = methods + (methodIdx++);
@ -68,18 +75,87 @@ void BytecodeInfoCollector::ProcessClasses(const CString &methodName)
bytecodeInfo_.mainMethodIndex = methodOffset;
}
new (methodLiteral) MethodLiteral(jsPandaFile_, mda.GetMethodId());
// new (methodLiteral) MethodLiteral(jsPandaFile_, mda.GetMethodId());
InitializeMemory(methodLiteral, jsPandaFile_, mda.GetMethodId());
methodLiteral->SetHotnessCounter(EcmaInterpreter::GetHotnessCounter(codeSize));
methodLiteral->InitializeCallField(
jsPandaFile_, codeDataAccessor.GetNumVregs(), codeDataAccessor.GetNumArgs());
const uint8_t *insns = codeDataAccessor.GetInstructions();
auto it = processedInsns.find(insns);
if (it == processedInsns.end()) {
CollectMethodPcs(codeSize, insns, methodLiteral);
processedInsns[insns] = bytecodeInfo_.methodPcInfos.size() - 1;
if (jsPandaFile_->IsNewVersion()) {
#ifdef NEW_INSTRUCTION_DEFINE
panda_file::IndexAccessor indexAccessor(*pf, methodId);
// int32_t index = indexAccessor.GetHeaderIndex();
panda_file::FunctionKind funcKind = indexAccessor.GetFunctionKind();
FunctionKind kind;
switch (funcKind) {
case panda_file::FunctionKind::NONE:
case panda_file::FunctionKind::FUNCTION:
kind = FunctionKind::BASE_CONSTRUCTOR;
break;
case panda_file::FunctionKind::NC_FUNCTION:
kind = FunctionKind::ARROW_FUNCTION;
break;
case panda_file::FunctionKind::GENERATOR_FUNCTION:
kind = FunctionKind::GENERATOR_FUNCTION;
break;
case panda_file::FunctionKind::ASYNC_FUNCTION:
kind = FunctionKind::ASYNC_FUNCTION;
break;
case panda_file::FunctionKind::ASYNC_GENERATOR_FUNCTION:
kind = FunctionKind::ASYNC_GENERATOR_FUNCTION;
break;
case panda_file::FunctionKind::ASYNC_NC_FUNCTION:
kind = FunctionKind::ASYNC_ARROW_FUNCTION;
break;
default:
UNREACHABLE();
}
methodLiteral->SetFunctionKind(kind);
#endif
auto it = processedInsns.find(insns);
if (it == processedInsns.end()) {
auto bcIns = BytecodeInst(insns);
auto bcInsLast = bcIns.JumpTo(codeSize);
bytecodeInfo_.methodPcInfos.emplace_back(MethodPcInfo { {}, {}, {}, codeSize });
int32_t offsetIndex = 1;
uint8_t *curPc = nullptr;
uint8_t *prePc = nullptr;
while (bcIns.GetAddress() != bcInsLast.GetAddress()) {
auto pc = const_cast<uint8_t *>(bcIns.GetAddress());
auto nextInst = bcIns.GetNext();
bcIns = nextInst;
auto &bytecodeBlockInfos = bytecodeInfo_.methodPcInfos.back().bytecodeBlockInfos;
auto &byteCodeCurPrePc = bytecodeInfo_.methodPcInfos.back().byteCodeCurPrePc;
auto &pcToBCOffset = bytecodeInfo_.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());
bytecodeInfo_.methodPcInfos.back().byteCodeCurPrePc[emptyPc] = prePc;
bytecodeInfo_.methodPcInfos.back().pcToBCOffset[emptyPc] = offsetIndex++;
processedInsns[insns] = bytecodeInfo_.methodPcInfos.size() - 1;
}
SetMethodPcInfoIndex(methodOffset, processedInsns[insns]);
} else {
auto it = processedInsns.find(insns);
if (it == processedInsns.end()) {
CollectMethodPcs(codeSize, insns, methodLiteral);
processedInsns[insns] = bytecodeInfo_.methodPcInfos.size() - 1;
}
SetMethodPcInfoIndex(methodOffset, processedInsns[insns]);
}
jsPandaFile_->SetMethodLiteralToMap(methodLiteral);
SetMethodPcInfoIndex(methodOffset, processedInsns[insns]);
});
}
LOG_COMPILER(INFO) << "Total number of methods in file: "
@ -252,9 +328,12 @@ void BytecodeInfoCollector::UpdateEcmaBytecodeICOffset(MethodLiteral* method, ui
void BytecodeInfoCollector::FixOpcode(MethodLiteral *method, const OldBytecodeInst &inst)
{
auto opcode = inst.GetOpcode();
auto pc = const_cast<uint8_t *>(inst.GetAddress());
std::cout << "WYL aot =========== inst: " << *pc << std::endl;
std::cout << "WYL aot =========== opcode: " << static_cast<uint16_t>(opcode) << std::endl;
EcmaOpcode newOpcode;
auto oldLen = OldBytecodeInst::Size(OldBytecodeInst::GetFormat(opcode));
auto pc = const_cast<uint8_t *>(inst.GetAddress());
pc = const_cast<uint8_t *>(inst.GetAddress());
// First level opcode
if (static_cast<uint16_t>(opcode) < 236) { // 236: second level bytecode index
@ -941,6 +1020,16 @@ void BytecodeInfoCollector::FixOpcode(MethodLiteral *method, const OldBytecodeIn
}
break;
}
case OldBytecodeInst::Opcode::ECMA_ASYNCGENERATORREJECT_PREF_V8_V8: {
newOpcode = EcmaOpcode::ASYNCGENERATORREJECT_V8;
*pc = static_cast<uint8_t>(newOpcode);
auto newLen = BytecodeInstruction::Size(newOpcode);
if (memmove_s(pc + 1, newLen - 1, pc + 2, oldLen - 2) != EOK) { // 2: skip second level inst and pref
LOG_FULL(FATAL) << "FixOpcode memmove_s fail";
UNREACHABLE();
}
break;
}
case OldBytecodeInst::Opcode::ECMA_CREATEASYNCGENERATOROBJ_PREF_V8: {
newOpcode = EcmaOpcode::CREATEASYNCGENERATOROBJ_V8;
*pc = static_cast<uint8_t>(newOpcode);
@ -1487,8 +1576,7 @@ void BytecodeInfoCollector::TranslateBCIns(const OldBytecodeInst &bcIns, const M
const panda_file::File *pf = jsPandaFile_->GetPandaFile();
if (bcIns.HasFlag(OldBytecodeInst::Flags::STRING_ID) &&
OldBytecodeInst::HasId(OldBytecodeInst::GetFormat(bcIns.GetOpcode()), 0)) {
auto index = jsPandaFile_->GetOrInsertConstantPool(
ConstPoolType::STRING, bcIns.GetId());
auto index = jsPandaFile_->GetOrInsertConstantPool(ConstPoolType::STRING, bcIns.GetId());
FixInstructionId32(bcIns, index);
} else {
OldBytecodeInst::Opcode opcode = static_cast<OldBytecodeInst::Opcode>(bcIns.GetOpcode());
@ -1513,6 +1601,14 @@ void BytecodeInfoCollector::TranslateBCIns(const OldBytecodeInst &bcIns, const M
index = jsPandaFile_->GetOrInsertConstantPool(ConstPoolType::GENERATOR_FUNCTION, methodId);
FixInstructionId32(bcIns, index);
break;
case OldBytecodeInst::Opcode::ECMA_DEFINEASYNCGENERATORFUNC_PREF_ID16_IMM16_V8:
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId()).GetOffset();
if (hasTSTypes_) {
CollectInnerMethods(method, methodId);
}
index = jsPandaFile_->GetOrInsertConstantPool(ConstPoolType::ASYNC_GENERATOR_FUNCTION, methodId);
FixInstructionId32(bcIns, index);
break;
case OldBytecodeInst::Opcode::ECMA_DEFINEASYNCFUNC_PREF_ID16_IMM16_V8:
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId()).GetOffset();
CollectInnerMethods(method, methodId);

View File

@ -31,7 +31,6 @@ bool PassManager::Compile(const std::string &fileName, AOTFileGenerator &generat
LOG_COMPILER(ERROR) << "Cannot execute panda file '" << fileName << "'";
return false;
}
auto bcInfoCollector = BytecodeInfoCollector(jsPandaFile, entry_);
jsPandaFile = ResolveModuleFile(jsPandaFile, fileName);
auto constantPool = CreateConstPool(jsPandaFile);

View File

@ -257,27 +257,28 @@ void SlowPathLowering::Lower(GateRef gate)
case EcmaOpcode::LDA_STR_ID16:
LowerLoadStr(gate, glue, jsFunc);
break;
case EcmaOpcode::CALLARG0DYN_PREF_V8:
LowerCallArg0(gate, glue);
break;
case EcmaOpcode::CALLARG1DYN_PREF_V8_V8:
// case EcmaOpcode::CALLARG0DYN_PREF_V8:
// LowerCallArg0(gate, glue);
// break;
case EcmaOpcode::CALLARG1_IMM8_V8:
case EcmaOpcode::DEPRECATED_CALLARG1_PREF_V8_V8:
LowerCallArg1(gate, glue);
break;
case EcmaOpcode::CALLARGS2DYN_PREF_V8_V8_V8:
LowerCallArgs2(gate, glue);
break;
case EcmaOpcode::CALLARGS3DYN_PREF_V8_V8_V8_V8:
LowerCallArgs3(gate, glue);
break;
case EcmaOpcode::CALLITHISRANGEDYN_PREF_IMM16_V8:
LowerCallThisRange(gate, glue);
break;
case EcmaOpcode::CALLSPREADDYN_PREF_V8_V8_V8:
LowerCallSpread(gate, glue);
break;
case EcmaOpcode::CALLIRANGEDYN_PREF_IMM16_V8:
LowerCallRange(gate, glue);
break;
// case EcmaOpcode::CALLARGS2DYN_PREF_V8_V8_V8:
// LowerCallArgs2(gate, glue);
// break;
// case EcmaOpcode::CALLARGS3DYN_PREF_V8_V8_V8_V8:
// LowerCallArgs3(gate, glue);
// break;
// case EcmaOpcode::CALLITHISRANGEDYN_PREF_IMM16_V8:
// LowerCallThisRange(gate, glue);
// break;
// case EcmaOpcode::CALLSPREADDYN_PREF_V8_V8_V8:
// LowerCallSpread(gate, glue);
// break;
// case EcmaOpcode::CALLIRANGEDYN_PREF_IMM16_V8:
// LowerCallRange(gate, glue);
// break;
case EcmaOpcode::DEPRECATED_LDLEXENV_PREF_NONE:
LowerLexicalEnv(gate, glue);
break;
@ -306,9 +307,9 @@ void SlowPathLowering::Lower(GateRef gate)
case EcmaOpcode::DEPRECATED_GETRESUMEMODE_PREF_V8:
LowerGetResumeMode(gate);
break;
case EcmaOpcode::ITERNEXT_PREF_V8:
LowerIterNext(gate, glue);
break;
// case EcmaOpcode::ITERNEXT_PREF_V8:
// LowerIterNext(gate, glue);
// break;
case EcmaOpcode::CLOSEITERATOR_IMM8_V8:
case EcmaOpcode::CLOSEITERATOR_IMM16_V8:
LowerCloseIterator(gate, glue);
@ -409,9 +410,9 @@ void SlowPathLowering::Lower(GateRef gate)
case EcmaOpcode::THROW_DELETESUPERPROPERTY_PREF_NONE:
LowerThrowDeleteSuperProperty(gate, glue);
break;
case EcmaOpcode::LDGLOBALTHIS_PREF:
LowerLdGlobal(gate, glue);
break;
// case EcmaOpcode::LDGLOBALTHIS_PREF:
// LowerLdGlobal(gate, glue);
// break;
case EcmaOpcode::LDSYMBOL:
LowerLdSymbol(gate, glue);
break;
@ -494,7 +495,7 @@ void SlowPathLowering::Lower(GateRef gate)
break;
case EcmaOpcode::GETTEMPLATEOBJECT_IMM8:
case EcmaOpcode::GETTEMPLATEOBJECT_IMM16:
case EcmaOpcode::DEPRECATED_GETTEMPLATEOBJECT_PREF_V8
case EcmaOpcode::DEPRECATED_GETTEMPLATEOBJECT_PREF_V8:
LowerGetTemplateObject(gate, glue);
break;
case EcmaOpcode::SETOBJECTWITHPROTO_IMM8_V8:
@ -605,11 +606,11 @@ void SlowPathLowering::Lower(GateRef gate)
case EcmaOpcode::DEPRECATED_LDSUPERBYVALUE_PREF_V8_V8:
LowerLdSuperByValue(gate, glue, jsFunc);
break;
case EcmaOpcode::STSUPERBYVALUE_PREF_V8_V8:
case EcmaOpcode::STSUPERBYVALUE_IMM16_V8_V8:
LowerStSuperByValue(gate, glue, jsFunc);
break;
case EcmaOpcode::TRYSTGLOBALBYNAME_IMM8_ID16:
case EcmaOpcode::TRYLDGLOBALBYNAME_IMM16_ID16:
case EcmaOpcode::TRYSTGLOBALBYNAME_IMM16_ID16:
LowerTryStGlobalByName(gate, glue, jsFunc);
break;
case EcmaOpcode::STCONSTTOGLOBALRECORD_IMM16_ID16:
@ -691,7 +692,7 @@ void SlowPathLowering::Lower(GateRef gate)
case EcmaOpcode::ASYNCGENERATORREJECT_V8:
LowerAsyncGeneratorReject(gate, glue);
break;
case EcmaOpcode::STARRAYSPREAD_PREF_V8_V8:
case EcmaOpcode::STARRAYSPREAD_V8_V8:
LowerStArraySpread(gate, glue);
break;
case EcmaOpcode::LDLEXVAR_IMM4_IMM4:
@ -1045,10 +1046,10 @@ void SlowPathLowering::LowerCallArg1(GateRef gate, GateRef glue)
GateRef actualArgc = builder_.Int64(ComputeCallArgc(gate, EcmaBytecode::CALLARG1DYN_PREF_V8_V8));
GateRef newTarget = builder_.Undefined();
GateRef thisObj = builder_.Undefined();
GateRef func = acc_.GetValueIn(gate, 0);
GateRef func = acc_.GetValueIn(gate, 1);
GateRef env = builder_.Undefined();
GateRef bcOffset = acc_.GetValueIn(gate, 2); // 2: bytecode offset
LowerToJSCall(gate, glue, {glue, env, actualArgc, func, newTarget, thisObj, acc_.GetValueIn(gate, 1), bcOffset});
LowerToJSCall(gate, glue, {glue, env, actualArgc, func, newTarget, thisObj, acc_.GetValueIn(gate, 0), bcOffset});
}
void SlowPathLowering::LowerCallArgs2(GateRef gate, GateRef glue)
@ -3148,7 +3149,7 @@ void SlowPathLowering::LowerDefineClassWithBuffer(GateRef gate, GateRef glue, Ga
GateRef length;
GateRef lexicalEnv;
if (isDeprecated) {
literalId = builder_.Int64Add(MethodId, builder_.Int64(1));
literalId = builder_.Int64Add(methodId, builder_.Int64(1));
length = acc_.GetValueIn(gate, 1);
lexicalEnv = acc_.GetValueIn(gate, 2);
} else {

View File

@ -186,8 +186,12 @@ JSHandle<Program> PandaFileTranslator::GenerateProgram(EcmaVM *vm, const JSPanda
constpool = ConstantPool::CreateConstPool(vm, jsPandaFile, mainMethodIndex);
#endif
} else {
constpool = ParseConstPool(vm, jsPandaFile);
CString entry = "";
if (!jsPandaFile->IsBundlePack()) {
entry = entryPoint.data();
}
}
constpool = ParseConstPool(vm, jsPandaFile);
vm->AddConstpool(jsPandaFile, constpool.GetTaggedValue(), index, total);
} else {
constpool = JSHandle<ConstantPool>(thread, constpoolVal);
@ -592,6 +596,7 @@ do { \
void PandaFileTranslator::FixOpcode(MethodLiteral *method, const OldBytecodeInst &inst)
{
auto opcode = inst.GetOpcode();
std::cout << "WYL c interpreter =========== opcode: " << static_cast<uint16_t>(opcode) << std::endl;
EcmaOpcode newOpcode;
auto oldLen = OldBytecodeInst::Size(OldBytecodeInst::GetFormat(opcode));
auto pc = const_cast<uint8_t *>(inst.GetAddress());