1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_COMPILER_CIRCUIT_H 17 #define ECMASCRIPT_COMPILER_CIRCUIT_H 18 19 #include <algorithm> 20 #include <iostream> 21 #include <map> 22 #include <unordered_map> 23 #include <vector> 24 25 #include "ecmascript/compiler/gate.h" 26 #include "ecmascript/compiler/gate_meta_data.h" 27 #include "ecmascript/compiler/gate_meta_data_builder.h" 28 #include "ecmascript/frames.h" 29 30 #include "libpandabase/macros.h" 31 #include "securec.h" 32 33 namespace panda::ecmascript::kungfu { 34 class Circuit { // note: calling NewGate could make all saved Gate* invalid 35 public: 36 Circuit(NativeAreaAllocator* allocator, bool isArch64 = true); 37 ~Circuit(); 38 NO_COPY_SEMANTIC(Circuit); 39 NO_MOVE_SEMANTIC(Circuit); 40 41 GateRef NewGate(const GateMetaData *meta, const std::vector<GateRef> &inList); 42 GateRef NewGate(const GateMetaData *meta, MachineType machineType, GateType type); 43 GateRef NewGate(const GateMetaData *meta, MachineType machineType, 44 const std::initializer_list<GateRef>& args, GateType type); 45 GateRef NewGate(const GateMetaData *meta, MachineType machineType, 46 size_t numIns, const GateRef inList[], GateType type); 47 void PrintAllGates() const; 48 void PrintAllGatesWithBytecode() const; 49 void GetAllGates(std::vector<GateRef>& gates) const; 50 static GateRef NullGate(); 51 void Verify(GateRef gate) const; 52 panda::ecmascript::FrameType GetFrameType() const; 53 void SetFrameType(panda::ecmascript::FrameType type); 54 GateRef GetConstantGate(MachineType machineType, uint64_t value, GateType type); 55 GateRef NewArg(MachineType machineType, size_t value, GateType type, GateRef argRoot); 56 GateRef GetConstantDataGate(uint64_t value, GateType type); 57 size_t GetGateCount() const; 58 TimeStamp GetTime() const; 59 void AdvanceTime() const; SetArch(bool isArch64)60 void SetArch(bool isArch64) 61 { 62 isArch64_ = isArch64; 63 } IsArch64()64 bool IsArch64() const 65 { 66 return isArch64_; 67 } 68 void InitRoot(); GetRoot()69 GateRef GetRoot() const 70 { 71 return root_; 72 } SetRoot(GateRef root)73 void SetRoot(GateRef root) 74 { 75 root_ = root; 76 } 77 chunk()78 Chunk* chunk() 79 { 80 return &chunk_; 81 } 82 GetMetaBuilder()83 GateMetaBuilder *GetMetaBuilder() 84 { 85 return &metaBuilder_; 86 } 87 88 GateRef GetStateRoot() const; 89 GateRef GetDependRoot() const; 90 GateRef GetArgRoot() const; 91 GateRef GetReturnRoot() const; 92 93 #define DECLARE_GATE_META(NAME, OP, R, S, D, V) \ 94 const GateMetaData* NAME() \ 95 { \ 96 return metaBuilder_.NAME(); \ 97 } 98 IMMUTABLE_META_DATA_CACHE_LIST(DECLARE_GATE_META) 99 #undef DECLARE_GATE_META 100 101 #define DECLARE_GATE_META(NAME, OP, R, S, D, V) \ 102 const GateMetaData* NAME(size_t value) \ 103 { \ 104 return metaBuilder_.NAME(value); \ 105 } GATE_META_DATA_LIST_WITH_SIZE(DECLARE_GATE_META)106 GATE_META_DATA_LIST_WITH_SIZE(DECLARE_GATE_META) 107 #undef DECLARE_GATE_META 108 109 #define DECLARE_GATE_META(NAME, OP, R, S, D, V) \ 110 const GateMetaData* NAME(uint64_t value) \ 111 { \ 112 return metaBuilder_.NAME(value); \ 113 } 114 GATE_META_DATA_LIST_WITH_ONE_PARAMETER(DECLARE_GATE_META) 115 #undef DECLARE_GATE_META 116 117 const GateMetaData* Nop() 118 { 119 return metaBuilder_.Nop(); 120 } 121 JSBytecode(size_t valuesIn,EcmaOpcode opcode,uint32_t bcIndex,bool writable)122 const GateMetaData* JSBytecode(size_t valuesIn, EcmaOpcode opcode, 123 uint32_t bcIndex, bool writable) 124 { 125 GateFlags flags = writable ? GateFlags::NONE_FLAG : GateFlags::NO_WRITE; 126 return metaBuilder_.JSBytecode(valuesIn, opcode, bcIndex, flags); 127 } 128 TypedBinaryOp(uint64_t value,TypedBinOp binOp)129 const GateMetaData* TypedBinaryOp(uint64_t value, TypedBinOp binOp) 130 { 131 return metaBuilder_.TypedBinaryOp(value, binOp); 132 } 133 GetMetaData(GateRef gate)134 const GateMetaData *GetMetaData(GateRef gate) const 135 { 136 return LoadGatePtrConst(gate)->GetMetaData(); 137 } 138 139 private: 140 static const size_t CIRCUIT_SPACE = 1U << 30U; // 1GB 141 142 void Print(GateRef gate) const; 143 GateType GetGateType(GateRef gate) const; 144 GateRef GetGateRef(const Gate *gate) const; 145 MachineType GetMachineType(GateRef gate) const; 146 void SetMark(GateRef gate, MarkCode mark) const; 147 OpCode GetOpCode(GateRef gate) const; 148 void SetMachineType(GateRef gate, MachineType machineType); 149 void SetGateType(GateRef gate, GateType type); 150 GateId GetId(GateRef gate) const; 151 void DeleteGate(GateRef gate); 152 void DecreaseIn(GateRef gate, size_t idx); 153 154 MarkCode GetMark(GateRef gate) const; 155 void DeleteIn(GateRef gate, size_t idx); 156 void ModifyIn(GateRef gate, size_t idx, GateRef in); 157 void NewIn(GateRef gate, size_t idx, GateRef in); 158 std::vector<GateRef> GetOutVector(GateRef gate) const; 159 bool IsFirstOutNull(GateRef gate) const; 160 bool IsInGateNull(GateRef gate, size_t idx) const; 161 GateRef GetIn(GateRef gate, size_t idx) const; 162 bool IsSelector(GateRef gate) const; 163 bool IsControlCase(GateRef gate) const; 164 bool IsLoopHead(GateRef gate) const; 165 void ResetAllGateTimeStamps() const; 166 uint8_t *AllocateSpace(size_t gateSize); 167 Gate *AllocateGateSpace(size_t numIns); 168 size_t GetCircuitDataSize() const; 169 const void *GetSpaceDataStartPtrConst() const; 170 const void *GetSpaceDataEndPtrConst() const; 171 const uint8_t *GetDataPtrConst(size_t offset) const; 172 uint8_t *GetDataPtr(size_t offset); 173 Gate *LoadGatePtr(GateRef shift); 174 const Gate *LoadGatePtrConst(GateRef shift) const; 175 176 private: 177 void* space_ {nullptr}; 178 size_t circuitSize_ {0}; 179 size_t gateCount_ {0}; 180 TimeStamp time_; 181 std::map<std::tuple<MachineType, BitField, GateType>, GateRef> constantCache_ {}; 182 std::map<BitField, GateRef> constantDataCache_ {}; 183 panda::ecmascript::FrameType frameType_ {panda::ecmascript::FrameType::OPTIMIZED_FRAME}; 184 bool isArch64_ { false }; 185 186 Chunk chunk_; 187 GateRef root_ { 0 }; 188 GateMetaBuilder metaBuilder_; 189 #ifndef NDEBUG 190 ChunkVector<GateRef> allGates_; 191 #endif 192 193 friend class GateAccessor; 194 friend class ConstGateAccessor; 195 friend class Verifier; 196 }; 197 } // namespace panda::ecmascript::kungfu 198 199 #endif // ECMASCRIPT_COMPILER_CIRCUIT_H 200