Generalize atomic_method_ref_map to support dex references
Generalize atomic method ref map to support dex references instead
of only method references.
The goal is to use this in a future CL to replace compiled_classes_.
Test: test-art-host
Change-Id: Ic6d1e619584f790eea68f5160fa0fcd664524cd7
diff --git a/compiler/utils/atomic_method_ref_map-inl.h b/compiler/utils/atomic_dex_ref_map-inl.h
similarity index 62%
rename from compiler/utils/atomic_method_ref_map-inl.h
rename to compiler/utils/atomic_dex_ref_map-inl.h
index ad3a099..c41d8fc 100644
--- a/compiler/utils/atomic_method_ref_map-inl.h
+++ b/compiler/utils/atomic_dex_ref_map-inl.h
@@ -14,72 +14,72 @@
* limitations under the License.
*/
-#ifndef ART_COMPILER_UTILS_ATOMIC_METHOD_REF_MAP_INL_H_
-#define ART_COMPILER_UTILS_ATOMIC_METHOD_REF_MAP_INL_H_
+#ifndef ART_COMPILER_UTILS_ATOMIC_DEX_REF_MAP_INL_H_
+#define ART_COMPILER_UTILS_ATOMIC_DEX_REF_MAP_INL_H_
-#include "atomic_method_ref_map.h"
+#include "atomic_dex_ref_map.h"
#include "dex_file-inl.h"
namespace art {
template <typename T>
-inline typename AtomicMethodRefMap<T>::InsertResult AtomicMethodRefMap<T>::Insert(
- MethodReference ref,
+inline typename AtomicDexRefMap<T>::InsertResult AtomicDexRefMap<T>::Insert(
+ DexFileReference ref,
const T& expected,
const T& desired) {
ElementArray* const array = GetArray(ref.dex_file);
if (array == nullptr) {
return kInsertResultInvalidDexFile;
}
- return (*array)[ref.dex_method_index].CompareExchangeStrongSequentiallyConsistent(
- expected, desired)
+ DCHECK_LT(ref.index, array->size());
+ return (*array)[ref.index].CompareExchangeStrongSequentiallyConsistent(expected, desired)
? kInsertResultSuccess
: kInsertResultCASFailure;
}
template <typename T>
-inline bool AtomicMethodRefMap<T>::Get(MethodReference ref, T* out) const {
+inline bool AtomicDexRefMap<T>::Get(DexFileReference ref, T* out) const {
const ElementArray* const array = GetArray(ref.dex_file);
if (array == nullptr) {
return false;
}
- *out = (*array)[ref.dex_method_index].LoadRelaxed();
+ *out = (*array)[ref.index].LoadRelaxed();
return true;
}
template <typename T>
-inline void AtomicMethodRefMap<T>::AddDexFile(const DexFile* dex_file) {
- arrays_.Put(dex_file, std::move(ElementArray(dex_file->NumMethodIds())));
+inline void AtomicDexRefMap<T>::AddDexFile(const DexFile* dex_file, size_t max_index) {
+ arrays_.Put(dex_file, std::move(ElementArray(max_index)));
}
template <typename T>
-inline typename AtomicMethodRefMap<T>::ElementArray* AtomicMethodRefMap<T>::GetArray(
+inline typename AtomicDexRefMap<T>::ElementArray* AtomicDexRefMap<T>::GetArray(
const DexFile* dex_file) {
auto it = arrays_.find(dex_file);
return (it != arrays_.end()) ? &it->second : nullptr;
}
template <typename T>
-inline const typename AtomicMethodRefMap<T>::ElementArray* AtomicMethodRefMap<T>::GetArray(
+inline const typename AtomicDexRefMap<T>::ElementArray* AtomicDexRefMap<T>::GetArray(
const DexFile* dex_file) const {
auto it = arrays_.find(dex_file);
return (it != arrays_.end()) ? &it->second : nullptr;
}
template <typename T> template <typename Visitor>
-inline void AtomicMethodRefMap<T>::Visit(const Visitor& visitor) {
+inline void AtomicDexRefMap<T>::Visit(const Visitor& visitor) {
for (auto& pair : arrays_) {
const DexFile* dex_file = pair.first;
const ElementArray& elements = pair.second;
for (size_t i = 0; i < elements.size(); ++i) {
- visitor(MethodReference(dex_file, i), elements[i].LoadRelaxed());
+ visitor(DexFileReference(dex_file, i), elements[i].LoadRelaxed());
}
}
}
template <typename T>
-inline void AtomicMethodRefMap<T>::ClearEntries() {
+inline void AtomicDexRefMap<T>::ClearEntries() {
for (auto& it : arrays_) {
for (auto& element : it.second) {
element.StoreRelaxed(nullptr);
@@ -89,4 +89,4 @@
} // namespace art
-#endif // ART_COMPILER_UTILS_ATOMIC_METHOD_REF_MAP_INL_H_
+#endif // ART_COMPILER_UTILS_ATOMIC_DEX_REF_MAP_INL_H_
diff --git a/compiler/utils/atomic_method_ref_map.h b/compiler/utils/atomic_dex_ref_map.h
similarity index 80%
rename from compiler/utils/atomic_method_ref_map.h
rename to compiler/utils/atomic_dex_ref_map.h
index fed848f..2da4ffa 100644
--- a/compiler/utils/atomic_method_ref_map.h
+++ b/compiler/utils/atomic_dex_ref_map.h
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-#ifndef ART_COMPILER_UTILS_ATOMIC_METHOD_REF_MAP_H_
-#define ART_COMPILER_UTILS_ATOMIC_METHOD_REF_MAP_H_
+#ifndef ART_COMPILER_UTILS_ATOMIC_DEX_REF_MAP_H_
+#define ART_COMPILER_UTILS_ATOMIC_DEX_REF_MAP_H_
#include "base/dchecked_vector.h"
-#include "method_reference.h"
+#include "dex_file.h"
#include "safe_map.h"
namespace art {
@@ -27,10 +27,10 @@
// Used by CompilerCallbacks to track verification information from the Runtime.
template <typename T>
-class AtomicMethodRefMap {
+class AtomicDexRefMap {
public:
- explicit AtomicMethodRefMap() {}
- ~AtomicMethodRefMap() {}
+ explicit AtomicDexRefMap() {}
+ ~AtomicDexRefMap() {}
// Atomically swap the element in if the existing value matches expected.
enum InsertResult {
@@ -38,14 +38,14 @@
kInsertResultCASFailure,
kInsertResultSuccess,
};
- InsertResult Insert(MethodReference ref, const T& expected, const T& desired);
+ InsertResult Insert(DexFileReference ref, const T& expected, const T& desired);
// Retreive an item, returns false if the dex file is not added.
- bool Get(MethodReference ref, T* out) const;
+ bool Get(DexFileReference ref, T* out) const;
// Dex files must be added before method references belonging to them can be used as keys. Not
// thread safe.
- void AddDexFile(const DexFile* dex_file);
+ void AddDexFile(const DexFile* dex_file, size_t max_index);
bool HaveDexFile(const DexFile* dex_file) const {
return arrays_.find(dex_file) != arrays_.end();
@@ -70,4 +70,4 @@
} // namespace art
-#endif // ART_COMPILER_UTILS_ATOMIC_METHOD_REF_MAP_H_
+#endif // ART_COMPILER_UTILS_ATOMIC_DEX_REF_MAP_H_
diff --git a/compiler/utils/atomic_method_ref_map_test.cc b/compiler/utils/atomic_dex_ref_map_test.cc
similarity index 64%
rename from compiler/utils/atomic_method_ref_map_test.cc
rename to compiler/utils/atomic_dex_ref_map_test.cc
index 9e5bf4b..ae19a9c 100644
--- a/compiler/utils/atomic_method_ref_map_test.cc
+++ b/compiler/utils/atomic_dex_ref_map_test.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "atomic_method_ref_map-inl.h"
+#include "atomic_dex_ref_map-inl.h"
#include <memory>
@@ -25,46 +25,46 @@
namespace art {
-class AtomicMethodRefMapTest : public CommonRuntimeTest {};
+class AtomicDexRefMapTest : public CommonRuntimeTest {};
-TEST_F(AtomicMethodRefMapTest, RunTests) {
+TEST_F(AtomicDexRefMapTest, RunTests) {
ScopedObjectAccess soa(Thread::Current());
std::unique_ptr<const DexFile> dex(OpenTestDexFile("Interfaces"));
ASSERT_TRUE(dex != nullptr);
- using Map = AtomicMethodRefMap<int>;
+ using Map = AtomicDexRefMap<int>;
Map map;
int value = 123;
// Error case: Not already inserted.
- EXPECT_FALSE(map.Get(MethodReference(dex.get(), 1), &value));
+ EXPECT_FALSE(map.Get(DexFileReference(dex.get(), 1), &value));
EXPECT_FALSE(map.HaveDexFile(dex.get()));
// Error case: Dex file not registered.
- EXPECT_TRUE(map.Insert(MethodReference(dex.get(), 1), 0, 1) == Map::kInsertResultInvalidDexFile);
- map.AddDexFile(dex.get());
+ EXPECT_TRUE(map.Insert(DexFileReference(dex.get(), 1), 0, 1) == Map::kInsertResultInvalidDexFile);
+ map.AddDexFile(dex.get(), dex->NumMethodIds());
EXPECT_TRUE(map.HaveDexFile(dex.get()));
EXPECT_GT(dex->NumMethodIds(), 10u);
// After we have added the get should succeed but return the default value.
- EXPECT_TRUE(map.Get(MethodReference(dex.get(), 1), &value));
+ EXPECT_TRUE(map.Get(DexFileReference(dex.get(), 1), &value));
EXPECT_EQ(value, 0);
// Actually insert an item and make sure we can retreive it.
static const int kInsertValue = 44;
- EXPECT_TRUE(map.Insert(MethodReference(dex.get(), 1), 0, kInsertValue) ==
+ EXPECT_TRUE(map.Insert(DexFileReference(dex.get(), 1), 0, kInsertValue) ==
Map::kInsertResultSuccess);
- EXPECT_TRUE(map.Get(MethodReference(dex.get(), 1), &value));
+ EXPECT_TRUE(map.Get(DexFileReference(dex.get(), 1), &value));
EXPECT_EQ(value, kInsertValue);
static const int kInsertValue2 = 123;
- EXPECT_TRUE(map.Insert(MethodReference(dex.get(), 2), 0, kInsertValue2) ==
+ EXPECT_TRUE(map.Insert(DexFileReference(dex.get(), 2), 0, kInsertValue2) ==
Map::kInsertResultSuccess);
- EXPECT_TRUE(map.Get(MethodReference(dex.get(), 1), &value));
+ EXPECT_TRUE(map.Get(DexFileReference(dex.get(), 1), &value));
EXPECT_EQ(value, kInsertValue);
- EXPECT_TRUE(map.Get(MethodReference(dex.get(), 2), &value));
+ EXPECT_TRUE(map.Get(DexFileReference(dex.get(), 2), &value));
EXPECT_EQ(value, kInsertValue2);
// Error case: Incorrect expected value for CAS.
- EXPECT_TRUE(map.Insert(MethodReference(dex.get(), 1), 0, kInsertValue + 1) ==
+ EXPECT_TRUE(map.Insert(DexFileReference(dex.get(), 1), 0, kInsertValue + 1) ==
Map::kInsertResultCASFailure);
// Correctly overwrite the value and verify.
- EXPECT_TRUE(map.Insert(MethodReference(dex.get(), 1), kInsertValue, kInsertValue + 1) ==
+ EXPECT_TRUE(map.Insert(DexFileReference(dex.get(), 1), kInsertValue, kInsertValue + 1) ==
Map::kInsertResultSuccess);
- EXPECT_TRUE(map.Get(MethodReference(dex.get(), 1), &value));
+ EXPECT_TRUE(map.Get(DexFileReference(dex.get(), 1), &value));
EXPECT_EQ(value, kInsertValue + 1);
}