From f36c5d42c7f250e11bfd57b06355a22b71eaf7f0 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Sat, 9 Sep 2023 16:07:37 +0200 Subject: [PATCH] Avoid Unsafe usage where possible (#2403) --- .../PaperweightPlatformAdapter.java | 24 +++---------- .../v1_17_R1_2/regen/PaperweightRegen.java | 2 +- .../v1_18_R2/PaperweightPlatformAdapter.java | 35 ++++--------------- .../fawe/v1_18_R2/regen/PaperweightRegen.java | 2 +- .../v1_19_R3/PaperweightPlatformAdapter.java | 34 ++++-------------- .../fawe/v1_19_R3/regen/PaperweightRegen.java | 2 +- .../v1_20_R1/PaperweightPlatformAdapter.java | 34 ++++-------------- .../fawe/v1_20_R1/regen/PaperweightRegen.java | 2 +- .../core/util/ReflectionUtils.java | 19 ++++++++-- 9 files changed, 43 insertions(+), 111 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java index 688a84a14..0854fc7ad 100644 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java @@ -85,11 +85,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final MethodHandle methodGetVisibleChunk; - private static final int CHUNKSECTION_BASE; - private static final int CHUNKSECTION_SHIFT; - private static final Field fieldLock; - private static final long fieldLockOffset; private static final Field fieldGameEventDispatcherSections; private static final MethodHandle methodremoveBlockEntityTicker; @@ -127,15 +123,12 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { getVisibleChunkIfPresent.setAccessible(true); methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent); - Unsafe unsafe = ReflectionUtils.getUnsafe(); if (!PaperLib.isPaper()) { - fieldLock = PalettedContainer.class.getDeclaredField(Refraction.pickName("lock", "m")); - fieldLockOffset = unsafe.objectFieldOffset(fieldLock); + fieldLock.setAccessible(true); } else { // in paper, the used methods are synchronized properly fieldLock = null; - fieldLockOffset = -1; } fieldGameEventDispatcherSections = LevelChunk.class.getDeclaredField(Refraction.pickName( @@ -152,13 +145,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p")); fieldRemove.setAccessible(true); - - CHUNKSECTION_BASE = unsafe.arrayBaseOffset(LevelChunkSection[].class); - int scale = unsafe.arrayIndexScale(LevelChunkSection[].class); - if ((scale & (scale - 1)) != 0) { - throw new Error("data type scale not a power of two"); - } - CHUNKSECTION_SHIFT = 31 - Integer.numberOfLeadingZeros(scale); } catch (RuntimeException e) { throw e; } catch (Throwable rethrow) { @@ -173,9 +159,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { LevelChunkSection value, int layer ) { - long offset = ((long) layer << CHUNKSECTION_SHIFT) + CHUNKSECTION_BASE; if (layer >= 0 && layer < sections.length) { - return ReflectionUtils.getUnsafe().compareAndSwapObject(sections, offset, expected, value); + return ReflectionUtils.compareAndSet(sections, expected, value, layer); } return false; } @@ -190,14 +175,13 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } try { synchronized (section) { - Unsafe unsafe = ReflectionUtils.getUnsafe(); PalettedContainer blocks = section.getStates(); - Semaphore currentLock = (Semaphore) unsafe.getObject(blocks, fieldLockOffset); + Semaphore currentLock = (Semaphore) fieldLock.get(blocks); if (currentLock instanceof DelegateSemaphore delegateSemaphore) { return delegateSemaphore; } DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); - unsafe.putObject(blocks, fieldLockOffset, newLock); + fieldLock.set(blocks, newLock); return newLock; } } catch (Throwable e) { diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/regen/PaperweightRegen.java index 4d7a749de..63d93156b 100644 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/regen/PaperweightRegen.java +++ b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/regen/PaperweightRegen.java @@ -329,7 +329,7 @@ public class PaperweightRegen extends Regenerator= 0 && layer < sections.length) { - return ReflectionUtils.getUnsafe().compareAndSwapObject(sections, offset, expected, value); + return ReflectionUtils.compareAndSet(sections, expected, value, layer); } return false; } @@ -207,19 +188,15 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } try { synchronized (section) { - Unsafe unsafe = ReflectionUtils.getUnsafe(); PalettedContainer blocks = section.getStates(); - ThreadingDetector currentThreadingDetector = (ThreadingDetector) unsafe.getObject( - blocks, - fieldThreadingDetectorOffset - ); + ThreadingDetector currentThreadingDetector = (ThreadingDetector) fieldThreadingDetector.get(blocks); synchronized (currentThreadingDetector) { - Semaphore currentLock = (Semaphore) unsafe.getObject(currentThreadingDetector, fieldLockOffset); + Semaphore currentLock = (Semaphore) fieldLock.get(currentThreadingDetector); if (currentLock instanceof DelegateSemaphore delegateSemaphore) { return delegateSemaphore; } DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); - unsafe.putObject(currentThreadingDetector, fieldLockOffset, newLock); + fieldLock.set(currentThreadingDetector, newLock); return newLock; } } diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/regen/PaperweightRegen.java index 34e18f748..8403d531d 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/regen/PaperweightRegen.java +++ b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/regen/PaperweightRegen.java @@ -342,7 +342,7 @@ public class PaperweightRegen extends Regenerator= 0 && layer < sections.length) { - return ReflectionUtils.getUnsafe().compareAndSwapObject(sections, offset, expected, value); + return ReflectionUtils.compareAndSet(sections, expected, value, layer); } return false; } @@ -243,19 +225,15 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } try { synchronized (section) { - Unsafe unsafe = ReflectionUtils.getUnsafe(); PalettedContainer blocks = section.getStates(); - ThreadingDetector currentThreadingDetector = (ThreadingDetector) unsafe.getObject( - blocks, - fieldThreadingDetectorOffset - ); + ThreadingDetector currentThreadingDetector = (ThreadingDetector) fieldThreadingDetector.get(blocks); synchronized (currentThreadingDetector) { - Semaphore currentLock = (Semaphore) unsafe.getObject(currentThreadingDetector, fieldLockOffset); + Semaphore currentLock = (Semaphore) fieldLock.get(currentThreadingDetector); if (currentLock instanceof DelegateSemaphore delegateSemaphore) { return delegateSemaphore; } DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); - unsafe.putObject(currentThreadingDetector, fieldLockOffset, newLock); + fieldLock.set(currentThreadingDetector, newLock); return newLock; } } diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java index 22bae54fe..7e2f3eaee 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java @@ -369,7 +369,7 @@ public class PaperweightRegen extends Regenerator= 0 && layer < sections.length) { - return ReflectionUtils.getUnsafe().compareAndSwapObject(sections, offset, expected, value); + return ReflectionUtils.compareAndSet(sections, expected, value, layer); } return false; } @@ -266,19 +248,15 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } try { synchronized (section) { - Unsafe unsafe = ReflectionUtils.getUnsafe(); PalettedContainer blocks = section.getStates(); - ThreadingDetector currentThreadingDetector = (ThreadingDetector) unsafe.getObject( - blocks, - fieldThreadingDetectorOffset - ); + ThreadingDetector currentThreadingDetector = (ThreadingDetector) fieldThreadingDetector.get(blocks); synchronized (currentThreadingDetector) { - Semaphore currentLock = (Semaphore) unsafe.getObject(currentThreadingDetector, fieldLockOffset); + Semaphore currentLock = (Semaphore) fieldLock.get(currentThreadingDetector); if (currentLock instanceof DelegateSemaphore delegateSemaphore) { return delegateSemaphore; } DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); - unsafe.putObject(currentThreadingDetector, fieldLockOffset, newLock); + fieldLock.set(currentThreadingDetector, newLock); return newLock; } } diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/regen/PaperweightRegen.java index 812cf1d4c..99e001837 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/regen/PaperweightRegen.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/regen/PaperweightRegen.java @@ -370,7 +370,7 @@ public class PaperweightRegen extends Regenerator the type of elements in the array + * @return true if the value at the index was successfully updated to the new value, false otherwise + * @see VarHandle#compareAndSet(Object...) + */ + public static boolean compareAndSet(T[] array, T expectedValue, T newValue, int index) { + return REFERENCE_ARRAY_HANDLE.compareAndSet(array, index, expectedValue, newValue); + } + public static void setAccessibleNonFinal(Field field) { // let's make the field accessible field.setAccessible(true);