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