135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko/*
235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko * Copyright (C) 2015 The Android Open Source Project
335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko *
435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko * Licensed under the Apache License, Version 2.0 (the "License");
535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko * you may not use this file except in compliance with the License.
635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko * You may obtain a copy of the License at
735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko *
835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko *      http://www.apache.org/licenses/LICENSE-2.0
935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko *
1035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko * Unless required by applicable law or agreed to in writing, software
1135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko * distributed under the License is distributed on an "AS IS" BASIS,
1235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko * See the License for the specific language governing permissions and
1435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko * limitations under the License.
1535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko */
1635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
1735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include <algorithm>
1835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include <ostream>
1935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
2035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include "compiled_method_storage.h"
2135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
2235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include "base/logging.h"
2335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include "compiled_method.h"
2435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include "thread-inl.h"
2535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include "utils.h"
2635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include "utils/dedupe_set-inl.h"
2735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include "utils/swap_space.h"
2835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
2935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markonamespace art {
3035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
3135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markonamespace {  // anonymous namespace
3235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
3335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markotemplate <typename T>
3435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoconst LengthPrefixedArray<T>* CopyArray(SwapSpace* swap_space, const ArrayRef<const T>& array) {
3535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  DCHECK(!array.empty());
3635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  SwapAllocator<uint8_t> allocator(swap_space);
3735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  void* storage = allocator.allocate(LengthPrefixedArray<T>::ComputeSize(array.size()));
3835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  LengthPrefixedArray<T>* array_copy = new(storage) LengthPrefixedArray<T>(array.size());
3935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  std::copy(array.begin(), array.end(), array_copy->begin());
4035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  return array_copy;
4135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
4235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
4335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markotemplate <typename T>
4435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markovoid ReleaseArray(SwapSpace* swap_space, const LengthPrefixedArray<T>* array) {
4535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  SwapAllocator<uint8_t> allocator(swap_space);
4635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  size_t size = LengthPrefixedArray<T>::ComputeSize(array->size());
4735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  array->~LengthPrefixedArray<T>();
4835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  allocator.deallocate(const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(array)), size);
4935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
5035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
5135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}  // anonymous namespace
5235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
5335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markotemplate <typename T, typename DedupeSetType>
5435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoinline const LengthPrefixedArray<T>* CompiledMethodStorage::AllocateOrDeduplicateArray(
5535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    const ArrayRef<const T>& data,
5635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    DedupeSetType* dedupe_set) {
5735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  if (data.empty()) {
5835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    return nullptr;
5935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  } else if (!DedupeEnabled()) {
6035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    return CopyArray(swap_space_.get(), data);
6135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  } else {
6235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    return dedupe_set->Add(Thread::Current(), data);
6335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  }
6435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
6535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
6635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markotemplate <typename T>
6735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoinline void CompiledMethodStorage::ReleaseArrayIfNotDeduplicated(
6835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    const LengthPrefixedArray<T>* array) {
6935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  if (array != nullptr && !DedupeEnabled()) {
7035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    ReleaseArray(swap_space_.get(), array);
7135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  }
7235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
7335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
7435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markotemplate <typename ContentType>
7535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoclass CompiledMethodStorage::DedupeHashFunc {
7635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko private:
7735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  static constexpr bool kUseMurmur3Hash = true;
7835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
7935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko public:
8035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  size_t operator()(const ArrayRef<ContentType>& array) const {
8135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    const uint8_t* data = reinterpret_cast<const uint8_t*>(array.data());
8235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    // TODO: More reasonable assertion.
8335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    // static_assert(IsPowerOfTwo(sizeof(ContentType)),
8435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    //    "ContentType is not power of two, don't know whether array layout is as assumed");
8535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    uint32_t len = sizeof(ContentType) * array.size();
8635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    if (kUseMurmur3Hash) {
8735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      static constexpr uint32_t c1 = 0xcc9e2d51;
8835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      static constexpr uint32_t c2 = 0x1b873593;
8935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      static constexpr uint32_t r1 = 15;
9035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      static constexpr uint32_t r2 = 13;
9135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      static constexpr uint32_t m = 5;
9235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      static constexpr uint32_t n = 0xe6546b64;
9335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
9435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      uint32_t hash = 0;
9535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
9635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      const int nblocks = len / 4;
9735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      typedef __attribute__((__aligned__(1))) uint32_t unaligned_uint32_t;
9835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      const unaligned_uint32_t *blocks = reinterpret_cast<const uint32_t*>(data);
9935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      int i;
10035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      for (i = 0; i < nblocks; i++) {
10135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko        uint32_t k = blocks[i];
10235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko        k *= c1;
10335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko        k = (k << r1) | (k >> (32 - r1));
10435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko        k *= c2;
10535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
10635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko        hash ^= k;
10735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko        hash = ((hash << r2) | (hash >> (32 - r2))) * m + n;
10835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      }
10935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
11035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      const uint8_t *tail = reinterpret_cast<const uint8_t*>(data + nblocks * 4);
11135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      uint32_t k1 = 0;
11235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
11335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      switch (len & 3) {
11435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko        case 3:
11535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko          k1 ^= tail[2] << 16;
11635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko          FALLTHROUGH_INTENDED;
11735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko        case 2:
11835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko          k1 ^= tail[1] << 8;
11935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko          FALLTHROUGH_INTENDED;
12035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko        case 1:
12135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko          k1 ^= tail[0];
12235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
12335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko          k1 *= c1;
12435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko          k1 = (k1 << r1) | (k1 >> (32 - r1));
12535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko          k1 *= c2;
12635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko          hash ^= k1;
12735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      }
12835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
12935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      hash ^= len;
13035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      hash ^= (hash >> 16);
13135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      hash *= 0x85ebca6b;
13235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      hash ^= (hash >> 13);
13335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      hash *= 0xc2b2ae35;
13435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      hash ^= (hash >> 16);
13535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
13635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      return hash;
13735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    } else {
13835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      size_t hash = 0x811c9dc5;
13935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      for (uint32_t i = 0; i < len; ++i) {
14035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko        hash = (hash * 16777619) ^ data[i];
14135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      }
14235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      hash += hash << 13;
14335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      hash ^= hash >> 7;
14435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      hash += hash << 3;
14535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      hash ^= hash >> 17;
14635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      hash += hash << 5;
14735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      return hash;
14835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    }
14935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  }
15035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko};
15135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
15235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markotemplate <typename T>
15335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoclass CompiledMethodStorage::LengthPrefixedArrayAlloc {
15435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko public:
15535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  explicit LengthPrefixedArrayAlloc(SwapSpace* swap_space)
15635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      : swap_space_(swap_space) {
15735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  }
15835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
15935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  const LengthPrefixedArray<T>* Copy(const ArrayRef<const T>& array) {
16035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    return CopyArray(swap_space_, array);
16135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  }
16235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
16335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  void Destroy(const LengthPrefixedArray<T>* array) {
16435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    ReleaseArray(swap_space_, array);
16535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  }
16635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
16735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko private:
16835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  SwapSpace* const swap_space_;
16935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko};
17035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
17135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir MarkoCompiledMethodStorage::CompiledMethodStorage(int swap_fd)
17235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    : swap_space_(swap_fd == -1 ? nullptr : new SwapSpace(swap_fd, 10 * MB)),
17335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      dedupe_enabled_(true),
17435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      dedupe_code_("dedupe code", LengthPrefixedArrayAlloc<uint8_t>(swap_space_.get())),
17535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      dedupe_src_mapping_table_("dedupe source mapping table",
17635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko                                LengthPrefixedArrayAlloc<SrcMapElem>(swap_space_.get())),
17735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      dedupe_vmap_table_("dedupe vmap table",
17835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko                         LengthPrefixedArrayAlloc<uint8_t>(swap_space_.get())),
17935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      dedupe_cfi_info_("dedupe cfi info", LengthPrefixedArrayAlloc<uint8_t>(swap_space_.get())),
18035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko      dedupe_linker_patches_("dedupe cfi info",
18135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko                             LengthPrefixedArrayAlloc<LinkerPatch>(swap_space_.get())) {
18235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
18335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
18435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir MarkoCompiledMethodStorage::~CompiledMethodStorage() {
18535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  // All done by member destructors.
18635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
18735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
18835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markovoid CompiledMethodStorage::DumpMemoryUsage(std::ostream& os, bool extended) const {
18935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  if (swap_space_.get() != nullptr) {
190dd9473b94c15c8cbdfcce702fdc7a50acdfbfd8bAnton Kirilov    const size_t swap_size = swap_space_->GetSize();
191dd9473b94c15c8cbdfcce702fdc7a50acdfbfd8bAnton Kirilov    os << " swap=" << PrettySize(swap_size) << " (" << swap_size << "B)";
19235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  }
19335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  if (extended) {
19435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    Thread* self = Thread::Current();
19535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    os << "\nCode dedupe: " << dedupe_code_.DumpStats(self);
19635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    os << "\nVmap table dedupe: " << dedupe_vmap_table_.DumpStats(self);
19735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    os << "\nCFI info dedupe: " << dedupe_cfi_info_.DumpStats(self);
19835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  }
19935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
20035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
20135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoconst LengthPrefixedArray<uint8_t>* CompiledMethodStorage::DeduplicateCode(
20235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    const ArrayRef<const uint8_t>& code) {
20335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  return AllocateOrDeduplicateArray(code, &dedupe_code_);
20435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
20535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
20635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markovoid CompiledMethodStorage::ReleaseCode(const LengthPrefixedArray<uint8_t>* code) {
20735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  ReleaseArrayIfNotDeduplicated(code);
20835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
20935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
21035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoconst LengthPrefixedArray<SrcMapElem>* CompiledMethodStorage::DeduplicateSrcMappingTable(
21135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    const ArrayRef<const SrcMapElem>& src_map) {
21235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  return AllocateOrDeduplicateArray(src_map, &dedupe_src_mapping_table_);
21335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
21435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
21535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markovoid CompiledMethodStorage::ReleaseSrcMappingTable(const LengthPrefixedArray<SrcMapElem>* src_map) {
21635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  ReleaseArrayIfNotDeduplicated(src_map);
21735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
21835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
21935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoconst LengthPrefixedArray<uint8_t>* CompiledMethodStorage::DeduplicateVMapTable(
22035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    const ArrayRef<const uint8_t>& table) {
22135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  return AllocateOrDeduplicateArray(table, &dedupe_vmap_table_);
22235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
22335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
22435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markovoid CompiledMethodStorage::ReleaseVMapTable(const LengthPrefixedArray<uint8_t>* table) {
22535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  ReleaseArrayIfNotDeduplicated(table);
22635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
22735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
22835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoconst LengthPrefixedArray<uint8_t>* CompiledMethodStorage::DeduplicateCFIInfo(
22935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    const ArrayRef<const uint8_t>& cfi_info) {
23035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  return AllocateOrDeduplicateArray(cfi_info, &dedupe_cfi_info_);
23135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
23235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
23335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markovoid CompiledMethodStorage::ReleaseCFIInfo(const LengthPrefixedArray<uint8_t>* cfi_info) {
23435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  ReleaseArrayIfNotDeduplicated(cfi_info);
23535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
23635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
23735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markoconst LengthPrefixedArray<LinkerPatch>* CompiledMethodStorage::DeduplicateLinkerPatches(
23835831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    const ArrayRef<const LinkerPatch>& linker_patches) {
23935831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  return AllocateOrDeduplicateArray(linker_patches, &dedupe_linker_patches_);
24035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
24135831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
24235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Markovoid CompiledMethodStorage::ReleaseLinkerPatches(
24335831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko    const LengthPrefixedArray<LinkerPatch>* linker_patches) {
24435831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  ReleaseArrayIfNotDeduplicated(linker_patches);
24535831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}
24635831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko
24735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko}  // namespace art
248