| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef ART_DEX2OAT_DRIVER_COMPILED_METHOD_STORAGE_H_ |
| #define ART_DEX2OAT_DRIVER_COMPILED_METHOD_STORAGE_H_ |
| |
| #include <iosfwd> |
| #include <map> |
| #include <memory> |
| |
| #include "base/array_ref.h" |
| #include "base/length_prefixed_array.h" |
| #include "base/macros.h" |
| #include "driver/compiled_code_storage.h" |
| #include "utils/dedupe_set.h" |
| #include "utils/swap_space.h" |
| |
| namespace art { |
| |
| namespace linker { |
| class LinkerPatch; |
| } // namespace linker |
| |
| // TODO: Find a better name. This stores both method and non-method (thunks) code. |
| class CompiledMethodStorage final : public CompiledCodeStorage { |
| public: |
| explicit CompiledMethodStorage(int swap_fd); |
| ~CompiledMethodStorage(); |
| |
| void DumpMemoryUsage(std::ostream& os, bool extended) const; |
| |
| void SetDedupeEnabled(bool dedupe_enabled) { |
| dedupe_enabled_ = dedupe_enabled; |
| } |
| bool DedupeEnabled() const { |
| return dedupe_enabled_; |
| } |
| |
| SwapAllocator<void> GetSwapSpaceAllocator() { |
| return SwapAllocator<void>(swap_space_.get()); |
| } |
| |
| const LengthPrefixedArray<uint8_t>* DeduplicateCode(const ArrayRef<const uint8_t>& code); |
| void ReleaseCode(const LengthPrefixedArray<uint8_t>* code); |
| size_t UniqueCodeEntries() const; |
| |
| const LengthPrefixedArray<uint8_t>* DeduplicateVMapTable(const ArrayRef<const uint8_t>& table); |
| void ReleaseVMapTable(const LengthPrefixedArray<uint8_t>* table); |
| size_t UniqueVMapTableEntries() const; |
| |
| const LengthPrefixedArray<uint8_t>* DeduplicateCFIInfo(const ArrayRef<const uint8_t>& cfi_info); |
| void ReleaseCFIInfo(const LengthPrefixedArray<uint8_t>* cfi_info); |
| size_t UniqueCFIInfoEntries() const; |
| |
| const LengthPrefixedArray<linker::LinkerPatch>* DeduplicateLinkerPatches( |
| const ArrayRef<const linker::LinkerPatch>& linker_patches); |
| void ReleaseLinkerPatches(const LengthPrefixedArray<linker::LinkerPatch>* linker_patches); |
| size_t UniqueLinkerPatchesEntries() const; |
| |
| CompiledMethod* CreateCompiledMethod(InstructionSet instruction_set, |
| ArrayRef<const uint8_t> code, |
| ArrayRef<const uint8_t> stack_map, |
| ArrayRef<const uint8_t> cfi, |
| ArrayRef<const linker::LinkerPatch> patches, |
| bool is_intrinsic) override; |
| |
| // Returns the code associated with the given patch. |
| // If the code has not been set, returns empty data. |
| // If `debug_name` is not null, stores the associated debug name in `*debug_name`. |
| ArrayRef<const uint8_t> GetThunkCode(const linker::LinkerPatch& linker_patch, |
| /*out*/ std::string* debug_name = nullptr) override; |
| |
| // Sets the code and debug name associated with the given patch. |
| void SetThunkCode(const linker::LinkerPatch& linker_patch, |
| ArrayRef<const uint8_t> code, |
| const std::string& debug_name) override; |
| |
| private: |
| class ThunkMapKey; |
| class ThunkMapValue; |
| using ThunkMapValueType = std::pair<const ThunkMapKey, ThunkMapValue>; |
| using ThunkMap = std::map<ThunkMapKey, |
| ThunkMapValue, |
| std::less<ThunkMapKey>, |
| SwapAllocator<ThunkMapValueType>>; |
| static_assert(std::is_same<ThunkMapValueType, ThunkMap::value_type>::value, "Value type check."); |
| |
| static ThunkMapKey GetThunkMapKey(const linker::LinkerPatch& linker_patch); |
| |
| template <typename T, typename DedupeSetType> |
| const LengthPrefixedArray<T>* AllocateOrDeduplicateArray(const ArrayRef<const T>& data, |
| DedupeSetType* dedupe_set); |
| |
| template <typename T> |
| void ReleaseArrayIfNotDeduplicated(const LengthPrefixedArray<T>* array); |
| |
| // DeDuplication data structures. |
| template <typename ContentType> |
| class DedupeHashFunc; |
| |
| template <typename T> |
| class LengthPrefixedArrayAlloc; |
| |
| template <typename T> |
| using ArrayDedupeSet = DedupeSet<ArrayRef<const T>, |
| LengthPrefixedArray<T>, |
| LengthPrefixedArrayAlloc<T>, |
| size_t, |
| DedupeHashFunc<const T>, |
| 4>; |
| |
| // Swap pool and allocator used for native allocations. May be file-backed. Needs to be first |
| // as other fields rely on this. |
| std::unique_ptr<SwapSpace> swap_space_; |
| |
| bool dedupe_enabled_; |
| |
| ArrayDedupeSet<uint8_t> dedupe_code_; |
| ArrayDedupeSet<uint8_t> dedupe_vmap_table_; |
| ArrayDedupeSet<uint8_t> dedupe_cfi_info_; |
| ArrayDedupeSet<linker::LinkerPatch> dedupe_linker_patches_; |
| |
| Mutex thunk_map_lock_; |
| ThunkMap thunk_map_ GUARDED_BY(thunk_map_lock_); |
| |
| DISALLOW_COPY_AND_ASSIGN(CompiledMethodStorage); |
| }; |
| |
| } // namespace art |
| |
| #endif // ART_DEX2OAT_DRIVER_COMPILED_METHOD_STORAGE_H_ |