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