diff options
Diffstat (limited to 'compiler/compiled_method.h')
-rw-r--r-- | compiler/compiled_method.h | 106 |
1 files changed, 105 insertions, 1 deletions
diff --git a/compiler/compiled_method.h b/compiler/compiled_method.h index cc46b92dc..cdae8d2d2 100644 --- a/compiler/compiled_method.h +++ b/compiler/compiled_method.h @@ -22,7 +22,9 @@ #include <vector> #include "instruction_set.h" +#include "method_reference.h" #include "utils.h" +#include "utils/array_ref.h" namespace llvm { class Function; @@ -171,6 +173,101 @@ class SrcMap FINAL : public std::vector<SrcMapElem> { } }; +enum LinkerPatchType { + kLinkerPatchMethod, + kLinkerPatchCall, + kLinkerPatchCallRelative, // NOTE: Actual patching is instruction_set-dependent. + kLinkerPatchType, +}; + +class LinkerPatch { + public: + static LinkerPatch MethodPatch(size_t literal_offset, + const DexFile* target_dex_file, + uint32_t target_method_idx) { + return LinkerPatch(literal_offset, kLinkerPatchMethod, + target_method_idx, target_dex_file); + } + + static LinkerPatch CodePatch(size_t literal_offset, + const DexFile* target_dex_file, + uint32_t target_method_idx) { + return LinkerPatch(literal_offset, kLinkerPatchCall, + target_method_idx, target_dex_file); + } + + static LinkerPatch RelativeCodePatch(size_t literal_offset, + const DexFile* target_dex_file, + uint32_t target_method_idx) { + return LinkerPatch(literal_offset, kLinkerPatchCallRelative, + target_method_idx, target_dex_file); + } + + static LinkerPatch TypePatch(size_t literal_offset, + const DexFile* target_dex_file, + uint32_t target_type_idx) { + return LinkerPatch(literal_offset, kLinkerPatchType, target_type_idx, target_dex_file); + } + + LinkerPatch(const LinkerPatch& other) = default; + LinkerPatch& operator=(const LinkerPatch& other) = default; + + size_t LiteralOffset() const { + return literal_offset_; + } + + LinkerPatchType Type() const { + return patch_type_; + } + + MethodReference TargetMethod() const { + DCHECK(patch_type_ == kLinkerPatchMethod || + patch_type_ == kLinkerPatchCall || patch_type_ == kLinkerPatchCallRelative); + return MethodReference(target_dex_file_, target_idx_); + } + + const DexFile* TargetTypeDexFile() const { + DCHECK(patch_type_ == kLinkerPatchType); + return target_dex_file_; + } + + uint32_t TargetTypeIndex() const { + DCHECK(patch_type_ == kLinkerPatchType); + return target_idx_; + } + + private: + LinkerPatch(size_t literal_offset, LinkerPatchType patch_type, + uint32_t target_idx, const DexFile* target_dex_file) + : literal_offset_(literal_offset), + patch_type_(patch_type), + target_idx_(target_idx), + target_dex_file_(target_dex_file) { + } + + size_t literal_offset_; + LinkerPatchType patch_type_; + uint32_t target_idx_; // Method index (Call/Method patches) or type index (Type patches). + const DexFile* target_dex_file_; + + friend bool operator==(const LinkerPatch& lhs, const LinkerPatch& rhs); + friend bool operator<(const LinkerPatch& lhs, const LinkerPatch& rhs); +}; + +inline bool operator==(const LinkerPatch& lhs, const LinkerPatch& rhs) { + return lhs.literal_offset_ == rhs.literal_offset_ && + lhs.patch_type_ == rhs.patch_type_ && + lhs.target_idx_ == rhs.target_idx_ && + lhs.target_dex_file_ == rhs.target_dex_file_; +} + +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_idx_ != rhs.target_idx_) ? lhs.target_idx_ < rhs.target_idx_ + : lhs.target_dex_file_ < rhs.target_dex_file_; +} + class CompiledMethod FINAL : public CompiledCode { public: // Constructs a CompiledMethod for Quick. @@ -184,7 +281,8 @@ class CompiledMethod FINAL : public CompiledCode { const std::vector<uint8_t>& mapping_table, const std::vector<uint8_t>& vmap_table, const std::vector<uint8_t>& native_gc_map, - const std::vector<uint8_t>* cfi_info); + const std::vector<uint8_t>* cfi_info, + const ArrayRef<LinkerPatch>& patches = ArrayRef<LinkerPatch>()); // Constructs a CompiledMethod for Optimizing. CompiledMethod(CompilerDriver* driver, @@ -250,6 +348,10 @@ class CompiledMethod FINAL : public CompiledCode { return cfi_info_; } + const std::vector<LinkerPatch>& GetPatches() const { + return patches_; + } + private: // For quick code, the size of the activation used by the code. const size_t frame_size_in_bytes_; @@ -269,6 +371,8 @@ class CompiledMethod FINAL : public CompiledCode { std::vector<uint8_t>* gc_map_; // For quick code, a FDE entry for the debug_frame section. std::vector<uint8_t>* cfi_info_; + // For quick code, linker patches needed by the method. + std::vector<LinkerPatch> patches_; }; } // namespace art |