1 /** 2 * Copyright (c) 2021-2022 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 stack_maps_(allocator), 30 inline_infos_(allocator), 31 roots_reg_masks_(allocator), 32 roots_stack_masks_(allocator), 33 method_ids_(allocator), 34 vregs_catalogue_(allocator), 35 vregs_map_(allocator), 36 vreg_masks_(allocator), 37 implicit_nullchecks_(allocator), 38 constant_table_(allocator), 39 current_vregs_(allocator->Adapter()), 40 last_vregs_(allocator->Adapter()), 41 vregs_last_change_(allocator->Adapter()), 42 inline_info_stack_(allocator->Adapter()), 43 vregs_map_storage_(allocator->Adapter()), 44 vregs_mask_storage_(allocator) 45 { 46 } 47 48 NO_COPY_SEMANTIC(CodeInfoBuilder); 49 NO_MOVE_SEMANTIC(CodeInfoBuilder); 50 ~CodeInfoBuilder() = default; 51 52 void BeginMethod(uint32_t frame_size, uint32_t vregs_count); 53 54 void EndMethod(); 55 56 void BeginStackMap(uint32_t bpc, uint32_t npc, ArenaBitVector *stack_roots, uint32_t regs_roots, 57 bool require_vreg_map, bool is_osr); 58 59 void EndStackMap(); 60 61 void BeginInlineInfo(void *method, uint32_t method_id, uint32_t bpc, uint32_t vregs_count); 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 current_vregs_.push_back(reg); 70 } 71 72 void AddConstant(uint64_t value, VRegInfo::Type type, bool is_acc); 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 instruction_native_pc,uint32_t offset)87 void AddImplicitNullCheck(uint32_t instruction_native_pc, uint32_t offset) 88 { 89 implicit_nullchecks_.Add({instruction_native_pc, 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++, &stack_maps_); 102 func(index++, &inline_infos_); 103 func(index++, &roots_reg_masks_); 104 func(index++, &roots_stack_masks_); 105 func(index++, &method_ids_); 106 func(index++, &vreg_masks_); 107 func(index++, &vregs_map_); 108 func(index++, &vregs_catalogue_); 109 func(index++, &implicit_nullchecks_); 110 func(index++, &constant_table_); 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 vregs_count_ {0}; 122 uint32_t current_vregs_count_ {0}; 123 124 CodeInfoHeader header_ {}; 125 126 // Tables 127 BitTableBuilder<StackMap> stack_maps_; 128 BitTableBuilder<InlineInfo> inline_infos_; 129 BitTableBuilder<RegisterMask> roots_reg_masks_; 130 BitmapTableBuilder roots_stack_masks_; 131 BitTableBuilder<MethodId> method_ids_; 132 BitTableBuilder<VRegisterInfo> vregs_catalogue_; 133 BitTableBuilder<VRegisterCatalogueIndex> vregs_map_; 134 BitmapTableBuilder vreg_masks_; 135 BitTableBuilder<ImplicitNullChecks> implicit_nullchecks_; 136 BitTableBuilder<ConstantTable> constant_table_; 137 138 // Auxiliary containers 139 BitTableBuilder<StackMap>::Entry current_stack_map_; 140 ArenaVector<VRegInfo> current_vregs_; 141 ArenaVector<VRegInfo> last_vregs_; 142 ArenaVector<uint32_t> vregs_last_change_; 143 ArenaVector<BitTableBuilder<InlineInfo>::Entry> inline_info_stack_; 144 ArenaVector<BitTableBuilder<VRegisterCatalogueIndex>::Entry> vregs_map_storage_; 145 ArenaBitVector vregs_mask_storage_; 146 147 #ifndef NDEBUG 148 bool was_method_begin_ {false}; 149 bool was_stack_map_begin_ {false}; 150 bool was_inline_info_begin_ {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