mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-06 23:54:03 +00:00
Refactor build deopt frame state
use dfs order build frame state issue: I5VVZQ Signed-off-by: sunzhe23 <sunzhe23@huawei.com>
This commit is contained in:
parent
b3f51ddf4c
commit
5c51bf4087
@ -63,13 +63,13 @@ size_t ArgumentAccessor::GetFunctionArgIndex(const size_t currentVreg, const boo
|
||||
return static_cast<size_t>(CommonArgIdx::NEW_TARGET);
|
||||
}
|
||||
if (!haveFunc && currentVreg == 1) {
|
||||
return static_cast<size_t>(CommonArgIdx::THIS);
|
||||
return static_cast<size_t>(CommonArgIdx::THIS_OBJECT);
|
||||
}
|
||||
if (!haveNewTarget && currentVreg == 0) {
|
||||
return static_cast<size_t>(CommonArgIdx::FUNC);
|
||||
}
|
||||
if (!haveNewTarget && currentVreg == 1) {
|
||||
return static_cast<size_t>(CommonArgIdx::THIS);
|
||||
return static_cast<size_t>(CommonArgIdx::THIS_OBJECT);
|
||||
}
|
||||
if (!haveThis && currentVreg == 0) {
|
||||
return static_cast<size_t>(CommonArgIdx::FUNC);
|
||||
@ -87,7 +87,7 @@ size_t ArgumentAccessor::GetFunctionArgIndex(const size_t currentVreg, const boo
|
||||
return static_cast<size_t>(CommonArgIdx::NEW_TARGET);
|
||||
}
|
||||
if (haveThis) {
|
||||
return static_cast<size_t>(CommonArgIdx::THIS);
|
||||
return static_cast<size_t>(CommonArgIdx::THIS_OBJECT);
|
||||
}
|
||||
}
|
||||
return currentVreg - numCommonArgs + static_cast<size_t>(CommonArgIdx::NUM_OF_ARGS);
|
||||
|
@ -29,7 +29,7 @@ enum class CommonArgIdx : uint8_t {
|
||||
ACTUAL_ARGC,
|
||||
FUNC,
|
||||
NEW_TARGET,
|
||||
THIS,
|
||||
THIS_OBJECT,
|
||||
NUM_OF_ARGS,
|
||||
};
|
||||
|
||||
|
@ -385,8 +385,10 @@ void BytecodeCircuitBuilder::BuildBasicBlocks(std::map<std::pair<uint8_t *, uint
|
||||
void BytecodeCircuitBuilder::ComputeDominatorTree()
|
||||
{
|
||||
// Construct graph backward order
|
||||
std::map<size_t, size_t> bbIdToDfsTimestamp;
|
||||
std::unordered_map<size_t, size_t> dfsFatherIdx;
|
||||
std::unordered_map<size_t, size_t> bbDfsTimestampToIdx;
|
||||
std::vector<size_t> basicBlockList;
|
||||
size_t timestamp = 0;
|
||||
std::deque<size_t> pendingList;
|
||||
std::vector<size_t> visited(graph_.size(), 0);
|
||||
@ -396,30 +398,30 @@ void BytecodeCircuitBuilder::ComputeDominatorTree()
|
||||
while (!pendingList.empty()) {
|
||||
size_t curBlockId = pendingList.back();
|
||||
pendingList.pop_back();
|
||||
bbDfsList_.push_back(curBlockId);
|
||||
bbIdToDfsTimestamp_[curBlockId] = timestamp++;
|
||||
basicBlockList.push_back(curBlockId);
|
||||
bbIdToDfsTimestamp[curBlockId] = timestamp++;
|
||||
for (const auto &succBlock: graph_[curBlockId].succs) {
|
||||
if (visited[succBlock->id] == 0) {
|
||||
visited[succBlock->id] = 1;
|
||||
pendingList.push_back(succBlock->id);
|
||||
dfsFatherIdx[succBlock->id] = bbIdToDfsTimestamp_[curBlockId];
|
||||
dfsFatherIdx[succBlock->id] = bbIdToDfsTimestamp[curBlockId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t idx = 0; idx < bbDfsList_.size(); idx++) {
|
||||
bbDfsTimestampToIdx[bbDfsList_[idx]] = idx;
|
||||
for (size_t idx = 0; idx < basicBlockList.size(); idx++) {
|
||||
bbDfsTimestampToIdx[basicBlockList[idx]] = idx;
|
||||
}
|
||||
RemoveDeadRegions();
|
||||
RemoveDeadRegions(bbIdToDfsTimestamp);
|
||||
|
||||
std::vector<size_t> immDom(bbDfsList_.size()); // immediate dominator with dfs order index
|
||||
std::vector<size_t> semiDom(bbDfsList_.size());
|
||||
std::vector<size_t> immDom(basicBlockList.size()); // immediate dominator with dfs order index
|
||||
std::vector<size_t> semiDom(basicBlockList.size());
|
||||
std::vector<size_t> realImmDom(graph_.size()); // immediate dominator with real index
|
||||
std::vector<std::vector<size_t> > semiDomTree(bbDfsList_.size());
|
||||
std::vector<std::vector<size_t> > semiDomTree(basicBlockList.size());
|
||||
{
|
||||
std::vector<size_t> parent(bbDfsList_.size());
|
||||
std::vector<size_t> parent(basicBlockList.size());
|
||||
std::iota(parent.begin(), parent.end(), 0);
|
||||
std::vector<size_t> minIdx(bbDfsList_.size());
|
||||
std::vector<size_t> minIdx(basicBlockList.size());
|
||||
std::function<size_t(size_t)> unionFind = [&] (size_t idx) -> size_t {
|
||||
if (parent[idx] == idx) return idx;
|
||||
size_t unionFindSetRoot = unionFind(parent[idx]);
|
||||
@ -435,8 +437,8 @@ void BytecodeCircuitBuilder::ComputeDominatorTree()
|
||||
};
|
||||
std::iota(semiDom.begin(), semiDom.end(), 0);
|
||||
semiDom[0] = semiDom.size();
|
||||
for (size_t idx = bbDfsList_.size() - 1; idx >= 1; idx--) {
|
||||
for (const auto &preBlock : graph_[bbDfsList_[idx]].preds) {
|
||||
for (size_t idx = basicBlockList.size() - 1; idx >= 1; idx--) {
|
||||
for (const auto &preBlock : graph_[basicBlockList[idx]].preds) {
|
||||
if (bbDfsTimestampToIdx[preBlock->id] < idx) {
|
||||
semiDom[idx] = std::min(semiDom[idx], bbDfsTimestampToIdx[preBlock->id]);
|
||||
} else {
|
||||
@ -453,14 +455,14 @@ void BytecodeCircuitBuilder::ComputeDominatorTree()
|
||||
}
|
||||
}
|
||||
minIdx[idx] = idx;
|
||||
merge(dfsFatherIdx[bbDfsList_[idx]], idx);
|
||||
merge(dfsFatherIdx[basicBlockList[idx]], idx);
|
||||
semiDomTree[semiDom[idx]].push_back(idx);
|
||||
}
|
||||
for (size_t idx = 1; idx < bbDfsList_.size(); idx++) {
|
||||
for (size_t idx = 1; idx < basicBlockList.size(); idx++) {
|
||||
if (immDom[idx] != semiDom[idx]) {
|
||||
immDom[idx] = immDom[immDom[idx]];
|
||||
}
|
||||
realImmDom[bbDfsList_[idx]] = bbDfsList_[immDom[idx]];
|
||||
realImmDom[basicBlockList[idx]] = basicBlockList[immDom[idx]];
|
||||
}
|
||||
semiDom[0] = 0;
|
||||
}
|
||||
@ -525,12 +527,12 @@ void BytecodeCircuitBuilder::ComputeDomFrontiers(const std::vector<size_t> &immD
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeCircuitBuilder::RemoveDeadRegions()
|
||||
void BytecodeCircuitBuilder::RemoveDeadRegions(const std::map<size_t, size_t> &bbIdToDfsTimestamp)
|
||||
{
|
||||
for (auto &block: graph_) {
|
||||
std::vector<BytecodeRegion *> newPreds;
|
||||
for (auto &bb : block.preds) {
|
||||
if (bbIdToDfsTimestamp_.count(bb->id)) {
|
||||
if (bbIdToDfsTimestamp.count(bb->id)) {
|
||||
newPreds.emplace_back(bb);
|
||||
}
|
||||
}
|
||||
@ -538,7 +540,7 @@ void BytecodeCircuitBuilder::RemoveDeadRegions()
|
||||
}
|
||||
|
||||
for (auto &block : graph_) {
|
||||
block.isDead = !bbIdToDfsTimestamp_.count(block.id);
|
||||
block.isDead = !bbIdToDfsTimestamp.count(block.id);
|
||||
if (block.isDead) {
|
||||
block.succs.clear();
|
||||
}
|
||||
@ -1743,7 +1745,6 @@ void BytecodeCircuitBuilder::BuildCircuitArgs()
|
||||
argAcc_.CollectArgs();
|
||||
if (hasTypes_) {
|
||||
argAcc_.FillArgsGateType(&typeRecorder_);
|
||||
frameStateBuilder_.BuildArgsValues(&argAcc_);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1998,7 +1999,7 @@ GateRef BytecodeCircuitBuilder::NewConst(const BytecodeInfo &info)
|
||||
gate = argAcc_.GetCommonArgGate(CommonArgIdx::NEW_TARGET);
|
||||
break;
|
||||
case EcmaOpcode::LDTHIS:
|
||||
gate = argAcc_.GetCommonArgGate(CommonArgIdx::THIS);
|
||||
gate = argAcc_.GetCommonArgGate(CommonArgIdx::THIS_OBJECT);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -2360,56 +2361,125 @@ GateRef BytecodeCircuitBuilder::RenameVariable(const size_t bbId, const uint8_t
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeCircuitBuilder::BuildDfsList()
|
||||
{
|
||||
bbDfsList_.clear();
|
||||
|
||||
std::deque<size_t> pendingList;
|
||||
std::vector<bool> visited(graph_.size(), false);
|
||||
auto basicBlockId = graph_[0].id;
|
||||
pendingList.push_back(basicBlockId);
|
||||
while (!pendingList.empty()) {
|
||||
size_t curBlockId = pendingList.back();
|
||||
if (visited[curBlockId]) {
|
||||
bbDfsList_.push_back(curBlockId);
|
||||
pendingList.pop_back();
|
||||
continue;
|
||||
}
|
||||
visited[curBlockId] = true;
|
||||
for (const auto &succBlock: graph_[curBlockId].succs) {
|
||||
if (!visited[succBlock->id]) {
|
||||
pendingList.push_back(succBlock->id);
|
||||
}
|
||||
}
|
||||
for (const auto &succBlock: graph_[curBlockId].catchs) {
|
||||
if (!visited[succBlock->id]) {
|
||||
pendingList.push_back(succBlock->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeCircuitBuilder::FrameStateReplacePhi(GateRef phi, size_t reg)
|
||||
{
|
||||
ASSERT(gateAcc_.GetOpCode(phi) == OpCode::VALUE_SELECTOR);
|
||||
auto numValue = gateAcc_.GetNumValueIn(phi);
|
||||
for (size_t i = 0; i < numValue; i++) {
|
||||
auto value = gateAcc_.GetValueIn(phi, i);
|
||||
auto it = jsgateToBytecode_.find(value);
|
||||
if (it == jsgateToBytecode_.cend()) {
|
||||
continue;
|
||||
}
|
||||
auto id = jsgateToBytecode_.at(value).first;
|
||||
frameStateBuilder_.AdvenceToBasicBlock(id);
|
||||
frameStateBuilder_.UpdateVirtualRegister(reg, value);
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeCircuitBuilder::BuildFrameState()
|
||||
{
|
||||
const uint8_t *predPc = nullptr;
|
||||
BuildDfsList();
|
||||
auto undefinedGate = circuit_.GetConstantGate(MachineType::I64,
|
||||
JSTaggedValue::VALUE_UNDEFINED,
|
||||
GateType::TaggedValue());
|
||||
for (auto &dfsOrder : bbDfsList_) {
|
||||
auto bb = graph_[dfsOrder];
|
||||
if (bb.isDead) {
|
||||
continue;
|
||||
}
|
||||
if (bb.preds.size() != 0) {
|
||||
std::sort(bb.preds.begin(), bb.preds.end(), [this](BytecodeRegion *a, BytecodeRegion *b) {
|
||||
return bbIdToDfsTimestamp_[a->id] < bbIdToDfsTimestamp_[b->id];
|
||||
});
|
||||
auto predBb = bb.preds.at(0);
|
||||
predPc = predBb->end;
|
||||
}
|
||||
frameStateBuilder_.AdvenceToSuccessor(predPc, bb.end);
|
||||
frameStateBuilder_.AdvenceToBasicBlock(bb.id);
|
||||
ReverseEnumerateBlock(bb, [this, undefinedGate]
|
||||
(uint8_t * pc, BytecodeInfo &bytecodeInfo) -> bool {
|
||||
GateRef gate = Circuit::NullGate();
|
||||
if (bytecodeInfo.IsMov()) {
|
||||
// end def live range
|
||||
if (bytecodeInfo.accOut) {
|
||||
frameStateBuilder_.UpdateAccumulator(undefinedGate);
|
||||
gate = frameStateBuilder_.ValuesAtAccumulator();
|
||||
} else if (bytecodeInfo.vregOut.size() != 0) {
|
||||
auto out = bytecodeInfo.vregOut[0];
|
||||
gate = frameStateBuilder_.ValuesAt(out);
|
||||
frameStateBuilder_.UpdateVirtualRegister(out, undefinedGate);
|
||||
}
|
||||
// start use live range
|
||||
if (bytecodeInfo.accIn) {
|
||||
frameStateBuilder_.UpdateAccumulator(gate);
|
||||
} else if (bytecodeInfo.inputs.size() != 0) {
|
||||
auto vreg = std::get<VirtualRegister>(bytecodeInfo.inputs.at(0)).GetId();
|
||||
frameStateBuilder_.UpdateVirtualRegister(vreg, gate);
|
||||
}
|
||||
return true;
|
||||
} else if (bytecodeInfo.IsGeneral() || bytecodeInfo.IsReturn() || bytecodeInfo.IsCondJump()) {
|
||||
gate = byteCodeToJSGate_.at(pc);
|
||||
}
|
||||
// end def live range
|
||||
if (bytecodeInfo.accOut) {
|
||||
frameStateBuilder_.UpdateAccumulator(undefinedGate);
|
||||
}
|
||||
for (const auto &out: bytecodeInfo.vregOut) {
|
||||
frameStateBuilder_.UpdateVirtualRegister(out, undefinedGate);
|
||||
}
|
||||
// start use live range
|
||||
if (bytecodeInfo.accIn) {
|
||||
auto id = bytecodeInfo.inputs.size();
|
||||
GateRef def = gateAcc_.GetValueIn(gate, id);
|
||||
frameStateBuilder_.UpdateAccumulator(def);
|
||||
}
|
||||
for (size_t i = 0; i < bytecodeInfo.inputs.size(); i++) {
|
||||
auto in = bytecodeInfo.inputs[i];
|
||||
if (std::holds_alternative<VirtualRegister>(in)) {
|
||||
auto vreg = std::get<VirtualRegister>(in).GetId();
|
||||
GateRef def = gateAcc_.GetValueIn(gate, i);
|
||||
frameStateBuilder_.UpdateVirtualRegister(vreg, def);
|
||||
}
|
||||
}
|
||||
// build guard
|
||||
if (bytecodeInfo.deopt) {
|
||||
GateRef glue = argAcc_.GetCommonArgGate(CommonArgIdx::GLUE);
|
||||
frameStateBuilder_.BindGuard(gate, bytecodeInfo.pcOffset, glue);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
// replace phi
|
||||
if (bb.valueSelectorAccGate != Circuit::NullGate()) {
|
||||
frameStateBuilder_.UpdateAccumulator(bb.valueSelectorAccGate);
|
||||
auto reg = frameStateBuilder_.GetAccumulatorIndex();
|
||||
FrameStateReplacePhi(bb.valueSelectorAccGate, reg);
|
||||
}
|
||||
for (auto &it : bb.vregToValSelectorGate) {
|
||||
auto reg = it.first;
|
||||
auto gate = it.second;
|
||||
frameStateBuilder_.UpdateVirtualRegister(reg, gate);
|
||||
FrameStateReplacePhi(gate, reg);
|
||||
}
|
||||
EnumerateBlock(bb, [this](uint8_t * pc, BytecodeInfo &bytecodeInfo) -> bool {
|
||||
GateRef gate = Circuit::NullGate();
|
||||
if (bytecodeInfo.IsMov()) {
|
||||
if (bytecodeInfo.accIn) {
|
||||
gate = frameStateBuilder_.ValuesAtAccumulator();
|
||||
} else if (bytecodeInfo.inputs.size() != 0) {
|
||||
auto index = std::get<VirtualRegister>(bytecodeInfo.inputs.at(0)).GetId();
|
||||
gate = frameStateBuilder_.ValuesAt(index);
|
||||
}
|
||||
} else if (bytecodeInfo.IsGeneral()) {
|
||||
gate = byteCodeToJSGate_.at(pc);
|
||||
if (bytecodeInfo.deopt) {
|
||||
GateRef glue = argAcc_.GetCommonArgGate(CommonArgIdx::GLUE);
|
||||
frameStateBuilder_.BindGuard(gate, bytecodeInfo.pcOffset, glue, jsgateToBytecode_);
|
||||
}
|
||||
} else if (bytecodeInfo.IsSetConstant()) {
|
||||
gate = byteCodeToJSGate_.at(pc);
|
||||
}
|
||||
if (bytecodeInfo.accOut) {
|
||||
frameStateBuilder_.UpdateAccumulator(gate);
|
||||
}
|
||||
for (const auto &out: bytecodeInfo.vregOut) {
|
||||
frameStateBuilder_.UpdateVirtualRegister(out, gate);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -571,6 +571,23 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <class Callback>
|
||||
void ReverseEnumerateBlock(BytecodeRegion &bb, const Callback &cb)
|
||||
{
|
||||
auto pc = bb.end;
|
||||
while (true) {
|
||||
auto bytecodeInfo = GetBytecodeInfo(pc);
|
||||
bool ret = cb(pc, bytecodeInfo);
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
pc = byteCodeCurPrePc_.at(pc);
|
||||
if (pc <= bb.start || pc >= bb.end) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::map<const uint8_t *, int32_t> &GetPcToBCOffset() const
|
||||
{
|
||||
return pcToBCOffset_;
|
||||
@ -583,7 +600,7 @@ private:
|
||||
void ComputeDominatorTree();
|
||||
void BuildImmediateDominator(const std::vector<size_t> &immDom);
|
||||
void ComputeDomFrontiers(const std::vector<size_t> &immDom);
|
||||
void RemoveDeadRegions();
|
||||
void RemoveDeadRegions(const std::map<size_t, size_t> &bbIdToDfsTimestamp);
|
||||
void InsertPhi();
|
||||
void InsertExceptionPhi(std::map<uint16_t, std::set<size_t>> &defsitesInfo);
|
||||
void UpdateCFG();
|
||||
@ -606,6 +623,8 @@ private:
|
||||
void NewPhi(BytecodeRegion &bb, uint16_t reg, bool acc, GateRef ¤tPhi);
|
||||
GateRef RenameVariable(const size_t bbId, const uint8_t *end, const uint16_t reg, const bool acc);
|
||||
void BuildCircuit();
|
||||
void BuildDfsList();
|
||||
void FrameStateReplacePhi(GateRef phi, size_t reg);
|
||||
void BuildFrameState();
|
||||
GateRef GetExistingRestore(GateRef resumeGate, uint16_t tmpReg) const;
|
||||
void SetExistingRestore(GateRef resumeGate, uint16_t tmpReg, GateRef restoreGate);
|
||||
@ -641,7 +660,6 @@ private:
|
||||
FrameStateBuilder frameStateBuilder_;
|
||||
std::string methodName_;
|
||||
std::vector<size_t> bbDfsList_;
|
||||
std::map<size_t, size_t> bbIdToDfsTimestamp_; // (basicblock id, dfs order)
|
||||
};
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_CLASS_LINKER_BYTECODE_CIRCUIT_IR_BUILDER_H
|
||||
|
@ -375,29 +375,9 @@ GateRef CircuitBuilder::TaggedFalse()
|
||||
|
||||
GateRef CircuitBuilder::GetValueFromTaggedArray(GateRef array, GateRef index)
|
||||
{
|
||||
Label subentry(env_);
|
||||
SubCfgEntry(&subentry);
|
||||
Label exit(env_);
|
||||
Label isUndefined(env_);
|
||||
Label notUndefined(env_);
|
||||
GateRef initVal = UndefineConstant();
|
||||
DEFVAlUE(result, env_, VariableType::JS_ANY(), initVal);
|
||||
Branch(TaggedIsUndefined(array), &isUndefined, ¬Undefined);
|
||||
Bind(&isUndefined);
|
||||
{
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(¬Undefined);
|
||||
{
|
||||
GateRef offset = PtrMul(ChangeInt32ToIntPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
|
||||
GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
|
||||
result = Load(VariableType::JS_ANY(), array, dataOffset);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&exit);
|
||||
auto ret = *result;
|
||||
SubCfgExit();
|
||||
return ret;
|
||||
GateRef offset = PtrMul(ChangeInt32ToIntPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
|
||||
GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
|
||||
return Load(VariableType::JS_ANY(), array, dataOffset);
|
||||
}
|
||||
|
||||
void CircuitBuilder::SetValueToTaggedArray(VariableType valType, GateRef glue,
|
||||
|
@ -12,7 +12,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "ecmascript/compiler/argument_accessor.h"
|
||||
#include "ecmascript/compiler/frame_states.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
@ -24,7 +23,6 @@ FrameStateInfo *FrameStateInfo::Clone()
|
||||
FrameStateBuilder::FrameStateBuilder(Circuit *circuit, const MethodLiteral *literal)
|
||||
: literal_(literal), circuit_(circuit), gateAcc_(circuit)
|
||||
{
|
||||
currentInfo_ = new FrameStateInfo(literal_);
|
||||
}
|
||||
|
||||
FrameStateBuilder::~FrameStateBuilder()
|
||||
@ -37,62 +35,28 @@ FrameStateBuilder::~FrameStateBuilder()
|
||||
currentInfo_ = nullptr;
|
||||
}
|
||||
|
||||
void FrameStateBuilder::BuildArgsValues(ArgumentAccessor *argAcc)
|
||||
void FrameStateBuilder::InitFrameValues()
|
||||
{
|
||||
auto callFieldNumVregs = literal_->GetNumVregsWithCallField();
|
||||
auto values = currentInfo_->GetValues();
|
||||
auto undefinedGate = circuit_->GetConstantGate(MachineType::I64,
|
||||
JSTaggedValue::VALUE_UNDEFINED,
|
||||
GateType::TaggedValue());
|
||||
auto values = currentInfo_->GetValues();
|
||||
for (size_t i = 0; i < callFieldNumVregs; i++) {
|
||||
values->push_back(undefinedGate);
|
||||
}
|
||||
if (literal_->HaveFuncWithCallField()) {
|
||||
auto gate = argAcc->GetCommonArgGate(CommonArgIdx::FUNC);
|
||||
values->push_back(gate);
|
||||
}
|
||||
if (literal_->HaveNewTargetWithCallField()) {
|
||||
auto gate = argAcc->GetCommonArgGate(CommonArgIdx::NEW_TARGET);
|
||||
values->push_back(gate);
|
||||
}
|
||||
if (literal_->HaveThisWithCallField()) {
|
||||
auto gate = argAcc->GetCommonArgGate(CommonArgIdx::THIS);
|
||||
values->push_back(gate);
|
||||
}
|
||||
|
||||
auto numArgs = literal_->GetNumArgsWithCallField();
|
||||
auto numArgs = literal_->GetNumberVRegs();
|
||||
for (size_t i = 0; i < numArgs; i++) {
|
||||
auto gate = argAcc->ArgsAt(i + static_cast<size_t>(CommonArgIdx::NUM_OF_ARGS));
|
||||
values->push_back(gate);
|
||||
values->push_back(undefinedGate);
|
||||
}
|
||||
// push acc
|
||||
values->push_back(undefinedGate);
|
||||
ASSERT(currentInfo_->GetNumberVRegs() == values->size());
|
||||
}
|
||||
|
||||
GateRef FrameStateBuilder::FrameState(size_t pcOffset,
|
||||
std::map<GateRef, std::pair<size_t, const uint8_t *>> &jsgateToBytecode)
|
||||
GateRef FrameStateBuilder::FrameState(size_t pcOffset)
|
||||
{
|
||||
auto numVregs = currentInfo_->GetNumberVRegs();
|
||||
size_t frameStateInputs = numVregs + 1; // +1: for pc
|
||||
std::vector<GateRef> inList(frameStateInputs, Circuit::NullGate());
|
||||
for (size_t i = 0; i < numVregs; i++) {
|
||||
auto iter = jsgateToBytecode.find(ValuesAt(i));
|
||||
if (iter != jsgateToBytecode.end()) {
|
||||
auto pc = iter->second.second;
|
||||
BytecodeInstruction inst(pc);
|
||||
EcmaOpcode op = inst.GetOpcode();
|
||||
// vreg needed remove from framstate if it comes from RESUMEGENERATOR, otherwisethe upperbound will not be
|
||||
// found
|
||||
if (op == EcmaOpcode::RESUMEGENERATOR) {
|
||||
inList[i] = circuit_->GetConstantGate(MachineType::I64, JSTaggedValue::VALUE_UNDEFINED,
|
||||
GateType::TaggedValue());
|
||||
} else {
|
||||
inList[i] = ValuesAt(i);
|
||||
}
|
||||
} else {
|
||||
inList[i] = ValuesAt(i);
|
||||
}
|
||||
inList[i] = ValuesAt(i);
|
||||
}
|
||||
auto pcGate = circuit_->GetConstantGate(MachineType::I64,
|
||||
pcOffset,
|
||||
@ -101,11 +65,10 @@ GateRef FrameStateBuilder::FrameState(size_t pcOffset,
|
||||
return circuit_->NewGate(OpCode(OpCode::FRAME_STATE), frameStateInputs, inList, GateType::Empty());
|
||||
}
|
||||
|
||||
void FrameStateBuilder::BindGuard(GateRef gate, size_t pcOffset, GateRef glue,
|
||||
std::map<GateRef, std::pair<size_t, const uint8_t *>> &jsgateToBytecode)
|
||||
void FrameStateBuilder::BindGuard(GateRef gate, size_t pcOffset, GateRef glue)
|
||||
{
|
||||
auto depend = gateAcc_.GetDep(gate);
|
||||
GateRef frameState = FrameState(pcOffset, jsgateToBytecode);
|
||||
GateRef frameState = FrameState(pcOffset);
|
||||
auto trueGate = circuit_->GetConstantGate(MachineType::I1,
|
||||
1, // 1: true
|
||||
GateType::NJSValue());
|
||||
@ -114,18 +77,19 @@ void FrameStateBuilder::BindGuard(GateRef gate, size_t pcOffset, GateRef glue,
|
||||
gateAcc_.ReplaceDependIn(gate, guard);
|
||||
}
|
||||
|
||||
void FrameStateBuilder::AdvenceToSuccessor(const uint8_t *predPc, const uint8_t *endPc)
|
||||
void FrameStateBuilder::AdvenceToBasicBlock(size_t id)
|
||||
{
|
||||
size_t pcOffset = static_cast<size_t>(endPc - literal_->GetBytecodeArray());
|
||||
if (predPc != nullptr) {
|
||||
size_t predPcOffset = static_cast<size_t>(predPc - literal_->GetBytecodeArray());
|
||||
auto predFrameInfo = stateInfos_[predPcOffset];
|
||||
ASSERT(predFrameInfo != nullptr);
|
||||
currentInfo_ = predFrameInfo;
|
||||
currentInfo_ = CloneFrameState(pcOffset);
|
||||
} else {
|
||||
// for first block
|
||||
stateInfos_[pcOffset] = currentInfo_;
|
||||
if (currentInfo_ == nullptr) {
|
||||
// for last block
|
||||
currentInfo_ = new FrameStateInfo(literal_);
|
||||
stateInfos_[id] = currentInfo_;
|
||||
InitFrameValues();
|
||||
return;
|
||||
}
|
||||
auto frameInfo = stateInfos_[id];
|
||||
if (frameInfo == nullptr) {
|
||||
frameInfo = CloneFrameState(currentInfo_, id);
|
||||
}
|
||||
currentInfo_ = frameInfo;
|
||||
}
|
||||
}
|
@ -77,6 +77,10 @@ public:
|
||||
SetValuesAt(index, gate);
|
||||
}
|
||||
FrameStateInfo *Clone();
|
||||
size_t GetAccumulatorIndex() const
|
||||
{
|
||||
return accumulator_index_;
|
||||
}
|
||||
private:
|
||||
size_t numVregs_ {0};
|
||||
size_t accumulator_index_ {0};
|
||||
@ -100,7 +104,6 @@ public:
|
||||
return currentInfo_->ValuesAtAccumulator();
|
||||
}
|
||||
|
||||
void BuildArgsValues(ArgumentAccessor *argAcc);
|
||||
void UpdateAccumulator(GateRef gate)
|
||||
{
|
||||
currentInfo_->UpdateAccumulator(gate);
|
||||
@ -109,19 +112,22 @@ public:
|
||||
{
|
||||
currentInfo_->UpdateVirtualRegister(index, gate);
|
||||
}
|
||||
void BindGuard(GateRef gate, size_t pcOffset, GateRef glue,
|
||||
std::map<GateRef, std::pair<size_t, const uint8_t *>> &jsgateToBytecode);
|
||||
|
||||
void AdvenceToSuccessor(const uint8_t *predPc, const uint8_t *endPc);
|
||||
private:
|
||||
FrameStateInfo *CloneFrameState(size_t pcOffset)
|
||||
void BindGuard(GateRef gate, size_t pcOffset, GateRef glue);
|
||||
void AdvenceToBasicBlock(size_t id);
|
||||
size_t GetAccumulatorIndex() const
|
||||
{
|
||||
ASSERT(stateInfos_[pcOffset] == nullptr);
|
||||
auto info = currentInfo_->Clone();
|
||||
stateInfos_[pcOffset] = info;
|
||||
return currentInfo_->GetAccumulatorIndex();
|
||||
}
|
||||
private:
|
||||
FrameStateInfo *CloneFrameState(FrameStateInfo *current, size_t id)
|
||||
{
|
||||
ASSERT(stateInfos_[id] == nullptr);
|
||||
auto info = current->Clone();
|
||||
stateInfos_[id] = info;
|
||||
return info;
|
||||
}
|
||||
GateRef FrameState(size_t pcOffset, std::map<GateRef, std::pair<size_t, const uint8_t *>> &jsgateToBytecode);
|
||||
GateRef FrameState(size_t pcOffset);
|
||||
void InitFrameValues();
|
||||
|
||||
FrameStateInfo *currentInfo_{nullptr};
|
||||
const MethodLiteral *literal_ {nullptr};
|
||||
|
@ -1269,17 +1269,17 @@ std::string Gate::GateTypeStr(GateType gateType) const
|
||||
void Gate::Print(std::string bytecode, bool inListPreview, size_t highlightIdx) const
|
||||
{
|
||||
if (GetOpCode() != OpCode::NOP) {
|
||||
std::string log("(id=" + std::to_string(id_) + ", op=" + GetOpCode().Str() + ", ");
|
||||
log += ((bytecode.compare("") == 0) ? "" : "bytecode=") + bytecode;
|
||||
log += ((bytecode.compare("") == 0) ? "" : ", ");
|
||||
log += "MType=" + MachineTypeStr(GetMachineType()) + ", ";
|
||||
std::string log("{\"id\":" + std::to_string(id_) + ", \"op\":\"" + GetOpCode().Str() + "\", ");
|
||||
log += ((bytecode.compare("") == 0) ? "" : "\"bytecode\":\"") + bytecode;
|
||||
log += ((bytecode.compare("") == 0) ? "" : "\", ");
|
||||
log += "\"MType\":\"" + MachineTypeStr(GetMachineType()) + ", ";
|
||||
std::stringstream buf;
|
||||
buf << std::hex << bitfield_;
|
||||
log += "bitfield=" + buf.str() + ", ";
|
||||
log += "type=" + GateTypeStr(type_) + ", ";
|
||||
log += "stamp=" + std::to_string(static_cast<uint32_t>(stamp_)) + ", ";
|
||||
log += "mark=" + std::to_string(static_cast<uint32_t>(mark_)) + ", ";
|
||||
log += "in=[";
|
||||
log += "\",\"in\":[";
|
||||
|
||||
size_t idx = 0;
|
||||
auto stateSize = GetStateCount();
|
||||
@ -1293,7 +1293,7 @@ void Gate::Print(std::string bytecode, bool inListPreview, size_t highlightIdx)
|
||||
PrintInGate(stateSize + dependSize + valueSize + rootSize, idx, stateSize + dependSize + valueSize,
|
||||
inListPreview, highlightIdx, log, true);
|
||||
|
||||
log += "], out=[";
|
||||
log += "], \"out\":[";
|
||||
|
||||
if (!IsFirstOutNull()) {
|
||||
const Out *curOut = GetFirstOutConst();
|
||||
@ -1302,12 +1302,12 @@ void Gate::Print(std::string bytecode, bool inListPreview, size_t highlightIdx)
|
||||
|
||||
while (!curOut->IsNextOutNull()) {
|
||||
curOut = curOut->GetNextOutConst();
|
||||
log += " " + std::to_string(curOut->GetGateConst()->GetId()) +
|
||||
log += ", " + std::to_string(curOut->GetGateConst()->GetId()) +
|
||||
(inListPreview ? std::string(":" + curOut->GetGateConst()->GetOpCode().Str())
|
||||
: std::string(""));
|
||||
}
|
||||
}
|
||||
log += "])";
|
||||
log += "]},";
|
||||
LOG_COMPILER(INFO) << std::dec << log;
|
||||
}
|
||||
}
|
||||
@ -1315,15 +1315,15 @@ void Gate::Print(std::string bytecode, bool inListPreview, size_t highlightIdx)
|
||||
void Gate::ShortPrint(std::string bytecode, bool inListPreview, size_t highlightIdx) const
|
||||
{
|
||||
if (GetOpCode() != OpCode::NOP) {
|
||||
std::string log("(id=" + std::to_string(id_) + ", op=" + GetOpCode().Str() + ", ");
|
||||
std::string log("(\"id\"=" + std::to_string(id_) + ", \"op\"=\"" + GetOpCode().Str() + "\", ");
|
||||
log += ((bytecode.compare("") == 0) ? "" : "bytecode=") + bytecode;
|
||||
log += ((bytecode.compare("") == 0) ? "" : ", ");
|
||||
log += "MType=" + MachineTypeStr(GetMachineType()) + ", ";
|
||||
log += "\"MType\"=\"" + MachineTypeStr(GetMachineType()) + ", ";
|
||||
std::stringstream buf;
|
||||
buf << std::hex << bitfield_;
|
||||
log += "bitfield=" + buf.str() + ", ";
|
||||
log += "type=" + GateTypeStr(type_) + ", ";
|
||||
log += "in=[";
|
||||
log += "\", in=[";
|
||||
|
||||
size_t idx = 0;
|
||||
auto stateSize = GetStateCount();
|
||||
@ -1346,7 +1346,7 @@ void Gate::ShortPrint(std::string bytecode, bool inListPreview, size_t highlight
|
||||
|
||||
while (!curOut->IsNextOutNull()) {
|
||||
curOut = curOut->GetNextOutConst();
|
||||
log += " " + std::to_string(curOut->GetGateConst()->GetId()) +
|
||||
log += ", " + std::to_string(curOut->GetGateConst()->GetId()) +
|
||||
(inListPreview ? std::string(":" + curOut->GetGateConst()->GetOpCode().Str())
|
||||
: std::string(""));
|
||||
}
|
||||
@ -1361,7 +1361,7 @@ size_t Gate::PrintInGate(size_t numIns, size_t idx, size_t size, bool inListPrev
|
||||
{
|
||||
log += "[";
|
||||
for (; idx < numIns; idx++) {
|
||||
log += ((idx == size) ? "" : " ");
|
||||
log += ((idx == size) ? "" : ", ");
|
||||
log += ((idx == highlightIdx) ? "\033[4;31m" : "");
|
||||
log += ((IsInGateNull(idx)
|
||||
? "N"
|
||||
|
@ -457,4 +457,21 @@ void GateAccessor::DeleteGuardAndFrameState(GateRef gate)
|
||||
DeleteGate(guard);
|
||||
}
|
||||
}
|
||||
|
||||
void GateAccessor::ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value)
|
||||
{
|
||||
auto uses = Uses(gate);
|
||||
for (auto useIt = uses.begin(); useIt != uses.end();) {
|
||||
if (IsStateIn(useIt)) {
|
||||
useIt = ReplaceIn(useIt, state);
|
||||
} else if (IsDependIn(useIt)) {
|
||||
useIt = ReplaceIn(useIt, depend);
|
||||
} else if (IsValueIn(useIt)) {
|
||||
useIt = ReplaceIn(useIt, value);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
DeleteGate(gate);
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -364,6 +364,7 @@ public:
|
||||
bool IsDependIn(GateRef gate, size_t index) const;
|
||||
bool IsValueIn(GateRef gate, size_t index) const;
|
||||
void DeleteGuardAndFrameState(GateRef gate);
|
||||
void ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value);
|
||||
|
||||
private:
|
||||
ConstUseIterator ConstUseBegin(GateRef gate) const
|
||||
|
@ -71,9 +71,6 @@ struct CodeInfo {
|
||||
if (reqSecs_ == reinterpret_cast<uint8_t *>(-1)) {
|
||||
reqSecs_ = nullptr;
|
||||
}
|
||||
// align machineCode for aarch64
|
||||
reqSecs_ += MachineCode::DATA_OFFSET +
|
||||
AlignUp(sizeof(Region), static_cast<size_t>(MemAlignment::MEM_ALIGN_REGION));
|
||||
unreqSecs_ = static_cast<uint8_t *>(mmap(nullptr, UNREQUIRED_SECS_LIMIT, protRWX, flags, -1, 0));
|
||||
if (unreqSecs_ == reinterpret_cast<uint8_t *>(-1)) {
|
||||
unreqSecs_ = nullptr;
|
||||
@ -84,8 +81,6 @@ struct CodeInfo {
|
||||
{
|
||||
Reset();
|
||||
if (reqSecs_ != nullptr) {
|
||||
reqSecs_ -= MachineCode::DATA_OFFSET +
|
||||
AlignUp(sizeof(Region), static_cast<size_t>(MemAlignment::MEM_ALIGN_REGION));
|
||||
munmap(reqSecs_, REQUIRED_SECS_LIMIT);
|
||||
}
|
||||
reqSecs_ = nullptr;
|
||||
|
@ -299,7 +299,7 @@ void SlowPathLowering::Lower(GateRef gate)
|
||||
GateRef newTarget = argAcc_.GetCommonArgGate(CommonArgIdx::NEW_TARGET);
|
||||
GateRef jsFunc = argAcc_.GetCommonArgGate(CommonArgIdx::FUNC);
|
||||
GateRef actualArgc = argAcc_.GetCommonArgGate(CommonArgIdx::ACTUAL_ARGC);
|
||||
GateRef thisObj = argAcc_.GetCommonArgGate(CommonArgIdx::THIS);
|
||||
GateRef thisObj = argAcc_.GetCommonArgGate(CommonArgIdx::THIS_OBJECT);
|
||||
|
||||
auto pc = bcBuilder_->GetJSBytecode(gate);
|
||||
EcmaOpcode op = bcBuilder_->PcToOpcode(pc);
|
||||
@ -869,7 +869,7 @@ void SlowPathLowering::SaveFrameToContext(GateRef gate, GateRef glue, GateRef js
|
||||
|
||||
// set this
|
||||
GateRef thisOffset = builder_.IntPtr(GeneratorContext::GENERATOR_THIS_OFFSET);
|
||||
GateRef thisObj = argAcc_.GetCommonArgGate(CommonArgIdx::THIS);
|
||||
GateRef thisObj = argAcc_.GetCommonArgGate(CommonArgIdx::THIS_OBJECT);
|
||||
builder_.Store(VariableType::JS_ANY(), glue, context, thisOffset, thisObj);
|
||||
|
||||
// set method
|
||||
@ -2851,7 +2851,7 @@ void SlowPathLowering::LowerStObjByValue(GateRef gate, GateRef glue, GateRef thi
|
||||
{
|
||||
GateRef undefined = builder_.UndefineConstant();
|
||||
result = LowerCallRuntime(glue, RTSTUB_ID(StoreICByValue), {undefined, receiver, propKey, accValue,
|
||||
builder_.ToTaggedInt(undefined)});
|
||||
builder_.ToTaggedInt(builder_.Int64(0))});
|
||||
builder_.Branch(builder_.IsSpecial(result, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
}
|
||||
|
@ -1023,17 +1023,16 @@ void OptimizedCall::DeoptHandlerAsm(ExtendedAssembler *assembler)
|
||||
__ CallAssemblerStub(RTSTUB_ID(CallRuntime), false);
|
||||
__ Add(sp, sp, Immediate(DOUBLE_SLOT_SIZE)); // 2: skip runtimeId argc
|
||||
|
||||
__ CalleeRestore();
|
||||
Register context(X2);
|
||||
__ Mov(context, Register(X0));
|
||||
__ Ldr(glueReg, MemoryOperand(sp, 0));
|
||||
|
||||
Register ret(X0);
|
||||
Label stackOverflow;
|
||||
__ Cmp(ret, Immediate(JSTaggedValue::VALUE_EXCEPTION));
|
||||
__ B(Condition::EQ, &stackOverflow);
|
||||
|
||||
__ CalleeRestore();
|
||||
|
||||
Register context(X2);
|
||||
__ Mov(context, Register(X0));
|
||||
__ Ldr(glueReg, MemoryOperand(sp, 0));
|
||||
|
||||
Label target;
|
||||
Register temp(X1);
|
||||
__ Ldr(fp, MemoryOperand(context, AsmStackContext::GetCallerFpOffset(false)));
|
||||
@ -1054,9 +1053,7 @@ void OptimizedCall::DeoptHandlerAsm(ExtendedAssembler *assembler)
|
||||
// 2 : 2 means pair
|
||||
__ Stp(runtimeId, Register(Zero), MemoryOperand(sp, -DOUBLE_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ CallAssemblerStub(RTSTUB_ID(CallRuntime), false);
|
||||
__ Add(sp, sp, Immediate(DOUBLE_SLOT_SIZE)); // 2: skip runtimeId argc
|
||||
|
||||
__ CalleeRestore();
|
||||
__ Add(sp, sp, Immediate(2 * DOUBLE_SLOT_SIZE)); // 2: skip runtimeId&argc glue&type
|
||||
__ RestoreFpAndLr();
|
||||
__ Ret();
|
||||
}
|
||||
|
@ -1272,29 +1272,31 @@ void OptimizedCall::DeoptHandlerAsm(ExtendedAssembler *assembler)
|
||||
{
|
||||
__ BindAssemblerStub(RTSTUB_ID(DeoptHandlerAsm));
|
||||
|
||||
Register glueReg = rdi;
|
||||
__ Pushq(rbp);
|
||||
__ Movq(rsp, rbp);
|
||||
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_FRAME));
|
||||
__ Push(glueReg);
|
||||
__ PushCppCalleeSaveRegisters();
|
||||
|
||||
Register glueReg = rdi;
|
||||
__ Push(glueReg);
|
||||
__ Movq(rdi, rax); // glue
|
||||
__ PushAlignBytes();
|
||||
__ Pushq(0); // argc
|
||||
__ Pushq(kungfu::RuntimeStubCSigns::ID_DeoptHandler);
|
||||
__ CallAssemblerStub(RTSTUB_ID(CallRuntime), false);
|
||||
__ Addq(3 * FRAME_SLOT_SIZE, rsp); // 3: skip runtimeId argc argv[0] argv[1]
|
||||
__ Pop(glueReg);
|
||||
__ Addq(3 * FRAME_SLOT_SIZE, rsp); // 3: skip runtimeId argc & align
|
||||
|
||||
Register context = rsi;
|
||||
__ Movq(rax, context);
|
||||
|
||||
Label target;
|
||||
__ PopCppCalleeSaveRegisters();
|
||||
__ Pop(glueReg);
|
||||
|
||||
Label stackOverflow;
|
||||
__ Cmpq(JSTaggedValue::VALUE_EXCEPTION, rax);
|
||||
__ Je(&stackOverflow);
|
||||
|
||||
Label target;
|
||||
__ PopCppCalleeSaveRegisters();
|
||||
__ Movq(Operand(context, AsmStackContext::GetCallerFpOffset(false)), rbp);
|
||||
__ Movq(Operand(context, AsmStackContext::GetCallFrameTopOffset(false)), rsp);
|
||||
__ Subq(FRAME_SLOT_SIZE, rsp); // skip lr
|
||||
@ -1313,10 +1315,7 @@ void OptimizedCall::DeoptHandlerAsm(ExtendedAssembler *assembler)
|
||||
__ Pushq(0); // argc
|
||||
__ Pushq(kungfu::RuntimeStubCSigns::ID_ThrowStackOverflowException);
|
||||
__ CallAssemblerStub(RTSTUB_ID(CallRuntime), false);
|
||||
__ Addq(16, rsp); // 16: skip runtimeId argc
|
||||
|
||||
__ PopCppCalleeSaveRegisters();
|
||||
__ Addq(FRAME_SLOT_SIZE, rsp);
|
||||
__ Addq(FRAME_SLOT_SIZE * 3, rsp); // skip runtimeId argc & type
|
||||
__ Popq(rbp);
|
||||
__ Ret();
|
||||
}
|
||||
|
@ -432,9 +432,10 @@ void TSTypeLowering::SpeculateNumbers(GateRef gate)
|
||||
// guard maybe not a GUARD
|
||||
GateRef guard = acc_.GetDep(gate);
|
||||
if (check != Circuit::NullGate()) {
|
||||
ASSERT(acc_.GetOpCode(guard) == OpCode::GUARD);
|
||||
acc_.ReplaceIn(guard, 1, check);
|
||||
}
|
||||
|
||||
|
||||
// Replace the old NumberBinaryOp<Op> with TypedBinaryOp<Op>
|
||||
GateRef result = builder_.TypedBinaryOp<Op>(left, right, leftType, rightType, gateType);
|
||||
|
||||
@ -460,6 +461,7 @@ void TSTypeLowering::SpeculateNumber(GateRef gate)
|
||||
// guard maybe not a GUARD
|
||||
GateRef guard = acc_.GetDep(gate);
|
||||
if (check != Circuit::NullGate()) {
|
||||
ASSERT(acc_.GetOpCode(guard) == OpCode::GUARD);
|
||||
acc_.ReplaceIn(guard, 1, check);
|
||||
}
|
||||
|
||||
@ -496,6 +498,7 @@ void TSTypeLowering::LowerPrimitiveTypeToNumber(GateRef gate)
|
||||
// guard maybe not a GUARD
|
||||
GateRef guard = acc_.GetDep(gate);
|
||||
if (check != Circuit::NullGate()) {
|
||||
ASSERT(acc_.GetOpCode(guard) == OpCode::GUARD);
|
||||
acc_.ReplaceIn(guard, 1, check);
|
||||
}
|
||||
|
||||
@ -520,23 +523,6 @@ void TSTypeLowering::SpeculateConditionJump(GateRef gate)
|
||||
GateRef value = acc_.GetValueIn(gate, 0);
|
||||
GateRef condition = builder_.IsSpecial(value, JSTaggedValue::VALUE_FALSE);
|
||||
GateRef ifBranch = builder_.Branch(acc_.GetState(gate), condition);
|
||||
ReplaceGate(gate, ifBranch, builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
||||
void TSTypeLowering::ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value)
|
||||
{
|
||||
auto uses = acc_.Uses(gate);
|
||||
for (auto useIt = uses.begin(); useIt != uses.end();) {
|
||||
if (acc_.IsStateIn(useIt)) {
|
||||
useIt = acc_.ReplaceIn(useIt, state);
|
||||
} else if (acc_.IsDependIn(useIt)) {
|
||||
useIt = acc_.ReplaceIn(useIt, depend);
|
||||
} else if (acc_.IsValueIn(useIt)) {
|
||||
useIt = acc_.ReplaceIn(useIt, value);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
acc_.DeleteGate(gate);
|
||||
acc_.ReplaceGate(gate, ifBranch, builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -48,7 +48,6 @@ private:
|
||||
void DeleteGates(GateRef hir, std::vector<GateRef> &unusedGate);
|
||||
void ReplaceHIRGate(GateRef hir, GateRef outir, GateRef state, GateRef depend,
|
||||
std::vector<GateRef> &unuseGate);
|
||||
void ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value);
|
||||
void LowerTypedAdd(GateRef gate);
|
||||
void LowerTypedSub(GateRef gate);
|
||||
void LowerTypedMul(GateRef gate);
|
||||
|
@ -98,7 +98,7 @@ void TypeLowering::LowerPrimitiveToNumber(GateRef dst, GateRef src, GateType src
|
||||
UNREACHABLE();
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
ReplaceGate(dst, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
acc_.ReplaceGate(dst, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerTypeCheck(GateRef gate)
|
||||
@ -388,7 +388,7 @@ void TypeLowering::LowerNumberAdd(GateRef gate)
|
||||
GateType rightType = GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = CalculateNumbers<OpCode::ADD>(left, right, leftType, rightType);
|
||||
ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberSub(GateRef gate)
|
||||
@ -399,7 +399,7 @@ void TypeLowering::LowerNumberSub(GateRef gate)
|
||||
GateType rightType = GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = CalculateNumbers<OpCode::SUB>(left, right, leftType, rightType);
|
||||
ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberMul(GateRef gate)
|
||||
@ -410,7 +410,7 @@ void TypeLowering::LowerNumberMul(GateRef gate)
|
||||
GateType rightType = GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = CalculateNumbers<OpCode::MUL>(left, right, leftType, rightType);
|
||||
ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberLess(GateRef gate)
|
||||
@ -421,7 +421,7 @@ void TypeLowering::LowerNumberLess(GateRef gate)
|
||||
GateType rightType = GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = CompareNumbers<TypedBinOp::TYPED_LESS>(left, right, leftType, rightType);
|
||||
ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberLessEq(GateRef gate)
|
||||
@ -432,7 +432,7 @@ void TypeLowering::LowerNumberLessEq(GateRef gate)
|
||||
GateType rightType = GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = CompareNumbers<TypedBinOp::TYPED_LESSEQ>(left, right, leftType, rightType);
|
||||
ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberGreater(GateRef gate)
|
||||
@ -443,7 +443,7 @@ void TypeLowering::LowerNumberGreater(GateRef gate)
|
||||
GateType rightType = GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = CompareNumbers<TypedBinOp::TYPED_LESS>(right, left, rightType, leftType);
|
||||
ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberGreaterEq(GateRef gate)
|
||||
@ -454,7 +454,7 @@ void TypeLowering::LowerNumberGreaterEq(GateRef gate)
|
||||
GateType rightType = GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = CompareNumbers<TypedBinOp::TYPED_LESSEQ>(right, left, rightType, leftType);
|
||||
ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberDiv(GateRef gate)
|
||||
@ -465,7 +465,7 @@ void TypeLowering::LowerNumberDiv(GateRef gate)
|
||||
GateType rightType = GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = DivNumbers(left, right, leftType, rightType);
|
||||
ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberEq(GateRef gate)
|
||||
@ -476,7 +476,7 @@ void TypeLowering::LowerNumberEq(GateRef gate)
|
||||
GateType rightType = GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = CompareNumbers<TypedBinOp::TYPED_EQ>(left, right, leftType, rightType);
|
||||
ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberNotEq(GateRef gate)
|
||||
@ -487,7 +487,7 @@ void TypeLowering::LowerNumberNotEq(GateRef gate)
|
||||
GateType rightType = GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = CompareNumbers<TypedBinOp::TYPED_NOTEQ>(left, right, leftType, rightType);
|
||||
ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberInc(GateRef gate)
|
||||
@ -496,7 +496,7 @@ void TypeLowering::LowerNumberInc(GateRef gate)
|
||||
GateType valueType = GetLeftType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = MonocularNumber<TypedUnOp::TYPED_INC>(value, valueType);
|
||||
ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberDec(GateRef gate)
|
||||
@ -505,24 +505,7 @@ void TypeLowering::LowerNumberDec(GateRef gate)
|
||||
GateType valueType = GetLeftType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = MonocularNumber<TypedUnOp::TYPED_DEC>(value, valueType);
|
||||
ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value)
|
||||
{
|
||||
auto uses = acc_.Uses(gate);
|
||||
for (auto useIt = uses.begin(); useIt != uses.end();) {
|
||||
if (acc_.IsStateIn(useIt)) {
|
||||
useIt = acc_.ReplaceIn(useIt, state);
|
||||
} else if (acc_.IsDependIn(useIt)) {
|
||||
useIt = acc_.ReplaceIn(useIt, depend);
|
||||
} else if (acc_.IsValueIn(useIt)) {
|
||||
useIt = acc_.ReplaceIn(useIt, value);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
acc_.DeleteGate(gate);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
template<OpCode::Op Op>
|
||||
|
@ -154,7 +154,6 @@ private:
|
||||
void LowerNumberNotEq(GateRef gate);
|
||||
void LowerNumberInc(GateRef gate);
|
||||
void LowerNumberDec(GateRef gate);
|
||||
void ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value);
|
||||
|
||||
template<OpCode::Op Op>
|
||||
GateRef FastAddOrSubOrMul(GateRef left, GateRef right);
|
||||
|
@ -20,11 +20,6 @@
|
||||
#include "ecmascript/stubs/runtime_stubs-inl.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
using DeoptFromAOTType = JSTaggedType (*)(uintptr_t glue, JSTaggedType* sp,
|
||||
uintptr_t vregsSp, uintptr_t stateSp, JSTaggedType callTarget);
|
||||
static constexpr size_t LEXENV_INDEX = 1;
|
||||
static constexpr size_t THIS_VALUE_INDEX = 5;
|
||||
|
||||
class FrameWriter {
|
||||
public:
|
||||
explicit FrameWriter(Deoptimizier *deoptimizier) : thread_(deoptimizier->GetThread())
|
||||
@ -73,7 +68,7 @@ private:
|
||||
|
||||
void Deoptimizier::CollectVregs(const std::vector<kungfu::ARKDeopt>& deoptBundle)
|
||||
{
|
||||
vregs_.clear();
|
||||
deoptVregs_.clear();
|
||||
for (size_t i = 0; i < deoptBundle.size(); i++) {
|
||||
kungfu::ARKDeopt deopt = deoptBundle.at(i);
|
||||
JSTaggedType v;
|
||||
@ -100,7 +95,7 @@ void Deoptimizier::CollectVregs(const std::vector<kungfu::ARKDeopt>& deoptBundle
|
||||
v = JSTaggedType(static_cast<int64_t>(std::get<kungfu::OffsetType>(deopt.value)));
|
||||
}
|
||||
if (id != static_cast<kungfu::OffsetType>(SpecVregIndex::PC_INDEX)) {
|
||||
vregs_[id] = JSTaggedValue(v);
|
||||
deoptVregs_[id] = JSTaggedValue(v);
|
||||
} else {
|
||||
pc_ = static_cast<uint32_t>(v);
|
||||
}
|
||||
@ -122,23 +117,18 @@ void Deoptimizier::CollectDeoptBundleVec(std::vector<kungfu::ARKDeopt>& deoptBun
|
||||
context_.calleeRegAndOffset = calleeRegInfo;
|
||||
context_.callsiteSp = it.GetCallSiteSp();
|
||||
context_.callsiteFp = reinterpret_cast<uintptr_t>(it.GetSp());
|
||||
context_.preFrameSp = frame->ComputePrevFrameSp(it);
|
||||
context_.returnAddr = frame->GetReturnAddr();
|
||||
uint64_t argc = frame->GetArgc(context_.preFrameSp);
|
||||
auto argv = frame->GetArgv(reinterpret_cast<uintptr_t *>(context_.preFrameSp));
|
||||
if (argc > 0) {
|
||||
ASSERT(argc >= FIXED_NUM_ARGS);
|
||||
callTarget_ = JSTaggedValue(argv[0]);
|
||||
}
|
||||
AotArgvs_ = argv;
|
||||
auto preFrameSp = frame->ComputePrevFrameSp(it);
|
||||
frameArgc_ = frame->GetArgc(preFrameSp);
|
||||
frameArgvs_ = frame->GetArgv(preFrameSp);
|
||||
env_ = frame->GetEnv();
|
||||
stackContext_.callFrameTop_ = it.GetPrevFrameCallSiteSp();
|
||||
stackContext_.returnAddr_ = context_.returnAddr;
|
||||
stackContext_.returnAddr_ = frame->GetReturnAddr();
|
||||
stackContext_.callerFp_ = reinterpret_cast<uintptr_t>(frame->GetPrevFrameFp());
|
||||
break;
|
||||
}
|
||||
case FrameType::OPTIMIZED_FRAME: {
|
||||
auto sp = reinterpret_cast<uintptr_t*>(it.GetSp());
|
||||
sp--; // skip type
|
||||
sp -= 2; // 2: skip type & glue
|
||||
calleeRegAddr_ = sp - numCalleeRegs_;
|
||||
break;
|
||||
}
|
||||
@ -173,33 +163,90 @@ void Deoptimizier::RelocateCalleeSave()
|
||||
}
|
||||
}
|
||||
|
||||
bool Deoptimizier::CollectVirtualRegisters(Method* method, FrameWriter *frameWriter)
|
||||
{
|
||||
int32_t actualNumArgs = static_cast<int32_t>(frameArgc_) - NUM_MANDATORY_JSFUNC_ARGS;
|
||||
bool haveExtra = method->HaveExtraWithCallField();
|
||||
int32_t declaredNumArgs = static_cast<int32_t>(method->GetNumArgsWithCallField());
|
||||
int32_t callFieldNumVregs = static_cast<int32_t>(method->GetNumVregsWithCallField());
|
||||
// layout of frame:
|
||||
// [maybe argc] [actual args] [reserved args] [call field virtual regs]
|
||||
|
||||
// [maybe argc]
|
||||
if (declaredNumArgs != actualNumArgs && haveExtra) {
|
||||
auto value = JSTaggedValue(actualNumArgs);
|
||||
frameWriter->PushValue(value.GetRawData());
|
||||
}
|
||||
int32_t reservedCount = std::max(actualNumArgs, declaredNumArgs);
|
||||
int32_t virtualIndex = reservedCount + callFieldNumVregs +
|
||||
static_cast<int32_t>(method->GetNumRevervedArgs()) - 1;
|
||||
if (!frameWriter->Reserve(static_cast<size_t>(virtualIndex))) {
|
||||
return false;
|
||||
}
|
||||
// [actual args]
|
||||
if (declaredNumArgs > actualNumArgs) {
|
||||
frameWriter->PushValue(JSTaggedValue::Undefined().GetRawData());
|
||||
virtualIndex--;
|
||||
}
|
||||
for (int32_t i = actualNumArgs - 1; i >= 0; i--) {
|
||||
JSTaggedValue value = JSTaggedValue::Undefined();
|
||||
// deopt value
|
||||
if (hasDeoptValue(virtualIndex)) {
|
||||
value = deoptVregs_.at(static_cast<kungfu::OffsetType>(virtualIndex));
|
||||
} else {
|
||||
value = GetActualFrameArgs(i);
|
||||
}
|
||||
frameWriter->PushValue(value.GetRawData());
|
||||
virtualIndex--;
|
||||
}
|
||||
|
||||
// [reserved args]
|
||||
if (method->HaveThisWithCallField()) {
|
||||
JSTaggedValue value = GetFrameArgv(kungfu::CommonArgIdx::THIS_OBJECT);
|
||||
frameWriter->PushValue(value.GetRawData());
|
||||
virtualIndex--;
|
||||
}
|
||||
if (method->HaveNewTargetWithCallField()) {
|
||||
JSTaggedValue value = GetFrameArgv(kungfu::CommonArgIdx::NEW_TARGET);
|
||||
frameWriter->PushValue(value.GetRawData());
|
||||
virtualIndex--;
|
||||
}
|
||||
if (method->HaveFuncWithCallField()) {
|
||||
JSTaggedValue value = GetFrameArgv(kungfu::CommonArgIdx::FUNC);
|
||||
frameWriter->PushValue(value.GetRawData());
|
||||
virtualIndex--;
|
||||
}
|
||||
|
||||
// [call field virtual regs]
|
||||
for (int32_t i = virtualIndex; i >= 0; i--) {
|
||||
JSTaggedValue value = JSTaggedValue::Undefined();
|
||||
if (hasDeoptValue(virtualIndex)) {
|
||||
value = deoptVregs_.at(static_cast<kungfu::OffsetType>(virtualIndex));
|
||||
}
|
||||
frameWriter->PushValue(value.GetRawData());
|
||||
virtualIndex--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
JSTaggedType Deoptimizier::ConstructAsmInterpretFrame()
|
||||
{
|
||||
ASSERT(thread_ != nullptr);
|
||||
auto fun = callTarget_;
|
||||
JSTaggedValue callTarget = GetFrameArgv(kungfu::CommonArgIdx::FUNC);
|
||||
FrameWriter frameWriter(this);
|
||||
// Push asm interpreter frame
|
||||
auto method = GetMethod(callTarget_);
|
||||
auto numVRegs = method->GetNumberVRegs();
|
||||
if (!frameWriter.Reserve(numVRegs)) {
|
||||
auto method = GetMethod(callTarget);
|
||||
if (!CollectVirtualRegisters(method, &frameWriter)) {
|
||||
return JSTaggedValue::Exception().GetRawData();
|
||||
}
|
||||
|
||||
for (int32_t i = numVRegs - 1; i >= 0; i--) {
|
||||
JSTaggedValue value = JSTaggedValue::Undefined();
|
||||
if (vregs_.find(static_cast<kungfu::OffsetType>(i)) != vregs_.end()) {
|
||||
value = vregs_.at(static_cast<kungfu::OffsetType>(i));
|
||||
}
|
||||
frameWriter.PushValue(value.GetRawData());
|
||||
}
|
||||
const uint8_t *resumePc = method->GetBytecodeArray() + pc_;
|
||||
AsmInterpretedFrame *statePtr = frameWriter.ReserveAsmInterpretedFrame();
|
||||
JSTaggedValue env = JSTaggedValue(GetArgv(LEXENV_INDEX));
|
||||
JSTaggedValue thisObj = JSTaggedValue(GetArgv(THIS_VALUE_INDEX));
|
||||
auto acc = vregs_.at(static_cast<kungfu::OffsetType>(SpecVregIndex::ACC_INDEX));
|
||||
statePtr->function = fun;
|
||||
|
||||
JSTaggedValue thisObj = GetFrameArgv(kungfu::CommonArgIdx::THIS_OBJECT);;
|
||||
auto acc = deoptVregs_.at(static_cast<kungfu::OffsetType>(SpecVregIndex::ACC_INDEX));
|
||||
statePtr->function = callTarget;
|
||||
statePtr->acc = acc;
|
||||
statePtr->env = env;
|
||||
statePtr->env = env_;
|
||||
statePtr->callSize = 0;
|
||||
statePtr->fp = 0; // need update
|
||||
statePtr->thisObj = thisObj;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define ECMASCRIPT_DEOPTIMIZER_H
|
||||
#include "ecmascript/base/aligned_struct.h"
|
||||
#include "ecmascript/calleeReg.h"
|
||||
#include "ecmascript/compiler/argument_accessor.h"
|
||||
#include "ecmascript/js_handle.h"
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
#include "ecmascript/llvm_stackmap_type.h"
|
||||
@ -34,8 +35,6 @@ enum class SpecVregIndex: int {
|
||||
struct Context {
|
||||
uintptr_t callsiteSp;
|
||||
uintptr_t callsiteFp;
|
||||
uintptr_t* preFrameSp;
|
||||
uintptr_t returnAddr;
|
||||
kungfu::CalleeRegAndOffsetVec calleeRegAndOffset;
|
||||
};
|
||||
|
||||
@ -86,22 +85,18 @@ struct AsmStackContext : public base::AlignedStruct<base::AlignedPointer::Size()
|
||||
// out put data
|
||||
};
|
||||
|
||||
class Deoptimizier {
|
||||
class FrameWriter;
|
||||
class Deoptimizier
|
||||
{
|
||||
public:
|
||||
static constexpr uint64_t LLVM_DEOPT_RELOCATE_ADDR = 0xabcdef0f;
|
||||
explicit Deoptimizier(JSThread * thread) : thread_(thread)
|
||||
{
|
||||
Deoptimizier(JSThread * thread) : thread_(thread) {
|
||||
kungfu::CalleeReg callreg;
|
||||
numCalleeRegs_ = callreg.GetCallRegNum();
|
||||
}
|
||||
void CollectVregs(const std::vector<kungfu::ARKDeopt>& deoptBundle);
|
||||
void CollectDeoptBundleVec(std::vector<kungfu::ARKDeopt>& deoptBundle);
|
||||
JSTaggedType ConstructAsmInterpretFrame();
|
||||
JSTaggedType GetArgv(int idx)
|
||||
{
|
||||
ASSERT(AotArgvs_ != nullptr);
|
||||
return AotArgvs_[static_cast<int>(idx)];
|
||||
}
|
||||
|
||||
|
||||
JSThread *GetThread() const
|
||||
{
|
||||
@ -109,6 +104,30 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
size_t GetFrameIndex(kungfu::CommonArgIdx index)
|
||||
{
|
||||
return static_cast<size_t>(index) - static_cast<size_t>(kungfu::CommonArgIdx::FUNC);
|
||||
}
|
||||
JSTaggedValue GetFrameArgv(size_t idx)
|
||||
{
|
||||
ASSERT(frameArgvs_ != nullptr);
|
||||
ASSERT(idx < frameArgc_);
|
||||
return JSTaggedValue(frameArgvs_[idx]);
|
||||
}
|
||||
JSTaggedValue GetFrameArgv(kungfu::CommonArgIdx index)
|
||||
{
|
||||
return GetFrameArgv(GetFrameIndex(index));
|
||||
}
|
||||
JSTaggedValue GetActualFrameArgs(int32_t index)
|
||||
{
|
||||
index += NUM_MANDATORY_JSFUNC_ARGS;
|
||||
return GetFrameArgv(static_cast<size_t>(index));
|
||||
}
|
||||
bool CollectVirtualRegisters(Method* method, FrameWriter *frameWriter);
|
||||
bool hasDeoptValue(int32_t index)
|
||||
{
|
||||
return deoptVregs_.find(static_cast<kungfu::OffsetType>(index)) != deoptVregs_.end();
|
||||
}
|
||||
Method* GetMethod(JSTaggedValue &target);
|
||||
void RelocateCalleeSave();
|
||||
JSThread *thread_ {nullptr};
|
||||
@ -116,11 +135,12 @@ private:
|
||||
size_t numCalleeRegs_ {0};
|
||||
AsmStackContext stackContext_;
|
||||
|
||||
std::unordered_map<kungfu::OffsetType, JSTaggedValue> vregs_;
|
||||
struct Context context_ {0, 0, nullptr, 0, {}};
|
||||
std::unordered_map<kungfu::OffsetType, JSTaggedValue> deoptVregs_;
|
||||
struct Context context_ {0, 0, {}};
|
||||
uint32_t pc_;
|
||||
JSTaggedValue callTarget_ {JSTaggedValue::Undefined()};
|
||||
JSTaggedType *AotArgvs_ {nullptr};
|
||||
JSTaggedValue env_ {JSTaggedValue::Undefined()};
|
||||
size_t frameArgc_ {0};
|
||||
JSTaggedType *frameArgvs_ {nullptr};
|
||||
};
|
||||
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -122,7 +122,12 @@ public:
|
||||
|
||||
uint32_t GetNumArgs() const
|
||||
{
|
||||
return GetNumArgsWithCallField() + HaveFuncWithCallField() +
|
||||
return GetNumArgsWithCallField() + GetNumRevervedArgs();
|
||||
}
|
||||
|
||||
uint32_t GetNumRevervedArgs() const
|
||||
{
|
||||
return HaveFuncWithCallField() +
|
||||
HaveNewTargetWithCallField() + HaveThisWithCallField();
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,7 @@ group("ark_typeinfer_test") {
|
||||
"trystglobalbyname:trystglobalbynameAotTypeInferAction",
|
||||
"tsarraytobuiltin:tsarraytobuiltinAotTypeInferAction",
|
||||
"typeof:typeofAotTypeInferAction",
|
||||
"variable_after_loops:variable_after_loopsAotTypeInferAction",
|
||||
|
||||
#"variable_after_loops:variable_after_loopsAotTypeInferAction",
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user