mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 04:51:24 +07:00
IJPL-191435 Unsafe::arrayBaseOffset called in Kotlin under JDK 24
- unify duplicate ConcurrentIntObjectHashMap implementations to work via VarHandles if available GitOrigin-RevId: 084232c35927181a80917c12f6e0bca9b7380483
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5126eaa8bd
commit
d2a42ea691
@@ -61,10 +61,10 @@ public class CoreProgressManager extends ProgressManager implements Disposable {
|
||||
private static final Map<ProgressIndicator, Set<Thread>> threadsUnderIndicator = new HashMap<>(); // guarded by threadsUnderIndicator
|
||||
// the active indicator for the thread id
|
||||
private static final ConcurrentLongObjectMap<ProgressIndicator> currentIndicators =
|
||||
Java11Shim.INSTANCE.createConcurrentLongObjectMap();
|
||||
Java11Shim.Companion.createConcurrentLongObjectMap();
|
||||
// top-level indicators for the thread id
|
||||
private static final ConcurrentLongObjectMap<ProgressIndicator> threadTopLevelIndicators =
|
||||
Java11Shim.INSTANCE.createConcurrentLongObjectMap();
|
||||
Java11Shim.Companion.createConcurrentLongObjectMap();
|
||||
// threads which are running under canceled indicator
|
||||
private static final Set<Thread> threadsUnderCanceledIndicator = new HashSet<>(); // guarded by threadsUnderIndicator
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.platform.ide.bootstrap
|
||||
|
||||
import com.intellij.concurrency.VarHandleWrapperImpl
|
||||
@@ -67,4 +67,4 @@ class Java11ShimImpl : Java11Shim() {
|
||||
stream.skip(stackFrameIndex.toLong()).map { it.declaringClass }.findFirst().orElse(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -527,13 +527,6 @@ public class ContainerUtilCollectionsTest extends Assert {
|
||||
assertTrue(map.isEmpty());
|
||||
}
|
||||
|
||||
@Test(timeout = TIMEOUT)
|
||||
public void testOldConcurrentLongObjectHashMap() {
|
||||
ConcurrentLongObjectMap<Object> map = Java11Shim.INSTANCE.createConcurrentLongObjectMap();
|
||||
check(map);
|
||||
}
|
||||
|
||||
|
||||
@Test(timeout = TIMEOUT)
|
||||
public void testConcurrentIntObjectHashMap() {
|
||||
IntObjectMap<Object> map = ConcurrentCollectionFactory.createConcurrentIntObjectMap();
|
||||
@@ -555,27 +548,6 @@ public class ContainerUtilCollectionsTest extends Assert {
|
||||
assertEquals(0, map.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOldConcurrentIntObjectHashMap() {
|
||||
IntObjectMap<Object> map = ContainerUtil.createConcurrentIntObjectMap();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
Object prev = map.put(i, i);
|
||||
assertNull(prev);
|
||||
Object ret = map.get(i);
|
||||
assertTrue(ret instanceof Integer);
|
||||
assertEquals(i, ret);
|
||||
|
||||
if (i != 0) {
|
||||
Object remove = map.remove(i - 1);
|
||||
assertTrue(remove instanceof Integer);
|
||||
assertEquals(i - 1, remove);
|
||||
}
|
||||
assertEquals(1, map.size());
|
||||
}
|
||||
map.clear();
|
||||
assertEquals(0, map.size());
|
||||
}
|
||||
|
||||
@Test(timeout = TIMEOUT)
|
||||
public void testConcurrentWeakKeyWeakValueMapTossed() {
|
||||
ConcurrentMap<Object, Object> map = CollectionFactory.createConcurrentWeakKeyWeakValueMap();
|
||||
@@ -851,7 +823,7 @@ public class ContainerUtilCollectionsTest extends Assert {
|
||||
checkEntrySetIterator(ContainerUtil.createIntKeyWeakValueMap());
|
||||
|
||||
checkEntrySetIterator(ConcurrentCollectionFactory.createConcurrentLongObjectMap());
|
||||
checkEntrySetIterator(Java11Shim.INSTANCE.createConcurrentLongObjectMap());
|
||||
checkEntrySetIterator(Java11Shim.Companion.createConcurrentLongObjectMap());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -74,24 +74,24 @@ public final class ConcurrentCollectionFactory {
|
||||
|
||||
@Contract(value = " -> new", pure = true)
|
||||
public static @NotNull <V> ConcurrentLongObjectMap<@NotNull V> createConcurrentLongObjectMap() {
|
||||
return Java11Shim.INSTANCE.createConcurrentLongObjectMap();
|
||||
return Java11Shim.Companion.createConcurrentLongObjectMap();
|
||||
}
|
||||
|
||||
@Contract(value = " -> new", pure = true)
|
||||
public static @NotNull <V> ConcurrentIntObjectMap<@NotNull V> createConcurrentIntObjectMap() {
|
||||
return new ConcurrentIntObjectHashMap<>();
|
||||
return Java11Shim.Companion.createConcurrentIntObjectMap();
|
||||
}
|
||||
|
||||
@Contract(value = "_,_,_ -> new", pure = true)
|
||||
public static @NotNull <V> ConcurrentIntObjectMap<@NotNull V> createConcurrentIntObjectMap(int initialCapacity, float loadFactor, int concurrencyLevel) {
|
||||
return new ConcurrentIntObjectHashMap<>(initialCapacity, loadFactor, concurrencyLevel);
|
||||
return Java11Shim.Companion.createConcurrentIntObjectMap(initialCapacity, loadFactor, concurrencyLevel);
|
||||
}
|
||||
@Contract(value = " -> new", pure = true)
|
||||
public static @NotNull <V> ConcurrentIntObjectMap<@NotNull V> createConcurrentIntObjectSoftValueMap() {
|
||||
return new ConcurrentIntKeySoftValueHashMap<>();
|
||||
return Java11Shim.Companion.createConcurrentIntObjectSoftValueMap();
|
||||
}
|
||||
@Contract(value = " -> new", pure = true)
|
||||
public static @NotNull <V> ConcurrentIntObjectMap<@NotNull V> createConcurrentIntObjectWeakValueMap() {
|
||||
return new ConcurrentIntKeyWeakValueHashMap<>();
|
||||
return Java11Shim.Companion.createConcurrentIntObjectWeakValueMap();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,8 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.concurrency;
|
||||
package com.intellij.util.containers;
|
||||
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ConcurrentIntObjectMap;
|
||||
import com.intellij.util.containers.ReferenceQueueable;
|
||||
import com.intellij.util.containers.SimpleEntry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
@@ -162,7 +159,7 @@ abstract class ConcurrentIntKeyRefValueHashMap<V> implements ConcurrentIntObject
|
||||
|
||||
private @NotNull Iterator<Entry<V>> entriesIterator() {
|
||||
final Iterator<Entry<IntReference<V>>> entryIterator = myMap.entrySet().iterator();
|
||||
return new Iterator<>() {
|
||||
return new Iterator<Entry<V>>() {
|
||||
private Entry<V> nextVEntry;
|
||||
private Entry<IntReference<V>> nextReferenceEntry;
|
||||
private Entry<IntReference<V>> lastReturned;
|
||||
@@ -224,7 +221,7 @@ abstract class ConcurrentIntKeyRefValueHashMap<V> implements ConcurrentIntObject
|
||||
@Override
|
||||
public @NotNull Enumeration<V> elements() {
|
||||
final Enumeration<IntReference<V>> elementRefs = myMap.elements();
|
||||
return new Enumeration<>() {
|
||||
return new Enumeration<V>() {
|
||||
private V findNextRef() {
|
||||
while (elementRefs.hasMoreElements()) {
|
||||
IntReference<V> result = elementRefs.nextElement();
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.concurrency;
|
||||
package com.intellij.util.containers;
|
||||
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -10,7 +10,7 @@ import java.lang.ref.SoftReference;
|
||||
/**
|
||||
* Concurrent key:int -> soft value:V map
|
||||
* Null values are NOT allowed
|
||||
* Use {@link ConcurrentCollectionFactory#createConcurrentIntObjectSoftValueMap()} to create this
|
||||
* Use {@link com.intellij.concurrency.ConcurrentCollectionFactory#createConcurrentIntObjectSoftValueMap()} to create this
|
||||
*/
|
||||
final class ConcurrentIntKeySoftValueHashMap<V> extends ConcurrentIntKeyRefValueHashMap<V> {
|
||||
private static final class MyRef<V> extends SoftReference<V> implements IntReference<V> {
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.concurrency;
|
||||
package com.intellij.util.containers;
|
||||
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -10,7 +10,7 @@ import java.lang.ref.WeakReference;
|
||||
/**
|
||||
* Concurrent key:int -> weak value:V map
|
||||
* Null values are NOT allowed
|
||||
* Use {@link ConcurrentCollectionFactory#createConcurrentIntObjectWeakValueMap()} to create
|
||||
* Use {@link com.intellij.concurrency.ConcurrentCollectionFactory#createConcurrentIntObjectWeakValueMap()} to create
|
||||
*/
|
||||
final class ConcurrentIntKeyWeakValueHashMap<V> extends ConcurrentIntKeyRefValueHashMap<V> {
|
||||
private static final class MyRef<V> extends WeakReference<V> implements IntReference<V> {
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2672,7 +2672,7 @@ public final class ContainerUtil {
|
||||
@Deprecated
|
||||
@Contract(value = " -> new", pure = true)
|
||||
public static @NotNull <V> ConcurrentIntObjectMap<@NotNull V> createConcurrentIntObjectMap() {
|
||||
return new ConcurrentIntObjectHashMap<>();
|
||||
return Java11Shim.Companion.createConcurrentIntObjectMap();
|
||||
}
|
||||
|
||||
@Contract(value = " -> new", pure = true)
|
||||
|
||||
@@ -12,6 +12,11 @@ abstract class Java11Shim {
|
||||
companion object {
|
||||
@JvmField
|
||||
var INSTANCE: Java11Shim = DefaultJava11Shim()
|
||||
fun <V> createConcurrentLongObjectMap(): ConcurrentLongObjectMap<V> = ConcurrentLongObjectHashMap()
|
||||
fun <V> createConcurrentIntObjectMap(): ConcurrentIntObjectMap<V> = ConcurrentIntObjectHashMap()
|
||||
fun <V> createConcurrentIntObjectMap(initialCapacity:Int, loadFactor:Float, concurrencyLevel:Int): ConcurrentIntObjectMap<V> = ConcurrentIntObjectHashMap(initialCapacity, loadFactor, concurrencyLevel)
|
||||
fun <V> createConcurrentIntObjectSoftValueMap(): ConcurrentIntObjectMap<V> = ConcurrentIntKeySoftValueHashMap()
|
||||
fun <V> createConcurrentIntObjectWeakValueMap(): ConcurrentIntObjectMap<V> = ConcurrentIntKeyWeakValueHashMap()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,9 +42,5 @@ abstract class Java11Shim {
|
||||
|
||||
abstract fun <E> listOf(array: Array<E>, size: Int): List<E>
|
||||
|
||||
fun <V : Any> createConcurrentLongObjectMap(): ConcurrentLongObjectMap<V> {
|
||||
return ConcurrentLongObjectHashMap()
|
||||
}
|
||||
|
||||
abstract fun getCallerClass(stackFrameIndex: Int): Class<*>?
|
||||
}
|
||||
@@ -17,7 +17,6 @@ public final class Unsafe {
|
||||
private static final MethodHandle compareAndSwapObject;
|
||||
private static final MethodHandle compareAndSwapInt;
|
||||
private static final MethodHandle compareAndSwapLong;
|
||||
private static final MethodHandle getAndAddInt;
|
||||
private static final MethodHandle objectFieldOffset;
|
||||
private static final MethodHandle arrayIndexScale;
|
||||
private static final MethodHandle arrayBaseOffset;
|
||||
@@ -30,7 +29,6 @@ public final class Unsafe {
|
||||
compareAndSwapObject = find("compareAndSwapObject", boolean.class, Object.class, long.class, Object.class, Object.class);
|
||||
compareAndSwapInt = find("compareAndSwapInt", boolean.class, Object.class, long.class, int.class, int.class);
|
||||
compareAndSwapLong = find("compareAndSwapLong", boolean.class, Object.class, long.class, long.class, long.class);
|
||||
getAndAddInt = find("getAndAddInt", int.class, Object.class, long.class, int.class);
|
||||
objectFieldOffset = find("objectFieldOffset", long.class, Field.class);
|
||||
arrayBaseOffset = find("arrayBaseOffset", int.class, Class.class);
|
||||
arrayIndexScale = find("arrayIndexScale", int.class, Class.class);
|
||||
@@ -49,7 +47,7 @@ public final class Unsafe {
|
||||
.bindTo(unsafe);
|
||||
}
|
||||
|
||||
public static boolean compareAndSwapInt(Object object, long offset, int expected, int value) {
|
||||
static boolean compareAndSwapInt(Object object, long offset, int expected, int value) {
|
||||
try {
|
||||
return (boolean)compareAndSwapInt.invokeExact(object, offset, expected, value);
|
||||
}
|
||||
@@ -58,7 +56,7 @@ public final class Unsafe {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean compareAndSwapLong(@NotNull Object object, long offset, long expected, long value) {
|
||||
static boolean compareAndSwapLong(@NotNull Object object, long offset, long expected, long value) {
|
||||
try {
|
||||
return (boolean)compareAndSwapLong.invokeExact(object, offset, expected, value);
|
||||
}
|
||||
@@ -66,15 +64,8 @@ public final class Unsafe {
|
||||
throw new RuntimeException(throwable);
|
||||
}
|
||||
}
|
||||
public static int getAndAddInt(Object object, long offset, int v) {
|
||||
try {
|
||||
return (int)getAndAddInt.invokeExact(object, offset, v);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
public static Object getObjectVolatile(Object object, long offset) {
|
||||
|
||||
static Object getObjectVolatile(Object object, long offset) {
|
||||
try {
|
||||
return getObjectVolatile.invokeExact(object, offset);
|
||||
}
|
||||
@@ -83,9 +74,9 @@ public final class Unsafe {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean compareAndSwapObject(Object o, long offset,
|
||||
Object expected,
|
||||
Object x) {
|
||||
static boolean compareAndSwapObject(Object o, long offset,
|
||||
Object expected,
|
||||
Object x) {
|
||||
try {
|
||||
return (boolean)compareAndSwapObject.invokeExact(o, offset, expected, x);
|
||||
}
|
||||
@@ -94,7 +85,7 @@ public final class Unsafe {
|
||||
}
|
||||
}
|
||||
|
||||
public static void putObjectVolatile(Object o, long offset, Object x) {
|
||||
static void putObjectVolatile(Object o, long offset, Object x) {
|
||||
try {
|
||||
putObjectVolatile.invokeExact(o, offset, x);
|
||||
}
|
||||
@@ -102,7 +93,7 @@ public final class Unsafe {
|
||||
throw new RuntimeException(throwable);
|
||||
}
|
||||
}
|
||||
public static long objectFieldOffset(Field f) {
|
||||
static long objectFieldOffset(Field f) {
|
||||
try {
|
||||
return (long)objectFieldOffset.invokeExact(f);
|
||||
}
|
||||
@@ -111,7 +102,7 @@ public final class Unsafe {
|
||||
}
|
||||
}
|
||||
|
||||
public static int arrayIndexScale(Class<?> arrayClass) {
|
||||
static int arrayIndexScale(Class<?> arrayClass) {
|
||||
try {
|
||||
return (int)arrayIndexScale.invokeExact(arrayClass);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ internal open class ImmutableEntityStorageImpl(
|
||||
|
||||
// I suppose that we can use some kind of array of arrays to get a quicker access (just two accesses by-index)
|
||||
// However, it's not implemented currently because I'm not sure about threading.
|
||||
private val entityCache: ConcurrentLongObjectMap<WorkspaceEntity> = Java11Shim.INSTANCE.createConcurrentLongObjectMap()
|
||||
private val entityCache: ConcurrentLongObjectMap<WorkspaceEntity> = Java11Shim.createConcurrentLongObjectMap()
|
||||
|
||||
override fun <T> cached(query: StorageQuery<T>): T {
|
||||
return snapshotCache.cached(query, this, null).value
|
||||
|
||||
Reference in New Issue
Block a user