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