!3269 Refactor save register and restore register

Merge pull request !3269 from 许杰/refactor_generator
This commit is contained in:
openharmony_ci 2022-12-23 12:15:29 +00:00 committed by Gitee
commit 94b01d742c
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
14 changed files with 226 additions and 85 deletions

View File

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

View File

@ -57,8 +57,6 @@ private:
void UpdateValueSelector(GateRef prevLoopBeginGate, GateRef controlStateGate, GateRef prevBcOffsetPhiGate);
GateRef GetFirstRestoreRegister(GateRef gate) const;
BytecodeCircuitBuilder *bcBuilder_;
Circuit *circuit_;
CircuitBuilder builder_;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,27 +3102,27 @@ 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);
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];
}
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) {
@ -3129,8 +3131,7 @@ void SlowPathLowering::LowerResumeGenerator(GateRef gate)
use++;
}
}
acc_.DeleteGate(item);
}
acc_.DeleteGate(restoreRegs);
// 1: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 1);