summaryrefslogtreecommitdiff
path: root/core/java/android/util/ArrayMap.java
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2016-02-27 21:10:34 -0700
committerJeff Sharkey <jsharkey@android.com>2016-02-27 21:15:01 -0700
commit3d1cb6a2b6882a9b702fc97aa50b2d5779956492 (patch)
tree1c2b760b33aa8667172e2f3f42034385fb718cf4 /core/java/android/util/ArrayMap.java
parentb15a71913eaea4d2e7063437b3d1a8db5d98c221 (diff)
Utility to detect lock inversions in system.
This change adds a new LockGuard utility class that can be used to detect lock inversions across the system server. For example, if a thread is trying to acquire the ActivityManager lock while holding the PackageManager lock, it will yell. This class requires no prior knowledge of locks or their ordering; it derives all of this data at runtime. However, this means the overhead is substantial and it should not be enabled by default. Adds overrides to ArrayMap and ArraySet to use identityHashCode() instead of the hashCode() provided by the object. Bug: 27336728 Change-Id: I26c31bc99fe8d61ff13c3455aaeddd5517e44433
Diffstat (limited to 'core/java/android/util/ArrayMap.java')
-rw-r--r--core/java/android/util/ArrayMap.java39
1 files changed, 22 insertions, 17 deletions
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
index bdb1fdcb9ff8..92a5803b5ddb 100644
--- a/core/java/android/util/ArrayMap.java
+++ b/core/java/android/util/ArrayMap.java
@@ -67,7 +67,7 @@ public final class ArrayMap<K, V> implements Map<K, V> {
/**
* @hide Special immutable empty ArrayMap.
*/
- public static final ArrayMap EMPTY = new ArrayMap(true);
+ public static final ArrayMap EMPTY = new ArrayMap<>(-1);
/**
* Caches of small array objects to avoid spamming garbage. The cache
@@ -80,6 +80,7 @@ public final class ArrayMap<K, V> implements Map<K, V> {
static Object[] mTwiceBaseCache;
static int mTwiceBaseCacheSize;
+ final boolean mIdentityHashCode;
int[] mHashes;
Object[] mArray;
int mSize;
@@ -236,30 +237,32 @@ public final class ArrayMap<K, V> implements Map<K, V> {
* will grow once items are added to it.
*/
public ArrayMap() {
- mHashes = EmptyArray.INT;
- mArray = EmptyArray.OBJECT;
- mSize = 0;
+ this(0, false);
}
/**
* Create a new ArrayMap with a given initial capacity.
*/
public ArrayMap(int capacity) {
- if (capacity == 0) {
- mHashes = EmptyArray.INT;
- mArray = EmptyArray.OBJECT;
- } else {
- allocArrays(capacity);
- }
- mSize = 0;
+ this(capacity, false);
}
- private ArrayMap(boolean immutable) {
+ /** {@hide} */
+ public ArrayMap(int capacity, boolean identityHashCode) {
+ mIdentityHashCode = identityHashCode;
+
// If this is immutable, use the sentinal EMPTY_IMMUTABLE_INTS
// instance instead of the usual EmptyArray.INT. The reference
// is checked later to see if the array is allowed to grow.
- mHashes = immutable ? EMPTY_IMMUTABLE_INTS : EmptyArray.INT;
- mArray = EmptyArray.OBJECT;
+ if (capacity < 0) {
+ mHashes = EMPTY_IMMUTABLE_INTS;
+ mArray = EmptyArray.OBJECT;
+ } else if (capacity == 0) {
+ mHashes = EmptyArray.INT;
+ mArray = EmptyArray.OBJECT;
+ } else {
+ allocArrays(capacity);
+ }
mSize = 0;
}
@@ -336,7 +339,8 @@ public final class ArrayMap<K, V> implements Map<K, V> {
* @return Returns the index of the key if it exists, else a negative integer.
*/
public int indexOfKey(Object key) {
- return key == null ? indexOfNull() : indexOf(key, key.hashCode());
+ return key == null ? indexOfNull()
+ : indexOf(key, mIdentityHashCode ? System.identityHashCode(key) : key.hashCode());
}
int indexOfValue(Object value) {
@@ -437,7 +441,7 @@ public final class ArrayMap<K, V> implements Map<K, V> {
hash = 0;
index = indexOfNull();
} else {
- hash = key.hashCode();
+ hash = mIdentityHashCode ? System.identityHashCode(key) : key.hashCode();
index = indexOf(key, hash);
}
if (index >= 0) {
@@ -488,7 +492,8 @@ public final class ArrayMap<K, V> implements Map<K, V> {
*/
public void append(K key, V value) {
int index = mSize;
- final int hash = key == null ? 0 : key.hashCode();
+ final int hash = key == null ? 0
+ : (mIdentityHashCode ? System.identityHashCode(key) : key.hashCode());
if (index >= mHashes.length) {
throw new IllegalStateException("Array is full");
}