diff options
Diffstat (limited to 'compiler/compiled_method.h')
| -rw-r--r-- | compiler/compiled_method.h | 344 | 
1 files changed, 18 insertions, 326 deletions
| diff --git a/compiler/compiled_method.h b/compiler/compiled_method.h index 5ef6cbff78..892bc592db 100644 --- a/compiler/compiled_method.h +++ b/compiler/compiled_method.h @@ -17,27 +17,28 @@  #ifndef ART_COMPILER_COMPILED_METHOD_H_  #define ART_COMPILER_COMPILED_METHOD_H_ -#include <iosfwd>  #include <memory>  #include <string>  #include <vector>  #include "arch/instruction_set.h" -#include "base/array_ref.h" -#include "base/bit_utils.h" -#include "base/length_prefixed_array.h" -#include "dex_file_types.h" -#include "method_reference.h"  namespace art { +template <typename T> class ArrayRef;  class CompilerDriver;  class CompiledMethodStorage; +template<typename T> class LengthPrefixedArray; + +namespace linker { +class LinkerPatch; +}  // namespace linker  class CompiledCode {   public:    // For Quick to supply an code blob -  CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set, +  CompiledCode(CompilerDriver* compiler_driver, +               InstructionSet instruction_set,                 const ArrayRef<const uint8_t>& quick_code);    virtual ~CompiledCode(); @@ -46,9 +47,7 @@ class CompiledCode {      return instruction_set_;    } -  ArrayRef<const uint8_t> GetQuickCode() const { -    return GetArray(quick_code_); -  } +  ArrayRef<const uint8_t> GetQuickCode() const;    bool operator==(const CompiledCode& rhs) const; @@ -66,18 +65,11 @@ class CompiledCode {    // Returns a pointer suitable for invoking the code at the argument    // code_pointer address.  Mainly to cope with kThumb2 where the    // lower bit must be set to indicate Thumb mode. -  static const void* CodePointer(const void* code_pointer, -                                 InstructionSet instruction_set); +  static const void* CodePointer(const void* code_pointer, InstructionSet instruction_set);   protected:    template <typename T> -  static ArrayRef<const T> GetArray(const LengthPrefixedArray<T>* array) { -    if (array == nullptr) { -      return ArrayRef<const T>(); -    } -    DCHECK_NE(array->size(), 0u); -    return ArrayRef<const T>(&array->At(0), array->size()); -  } +  static ArrayRef<const T> GetArray(const LengthPrefixedArray<T>* array);    CompilerDriver* GetCompilerDriver() {      return compiler_driver_; @@ -92,298 +84,6 @@ class CompiledCode {    const LengthPrefixedArray<uint8_t>* const quick_code_;  }; -class SrcMapElem { - public: -  uint32_t from_; -  int32_t to_; -}; - -inline bool operator<(const SrcMapElem& lhs, const SrcMapElem& rhs) { -  if (lhs.from_ != rhs.from_) { -    return lhs.from_ < rhs.from_; -  } -  return lhs.to_ < rhs.to_; -} - -inline bool operator==(const SrcMapElem& lhs, const SrcMapElem& rhs) { -  return lhs.from_ == rhs.from_ && lhs.to_ == rhs.to_; -} - -class LinkerPatch { - public: -  // Note: We explicitly specify the underlying type of the enum because GCC -  // would otherwise select a bigger underlying type and then complain that -  //     'art::LinkerPatch::patch_type_' is too small to hold all -  //     values of 'enum class art::LinkerPatch::Type' -  // which is ridiculous given we have only a handful of values here. If we -  // choose to squeeze the Type into fewer than 8 bits, we'll have to declare -  // patch_type_ as an uintN_t and do explicit static_cast<>s. -  enum class Type : uint8_t { -    kMethodRelative,          // NOTE: Actual patching is instruction_set-dependent. -    kMethodBssEntry,          // NOTE: Actual patching is instruction_set-dependent. -    kCall, -    kCallRelative,            // NOTE: Actual patching is instruction_set-dependent. -    kTypeRelative,            // NOTE: Actual patching is instruction_set-dependent. -    kTypeClassTable,          // NOTE: Actual patching is instruction_set-dependent. -    kTypeBssEntry,            // NOTE: Actual patching is instruction_set-dependent. -    kStringRelative,          // NOTE: Actual patching is instruction_set-dependent. -    kStringInternTable,       // NOTE: Actual patching is instruction_set-dependent. -    kStringBssEntry,          // NOTE: Actual patching is instruction_set-dependent. -    kBakerReadBarrierBranch,  // NOTE: Actual patching is instruction_set-dependent. -  }; - -  static LinkerPatch RelativeMethodPatch(size_t literal_offset, -                                         const DexFile* target_dex_file, -                                         uint32_t pc_insn_offset, -                                         uint32_t target_method_idx) { -    LinkerPatch patch(literal_offset, Type::kMethodRelative, target_dex_file); -    patch.method_idx_ = target_method_idx; -    patch.pc_insn_offset_ = pc_insn_offset; -    return patch; -  } - -  static LinkerPatch MethodBssEntryPatch(size_t literal_offset, -                                         const DexFile* target_dex_file, -                                         uint32_t pc_insn_offset, -                                         uint32_t target_method_idx) { -    LinkerPatch patch(literal_offset, Type::kMethodBssEntry, target_dex_file); -    patch.method_idx_ = target_method_idx; -    patch.pc_insn_offset_ = pc_insn_offset; -    return patch; -  } - -  static LinkerPatch CodePatch(size_t literal_offset, -                               const DexFile* target_dex_file, -                               uint32_t target_method_idx) { -    LinkerPatch patch(literal_offset, Type::kCall, target_dex_file); -    patch.method_idx_ = target_method_idx; -    return patch; -  } - -  static LinkerPatch RelativeCodePatch(size_t literal_offset, -                                       const DexFile* target_dex_file, -                                       uint32_t target_method_idx) { -    LinkerPatch patch(literal_offset, Type::kCallRelative, target_dex_file); -    patch.method_idx_ = target_method_idx; -    return patch; -  } - -  static LinkerPatch RelativeTypePatch(size_t literal_offset, -                                       const DexFile* target_dex_file, -                                       uint32_t pc_insn_offset, -                                       uint32_t target_type_idx) { -    LinkerPatch patch(literal_offset, Type::kTypeRelative, target_dex_file); -    patch.type_idx_ = target_type_idx; -    patch.pc_insn_offset_ = pc_insn_offset; -    return patch; -  } - -  static LinkerPatch TypeClassTablePatch(size_t literal_offset, -                                         const DexFile* target_dex_file, -                                         uint32_t pc_insn_offset, -                                         uint32_t target_type_idx) { -    LinkerPatch patch(literal_offset, Type::kTypeClassTable, target_dex_file); -    patch.type_idx_ = target_type_idx; -    patch.pc_insn_offset_ = pc_insn_offset; -    return patch; -  } - -  static LinkerPatch TypeBssEntryPatch(size_t literal_offset, -                                       const DexFile* target_dex_file, -                                       uint32_t pc_insn_offset, -                                       uint32_t target_type_idx) { -    LinkerPatch patch(literal_offset, Type::kTypeBssEntry, target_dex_file); -    patch.type_idx_ = target_type_idx; -    patch.pc_insn_offset_ = pc_insn_offset; -    return patch; -  } - -  static LinkerPatch RelativeStringPatch(size_t literal_offset, -                                         const DexFile* target_dex_file, -                                         uint32_t pc_insn_offset, -                                         uint32_t target_string_idx) { -    LinkerPatch patch(literal_offset, Type::kStringRelative, target_dex_file); -    patch.string_idx_ = target_string_idx; -    patch.pc_insn_offset_ = pc_insn_offset; -    return patch; -  } - -  static LinkerPatch StringInternTablePatch(size_t literal_offset, -                                            const DexFile* target_dex_file, -                                            uint32_t pc_insn_offset, -                                            uint32_t target_string_idx) { -    LinkerPatch patch(literal_offset, Type::kStringInternTable, target_dex_file); -    patch.string_idx_ = target_string_idx; -    patch.pc_insn_offset_ = pc_insn_offset; -    return patch; -  } - -  static LinkerPatch StringBssEntryPatch(size_t literal_offset, -                                         const DexFile* target_dex_file, -                                         uint32_t pc_insn_offset, -                                         uint32_t target_string_idx) { -    LinkerPatch patch(literal_offset, Type::kStringBssEntry, target_dex_file); -    patch.string_idx_ = target_string_idx; -    patch.pc_insn_offset_ = pc_insn_offset; -    return patch; -  } - -  static LinkerPatch BakerReadBarrierBranchPatch(size_t literal_offset, -                                                 uint32_t custom_value1 = 0u, -                                                 uint32_t custom_value2 = 0u) { -    LinkerPatch patch(literal_offset, Type::kBakerReadBarrierBranch, nullptr); -    patch.baker_custom_value1_ = custom_value1; -    patch.baker_custom_value2_ = custom_value2; -    return patch; -  } - -  LinkerPatch(const LinkerPatch& other) = default; -  LinkerPatch& operator=(const LinkerPatch& other) = default; - -  size_t LiteralOffset() const { -    return literal_offset_; -  } - -  Type GetType() const { -    return patch_type_; -  } - -  bool IsPcRelative() const { -    switch (GetType()) { -      case Type::kMethodRelative: -      case Type::kMethodBssEntry: -      case Type::kCallRelative: -      case Type::kTypeRelative: -      case Type::kTypeClassTable: -      case Type::kTypeBssEntry: -      case Type::kStringRelative: -      case Type::kStringInternTable: -      case Type::kStringBssEntry: -      case Type::kBakerReadBarrierBranch: -        return true; -      default: -        return false; -    } -  } - -  MethodReference TargetMethod() const { -    DCHECK(patch_type_ == Type::kMethodRelative || -           patch_type_ == Type::kMethodBssEntry || -           patch_type_ == Type::kCall || -           patch_type_ == Type::kCallRelative); -    return MethodReference(target_dex_file_, method_idx_); -  } - -  const DexFile* TargetTypeDexFile() const { -    DCHECK(patch_type_ == Type::kTypeRelative || -           patch_type_ == Type::kTypeClassTable || -           patch_type_ == Type::kTypeBssEntry); -    return target_dex_file_; -  } - -  dex::TypeIndex TargetTypeIndex() const { -    DCHECK(patch_type_ == Type::kTypeRelative || -           patch_type_ == Type::kTypeClassTable || -           patch_type_ == Type::kTypeBssEntry); -    return dex::TypeIndex(type_idx_); -  } - -  const DexFile* TargetStringDexFile() const { -    DCHECK(patch_type_ == Type::kStringRelative || -           patch_type_ == Type::kStringInternTable || -           patch_type_ == Type::kStringBssEntry); -    return target_dex_file_; -  } - -  dex::StringIndex TargetStringIndex() const { -    DCHECK(patch_type_ == Type::kStringRelative || -           patch_type_ == Type::kStringInternTable || -           patch_type_ == Type::kStringBssEntry); -    return dex::StringIndex(string_idx_); -  } - -  uint32_t PcInsnOffset() const { -    DCHECK(patch_type_ == Type::kMethodRelative || -           patch_type_ == Type::kMethodBssEntry || -           patch_type_ == Type::kTypeRelative || -           patch_type_ == Type::kTypeClassTable || -           patch_type_ == Type::kTypeBssEntry || -           patch_type_ == Type::kStringRelative || -           patch_type_ == Type::kStringInternTable || -           patch_type_ == Type::kStringBssEntry); -    return pc_insn_offset_; -  } - -  uint32_t GetBakerCustomValue1() const { -    DCHECK(patch_type_ == Type::kBakerReadBarrierBranch); -    return baker_custom_value1_; -  } - -  uint32_t GetBakerCustomValue2() const { -    DCHECK(patch_type_ == Type::kBakerReadBarrierBranch); -    return baker_custom_value2_; -  } - - private: -  LinkerPatch(size_t literal_offset, Type patch_type, const DexFile* target_dex_file) -      : target_dex_file_(target_dex_file), -        literal_offset_(literal_offset), -        patch_type_(patch_type) { -    cmp1_ = 0u; -    cmp2_ = 0u; -    // The compiler rejects methods that are too big, so the compiled code -    // of a single method really shouln't be anywhere close to 16MiB. -    DCHECK(IsUint<24>(literal_offset)); -  } - -  const DexFile* target_dex_file_; -  // TODO: Clean up naming. Some patched locations are literals but others are not. -  uint32_t literal_offset_ : 24;  // Method code size up to 16MiB. -  Type patch_type_ : 8; -  union { -    uint32_t cmp1_;             // Used for relational operators. -    uint32_t method_idx_;       // Method index for Call/Method patches. -    uint32_t type_idx_;         // Type index for Type patches. -    uint32_t string_idx_;       // String index for String patches. -    uint32_t baker_custom_value1_; -    static_assert(sizeof(method_idx_) == sizeof(cmp1_), "needed by relational operators"); -    static_assert(sizeof(type_idx_) == sizeof(cmp1_), "needed by relational operators"); -    static_assert(sizeof(string_idx_) == sizeof(cmp1_), "needed by relational operators"); -    static_assert(sizeof(baker_custom_value1_) == sizeof(cmp1_), "needed by relational operators"); -  }; -  union { -    // Note: To avoid uninitialized padding on 64-bit systems, we use `size_t` for `cmp2_`. -    // This allows a hashing function to treat an array of linker patches as raw memory. -    size_t cmp2_;             // Used for relational operators. -    // Literal offset of the insn loading PC (same as literal_offset if it's the same insn, -    // may be different if the PC-relative addressing needs multiple insns). -    uint32_t pc_insn_offset_; -    uint32_t baker_custom_value2_; -    static_assert(sizeof(pc_insn_offset_) <= sizeof(cmp2_), "needed by relational operators"); -    static_assert(sizeof(baker_custom_value2_) <= sizeof(cmp2_), "needed by relational operators"); -  }; - -  friend bool operator==(const LinkerPatch& lhs, const LinkerPatch& rhs); -  friend bool operator<(const LinkerPatch& lhs, const LinkerPatch& rhs); -}; -std::ostream& operator<<(std::ostream& os, const LinkerPatch::Type& type); - -inline bool operator==(const LinkerPatch& lhs, const LinkerPatch& rhs) { -  return lhs.literal_offset_ == rhs.literal_offset_ && -      lhs.patch_type_ == rhs.patch_type_ && -      lhs.target_dex_file_ == rhs.target_dex_file_ && -      lhs.cmp1_ == rhs.cmp1_ && -      lhs.cmp2_ == rhs.cmp2_; -} - -inline bool operator<(const LinkerPatch& lhs, const LinkerPatch& rhs) { -  return (lhs.literal_offset_ != rhs.literal_offset_) ? lhs.literal_offset_ < rhs.literal_offset_ -      : (lhs.patch_type_ != rhs.patch_type_) ? lhs.patch_type_ < rhs.patch_type_ -      : (lhs.target_dex_file_ != rhs.target_dex_file_) ? lhs.target_dex_file_ < rhs.target_dex_file_ -      : (lhs.cmp1_ != rhs.cmp1_) ? lhs.cmp1_ < rhs.cmp1_ -      : lhs.cmp2_ < rhs.cmp2_; -} -  class CompiledMethod FINAL : public CompiledCode {   public:    // Constructs a CompiledMethod. @@ -398,7 +98,7 @@ class CompiledMethod FINAL : public CompiledCode {                   const ArrayRef<const uint8_t>& method_info,                   const ArrayRef<const uint8_t>& vmap_table,                   const ArrayRef<const uint8_t>& cfi_info, -                 const ArrayRef<const LinkerPatch>& patches); +                 const ArrayRef<const linker::LinkerPatch>& patches);    virtual ~CompiledMethod(); @@ -412,7 +112,7 @@ class CompiledMethod FINAL : public CompiledCode {        const ArrayRef<const uint8_t>& method_info,        const ArrayRef<const uint8_t>& vmap_table,        const ArrayRef<const uint8_t>& cfi_info, -      const ArrayRef<const LinkerPatch>& patches); +      const ArrayRef<const linker::LinkerPatch>& patches);    static void ReleaseSwapAllocatedCompiledMethod(CompilerDriver* driver, CompiledMethod* m); @@ -428,21 +128,13 @@ class CompiledMethod FINAL : public CompiledCode {      return fp_spill_mask_;    } -  ArrayRef<const uint8_t> GetMethodInfo() const { -    return GetArray(method_info_); -  } +  ArrayRef<const uint8_t> GetMethodInfo() const; -  ArrayRef<const uint8_t> GetVmapTable() const { -    return GetArray(vmap_table_); -  } +  ArrayRef<const uint8_t> GetVmapTable() const; -  ArrayRef<const uint8_t> GetCFIInfo() const { -    return GetArray(cfi_info_); -  } +  ArrayRef<const uint8_t> GetCFIInfo() const; -  ArrayRef<const LinkerPatch> GetPatches() const { -    return GetArray(patches_); -  } +  ArrayRef<const linker::LinkerPatch> GetPatches() const;   private:    // For quick code, the size of the activation used by the code. @@ -458,7 +150,7 @@ class CompiledMethod FINAL : public CompiledCode {    // For quick code, a FDE entry for the debug_frame section.    const LengthPrefixedArray<uint8_t>* const cfi_info_;    // For quick code, linker patches needed by the method. -  const LengthPrefixedArray<LinkerPatch>* const patches_; +  const LengthPrefixedArray<linker::LinkerPatch>* const patches_;  };  }  // namespace art |