1 /* 2 * Copyright (c) 2023-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 LIBLLVMBACKEND_OBJECT_CODE_CODE_INFO_PRODUCER_H 17 #define LIBLLVMBACKEND_OBJECT_CODE_CODE_INFO_PRODUCER_H 18 19 #include "compiler/optimizer/ir/runtime_interface.h" 20 #include "libpandabase/utils/bit_vector.h" 21 22 #include "created_object_file.h" 23 24 #include <llvm/Object/FaultMapParser.h> 25 #include <llvm/Object/StackMapParser.h> 26 27 namespace ark { 28 class Method; 29 } // namespace ark 30 31 namespace ark::compiler { 32 class CodeInfoBuilder; 33 } // namespace ark::compiler 34 35 namespace ark::llvmbackend { 36 37 class LLVMArkInterface; 38 39 class CodeInfoProducer { 40 private: 41 enum LocationHeader { 42 LOCATION_CC, 43 LOCATION_FLAGS, 44 LOCATION_DEOPT_COUNT, 45 LOCATION_INLINE_DEPTH, 46 LOCATION_INLINE_TABLE 47 }; 48 enum InlineRecord { INLINE_METHOD_ID, INLINE_BPC, INLINE_NEED_REGMAP, INLINE_VREG_COUNT, INLINE_VREGS }; 49 enum VRegRecord { VREG_IDX, VREG_TYPE, VREG_VALUE, VREG_RECORD_SIZE }; 50 51 public: 52 using LLVMStackMap = llvm::StackMapParser<llvm::support::little>; 53 using Function = LLVMStackMap::FunctionAccessor; 54 using Record = LLVMStackMap::RecordAccessor; 55 using Location = LLVMStackMap::LocationAccessor; 56 using StackMapSymbol = ark::llvmbackend::CreatedObjectFile::StackMapSymbol; 57 using CodeInfoBuilder = ark::compiler::CodeInfoBuilder; 58 59 explicit CodeInfoProducer(Arch arch, LLVMArkInterface *compilation); 60 61 void SetStackMap(const uint8_t *section, uintptr_t size); 62 void SetFaultMaps(const uint8_t *section, uintptr_t size); 63 64 void AddSymbol(Method *method, StackMapSymbol symbol); 65 void AddFaultMapSymbol(Method *method, uint32_t symbol); 66 67 void Produce(Method *method, ark::compiler::CodeInfoBuilder *builder) const; 68 69 private: 70 static void DumpStackMap(const std::unique_ptr<const LLVMStackMap> &stackmap, std::ostream &stream); 71 static void DumpStackMapFunction(const Function &function, std::ostream &stream, const std::string &prefix = ""); 72 static void DumpStackMapRecord(const Record &record, std::ostream &stream, const std::string &prefix = ""); 73 static void DumpStackMapLocation(const Location &location, std::ostream &stream, const std::string &prefix = ""); 74 75 uint16_t GetDwarfBase(Arch arch) const; 76 77 size_t GetArkFrameSlot(const Location &location, uint64_t stackSize, size_t slotSize) const; 78 79 unsigned CollectRoots(const Record &record, uint64_t stackSize, ArenaBitVector *stack) const; 80 81 void BuildSingleRegMap(CodeInfoBuilder *builder, const Record &record, int32_t methodIdIndex, int32_t vregsCount, 82 uint64_t stackSize) const; 83 void BuildRegMap(CodeInfoBuilder *builder, const Record &record, uint64_t stackSize) const; 84 85 void ConvertStackMaps(Method *method, CodeInfoBuilder *builder) const; 86 void EncodeNullChecks(Method *method, CodeInfoBuilder *builder) const; 87 88 private: 89 const Arch arch_; 90 LLVMArkInterface *compilation_; 91 std::unique_ptr<const LLVMStackMap> stackmap_; 92 std::unordered_map<Method *, StackMapSymbol> symbols_; 93 std::unordered_map<Method *, uint32_t> faultMapSymbols_; 94 std::unique_ptr<llvm::FaultMapParser> faultMapParser_; 95 }; 96 } // namespace ark::llvmbackend 97 #endif // LIBLLVMBACKEND_OBJECT_CODE_CODE_INFO_PRODUCER_H 98