• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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_UTILS_ATOMIC_DEX_REF_MAP_INL_H_
18 #define ART_COMPILER_UTILS_ATOMIC_DEX_REF_MAP_INL_H_
19 
20 #include "atomic_dex_ref_map.h"
21 
22 #include <type_traits>
23 
24 #include "base/macros.h"
25 #include "dex/class_reference.h"
26 #include "dex/dex_file-inl.h"
27 #include "dex/method_reference.h"
28 #include "dex/type_reference.h"
29 
30 namespace art HIDDEN {
31 
32 template <typename DexFileReferenceType, typename Value>
NumberOfDexIndices(const DexFile * dex_file)33 inline size_t AtomicDexRefMap<DexFileReferenceType, Value>::NumberOfDexIndices(
34     const DexFile* dex_file) {
35   // TODO: Use specialization for this? Not sure if worth it.
36   static_assert(std::is_same<DexFileReferenceType, MethodReference>::value ||
37                 std::is_same<DexFileReferenceType, ClassReference>::value ||
38                 std::is_same<DexFileReferenceType, TypeReference>::value,
39                 "invalid index type");
40   if (std::is_same<DexFileReferenceType, MethodReference>::value) {
41     return dex_file->NumMethodIds();
42   }
43   if (std::is_same<DexFileReferenceType, ClassReference>::value) {
44     return dex_file->NumClassDefs();
45   }
46   if (std::is_same<DexFileReferenceType, TypeReference>::value) {
47     return dex_file->NumTypeIds();
48   }
49   UNREACHABLE();
50 }
51 
52 template <typename DexFileReferenceType, typename Value>
53 inline typename AtomicDexRefMap<DexFileReferenceType, Value>::InsertResult
Insert(const DexFileReferenceType & ref,const Value & expected,const Value & desired)54     AtomicDexRefMap<DexFileReferenceType, Value>::Insert(const DexFileReferenceType& ref,
55                                                          const Value& expected,
56                                                          const Value& desired) {
57   ElementArray* const array = GetArray(ref.dex_file);
58   if (array == nullptr) {
59     return kInsertResultInvalidDexFile;
60   }
61   DCHECK_LT(ref.index, array->size());
62   return (*array)[ref.index].CompareAndSetStrongSequentiallyConsistent(expected, desired)
63       ? kInsertResultSuccess
64       : kInsertResultCASFailure;
65 }
66 
67 template <typename DexFileReferenceType, typename Value>
Get(const DexFileReferenceType & ref,Value * out)68 inline bool AtomicDexRefMap<DexFileReferenceType, Value>::Get(const DexFileReferenceType& ref,
69                                                               Value* out) const {
70   const ElementArray* const array = GetArray(ref.dex_file);
71   if (array == nullptr) {
72     return false;
73   }
74   *out = (*array)[ref.index].load(std::memory_order_relaxed);
75   return true;
76 }
77 
78 template <typename DexFileReferenceType, typename Value>
Remove(const DexFileReferenceType & ref,Value * out)79 inline bool AtomicDexRefMap<DexFileReferenceType, Value>::Remove(const DexFileReferenceType& ref,
80                                                                  Value* out) {
81   ElementArray* const array = GetArray(ref.dex_file);
82   if (array == nullptr) {
83     return false;
84   }
85   *out = (*array)[ref.index].exchange(nullptr, std::memory_order_seq_cst);
86   return true;
87 }
88 
89 template <typename DexFileReferenceType, typename Value>
AddDexFile(const DexFile * dex_file)90 inline void AtomicDexRefMap<DexFileReferenceType, Value>::AddDexFile(const DexFile* dex_file) {
91   arrays_.Put(dex_file, std::move(ElementArray(NumberOfDexIndices(dex_file))));
92 }
93 
94 template <typename DexFileReferenceType, typename Value>
AddDexFiles(const std::vector<const DexFile * > & dex_files)95 inline void AtomicDexRefMap<DexFileReferenceType, Value>::AddDexFiles(
96     const std::vector<const DexFile*>& dex_files) {
97   for (const DexFile* dex_file : dex_files) {
98     if (!HaveDexFile(dex_file)) {
99       AddDexFile(dex_file);
100     }
101   }
102 }
103 
104 template <typename DexFileReferenceType, typename Value>
105 inline typename AtomicDexRefMap<DexFileReferenceType, Value>::ElementArray*
GetArray(const DexFile * dex_file)106     AtomicDexRefMap<DexFileReferenceType, Value>::GetArray(const DexFile* dex_file) {
107   auto it = arrays_.find(dex_file);
108   return (it != arrays_.end()) ? &it->second : nullptr;
109 }
110 
111 template <typename DexFileReferenceType, typename Value>
112 inline const typename AtomicDexRefMap<DexFileReferenceType, Value>::ElementArray*
GetArray(const DexFile * dex_file)113     AtomicDexRefMap<DexFileReferenceType, Value>::GetArray(const DexFile* dex_file) const {
114   auto it = arrays_.find(dex_file);
115   return (it != arrays_.end()) ? &it->second : nullptr;
116 }
117 
118 template <typename DexFileReferenceType, typename Value> template <typename Visitor>
Visit(const Visitor & visitor)119 inline void AtomicDexRefMap<DexFileReferenceType, Value>::Visit(const Visitor& visitor) {
120   for (auto& pair : arrays_) {
121     const DexFile* dex_file = pair.first;
122     const ElementArray& elements = pair.second;
123     for (size_t i = 0; i < elements.size(); ++i) {
124       visitor(DexFileReference(dex_file, i), elements[i].load(std::memory_order_relaxed));
125     }
126   }
127 }
128 
129 template <typename DexFileReferenceType, typename Value>
ClearEntries()130 inline void AtomicDexRefMap<DexFileReferenceType, Value>::ClearEntries() {
131   for (auto& it : arrays_) {
132     for (auto& element : it.second) {
133       element.store(nullptr, std::memory_order_relaxed);
134     }
135   }
136 }
137 
138 template <typename DexFileReferenceType, typename Value>
GetDexFiles()139 inline std::vector<const DexFile*> AtomicDexRefMap<DexFileReferenceType, Value>::GetDexFiles()
140     const {
141   std::vector<const DexFile*> result;
142   result.reserve(arrays_.size());
143   for (auto& it : arrays_) {
144     result.push_back(it.first);
145   }
146   return result;
147 }
148 
149 }  // namespace art
150 
151 #endif  // ART_COMPILER_UTILS_ATOMIC_DEX_REF_MAP_INL_H_
152