• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 PANDA_CODE_INFO_BUILDER_H
17 #define PANDA_CODE_INFO_BUILDER_H
18 
19 #include "code_info.h"
20 #include "utils/arena_containers.h"
21 #include "utils/bit_vector.h"
22 
23 namespace ark::compiler {
24 
25 class SaveStateInst;
26 
27 class CodeInfoBuilder {
28 public:
CodeInfoBuilder(Arch arch,ArenaAllocator * allocator)29     CodeInfoBuilder(Arch arch, ArenaAllocator *allocator)
30         : arch_(arch),
31           stackMaps_(allocator),
32           inlineInfos_(allocator),
33           rootsRegMasks_(allocator),
34           rootsStackMasks_(allocator),
35           methodIds_(allocator),
36           vregsCatalogue_(allocator),
37           vregsMap_(allocator),
38           vregMasks_(allocator),
39           implicitNullchecks_(allocator),
40           constantTable_(allocator),
41           currentVregs_(allocator->Adapter()),
42           lastVregs_(allocator->Adapter()),
43           vregsLastChange_(allocator->Adapter()),
44           inlineInfoStack_(allocator->Adapter()),
45           vregsMapStorage_(allocator->Adapter()),
46           vregsMaskStorage_(allocator)
47     {
48     }
49 
50     NO_COPY_SEMANTIC(CodeInfoBuilder);
51     NO_MOVE_SEMANTIC(CodeInfoBuilder);
52     ~CodeInfoBuilder() = default;
53 
54     void BeginMethod(uint32_t frameSize, uint32_t vregsCount);
55 
56     void EndMethod();
57 
58     void BeginStackMap(uint32_t bpc, uint32_t npc, SaveStateInst *ss, bool requireVregMap);
59 
60     void EndStackMap();
61 
62     void BeginInlineInfo(void *method, uint32_t methodId, uint32_t bpc, uint32_t vregsCount);
63 
64     void EndInlineInfo();
65 
AddVReg(VRegInfo reg)66     void AddVReg(VRegInfo reg)
67     {
68         // Constant should be added via `AddConstant` method
69         ASSERT(reg.GetLocation() != VRegInfo::Location::CONSTANT);
70         currentVregs_.push_back(reg);
71     }
72 
73     void AddConstant(uint64_t value, VRegInfo::Type type, VRegInfo::VRegType vregType);
74 
SetFrameSize(uint32_t size)75     void SetFrameSize(uint32_t size)
76     {
77         header_.SetFrameSize(size);
78     }
79 
80     void Encode(ArenaVector<uint8_t> *stream, size_t offset = 0);
81 
SetSavedCalleeRegsMask(uint32_t mask,uint32_t vmask)82     void SetSavedCalleeRegsMask(uint32_t mask, uint32_t vmask)
83     {
84         header_.SetCalleeRegMask(mask);
85         header_.SetCalleeFpRegMask(vmask);
86     }
87 
AddImplicitNullCheck(uint32_t instructionNativePc,uint32_t offset)88     void AddImplicitNullCheck(uint32_t instructionNativePc, uint32_t offset)
89     {
90         implicitNullchecks_.Add({instructionNativePc, offset});
91     }
92 
SetHasFloatRegs(bool has)93     void SetHasFloatRegs(bool has)
94     {
95         header_.SetHasFloatRegs(has);
96     }
97 
98     template <typename Func>
EnumerateTables(Func func)99     constexpr void EnumerateTables(Func func)
100     {
101         size_t index = 0;
102         func(index++, &stackMaps_);
103         func(index++, &inlineInfos_);
104         func(index++, &rootsRegMasks_);
105         func(index++, &rootsStackMasks_);
106         func(index++, &methodIds_);
107         func(index++, &vregMasks_);
108         func(index++, &vregsMap_);
109         func(index++, &vregsCatalogue_);
110         func(index++, &implicitNullchecks_);
111         func(index++, &constantTable_);
112         ASSERT(index == CodeInfo::TABLES_COUNT);
113     }
114 
115     void DumpCurrentStackMap(std::ostream &stream) const;
116 
117 private:
118     void EmitVRegs();
119 
120 private:
121     Arch arch_;
122     uint32_t vregsCount_ {0};
123     uint32_t currentVregsCount_ {0};
124 
125     CodeInfoHeader header_ {};
126 
127     // Tables
128     BitTableBuilder<StackMap> stackMaps_;
129     BitTableBuilder<InlineInfo> inlineInfos_;
130     BitTableBuilder<RegisterMask> rootsRegMasks_;
131     BitmapTableBuilder rootsStackMasks_;
132     BitTableBuilder<MethodId> methodIds_;
133     BitTableBuilder<VRegisterInfo> vregsCatalogue_;
134     BitTableBuilder<VRegisterCatalogueIndex> vregsMap_;
135     BitmapTableBuilder vregMasks_;
136     BitTableBuilder<ImplicitNullChecks> implicitNullchecks_;
137     BitTableBuilder<ConstantTable> constantTable_;
138 
139     // Auxiliary containers
140     BitTableBuilder<StackMap>::Entry currentStackMap_;
141     ArenaVector<VRegInfo> currentVregs_;
142     ArenaVector<VRegInfo> lastVregs_;
143     ArenaVector<uint32_t> vregsLastChange_;
144     ArenaVector<BitTableBuilder<InlineInfo>::Entry> inlineInfoStack_;
145     ArenaVector<BitTableBuilder<VRegisterCatalogueIndex>::Entry> vregsMapStorage_;
146     ArenaBitVector vregsMaskStorage_;
147 
148 #ifndef NDEBUG
149     bool wasMethodBegin_ {false};
150     bool wasStackMapBegin_ {false};
151     bool wasInlineInfoBegin_ {false};
152 #endif
153 
154     static constexpr size_t MAX_VREG_LIVE_DISTANCE = 32;
155 };
156 
157 }  // namespace ark::compiler
158 
159 #endif  // PANDA_CODE_INFO_BUILDER_H
160