1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_COMPILER_COMPILED_METHOD_H_ 18 #define ART_COMPILER_COMPILED_METHOD_H_ 19 20 #include <memory> 21 #include <string> 22 #include <vector> 23 24 #include "instruction_set.h" 25 #include "utils.h" 26 #include "utils/array_ref.h" 27 #include "utils/swap_space.h" 28 29 namespace llvm { 30 class Function; 31 } // namespace llvm 32 33 namespace art { 34 35 class CompilerDriver; 36 37 class CompiledCode { 38 public: 39 // For Quick to supply an code blob 40 CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set, 41 const ArrayRef<const uint8_t>& quick_code); 42 43 // For Portable to supply an ELF object 44 CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set, 45 const std::string& elf_object, const std::string &symbol); 46 GetInstructionSet()47 InstructionSet GetInstructionSet() const { 48 return instruction_set_; 49 } 50 GetPortableCode()51 const SwapVector<uint8_t>* GetPortableCode() const { 52 return portable_code_; 53 } 54 GetQuickCode()55 const SwapVector<uint8_t>* GetQuickCode() const { 56 return quick_code_; 57 } 58 59 void SetCode(const ArrayRef<const uint8_t>* quick_code, 60 const ArrayRef<const uint8_t>* portable_code); 61 62 bool operator==(const CompiledCode& rhs) const; 63 64 // To align an offset from a page-aligned value to make it suitable 65 // for code storage. For example on ARM, to ensure that PC relative 66 // valu computations work out as expected. 67 uint32_t AlignCode(uint32_t offset) const; 68 static uint32_t AlignCode(uint32_t offset, InstructionSet instruction_set); 69 70 // returns the difference between the code address and a usable PC. 71 // mainly to cope with kThumb2 where the lower bit must be set. 72 size_t CodeDelta() const; 73 static size_t CodeDelta(InstructionSet instruction_set); 74 75 // Returns a pointer suitable for invoking the code at the argument 76 // code_pointer address. Mainly to cope with kThumb2 where the 77 // lower bit must be set to indicate Thumb mode. 78 static const void* CodePointer(const void* code_pointer, 79 InstructionSet instruction_set); 80 81 const std::string& GetSymbol() const; 82 const std::vector<uint32_t>& GetOatdataOffsetsToCompliledCodeOffset() const; 83 void AddOatdataOffsetToCompliledCodeOffset(uint32_t offset); 84 85 private: 86 CompilerDriver* const compiler_driver_; 87 88 const InstructionSet instruction_set_; 89 90 // The ELF image for portable. 91 SwapVector<uint8_t>* portable_code_; 92 93 // Used to store the PIC code for Quick. 94 SwapVector<uint8_t>* quick_code_; 95 96 // Used for the Portable ELF symbol name. 97 const std::string symbol_; 98 99 // There are offsets from the oatdata symbol to where the offset to 100 // the compiled method will be found. These are computed by the 101 // OatWriter and then used by the ElfWriter to add relocations so 102 // that MCLinker can update the values to the location in the linked .so. 103 std::vector<uint32_t> oatdata_offsets_to_compiled_code_offset_; 104 }; 105 106 class CompiledMethod : public CompiledCode { 107 public: 108 // Constructs a CompiledMethod for the non-LLVM compilers. 109 CompiledMethod(CompilerDriver* driver, 110 InstructionSet instruction_set, 111 const ArrayRef<const uint8_t>& quick_code, 112 const size_t frame_size_in_bytes, 113 const uint32_t core_spill_mask, 114 const uint32_t fp_spill_mask, 115 const ArrayRef<const uint8_t>& mapping_table, 116 const ArrayRef<const uint8_t>& vmap_table, 117 const ArrayRef<const uint8_t>& native_gc_map, 118 const ArrayRef<const uint8_t>& cfi_info); 119 120 // Constructs a CompiledMethod for the QuickJniCompiler. 121 CompiledMethod(CompilerDriver* driver, 122 InstructionSet instruction_set, 123 const ArrayRef<const uint8_t>& quick_code, 124 const size_t frame_size_in_bytes, 125 const uint32_t core_spill_mask, 126 const uint32_t fp_spill_mask); 127 128 // Constructs a CompiledMethod for the Portable compiler. 129 CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set, const std::string& code, 130 const ArrayRef<const uint8_t>& gc_map, const std::string& symbol); 131 132 // Constructs a CompiledMethod for the Portable JniCompiler. 133 CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set, const std::string& code, 134 const std::string& symbol); 135 ~CompiledMethod()136 ~CompiledMethod() {} 137 138 static CompiledMethod* SwapAllocCompiledMethod(CompilerDriver* driver, 139 InstructionSet instruction_set, 140 const ArrayRef<const uint8_t>& quick_code, 141 const size_t frame_size_in_bytes, 142 const uint32_t core_spill_mask, 143 const uint32_t fp_spill_mask, 144 const ArrayRef<const uint8_t>& mapping_table, 145 const ArrayRef<const uint8_t>& vmap_table, 146 const ArrayRef<const uint8_t>& native_gc_map, 147 const ArrayRef<const uint8_t>& cfi_info); 148 149 static CompiledMethod* SwapAllocCompiledMethod(CompilerDriver* driver, 150 InstructionSet instruction_set, 151 const ArrayRef<const uint8_t>& quick_code, 152 const size_t frame_size_in_bytes, 153 const uint32_t core_spill_mask, 154 const uint32_t fp_spill_mask); 155 156 static void ReleaseSwapAllocatedCompiledMethod(CompilerDriver* driver, CompiledMethod* m); 157 GetFrameSizeInBytes()158 size_t GetFrameSizeInBytes() const { 159 return frame_size_in_bytes_; 160 } 161 GetCoreSpillMask()162 uint32_t GetCoreSpillMask() const { 163 return core_spill_mask_; 164 } 165 GetFpSpillMask()166 uint32_t GetFpSpillMask() const { 167 return fp_spill_mask_; 168 } 169 GetMappingTable()170 const SwapVector<uint8_t>& GetMappingTable() const { 171 DCHECK(mapping_table_ != nullptr); 172 return *mapping_table_; 173 } 174 GetVmapTable()175 const SwapVector<uint8_t>& GetVmapTable() const { 176 DCHECK(vmap_table_ != nullptr); 177 return *vmap_table_; 178 } 179 GetGcMap()180 const SwapVector<uint8_t>& GetGcMap() const { 181 DCHECK(gc_map_ != nullptr); 182 return *gc_map_; 183 } 184 GetCFIInfo()185 const SwapVector<uint8_t>* GetCFIInfo() const { 186 return cfi_info_; 187 } 188 189 private: 190 // For quick code, the size of the activation used by the code. 191 const size_t frame_size_in_bytes_; 192 // For quick code, a bit mask describing spilled GPR callee-save registers. 193 const uint32_t core_spill_mask_; 194 // For quick code, a bit mask describing spilled FPR callee-save registers. 195 const uint32_t fp_spill_mask_; 196 // For quick code, a uleb128 encoded map from native PC offset to dex PC aswell as dex PC to 197 // native PC offset. Size prefixed. 198 SwapVector<uint8_t>* mapping_table_; 199 // For quick code, a uleb128 encoded map from GPR/FPR register to dex register. Size prefixed. 200 SwapVector<uint8_t>* vmap_table_; 201 // For quick code, a map keyed by native PC indices to bitmaps describing what dalvik registers 202 // are live. For portable code, the key is a dalvik PC. 203 SwapVector<uint8_t>* gc_map_; 204 // For quick code, a FDE entry for the debug_frame section. 205 SwapVector<uint8_t>* cfi_info_; 206 }; 207 208 } // namespace art 209 210 #endif // ART_COMPILER_COMPILED_METHOD_H_ 211