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 #include "compiled_method.h" 18 #include "driver/compiler_driver.h" 19 20 namespace art { 21 22 CompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set, 23 const std::vector<uint8_t>& code) 24 : compiler_driver_(compiler_driver), instruction_set_(instruction_set), code_(nullptr) { 25 SetCode(code); 26 } 27 28 CompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set, 29 const std::string& elf_object, const std::string& symbol) 30 : compiler_driver_(compiler_driver), instruction_set_(instruction_set), symbol_(symbol) { 31 CHECK_NE(elf_object.size(), 0U); 32 CHECK_NE(symbol.size(), 0U); 33 std::vector<uint8_t> temp_code(elf_object.size()); 34 for (size_t i = 0; i < elf_object.size(); ++i) { 35 temp_code[i] = elf_object[i]; 36 } 37 // TODO: we shouldn't just shove ELF objects in as "code" but 38 // change to have different kinds of compiled methods. This is 39 // being deferred until we work on hybrid execution or at least 40 // until we work on batch compilation. 41 SetCode(temp_code); 42 } 43 44 void CompiledCode::SetCode(const std::vector<uint8_t>& code) { 45 CHECK(!code.empty()); 46 code_ = compiler_driver_->DeduplicateCode(code); 47 } 48 49 uint32_t CompiledCode::AlignCode(uint32_t offset) const { 50 return AlignCode(offset, instruction_set_); 51 } 52 53 uint32_t CompiledCode::AlignCode(uint32_t offset, InstructionSet instruction_set) { 54 switch (instruction_set) { 55 case kArm: 56 case kThumb2: 57 return RoundUp(offset, kArmAlignment); 58 case kMips: 59 return RoundUp(offset, kMipsAlignment); 60 case kX86: 61 return RoundUp(offset, kX86Alignment); 62 default: 63 LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 64 return 0; 65 } 66 } 67 68 size_t CompiledCode::CodeDelta() const { 69 switch (instruction_set_) { 70 case kArm: 71 case kMips: 72 case kX86: 73 return 0; 74 case kThumb2: { 75 // +1 to set the low-order bit so a BLX will switch to Thumb mode 76 return 1; 77 } 78 default: 79 LOG(FATAL) << "Unknown InstructionSet: " << instruction_set_; 80 return 0; 81 } 82 } 83 84 const void* CompiledCode::CodePointer(const void* code_pointer, 85 InstructionSet instruction_set) { 86 switch (instruction_set) { 87 case kArm: 88 case kMips: 89 case kX86: 90 return code_pointer; 91 case kThumb2: { 92 uintptr_t address = reinterpret_cast<uintptr_t>(code_pointer); 93 // Set the low-order bit so a BLX will switch to Thumb mode 94 address |= 0x1; 95 return reinterpret_cast<const void*>(address); 96 } 97 default: 98 LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; 99 return NULL; 100 } 101 } 102 103 #if defined(ART_USE_PORTABLE_COMPILER) 104 const std::string& CompiledCode::GetSymbol() const { 105 CHECK_NE(0U, symbol_.size()); 106 return symbol_; 107 } 108 109 const std::vector<uint32_t>& CompiledCode::GetOatdataOffsetsToCompliledCodeOffset() const { 110 CHECK_NE(0U, oatdata_offsets_to_compiled_code_offset_.size()) << symbol_; 111 return oatdata_offsets_to_compiled_code_offset_; 112 } 113 114 void CompiledCode::AddOatdataOffsetToCompliledCodeOffset(uint32_t offset) { 115 oatdata_offsets_to_compiled_code_offset_.push_back(offset); 116 } 117 #endif 118 119 CompiledMethod::CompiledMethod(CompilerDriver& driver, 120 InstructionSet instruction_set, 121 const std::vector<uint8_t>& code, 122 const size_t frame_size_in_bytes, 123 const uint32_t core_spill_mask, 124 const uint32_t fp_spill_mask, 125 const std::vector<uint8_t>& mapping_table, 126 const std::vector<uint8_t>& vmap_table, 127 const std::vector<uint8_t>& native_gc_map) 128 : CompiledCode(&driver, instruction_set, code), frame_size_in_bytes_(frame_size_in_bytes), 129 core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask), 130 mapping_table_(driver.DeduplicateMappingTable(mapping_table)), 131 vmap_table_(driver.DeduplicateVMapTable(vmap_table)), 132 gc_map_(driver.DeduplicateGCMap(native_gc_map)) { 133 } 134 135 CompiledMethod::CompiledMethod(CompilerDriver& driver, 136 InstructionSet instruction_set, 137 const std::vector<uint8_t>& code, 138 const size_t frame_size_in_bytes, 139 const uint32_t core_spill_mask, 140 const uint32_t fp_spill_mask) 141 : CompiledCode(&driver, instruction_set, code), 142 frame_size_in_bytes_(frame_size_in_bytes), 143 core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask) { 144 mapping_table_ = driver.DeduplicateMappingTable(std::vector<uint8_t>()); 145 vmap_table_ = driver.DeduplicateVMapTable(std::vector<uint8_t>()); 146 gc_map_ = driver.DeduplicateGCMap(std::vector<uint8_t>()); 147 } 148 149 // Constructs a CompiledMethod for the Portable compiler. 150 CompiledMethod::CompiledMethod(CompilerDriver& driver, InstructionSet instruction_set, 151 const std::string& code, const std::vector<uint8_t>& gc_map, 152 const std::string& symbol) 153 : CompiledCode(&driver, instruction_set, code, symbol), 154 frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0), 155 fp_spill_mask_(0), gc_map_(driver.DeduplicateGCMap(gc_map)) { 156 mapping_table_ = driver.DeduplicateMappingTable(std::vector<uint8_t>()); 157 vmap_table_ = driver.DeduplicateVMapTable(std::vector<uint8_t>()); 158 } 159 160 CompiledMethod::CompiledMethod(CompilerDriver& driver, InstructionSet instruction_set, 161 const std::string& code, const std::string& symbol) 162 : CompiledCode(&driver, instruction_set, code, symbol), 163 frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0), 164 fp_spill_mask_(0) { 165 mapping_table_ = driver.DeduplicateMappingTable(std::vector<uint8_t>()); 166 vmap_table_ = driver.DeduplicateVMapTable(std::vector<uint8_t>()); 167 gc_map_ = driver.DeduplicateGCMap(std::vector<uint8_t>()); 168 } 169 170 } // namespace art 171