Home | History | Annotate | Download | only in compiler
      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