• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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