1 /* 2 * Copyright (C) 2015 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_DEX2OAT_DRIVER_COMPILED_METHOD_STORAGE_H_ 18 #define ART_DEX2OAT_DRIVER_COMPILED_METHOD_STORAGE_H_ 19 20 #include <iosfwd> 21 #include <map> 22 #include <memory> 23 24 #include "base/array_ref.h" 25 #include "base/length_prefixed_array.h" 26 #include "base/macros.h" 27 #include "driver/compiled_code_storage.h" 28 #include "utils/dedupe_set.h" 29 #include "utils/swap_space.h" 30 31 namespace art { 32 33 namespace linker { 34 class LinkerPatch; 35 } // namespace linker 36 37 // TODO: Find a better name. This stores both method and non-method (thunks) code. 38 class CompiledMethodStorage final : public CompiledCodeStorage { 39 public: 40 explicit CompiledMethodStorage(int swap_fd); 41 ~CompiledMethodStorage(); 42 43 void DumpMemoryUsage(std::ostream& os, bool extended) const; 44 SetDedupeEnabled(bool dedupe_enabled)45 void SetDedupeEnabled(bool dedupe_enabled) { 46 dedupe_enabled_ = dedupe_enabled; 47 } DedupeEnabled()48 bool DedupeEnabled() const { 49 return dedupe_enabled_; 50 } 51 GetSwapSpaceAllocator()52 SwapAllocator<void> GetSwapSpaceAllocator() { 53 return SwapAllocator<void>(swap_space_.get()); 54 } 55 56 const LengthPrefixedArray<uint8_t>* DeduplicateCode(const ArrayRef<const uint8_t>& code); 57 void ReleaseCode(const LengthPrefixedArray<uint8_t>* code); 58 size_t UniqueCodeEntries() const; 59 60 const LengthPrefixedArray<uint8_t>* DeduplicateVMapTable(const ArrayRef<const uint8_t>& table); 61 void ReleaseVMapTable(const LengthPrefixedArray<uint8_t>* table); 62 size_t UniqueVMapTableEntries() const; 63 64 const LengthPrefixedArray<uint8_t>* DeduplicateCFIInfo(const ArrayRef<const uint8_t>& cfi_info); 65 void ReleaseCFIInfo(const LengthPrefixedArray<uint8_t>* cfi_info); 66 size_t UniqueCFIInfoEntries() const; 67 68 const LengthPrefixedArray<linker::LinkerPatch>* DeduplicateLinkerPatches( 69 const ArrayRef<const linker::LinkerPatch>& linker_patches); 70 void ReleaseLinkerPatches(const LengthPrefixedArray<linker::LinkerPatch>* linker_patches); 71 size_t UniqueLinkerPatchesEntries() const; 72 73 CompiledMethod* CreateCompiledMethod(InstructionSet instruction_set, 74 ArrayRef<const uint8_t> code, 75 ArrayRef<const uint8_t> stack_map, 76 ArrayRef<const uint8_t> cfi, 77 ArrayRef<const linker::LinkerPatch> patches, 78 bool is_intrinsic) override; 79 80 // Returns the code associated with the given patch. 81 // If the code has not been set, returns empty data. 82 // If `debug_name` is not null, stores the associated debug name in `*debug_name`. 83 ArrayRef<const uint8_t> GetThunkCode(const linker::LinkerPatch& linker_patch, 84 /*out*/ std::string* debug_name = nullptr) override; 85 86 // Sets the code and debug name associated with the given patch. 87 void SetThunkCode(const linker::LinkerPatch& linker_patch, 88 ArrayRef<const uint8_t> code, 89 const std::string& debug_name) override; 90 91 private: 92 class ThunkMapKey; 93 class ThunkMapValue; 94 using ThunkMapValueType = std::pair<const ThunkMapKey, ThunkMapValue>; 95 using ThunkMap = std::map<ThunkMapKey, 96 ThunkMapValue, 97 std::less<ThunkMapKey>, 98 SwapAllocator<ThunkMapValueType>>; 99 static_assert(std::is_same<ThunkMapValueType, ThunkMap::value_type>::value, "Value type check."); 100 101 static ThunkMapKey GetThunkMapKey(const linker::LinkerPatch& linker_patch); 102 103 template <typename T, typename DedupeSetType> 104 const LengthPrefixedArray<T>* AllocateOrDeduplicateArray(const ArrayRef<const T>& data, 105 DedupeSetType* dedupe_set); 106 107 template <typename T> 108 void ReleaseArrayIfNotDeduplicated(const LengthPrefixedArray<T>* array); 109 110 // DeDuplication data structures. 111 template <typename ContentType> 112 class DedupeHashFunc; 113 114 template <typename T> 115 class LengthPrefixedArrayAlloc; 116 117 template <typename T> 118 using ArrayDedupeSet = DedupeSet<ArrayRef<const T>, 119 LengthPrefixedArray<T>, 120 LengthPrefixedArrayAlloc<T>, 121 size_t, 122 DedupeHashFunc<const T>, 123 4>; 124 125 // Swap pool and allocator used for native allocations. May be file-backed. Needs to be first 126 // as other fields rely on this. 127 std::unique_ptr<SwapSpace> swap_space_; 128 129 bool dedupe_enabled_; 130 131 ArrayDedupeSet<uint8_t> dedupe_code_; 132 ArrayDedupeSet<uint8_t> dedupe_vmap_table_; 133 ArrayDedupeSet<uint8_t> dedupe_cfi_info_; 134 ArrayDedupeSet<linker::LinkerPatch> dedupe_linker_patches_; 135 136 Mutex thunk_map_lock_; 137 ThunkMap thunk_map_ GUARDED_BY(thunk_map_lock_); 138 139 DISALLOW_COPY_AND_ASSIGN(CompiledMethodStorage); 140 }; 141 142 } // namespace art 143 144 #endif // ART_DEX2OAT_DRIVER_COMPILED_METHOD_STORAGE_H_ 145