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