mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-06 23:54:03 +00:00
!3269 Refactor save register and restore register
Merge pull request !3269 from 许杰/refactor_generator
This commit is contained in:
commit
94b01d742c
@ -67,7 +67,7 @@ void AsyncFunctionLowering::RebuildGeneratorCfg(GateRef resumeGate, GateRef rest
|
||||
{
|
||||
GateRef ifSuccess = accessor_.GetState(resumeGate);
|
||||
GateRef suspendGate = accessor_.GetState(ifSuccess);
|
||||
GateRef firstRestoreRegGate = GetFirstRestoreRegister(resumeGate);
|
||||
GateRef restoreRegGate = accessor_.GetDep(resumeGate);
|
||||
GateRef offsetConstantGate = accessor_.GetValueIn(suspendGate);
|
||||
offsetConstantGate = builder_.TruncInt64ToInt32(offsetConstantGate);
|
||||
auto stateInGate = accessor_.GetState(resumeGate);
|
||||
@ -87,7 +87,7 @@ void AsyncFunctionLowering::RebuildGeneratorCfg(GateRef resumeGate, GateRef rest
|
||||
if (flag) {
|
||||
accessor_.ReplaceStateIn(resumeGate, ifTrue);
|
||||
accessor_.ReplaceValueIn(resumeGate, newTarget);
|
||||
accessor_.ReplaceDependIn(firstRestoreRegGate, ifTrueDepend);
|
||||
accessor_.ReplaceDependIn(restoreRegGate, ifTrueDepend);
|
||||
circuit_->NewGate(circuit_->Return(), MachineType::NOVALUE,
|
||||
{ ifSuccess, suspendGate, suspendGate, circuit_->GetReturnRoot() },
|
||||
GateType::AnyType());
|
||||
@ -125,7 +125,7 @@ void AsyncFunctionLowering::RebuildGeneratorCfg(GateRef resumeGate, GateRef rest
|
||||
if (accessor_.GetOpCode(resumeStateGate) != OpCode::IF_TRUE) {
|
||||
accessor_.ReplaceStateIn(resumeGate, ifTrue);
|
||||
accessor_.ReplaceValueIn(resumeGate, newTarget);
|
||||
accessor_.ReplaceDependIn(firstRestoreRegGate, bcOffsetPhiGate);
|
||||
accessor_.ReplaceDependIn(restoreRegGate, bcOffsetPhiGate);
|
||||
circuit_->NewGate(circuit_->Return(), MachineType::NOVALUE,
|
||||
{ ifSuccess, suspendGate, suspendGate, circuit_->GetReturnRoot() },
|
||||
GateType::AnyType());
|
||||
@ -202,16 +202,5 @@ bool AsyncFunctionLowering::IsAsyncRelated() const
|
||||
{
|
||||
return bcBuilder_->GetAsyncRelatedGates().size() > 0;
|
||||
}
|
||||
|
||||
GateRef AsyncFunctionLowering::GetFirstRestoreRegister(GateRef gate) const
|
||||
{
|
||||
GateRef firstRestoreGate = 0;
|
||||
GateRef curRestoreGate = accessor_.GetDep(gate);
|
||||
while (accessor_.GetOpCode(curRestoreGate) == OpCode::RESTORE_REGISTER) {
|
||||
firstRestoreGate = curRestoreGate;
|
||||
curRestoreGate = accessor_.GetDep(curRestoreGate);
|
||||
}
|
||||
return firstRestoreGate;
|
||||
}
|
||||
} // panda::ecmascript::kungfu
|
||||
|
||||
|
@ -57,8 +57,6 @@ private:
|
||||
|
||||
void UpdateValueSelector(GateRef prevLoopBeginGate, GateRef controlStateGate, GateRef prevBcOffsetPhiGate);
|
||||
|
||||
GateRef GetFirstRestoreRegister(GateRef gate) const;
|
||||
|
||||
BytecodeCircuitBuilder *bcBuilder_;
|
||||
Circuit *circuit_;
|
||||
CircuitBuilder builder_;
|
||||
|
@ -817,6 +817,23 @@ void BytecodeCircuitBuilder::NewJSGate(BytecodeRegion &bb, GateRef &state, GateR
|
||||
}
|
||||
byteCodeToJSGate_[iterator.Index()] = gate;
|
||||
if (bytecodeInfo.IsGeneratorRelative()) {
|
||||
if (bytecodeInfo.GetOpcode() == EcmaOpcode::SUSPENDGENERATOR_V8) {
|
||||
auto hole = circuit_->GetConstantGate(MachineType::I64,
|
||||
JSTaggedValue::VALUE_HOLE,
|
||||
GateType::TaggedValue());
|
||||
uint32_t numRegs = method_->GetNumberVRegs();
|
||||
std::vector<GateRef> vec(numRegs + 1, hole);
|
||||
vec[0] = depend;
|
||||
GateRef saveRegs =
|
||||
circuit_->NewGate(circuit_->SaveRegister(numRegs), vec);
|
||||
gateAcc_.ReplaceDependIn(gate, saveRegs);
|
||||
} else if (bytecodeInfo.GetOpcode() == EcmaOpcode::RESUMEGENERATOR) {
|
||||
GateRef restoreRegs =
|
||||
circuit_->NewGate(circuit_->RestoreRegister(), { depend });
|
||||
gateAcc_.ReplaceDependIn(gate, restoreRegs);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
suspendAndResumeGates_.emplace_back(gate);
|
||||
}
|
||||
if (bytecodeInfo.IsThrow()) {
|
||||
@ -984,7 +1001,8 @@ void BytecodeCircuitBuilder::NewPhi(BytecodeRegion &bb, uint16_t reg, bool acc,
|
||||
gateAcc_.NewIn(currentPhi, 0, bb.stateStart);
|
||||
for (size_t i = 0; i < bb.numOfStatePreds; ++i) {
|
||||
auto &[predId, predBcIdx, isException] = bb.expandedPreds.at(i);
|
||||
gateAcc_.NewIn(currentPhi, i + 1, ResolveDef(predId, predBcIdx, reg, acc));
|
||||
std::pair<GateRef, uint32_t> needReplaceInfo(currentPhi, i + 1);
|
||||
gateAcc_.NewIn(currentPhi, i + 1, ResolveDef(predId, predBcIdx, reg, acc, needReplaceInfo));
|
||||
}
|
||||
} else {
|
||||
// 2: the number of value inputs and it is in accord with LOOP_BEGIN
|
||||
@ -998,7 +1016,9 @@ void BytecodeCircuitBuilder::NewPhi(BytecodeRegion &bb, uint16_t reg, bool acc,
|
||||
for (size_t i = 0; i < bb.numOfStatePreds; ++i) {
|
||||
auto &[predId, predBcIdx, isException] = bb.expandedPreds.at(i);
|
||||
if (bb.loopbackBlocks.count(predId)) {
|
||||
gateAcc_.NewIn(loopBackValue, loopBackIndex++, ResolveDef(predId, predBcIdx, reg, acc));
|
||||
std::pair<GateRef, uint32_t> needReplaceInfo(loopBackValue, loopBackIndex);
|
||||
gateAcc_.NewIn(loopBackValue, loopBackIndex++,
|
||||
ResolveDef(predId, predBcIdx, reg, acc, needReplaceInfo));
|
||||
}
|
||||
}
|
||||
inList = std::vector<GateRef>(1 + bb.numOfStatePreds - bb.numOfLoopBacks, Circuit::NullGate());
|
||||
@ -1010,7 +1030,8 @@ void BytecodeCircuitBuilder::NewPhi(BytecodeRegion &bb, uint16_t reg, bool acc,
|
||||
for (size_t i = 0; i < bb.numOfStatePreds; ++i) {
|
||||
auto &[predId, predBcIdx, isException] = bb.expandedPreds.at(i);
|
||||
if (!bb.loopbackBlocks.count(predId)) {
|
||||
gateAcc_.NewIn(forwardValue, forwardIndex++, ResolveDef(predId, predBcIdx, reg, acc));
|
||||
std::pair<GateRef, uint32_t> needReplaceInfo(forwardValue, forwardIndex);
|
||||
gateAcc_.NewIn(forwardValue, forwardIndex++, ResolveDef(predId, predBcIdx, reg, acc, needReplaceInfo));
|
||||
}
|
||||
}
|
||||
gateAcc_.NewIn(currentPhi, 1, forwardValue); // 1: index of forward value input
|
||||
@ -1019,8 +1040,8 @@ void BytecodeCircuitBuilder::NewPhi(BytecodeRegion &bb, uint16_t reg, bool acc,
|
||||
}
|
||||
|
||||
// recursive variables renaming algorithm
|
||||
GateRef BytecodeCircuitBuilder::ResolveDef(const size_t bbId, int32_t bcId,
|
||||
const uint16_t reg, const bool acc)
|
||||
GateRef BytecodeCircuitBuilder::ResolveDef(const size_t bbId, int32_t bcId, const uint16_t reg, const bool acc,
|
||||
std::pair<GateRef, uint32_t> &needReplaceInfo)
|
||||
{
|
||||
auto tmpReg = reg;
|
||||
// find def-site in bytecodes of basic block
|
||||
@ -1062,21 +1083,19 @@ GateRef BytecodeCircuitBuilder::ResolveDef(const size_t bbId, int32_t bcId,
|
||||
// New RESTORE_REGISTER HIR, used to restore the register content when processing resume instruction.
|
||||
// New SAVE_REGISTER HIR, used to save register content when processing suspend instruction.
|
||||
auto resumeGate = byteCodeToJSGate_.at(iterator.Index());
|
||||
ans = GetExistingRestore(resumeGate, tmpReg);
|
||||
if (ans != Circuit::NullGate()) {
|
||||
ans = gateAcc_.GetDep(resumeGate);
|
||||
auto regs = gateAcc_.GetRestoreRegsInfo(ans);
|
||||
auto it = regs.find(needReplaceInfo);
|
||||
if (it != regs.end()) {
|
||||
break;
|
||||
}
|
||||
GateRef resumeDependGate = gateAcc_.GetDep(resumeGate);
|
||||
ans = circuit_->NewGate(circuit_->RestoreRegister(tmpReg), MachineType::I64,
|
||||
{ resumeDependGate }, GateType::AnyType());
|
||||
SetExistingRestore(resumeGate, tmpReg, ans);
|
||||
gateAcc_.SetDep(resumeGate, ans);
|
||||
auto saveRegGate = ResolveDef(bbId, iterator.Index() - 1, tmpReg, tmpAcc);
|
||||
gateAcc_.SetRestoreRegsInfo(ans, needReplaceInfo, tmpReg);
|
||||
|
||||
auto saveRegGate = ResolveDef(bbId, iterator.Index() - 1, tmpReg, tmpAcc, needReplaceInfo);
|
||||
ASSERT(Bytecodes::GetOpcode(iterator.PeekPrevPc(2)) == EcmaOpcode::SUSPENDGENERATOR_V8); // 2: prev bc
|
||||
GateRef suspendGate = byteCodeToJSGate_.at(iterator.Index() - 2); // 2: prev bc
|
||||
auto dependGate = gateAcc_.GetDep(suspendGate);
|
||||
auto newDependGate = circuit_->NewGate(circuit_->SaveRegister(tmpReg), {dependGate, saveRegGate});
|
||||
gateAcc_.SetDep(suspendGate, newDependGate);
|
||||
GateRef saveRegs = gateAcc_.GetDep(suspendGate);
|
||||
gateAcc_.ReplaceValueIn(saveRegs, saveRegGate, tmpReg);
|
||||
break;
|
||||
}
|
||||
// find GET_EXCEPTION gate if this is a catch block
|
||||
@ -1112,7 +1131,7 @@ GateRef BytecodeCircuitBuilder::ResolveDef(const size_t bbId, int32_t bcId,
|
||||
}
|
||||
if (ans == Circuit::NullGate()) {
|
||||
// recursively find def-site in dominator block
|
||||
return ResolveDef(bb.iDominator->id, bb.iDominator->end, tmpReg, tmpAcc);
|
||||
return ResolveDef(bb.iDominator->id, bb.iDominator->end, tmpReg, tmpAcc, needReplaceInfo);
|
||||
} else {
|
||||
// def-site already found
|
||||
return ans;
|
||||
@ -1167,12 +1186,13 @@ void BytecodeCircuitBuilder::BuildCircuit()
|
||||
if (!gateAcc_.IsInGateNull(gate, inIdx)) {
|
||||
continue;
|
||||
}
|
||||
std::pair<GateRef, uint32_t> needReplaceInfo(gate, inIdx);
|
||||
if (valueIdx < bytecodeInfo.inputs.size()) {
|
||||
auto vregId = std::get<VirtualRegister>(bytecodeInfo.inputs.at(valueIdx)).GetId();
|
||||
GateRef defVreg = ResolveDef(bbIndex, bcIndex - 1, vregId, false);
|
||||
GateRef defVreg = ResolveDef(bbIndex, bcIndex - 1, vregId, false, needReplaceInfo);
|
||||
gateAcc_.NewIn(gate, inIdx, defVreg);
|
||||
} else {
|
||||
GateRef defAcc = ResolveDef(bbIndex, bcIndex - 1, 0, true);
|
||||
GateRef defAcc = ResolveDef(bbIndex, bcIndex - 1, 0, true, needReplaceInfo);
|
||||
gateAcc_.NewIn(gate, inIdx, defAcc);
|
||||
}
|
||||
}
|
||||
|
@ -433,7 +433,8 @@ private:
|
||||
void NewByteCode(BytecodeRegion &bb, GateRef &state, GateRef &depend);
|
||||
void BuildSubCircuit();
|
||||
void NewPhi(BytecodeRegion &bb, uint16_t reg, bool acc, GateRef ¤tPhi);
|
||||
GateRef ResolveDef(const size_t bbId, int32_t bcId, const uint16_t reg, const bool acc);
|
||||
GateRef ResolveDef(const size_t bbId, int32_t bcId, const uint16_t reg, const bool acc,
|
||||
std::pair<GateRef, uint32_t> &needReplaceInfo);
|
||||
void BuildCircuit();
|
||||
GateRef GetExistingRestore(GateRef resumeGate, uint16_t tmpReg) const;
|
||||
void SetExistingRestore(GateRef resumeGate, uint16_t tmpReg, GateRef restoreGate);
|
||||
|
@ -279,7 +279,7 @@ void Circuit::ModifyIn(GateRef gate, size_t idx, GateRef in)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
ASSERT(idx < LoadGatePtrConst(gate)->GetNumIns());
|
||||
ASSERT(!Circuit::IsInGateNull(gate, idx));
|
||||
ASSERT(!Circuit::IsInGateNull(gate, idx) || (GetOpCode(gate) == OpCode::SAVE_REGISTER));
|
||||
#endif
|
||||
LoadGatePtr(gate)->ModifyIn(idx, LoadGatePtr(in));
|
||||
}
|
||||
|
@ -130,6 +130,16 @@ public:
|
||||
return metaBuilder_.TypedBinaryOp(value, binOp);
|
||||
}
|
||||
|
||||
const GateMetaData* SaveRegister(uint64_t value)
|
||||
{
|
||||
return metaBuilder_.SaveRegister(value);
|
||||
}
|
||||
|
||||
const GateMetaData* RestoreRegister()
|
||||
{
|
||||
return metaBuilder_.RestoreRegister();
|
||||
}
|
||||
|
||||
const GateMetaData *GetMetaData(GateRef gate) const
|
||||
{
|
||||
return LoadGatePtrConst(gate)->GetMetaData();
|
||||
|
@ -394,22 +394,21 @@ void FrameStateBuilder::SaveBBBeginStateInfo(size_t bbId)
|
||||
|
||||
void FrameStateBuilder::UpdateVirtualRegistersOfSuspend(GateRef gate)
|
||||
{
|
||||
auto saveGate = gateAcc_.GetDep(gate);
|
||||
while (gateAcc_.GetOpCode(saveGate) == OpCode::SAVE_REGISTER) {
|
||||
auto vreg = static_cast<size_t>(gateAcc_.GetVirtualRegisterIndex(saveGate));
|
||||
auto def = gateAcc_.GetValueIn(saveGate, 0);
|
||||
UpdateVirtualRegister(vreg, def);
|
||||
saveGate = gateAcc_.GetDep(saveGate);
|
||||
auto saveRegsGate = gateAcc_.GetDep(gate);
|
||||
size_t numOfRegs = gateAcc_.GetNumOfSaveRegs(saveRegsGate);
|
||||
for (size_t i = 0; i < numOfRegs; i++) {
|
||||
GateRef def = gateAcc_.GetValueIn(saveRegsGate, i);
|
||||
UpdateVirtualRegister(i, def);
|
||||
}
|
||||
}
|
||||
|
||||
void FrameStateBuilder::UpdateVirtualRegistersOfResume(GateRef gate)
|
||||
{
|
||||
auto restoreGate = gateAcc_.GetDep(gate);
|
||||
while (gateAcc_.GetOpCode(restoreGate) == OpCode::RESTORE_REGISTER) {
|
||||
auto vreg = static_cast<size_t>(gateAcc_.GetVirtualRegisterIndex(restoreGate));
|
||||
auto info = gateAcc_.GetRestoreRegsInfo(restoreGate);
|
||||
for (auto it = info.begin(); it != info.end(); ++it) {
|
||||
auto vreg = it->second;
|
||||
UpdateVirtualRegister(vreg, Circuit::NullGate());
|
||||
restoreGate = gateAcc_.GetDep(restoreGate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -233,6 +233,16 @@ public:
|
||||
{
|
||||
return JSBytecodeMegaData::Cast(meta_);
|
||||
}
|
||||
|
||||
const RestoreRegsMetaData* GetRestoreRegsMetaData() const
|
||||
{
|
||||
return RestoreRegsMetaData::Cast(meta_);
|
||||
}
|
||||
|
||||
const SaveRegsMetaData* GetSaveRegsMetaData() const
|
||||
{
|
||||
return SaveRegsMetaData::Cast(meta_);
|
||||
}
|
||||
std::string MachineTypeStr(MachineType machineType) const;
|
||||
std::string GateTypeStr(GateType gateType) const;
|
||||
~Gate() = default;
|
||||
|
@ -190,6 +190,27 @@ EcmaOpcode GateAccessor::GetByteCodeOpcode(GateRef gate) const
|
||||
return gatePtr->GetJSBytecodeMetaData()->GetByteCodeOpcode();
|
||||
}
|
||||
|
||||
const std::map<std::pair<GateRef, uint32_t>, uint32_t> &GateAccessor::GetRestoreRegsInfo(GateRef gate) const
|
||||
{
|
||||
ASSERT(GetOpCode(gate) == OpCode::RESTORE_REGISTER);
|
||||
Gate *gatePtr = circuit_->LoadGatePtr(gate);
|
||||
return gatePtr->GetRestoreRegsMetaData()->GetRestoreRegsInfo();
|
||||
}
|
||||
|
||||
void GateAccessor::SetRestoreRegsInfo(GateRef gate, std::pair<GateRef, uint32_t> &info, uint32_t index) const
|
||||
{
|
||||
ASSERT(GetOpCode(gate) == OpCode::RESTORE_REGISTER);
|
||||
Gate *gatePtr = circuit_->LoadGatePtr(gate);
|
||||
const_cast<RestoreRegsMetaData*>(gatePtr->GetRestoreRegsMetaData())->SetRestoreRegsInfo(info, index);
|
||||
}
|
||||
|
||||
size_t GateAccessor::GetNumOfSaveRegs(GateRef gate) const
|
||||
{
|
||||
ASSERT(GetOpCode(gate) == OpCode::SAVE_REGISTER);
|
||||
Gate *gatePtr = circuit_->LoadGatePtr(gate);
|
||||
return static_cast<size_t>(gatePtr->GetSaveRegsMetaData()->GetNumValue());
|
||||
}
|
||||
|
||||
void GateAccessor::Print(GateRef gate) const
|
||||
{
|
||||
Gate *gatePtr = circuit_->LoadGatePtr(gate);
|
||||
|
@ -317,6 +317,9 @@ public:
|
||||
const std::string GetConstantString(GateRef gate) const;
|
||||
uint32_t GetBytecodeIndex(GateRef gate) const;
|
||||
EcmaOpcode GetByteCodeOpcode(GateRef gate) const;
|
||||
const std::map<std::pair<GateRef, uint32_t>, uint32_t> &GetRestoreRegsInfo(GateRef gate) const;
|
||||
void SetRestoreRegsInfo(GateRef gate, std::pair<GateRef, uint32_t> &info, uint32_t index) const;
|
||||
size_t GetNumOfSaveRegs(GateRef gate) const;
|
||||
void Print(GateRef gate) const;
|
||||
void ShortPrint(GateRef gate) const;
|
||||
GateId GetId(GateRef gate) const;
|
||||
|
@ -52,6 +52,8 @@ std::string GateMetaData::Str(OpCode opcode)
|
||||
GATE_META_DATA_LIST_WITH_SIZE(GATE_NAME_MAP)
|
||||
GATE_META_DATA_LIST_WITH_ONE_PARAMETER(GATE_NAME_MAP)
|
||||
GATE_META_DATA_LIST_WITH_STRING(GATE_NAME_MAP)
|
||||
GATE_META_DATA_IN_SAVE_REGISTER(GATE_NAME_MAP)
|
||||
GATE_META_DATA_IN_RESTORE_REGISTER(GATE_NAME_MAP)
|
||||
#undef GATE_NAME_MAP
|
||||
#define GATE_NAME_MAP(OP) { OpCode::OP, #OP },
|
||||
GATE_OPCODE_LIST(GATE_NAME_MAP)
|
||||
@ -243,4 +245,13 @@ const GateMetaData* GateMetaBuilder::NAME(const std::string &str) \
|
||||
}
|
||||
GATE_META_DATA_LIST_WITH_STRING(DECLARE_GATE_META)
|
||||
#undef DECLARE_GATE_META
|
||||
|
||||
#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \
|
||||
const GateMetaData* GateMetaBuilder::NAME(uint64_t value) \
|
||||
{ \
|
||||
auto meta = new (chunk_) SaveRegsMetaData(OpCode::OP, R, S, D, V, value); \
|
||||
return meta; \
|
||||
}
|
||||
GATE_META_DATA_IN_SAVE_REGISTER(DECLARE_GATE_META)
|
||||
#undef DECLARE_GATE_META
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "libpandabase/macros.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
using GateRef = int32_t;
|
||||
enum MachineType : uint8_t { // Bit width
|
||||
NOVALUE = 0,
|
||||
ANYVALUE,
|
||||
@ -218,8 +219,6 @@ std::string MachineTypeToStr(MachineType machineType);
|
||||
V(SwitchBranch, SWITCH_BRANCH, false, 1, 0, 1) \
|
||||
V(SwitchCase, SWITCH_CASE, false, 1, 0, 0) \
|
||||
V(HeapAlloc, HEAP_ALLOC, false, 1, 1, 1) \
|
||||
V(RestoreRegister, RESTORE_REGISTER, false, 0, 1, 0) \
|
||||
V(SaveRegister, SAVE_REGISTER, false, 0, 1, 1) \
|
||||
V(LoadElement, LOAD_ELEMENT, false, 1, 1, 2) \
|
||||
V(StoreElement, STORE_ELEMENT, false, 1, 1, 3) \
|
||||
V(ConstData, CONST_DATA, false, 0, 0, 0) \
|
||||
@ -234,6 +233,12 @@ std::string MachineTypeToStr(MachineType machineType);
|
||||
#define GATE_META_DATA_LIST_WITH_STRING(V) \
|
||||
V(ConstString, CONSTSTRING, false, 0, 0, 0)
|
||||
|
||||
#define GATE_META_DATA_IN_SAVE_REGISTER(V) \
|
||||
V(SaveRegister, SAVE_REGISTER, false, 0, 1, value)
|
||||
|
||||
#define GATE_META_DATA_IN_RESTORE_REGISTER(V) \
|
||||
V(RestoreRegister, RESTORE_REGISTER, false, 0, 1, 0)
|
||||
|
||||
#define GATE_OPCODE_LIST(V) \
|
||||
V(JS_BYTECODE) \
|
||||
V(TYPED_BINARY_OP)
|
||||
@ -245,6 +250,8 @@ enum class OpCode : uint8_t {
|
||||
GATE_META_DATA_LIST_WITH_SIZE(DECLARE_GATE_OPCODE)
|
||||
GATE_META_DATA_LIST_WITH_ONE_PARAMETER(DECLARE_GATE_OPCODE)
|
||||
GATE_META_DATA_LIST_WITH_STRING(DECLARE_GATE_OPCODE)
|
||||
GATE_META_DATA_IN_SAVE_REGISTER(DECLARE_GATE_OPCODE)
|
||||
GATE_META_DATA_IN_RESTORE_REGISTER(DECLARE_GATE_OPCODE)
|
||||
#undef DECLARE_GATE_OPCODE
|
||||
#define DECLARE_GATE_OPCODE(NAME) NAME,
|
||||
GATE_OPCODE_LIST(DECLARE_GATE_OPCODE)
|
||||
@ -261,6 +268,8 @@ public:
|
||||
MUTABLE_STRING,
|
||||
JSBYTECODE,
|
||||
TYPED_BINARY_OP,
|
||||
SAVE_REGISTERS_OP,
|
||||
RESTORE_REGISTERS_OP,
|
||||
};
|
||||
GateMetaData() = default;
|
||||
explicit GateMetaData(OpCode opcode, bool hasRoot,
|
||||
@ -324,6 +333,16 @@ public:
|
||||
return GetKind() == MUTABLE_STRING;
|
||||
}
|
||||
|
||||
bool IsSaveRegisterOp() const
|
||||
{
|
||||
return GetKind() == SAVE_REGISTERS_OP;
|
||||
}
|
||||
|
||||
bool IsRestoreRegisterOp() const
|
||||
{
|
||||
return GetKind() == RESTORE_REGISTERS_OP;
|
||||
}
|
||||
|
||||
bool IsRoot() const;
|
||||
bool IsProlog() const;
|
||||
bool IsFixed() const;
|
||||
@ -440,6 +459,55 @@ private:
|
||||
uint64_t value_ { 0 };
|
||||
};
|
||||
|
||||
class SaveRegsMetaData : public GateMetaData {
|
||||
public:
|
||||
explicit SaveRegsMetaData(OpCode opcode, bool hasRoot, uint32_t statesIn, uint16_t dependsIn, uint32_t valuesIn,
|
||||
uint64_t value) : GateMetaData(opcode, hasRoot, statesIn, dependsIn, valuesIn), numValue_(value)
|
||||
{
|
||||
SetKind(GateMetaData::SAVE_REGISTERS_OP);
|
||||
}
|
||||
|
||||
static const SaveRegsMetaData* Cast(const GateMetaData* meta)
|
||||
{
|
||||
ASSERT(meta->IsSaveRegisterOp());
|
||||
return static_cast<const SaveRegsMetaData*>(meta);
|
||||
}
|
||||
|
||||
uint64_t GetNumValue() const
|
||||
{
|
||||
return numValue_;
|
||||
}
|
||||
private:
|
||||
uint64_t numValue_ { 0 };
|
||||
};
|
||||
|
||||
class RestoreRegsMetaData : public GateMetaData {
|
||||
public:
|
||||
explicit RestoreRegsMetaData() : GateMetaData(OpCode::RESTORE_REGISTER, false, 0, 1, 0)
|
||||
{
|
||||
SetKind(GateMetaData::RESTORE_REGISTERS_OP);
|
||||
}
|
||||
|
||||
static const RestoreRegsMetaData* Cast(const GateMetaData* meta)
|
||||
{
|
||||
ASSERT(meta->IsRestoreRegisterOp());
|
||||
return static_cast<const RestoreRegsMetaData*>(meta);
|
||||
}
|
||||
|
||||
const std::map<std::pair<GateRef, uint32_t>, uint32_t> &GetRestoreRegsInfo() const
|
||||
{
|
||||
return restoreRegsInfo_;
|
||||
}
|
||||
|
||||
void SetRestoreRegsInfo(std::pair<GateRef, uint32_t> &needReplaceInfo, uint32_t regIdx)
|
||||
{
|
||||
restoreRegsInfo_[needReplaceInfo] = regIdx;
|
||||
}
|
||||
private:
|
||||
std::map<std::pair<GateRef, uint32_t>, uint32_t> restoreRegsInfo_;
|
||||
};
|
||||
|
||||
|
||||
class TypedBinaryMegaData : public OneParameterMetaData {
|
||||
public:
|
||||
explicit TypedBinaryMegaData(uint64_t value, TypedBinOp binOp)
|
||||
|
@ -107,6 +107,11 @@ public:
|
||||
GATE_META_DATA_LIST_WITH_ONE_PARAMETER(DECLARE_GATE_META)
|
||||
#undef DECLARE_GATE_META
|
||||
|
||||
#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \
|
||||
const GateMetaData* NAME(uint64_t value);
|
||||
GATE_META_DATA_IN_SAVE_REGISTER(DECLARE_GATE_META)
|
||||
#undef DECLARE_GATE_META
|
||||
|
||||
explicit GateMetaBuilder(Chunk* chunk);
|
||||
const GateMetaData* JSBytecode(size_t valuesIn, EcmaOpcode opcode, uint32_t bcIndex)
|
||||
{
|
||||
@ -123,6 +128,11 @@ public:
|
||||
return &cachedNop_;
|
||||
}
|
||||
|
||||
const GateMetaData* RestoreRegister()
|
||||
{
|
||||
return new (chunk_) RestoreRegsMetaData();
|
||||
}
|
||||
|
||||
GateMetaData* NewGateMetaData(const GateMetaData* other)
|
||||
{
|
||||
auto meta = new (chunk_) GateMetaData(other->opcode_, other->HasRoot(),
|
||||
|
@ -798,13 +798,9 @@ void SlowPathLowering::SaveFrameToContext(GateRef gate, GateRef jsFunc)
|
||||
GateRef genObj = acc_.GetValueIn(gate, 1);
|
||||
GateRef saveRegister = acc_.GetDep(gate);
|
||||
ASSERT(acc_.GetOpCode(saveRegister) == OpCode::SAVE_REGISTER);
|
||||
std::vector<GateRef> saveRegisterGates {};
|
||||
while (acc_.GetOpCode(saveRegister) == OpCode::SAVE_REGISTER) {
|
||||
saveRegisterGates.emplace_back(saveRegister);
|
||||
saveRegister = acc_.GetDep(saveRegister);
|
||||
}
|
||||
acc_.SetDep(gate, saveRegister);
|
||||
builder_.SetDepend(saveRegister);
|
||||
|
||||
acc_.SetDep(gate, acc_.GetDep(saveRegister));
|
||||
builder_.SetDepend(acc_.GetDep(saveRegister));
|
||||
GateRef context =
|
||||
builder_.Load(VariableType::JS_POINTER(), genObj, builder_.IntPtr(JSGeneratorObject::GENERATOR_CONTEXT_OFFSET));
|
||||
// new tagged array
|
||||
@ -815,12 +811,18 @@ void SlowPathLowering::SaveFrameToContext(GateRef gate, GateRef jsFunc)
|
||||
const int arrayId = RTSTUB_ID(NewTaggedArray);
|
||||
GateRef taggedArray = LowerCallRuntime(arrayId, {taggedLength});
|
||||
// setRegsArrays
|
||||
for (auto item : saveRegisterGates) {
|
||||
auto index = acc_.GetVirtualRegisterIndex(item);
|
||||
auto valueGate = acc_.GetValueIn(item);
|
||||
builder_.SetValueToTaggedArray(VariableType::JS_ANY(), glue_, taggedArray, builder_.Int32(index), valueGate);
|
||||
acc_.DeleteGate(item);
|
||||
}
|
||||
auto hole = circuit_->GetConstantGate(MachineType::I64,
|
||||
JSTaggedValue::VALUE_HOLE,
|
||||
GateType::TaggedValue());
|
||||
size_t numVreg = acc_.GetNumOfSaveRegs(saveRegister);
|
||||
for (size_t idx = 0; idx < numVreg; idx++) {
|
||||
GateRef tmpGate = acc_.GetValueIn(saveRegister, idx);
|
||||
if (tmpGate != hole) {
|
||||
builder_.SetValueToTaggedArray(VariableType::JS_ANY(), glue_, taggedArray, builder_.Int32(idx), tmpGate);
|
||||
}
|
||||
}
|
||||
|
||||
acc_.DeleteGate(saveRegister);
|
||||
|
||||
// setRegsArrays
|
||||
GateRef regsArrayOffset = builder_.IntPtr(GeneratorContext::GENERATOR_REGS_ARRAY_OFFSET);
|
||||
@ -3100,37 +3102,36 @@ GateRef SlowPathLowering::GetValueFromTaggedArray(GateRef arrayGate, GateRef ind
|
||||
void SlowPathLowering::LowerResumeGenerator(GateRef gate)
|
||||
{
|
||||
GateRef obj = acc_.GetValueIn(gate, 0);
|
||||
GateRef restoreGate = acc_.GetDep(gate);
|
||||
std::vector<GateRef> registerGates {};
|
||||
GateRef restoreRegs = acc_.GetDep(gate);
|
||||
auto restoreInfo = acc_.GetRestoreRegsInfo(restoreRegs);
|
||||
|
||||
while (acc_.GetOpCode(restoreGate) == OpCode::RESTORE_REGISTER) {
|
||||
registerGates.emplace_back(restoreGate);
|
||||
restoreGate = acc_.GetDep(restoreGate);
|
||||
}
|
||||
|
||||
acc_.SetDep(gate, restoreGate);
|
||||
builder_.SetDepend(restoreGate);
|
||||
acc_.SetDep(gate, acc_.GetDep(restoreRegs));
|
||||
builder_.SetDepend(acc_.GetDep(restoreRegs));
|
||||
GateRef contextOffset = builder_.IntPtr(JSGeneratorObject::GENERATOR_CONTEXT_OFFSET);
|
||||
GateRef contextGate = builder_.Load(VariableType::JS_POINTER(), obj, contextOffset);
|
||||
GateRef arrayOffset = builder_.IntPtr(GeneratorContext::GENERATOR_REGS_ARRAY_OFFSET);
|
||||
GateRef arrayGate = builder_.Load(VariableType::JS_POINTER(), contextGate, arrayOffset);
|
||||
|
||||
for (auto item : registerGates) {
|
||||
auto index = acc_.GetVirtualRegisterIndex(item);
|
||||
auto indexOffset = builder_.Int32(index);
|
||||
GateRef value = GetValueFromTaggedArray(arrayGate, indexOffset);
|
||||
auto uses = acc_.Uses(item);
|
||||
for (auto use = uses.begin(); use != uses.end();) {
|
||||
size_t valueStartIndex = acc_.GetStateCount(*use) + acc_.GetDependCount(*use);
|
||||
size_t valueEndIndex = valueStartIndex + acc_.GetInValueCount(*use);
|
||||
if (use.GetIndex() >= valueStartIndex && use.GetIndex() < valueEndIndex) {
|
||||
use = acc_.ReplaceIn(use, value);
|
||||
} else {
|
||||
use++;
|
||||
}
|
||||
auto uses = acc_.Uses(restoreRegs);
|
||||
for (auto use = uses.begin(); use != uses.end();) {
|
||||
int32_t vregId;
|
||||
if (acc_.GetOpCode(*use) == OpCode::SAVE_REGISTER) {
|
||||
vregId = use.GetIndex() - 1;
|
||||
} else {
|
||||
std::pair<GateRef, uint32_t> info(*use, use.GetIndex());
|
||||
vregId = restoreInfo[info];
|
||||
}
|
||||
acc_.DeleteGate(item);
|
||||
}
|
||||
auto vregIdOffset = builder_.Int32(vregId);
|
||||
GateRef value = GetValueFromTaggedArray(arrayGate, vregIdOffset);
|
||||
size_t valueStartIndex = acc_.GetStateCount(*use) + acc_.GetDependCount(*use);
|
||||
size_t valueEndIndex = valueStartIndex + acc_.GetInValueCount(*use);
|
||||
if (use.GetIndex() >= valueStartIndex && use.GetIndex() < valueEndIndex) {
|
||||
use = acc_.ReplaceIn(use, value);
|
||||
} else {
|
||||
use++;
|
||||
}
|
||||
}
|
||||
acc_.DeleteGate(restoreRegs);
|
||||
|
||||
// 1: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 1);
|
||||
|
Loading…
Reference in New Issue
Block a user