mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 16:13:49 +00:00
f15f4fcb24
Issues: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I9H3R6?from=project-issue Signed-off-by: liuzhijie <liuzhijie9@huawei.com> Change-Id: I6cfb557949befdd22343f3d9a5ed69bd9eb8a1fb
300 lines
11 KiB
C++
300 lines
11 KiB
C++
/*
|
|
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef ECMASCRIPT_COMPILER_GATE_H
|
|
#define ECMASCRIPT_COMPILER_GATE_H
|
|
|
|
#include <array>
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <optional>
|
|
#include <set>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <type_traits>
|
|
#include <vector>
|
|
|
|
#include "ecmascript/compiler/share_gate_meta_data.h"
|
|
#include "ecmascript/compiler/hcr_gate_meta_data.h"
|
|
#include "ecmascript/compiler/mcr_gate_meta_data.h"
|
|
#include "ecmascript/compiler/lcr_gate_meta_data.h"
|
|
#include "ecmascript/compiler/type.h"
|
|
|
|
#include "libpandabase/macros.h"
|
|
|
|
namespace panda::ecmascript::kungfu {
|
|
using BitField = uint64_t;
|
|
using GateRef = int32_t; // for external users
|
|
using GateId = uint32_t;
|
|
using GateOp = uint8_t;
|
|
using GateMark = uint8_t;
|
|
using TimeStamp = uint8_t;
|
|
using SecondaryOp = uint8_t;
|
|
using OutIdx = uint32_t;
|
|
class Gate;
|
|
class BytecodeCircuitBuilder;
|
|
|
|
enum MarkCode : GateMark {
|
|
NO_MARK = 0,
|
|
PREVISIT,
|
|
VISITED,
|
|
FINISHED,
|
|
};
|
|
|
|
class Out {
|
|
public:
|
|
Out() = default;
|
|
void SetNextOut(const Out *ptr);
|
|
[[nodiscard]] Out *GetNextOut();
|
|
[[nodiscard]] const Out *GetNextOutConst() const;
|
|
void SetPrevOut(const Out *ptr);
|
|
[[nodiscard]] Out *GetPrevOut();
|
|
[[nodiscard]] const Out *GetPrevOutConst() const;
|
|
void SetIndex(OutIdx idx);
|
|
[[nodiscard]] OutIdx GetIndex() const;
|
|
[[nodiscard]] Gate *GetGate();
|
|
[[nodiscard]] const Gate *GetGateConst() const;
|
|
void SetPrevOutNull();
|
|
[[nodiscard]] bool IsPrevOutNull() const;
|
|
void SetNextOutNull();
|
|
[[nodiscard]] bool IsNextOutNull() const;
|
|
[[nodiscard]] bool IsStateEdge() const;
|
|
~Out() = default;
|
|
|
|
private:
|
|
GateRef nextOut_;
|
|
GateRef prevOut_;
|
|
OutIdx idx_;
|
|
};
|
|
|
|
class In {
|
|
public:
|
|
In() = default;
|
|
void SetGate(const Gate *ptr);
|
|
[[nodiscard]] Gate *GetGate();
|
|
[[nodiscard]] const Gate *GetGateConst() const;
|
|
void SetGateNull();
|
|
[[nodiscard]] bool IsGateNull() const;
|
|
~In() = default;
|
|
|
|
private:
|
|
GateRef gatePtr_;
|
|
};
|
|
|
|
// Gate structure
|
|
// for example:
|
|
// ```
|
|
// g0 = op0(...)
|
|
// g1 = op1(...)
|
|
// g2 = op2(g0, g1)
|
|
// g3 = op3(g2)
|
|
// g4 = op4(g2, g0, g1)
|
|
// g5 = op5(g3, g4)
|
|
|
|
// +---- out[1] ----+---- out[0] ----+-------- g2 --------+-- in[0] --+-- in[1] --+
|
|
// | | | | | |
|
|
// | next=null | next=null | ... | | |
|
|
// | idx=1 | idx=0 | | g0 | g1 |
|
|
// | prev=g4.out[2] | prev=g4.out[1] | firstOut=g4.out[0] | | |
|
|
// | | | | | |
|
|
// +----------------+----------------+--------------------+-----------+-----------+
|
|
// ^ ^
|
|
// | |
|
|
// | |
|
|
// | | +---- out[0] ----+-------- g3 --------+-- in[0] --+
|
|
// | | | | | |
|
|
// | | | next=null | ... | |
|
|
// | | | idx=0 | | g2 |
|
|
// | | | prev=g4.out[0] | firstOut=g5.out[0] | |
|
|
// | | | | | |
|
|
// | | +----------------+--------------------+-----------+
|
|
// | | ^
|
|
// | | |
|
|
// | | |
|
|
// V V V
|
|
// +---- out[2] ----+---- out[1] ----+---- out[0] ----+-------- g4 --------+-- in[0] --+-- in[1] --+-- in[2] --+
|
|
// | | | | | | | |
|
|
// | next=g2.out[1] | next=g2.out[0] | next=g3.out[0] | ... | | | |
|
|
// | idx=2 | idx=1 | idx=0 | | g2 | g0 | g1 |
|
|
// | prev=null | prev=null | prev=null | firstOut=g5.out[1] | | | |
|
|
// | | | | | | | |
|
|
// +----------------+----------------+----------------+--------------------+-----------+-----------+-----------+
|
|
// ```
|
|
|
|
class Gate {
|
|
public:
|
|
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
|
Gate(const GateMetaData* meta, GateId id, Gate *inList[], MachineType machineType, GateType type);
|
|
static size_t GetGateSize(size_t numIns)
|
|
{
|
|
numIns = (numIns == 0) ? 1 : numIns;
|
|
return numIns * (sizeof(In) + sizeof(Out)) + sizeof(Gate);
|
|
}
|
|
static size_t GetOutListSize(size_t numIns)
|
|
{
|
|
numIns = (numIns == 0) ? 1 : numIns;
|
|
return numIns * sizeof(Out);
|
|
}
|
|
void NewIn(size_t idx, Gate *in);
|
|
void ModifyIn(size_t idx, Gate *in);
|
|
void DeleteIn(size_t idx);
|
|
void DeleteGate();
|
|
static constexpr GateRef InvalidGateRef = -1;
|
|
[[nodiscard]] Out *GetOut(size_t idx);
|
|
[[nodiscard]] Out *GetFirstOut();
|
|
[[nodiscard]] const Out *GetOutConst(size_t idx) const;
|
|
[[nodiscard]] const Out *GetFirstOutConst() const;
|
|
// note: GetFirstOut() is not equal to GetOut(0)
|
|
// note: behavior of GetFirstOut() is undefined when there are no Outs
|
|
// note: use IsFirstOutNull() to check first if there may be no Outs
|
|
void SetFirstOut(const Out *firstOut);
|
|
void SetFirstOutNull();
|
|
[[nodiscard]] bool IsFirstOutNull() const;
|
|
[[nodiscard]] In *GetIn(size_t idx);
|
|
[[nodiscard]] const In *GetInConst(size_t idx) const;
|
|
[[nodiscard]] Gate *GetInGate(size_t idx);
|
|
[[nodiscard]] const Gate *GetInGateConst(size_t idx) const;
|
|
// note: behavior of GetInGate(idx) is undefined when Ins[idx] is deleted or not assigned
|
|
// note: use IsInGateNull(idx) to check first if Ins[idx] may be deleted or not assigned
|
|
[[nodiscard]] bool IsInGateNull(size_t idx) const;
|
|
[[nodiscard]] OpCode GetOpCode() const;
|
|
[[nodiscard]] GateId GetId() const;
|
|
[[nodiscard]] size_t GetNumIns() const;
|
|
[[nodiscard]] size_t GetStateCount() const;
|
|
[[nodiscard]] size_t GetDependCount() const;
|
|
[[nodiscard]] size_t GetInValueCount() const;
|
|
[[nodiscard]] size_t GetInFrameStateCount() const;
|
|
[[nodiscard]] size_t GetInValueStarts() const;
|
|
[[nodiscard]] size_t GetRootCount() const;
|
|
[[nodiscard]] size_t GetInFrameStateStarts() const;
|
|
void AppendIn(const Gate *in); // considered very slow
|
|
void Print(std::string bytecode = "", bool inListPreview = false, size_t highlightIdx = -1) const;
|
|
void ShortPrint(std::string bytecode = "", bool inListPreview = false, size_t highlightIdx = -1) const;
|
|
size_t PrintInGate(size_t numIns, size_t idx, size_t size, bool inListPreview, size_t highlightIdx,
|
|
std::string &log, bool isEnd = false) const;
|
|
void PrintGateWithAdditionOp(std::string additionOp) const;
|
|
void PrintWithBytecode() const;
|
|
void CheckNullInput() const;
|
|
void CheckStateInput() const;
|
|
void CheckValueInput(bool isArch64) const;
|
|
void CheckDependInput() const;
|
|
void CheckRootInput() const;
|
|
void CheckFrameStateInput() const;
|
|
void CheckStateOutput(const std::string& methodName) const;
|
|
std::string GetValueInAndOut(bool inListPreview = false, size_t highlightIdx = -1) const;
|
|
void CheckBranchOutput() const;
|
|
void CheckNOP() const;
|
|
void CheckSelector() const;
|
|
void CheckRelay() const;
|
|
void Verify(bool isArch64, const std::string& methodName) const;
|
|
[[nodiscard]] MarkCode GetMark(TimeStamp stamp) const;
|
|
void SetMark(MarkCode mark, TimeStamp stamp);
|
|
MachineType GetMachineType() const
|
|
{
|
|
return machineType_;
|
|
}
|
|
void SetMachineType(MachineType machineType)
|
|
{
|
|
machineType_ = machineType;
|
|
}
|
|
GateType GetGateType() const
|
|
{
|
|
return type_;
|
|
}
|
|
void SetGateType(GateType type)
|
|
{
|
|
type_ = type;
|
|
}
|
|
const GateMetaData* GetMetaData() const
|
|
{
|
|
return meta_;
|
|
}
|
|
|
|
const OneParameterMetaData* GetOneParameterMetaData() const
|
|
{
|
|
return OneParameterMetaData::Cast(meta_);
|
|
}
|
|
|
|
const StringMetaData* GetStringMetaData() const
|
|
{
|
|
ASSERT(meta_->IsStringType());
|
|
return static_cast<const StringMetaData*>(meta_);
|
|
}
|
|
|
|
const JSBytecodeMetaData* GetJSBytecodeMetaData() const
|
|
{
|
|
return JSBytecodeMetaData::Cast(meta_);
|
|
}
|
|
|
|
const BoolMetaData* GetBoolMetaData() const
|
|
{
|
|
return BoolMetaData::Cast(meta_);
|
|
}
|
|
|
|
const TypedCallMetaData* GetTypedCallMetaData() const
|
|
{
|
|
return TypedCallMetaData::Cast(meta_);
|
|
}
|
|
|
|
const NewConstructMetaData* GetNewConstructMetaData() const
|
|
{
|
|
return NewConstructMetaData::Cast(meta_);
|
|
}
|
|
|
|
std::string MachineTypeStr(MachineType machineType) const;
|
|
std::string GateTypeStr(GateType gateType) const;
|
|
~Gate() = default;
|
|
|
|
private:
|
|
friend class Circuit;
|
|
friend class GateAccessor;
|
|
void CheckInputOpcode(size_t idx, OpCode expected) const;
|
|
void CheckInputMachineType(size_t idx, MachineType expected, bool isArch64) const;
|
|
void CheckNotInputMachineType(size_t idx, MachineType notExpected) const;
|
|
void CheckState(size_t idx) const;
|
|
void CheckGeneralState(size_t idx) const;
|
|
void CheckFailed(std::string errorString, size_t highlightIdx) const;
|
|
void SetMetaData(const GateMetaData* meta)
|
|
{
|
|
meta_ = meta;
|
|
}
|
|
uint64_t TryGetValue() const
|
|
{
|
|
if (meta_->IsOneParameterKind()) {
|
|
return GetOneParameterMetaData()->GetValue();
|
|
}
|
|
return 0;
|
|
}
|
|
// ...
|
|
// out(2)
|
|
// out(1)
|
|
// out(0)
|
|
const GateMetaData *meta_ { nullptr }; // uintptr_t
|
|
GateId id_ { 0 }; // uint32_t
|
|
GateType type_ { GateType::Empty() }; // uint32_t
|
|
MachineType machineType_ { MachineType::NOVALUE }; // uint8_t
|
|
TimeStamp stamp_ { 0 }; // uint8_t
|
|
MarkCode mark_ { MarkCode::NO_MARK }; // uint8_t
|
|
uint8_t bitField_ { 0 };
|
|
GateRef firstOut_ { 0 }; // int32_t
|
|
// in(0)
|
|
// in(1)
|
|
// in(2)
|
|
// ...
|
|
};
|
|
} // namespace panda::ecmascript::kungfu
|
|
|
|
#endif // ECMASCRIPT_COMPILER_GATE_H
|