diff --git a/src/java.base/share/classes/java/lang/Module.java b/src/java.base/share/classes/java/lang/Module.java index dcc92d012de59..0c84ef90e4bda 100644 --- a/src/java.base/share/classes/java/lang/Module.java +++ b/src/java.base/share/classes/java/lang/Module.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,6 @@ import java.net.URI; import java.net.URL; import java.security.CodeSource; -import java.security.ProtectionDomain; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -69,6 +68,8 @@ import jdk.internal.module.Resources; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; +import jdk.internal.vm.annotation.DontInline; +import jdk.internal.vm.annotation.ForceInline; import jdk.internal.vm.annotation.Stable; /** @@ -176,6 +177,7 @@ public final class Module implements AnnotatedElement { * @see ClassLoader#getUnnamedModule() * @jls 7.7.5 Unnamed Modules */ + @ForceInline public boolean isNamed() { return name != null; } @@ -186,6 +188,7 @@ public boolean isNamed() { * * @return The module name */ + @ForceInline public String getName() { return name; } @@ -195,6 +198,7 @@ public String getName() { * * @return The class loader for this module */ + @ForceInline public ClassLoader getClassLoader() { return loader; } @@ -205,6 +209,7 @@ public ClassLoader getClassLoader() { * * @return The module descriptor for this module */ + @ForceInline public ModuleDescriptor getDescriptor() { return descriptor; } @@ -224,6 +229,7 @@ public ModuleDescriptor getDescriptor() { * * @see java.lang.reflect.Proxy */ + @ForceInline public ModuleLayer getLayer() { if (isNamed()) { ModuleLayer layer = this.layer; @@ -253,6 +259,7 @@ Module implAddEnableNativeAccess() { * @return {@code true} if this module can access restricted methods. * @since 22 */ + @ForceInline public boolean isNativeAccessEnabled() { Module target = moduleForNativeAccess(); return EnableNativeAccess.isNativeAccessEnabled(target); @@ -269,8 +276,9 @@ private EnableNativeAccess() {} private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private static final long FIELD_OFFSET = UNSAFE.objectFieldOffset(Module.class, "enableNativeAccess"); + @ForceInline private static boolean isNativeAccessEnabled(Module target) { - return UNSAFE.getBooleanVolatile(target, FIELD_OFFSET); + return target.enableNativeAccess || UNSAFE.getBooleanVolatile(target, FIELD_OFFSET); } // Atomically sets enableNativeAccess if not already set @@ -282,53 +290,70 @@ private static boolean trySetEnableNativeAccess(Module target) { // Returns the Module object that holds the enableNativeAccess // flag for this module. + @ForceInline private Module moduleForNativeAccess() { return isNamed() ? this : ALL_UNNAMED_MODULE; } // This is invoked from Reflection.ensureNativeAccess + @ForceInline void ensureNativeAccess(Class owner, String methodName, Class currentClass, boolean jni) { // The target module whose enableNativeAccess flag is ensured Module target = moduleForNativeAccess(); ModuleBootstrap.IllegalNativeAccess illegalNativeAccess = ModuleBootstrap.illegalNativeAccess(); if (illegalNativeAccess != ModuleBootstrap.IllegalNativeAccess.ALLOW && !EnableNativeAccess.isNativeAccessEnabled(target)) { - String mod = isNamed() ? "module " + getName() : "an unnamed module"; - if (currentClass != null) { - // try to extract location of the current class (e.g. jar or folder) - CodeSource cs = currentClass.getProtectionDomain().getCodeSource(); - if (cs != null) { - URL url = cs.getLocation(); - if (url != null) { - mod += " (" + url + ")"; - } - } - } - if (illegalNativeAccess == ModuleBootstrap.IllegalNativeAccess.DENY) { - throw new IllegalCallerException("Illegal native access from " + mod); - } else if (EnableNativeAccess.trySetEnableNativeAccess(target)) { - // warn and set flag, so that only one warning is reported per module - String cls = owner.getName(); - String mtd = cls + "::" + methodName; - String modflag = isNamed() ? getName() : "ALL-UNNAMED"; - String caller = currentClass != null ? currentClass.getName() : "code"; - if (jni) { - VM.initialErr().printf(""" + ensureNativeAccessSlowPath(owner, methodName, currentClass, jni, target, illegalNativeAccess); + } + } + + @DontInline + void ensureNativeAccessSlowPath(Class owner, + String methodName, + Class currentClass, + boolean jni, + Module target, + ModuleBootstrap.IllegalNativeAccess illegalNativeAccess) { + String modDeclaredLabel = modDeclaredLabel(currentClass); + if (illegalNativeAccess == ModuleBootstrap.IllegalNativeAccess.DENY) { + throw new IllegalCallerException("Illegal native access from " + modDeclaredLabel); + } else if (EnableNativeAccess.trySetEnableNativeAccess(target)) { + // warn and set flag, so that only one warning is reported per module + String cls = owner.getName(); + String mtd = cls + "::" + methodName; + String modFlag = isNamed() ? getName() : "ALL-UNNAMED"; + String caller = currentClass != null ? currentClass.getName() : "code"; + if (jni) { + VM.initialErr().printf(""" WARNING: A native method in %s has been bound WARNING: %s is declared in %s WARNING: Use --enable-native-access=%s to avoid a warning for native methods declared in this module WARNING: Restricted methods will be blocked in a future release unless native access is enabled - %n""", cls, mtd, mod, modflag); - } else { - VM.initialErr().printf(""" + %n""", cls, mtd, modDeclaredLabel, modFlag); + } else { + VM.initialErr().printf(""" WARNING: A restricted method in %s has been called WARNING: %s has been called by %s in %s WARNING: Use --enable-native-access=%s to avoid a warning for callers in this module WARNING: Restricted methods will be blocked in a future release unless native access is enabled - %n""", cls, mtd, caller, mod, modflag); + %n""", cls, mtd, caller, modDeclaredLabel, modFlag); + } + } + } + + private String modDeclaredLabel(Class currentClass) { + String label = isNamed() ? "module " + getName() : "an unnamed module"; + if (currentClass != null) { + // try to extract location of the current class (e.g. jar or folder) + CodeSource cs = currentClass.getProtectionDomain().getCodeSource(); + if (cs != null) { + URL url = cs.getLocation(); + if (url != null) { + label += " (" + url + ")"; } } } + return label; } /** diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index aa9c8f312372e..a9c673e3b0099 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package java.lang; +import jdk.internal.vm.annotation.ForceInline; import jdk.internal.vm.annotation.IntrinsicCandidate; /** @@ -40,6 +41,7 @@ public class Object { /** * Constructs a new object. */ + @ForceInline @IntrinsicCandidate public Object() {} diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 241e479458d02..01198c768307a 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -81,6 +81,7 @@ import jdk.internal.vm.ContinuationScope; import jdk.internal.vm.StackableScope; import jdk.internal.vm.ThreadContainer; +import jdk.internal.vm.annotation.ForceInline; import jdk.internal.vm.annotation.IntrinsicCandidate; import jdk.internal.vm.annotation.Stable; import sun.reflect.annotation.AnnotationType; @@ -2080,6 +2081,7 @@ public boolean addEnableNativeAccess(ModuleLayer layer, String name) { public void addEnableNativeAccessToAllUnnamed() { Module.implAddEnableNativeAccessToAllUnnamed(); } + @ForceInline public void ensureNativeAccess(Module m, Class owner, String methodName, Class currentClass, boolean jni) { m.ensureNativeAccess(owner, methodName, currentClass, jni); } diff --git a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java index 83fb6881a411c..4493631d0ca7c 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -161,6 +161,7 @@ private NativeMemorySegmentImpl reinterpretInternal(Class callerClass, long n } // Using a static helper method ensures there is no unintended lambda capturing of `this` + @ForceInline private static Runnable cleanupAction(long address, long newSize, Consumer cleanup) { return cleanup != null ? () -> cleanup.accept(SegmentFactories.makeNativeSegmentUnchecked(address, newSize)) : diff --git a/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java b/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java index 2163146f1a93e..12cc8d9af68dc 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java @@ -210,6 +210,7 @@ public void checkValidStateRaw() { * @throws IllegalStateException if this session is already closed or if this is * a confined session and this method is called outside the owner thread. */ + @ForceInline public void checkValidState() { try { checkValidStateRaw(); diff --git a/src/java.base/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java index d0313adc88491..58f3b941d8076 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java @@ -38,12 +38,15 @@ */ public sealed class NativeMemorySegmentImpl extends AbstractMemorySegmentImpl permits MappedMemorySegmentImpl { + private static final boolean ADDRESS_SIZE_IS_4 = + Unsafe.getUnsafe().addressSize() == 4; + final long min; @ForceInline NativeMemorySegmentImpl(long min, long length, boolean readOnly, MemorySessionImpl scope) { super(length, readOnly, scope); - this.min = (Unsafe.getUnsafe().addressSize() == 4) + this.min = ADDRESS_SIZE_IS_4 // On 32-bit systems, normalize the upper unused 32-bits to zero ? min & 0x0000_0000_FFFF_FFFFL // On 64-bit systems, all the bits are used @@ -77,6 +80,7 @@ ByteBuffer makeByteBuffer() { return NIO_ACCESS.newDirectByteBuffer(min, (int) this.length, null, this); } + @ForceInline @Override public boolean isNative() { return true; @@ -93,6 +97,7 @@ public Object unsafeGetBase() { } @Override + @ForceInline public long maxAlignMask() { return 0; } diff --git a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java index dba2e6fa7ed14..d36386837b2ca 100644 --- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java +++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java @@ -3567,6 +3567,7 @@ public final long getLongUnaligned(Object o, long offset) { * @return the value fetched from the indicated object * @since 9 */ + @ForceInline public final long getLongUnaligned(Object o, long offset, boolean bigEndian) { return convEndian(bigEndian, getLongUnaligned(o, offset)); } @@ -3587,6 +3588,7 @@ public final int getIntUnaligned(Object o, long offset) { } } /** @see #getLongUnaligned(Object, long, boolean) */ + @ForceInline public final int getIntUnaligned(Object o, long offset, boolean bigEndian) { return convEndian(bigEndian, getIntUnaligned(o, offset)); } @@ -3602,6 +3604,7 @@ public final short getShortUnaligned(Object o, long offset) { } } /** @see #getLongUnaligned(Object, long, boolean) */ + @ForceInline public final short getShortUnaligned(Object o, long offset, boolean bigEndian) { return convEndian(bigEndian, getShortUnaligned(o, offset)); } @@ -3618,6 +3621,7 @@ public final char getCharUnaligned(Object o, long offset) { } /** @see #getLongUnaligned(Object, long, boolean) */ + @ForceInline public final char getCharUnaligned(Object o, long offset, boolean bigEndian) { return convEndian(bigEndian, getCharUnaligned(o, offset)); } @@ -3688,6 +3692,7 @@ public final void putLongUnaligned(Object o, long offset, long x) { * {@link NullPointerException} * @since 9 */ + @ForceInline public final void putLongUnaligned(Object o, long offset, long x, boolean bigEndian) { putLongUnaligned(o, offset, convEndian(bigEndian, x)); } @@ -3710,6 +3715,7 @@ public final void putIntUnaligned(Object o, long offset, int x) { } } /** @see #putLongUnaligned(Object, long, long, boolean) */ + @ForceInline public final void putIntUnaligned(Object o, long offset, int x, boolean bigEndian) { putIntUnaligned(o, offset, convEndian(bigEndian, x)); } @@ -3726,6 +3732,7 @@ public final void putShortUnaligned(Object o, long offset, short x) { } } /** @see #putLongUnaligned(Object, long, long, boolean) */ + @ForceInline public final void putShortUnaligned(Object o, long offset, short x, boolean bigEndian) { putShortUnaligned(o, offset, convEndian(bigEndian, x)); } @@ -3736,6 +3743,7 @@ public final void putCharUnaligned(Object o, long offset, char x) { putShortUnaligned(o, offset, (short)x); } /** @see #putLongUnaligned(Object, long, long, boolean) */ + @ForceInline public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) { putCharUnaligned(o, offset, convEndian(bigEndian, x)); } @@ -3829,10 +3837,10 @@ private void putShortParts(Object o, long offset, byte i0, byte i1) { private static long toUnsignedLong(int n) { return n & 0xffffffffl; } // Maybe byte-reverse an integer - private static char convEndian(boolean big, char n) { return big == BIG_ENDIAN ? n : Character.reverseBytes(n); } - private static short convEndian(boolean big, short n) { return big == BIG_ENDIAN ? n : Short.reverseBytes(n) ; } - private static int convEndian(boolean big, int n) { return big == BIG_ENDIAN ? n : Integer.reverseBytes(n) ; } - private static long convEndian(boolean big, long n) { return big == BIG_ENDIAN ? n : Long.reverseBytes(n) ; } + @ForceInline private static char convEndian(boolean big, char n) { return big == BIG_ENDIAN ? n : Character.reverseBytes(n); } + @ForceInline private static short convEndian(boolean big, short n) { return big == BIG_ENDIAN ? n : Short.reverseBytes(n) ; } + @ForceInline private static int convEndian(boolean big, int n) { return big == BIG_ENDIAN ? n : Integer.reverseBytes(n) ; } + @ForceInline private static long convEndian(boolean big, long n) { return big == BIG_ENDIAN ? n : Long.reverseBytes(n) ; } diff --git a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java index 0a9044178a443..b8cdd06a77ad0 100644 --- a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java +++ b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java @@ -56,6 +56,7 @@ import jdk.internal.loader.ClassLoaders; import jdk.internal.misc.CDS; import jdk.internal.perf.PerfCounter; +import jdk.internal.vm.annotation.ForceInline; /** * Initializes/boots the module system. @@ -820,6 +821,7 @@ public enum IllegalNativeAccess { DENY } + @ForceInline public static IllegalNativeAccess illegalNativeAccess() { return ILLEGAL_NATIVE_ACCESS; } @@ -887,6 +889,7 @@ private static Set decodeEnableNativeAccess() { /** * Process the --illegal-native-access option (and its default). */ + @ForceInline private static IllegalNativeAccess addIllegalNativeAccess() { String value = getAndRemoveProperty("jdk.module.illegal.native.access"); // don't use a switch: bootstrapping issues! diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/FFMVarHandleInlineTest.java b/test/micro/org/openjdk/bench/java/lang/foreign/FFMVarHandleInlineTest.java new file mode 100644 index 0000000000000..42643f8ef579a --- /dev/null +++ b/test/micro/org/openjdk/bench/java/lang/foreign/FFMVarHandleInlineTest.java @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.java.lang.foreign; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.CompilerControl; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; + +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.invoke.VarHandle; +import java.lang.ref.Reference; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +@State(Scope.Benchmark) +@Warmup(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS) +@Fork(value = 2, jvmArgsAppend = { + "-XX:+UnlockDiagnosticVMOptions", + "-Xbatch", + "-XX:MaxInlineLevel=15", + "-XX:CompileCommand=PrintInlining,org.openjdk.bench.java.lang.foreign.FFMVarHandleInlineTest::t_level15"}) +public class FFMVarHandleInlineTest { + + private static final boolean RANDOM_ORDER = true; + + /** + * Implements the following: + *
{@code
+     * int JAVA_INT_UNALIGNED(long offset) {
+     *     return MemorySegment
+     *         .ofAddress(offset)
+     *         .reinterpret(8L)
+     *         .get(ValueLayout.JAVA_INT_UNALIGNED, 0L)
+     * }
+     * }
+ */ + private static final VarHandle JAVA_INT_UNALIGNED; + + static { + try { + var ofAddress = MethodHandles.lookup() + .findStatic(MemorySegment.class, "ofAddress", MethodType.methodType(MemorySegment.class, long.class)); + + var reinterpret = MethodHandles.lookup() + .findVirtual(MemorySegment.class, "reinterpret", MethodType.methodType(MemorySegment.class, long.class)); + + var vh = ValueLayout.JAVA_INT_UNALIGNED.varHandle(); + + vh = MethodHandles.insertCoordinates(vh, 1, 0L); + vh = MethodHandles.filterCoordinates(vh, 0, MethodHandles.filterReturnValue( + ofAddress, + MethodHandles.insertArguments(reinterpret, 1, 8L) + )); + + JAVA_INT_UNALIGNED = vh.withInvokeExactBehavior(); + } catch (NoSuchMethodException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + // segment + offsets should comfortably fit in L1 cache + + private MemorySegment segment; + + private long[] offsets; + + @Param(value = { + "1024", // 1kb + }) + private int segmentSize; + + @Param(value = { + //"8", // 64b + //"512", // 4kb + "2048", // 16kb + }) + private int offsetCount; + + @Setup + public void init() { + var rand = new Random(42); + + // initialize segment with random values + segment = Arena.ofAuto().allocate(segmentSize); + for (int i = 0; i < segment.byteSize() / 8; i++) { + segment.setAtIndex(ValueLayout.JAVA_LONG, i, rand.nextLong()); + } + + var ints = (int) (segment.byteSize() >> 2); + + // initialize offset array + offsets = new long[offsetCount]; + for (int i = 0; i < offsets.length; i++) { + if (RANDOM_ORDER) { + offsets[i] = segment.address() + ((long) rand.nextInt(ints) << 2); // random + } else { + offsets[i] = segment.address() + ((long) (i % ints) << 2); // sequential + } + } + + // validate that all loops are implemented correctly + var ref = t0_reference(); + if ( + ref != t_level8() || + ref != t_level9() || + ref != t_level10() || + ref != t_level11() + ) { + throw new IllegalStateException(); + } + } + + @TearDown + public void tearDown() { + Reference.reachabilityFence(segment); + } + + //@Benchmark + public int t0_reference() { + var s = 0; + for (long offset : offsets) { + s += (int) JAVA_INT_UNALIGNED.get(offset); + } + return s; + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + //@Benchmark + public int t_level8() { + var s = 0; + for (long offset : offsets) { + s += level8(offset); + } + return s; + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + //@Benchmark + public int t_level9() { + var s = 0; + for (long offset : offsets) { + s += level9(offset); + } + return s; + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + //@Benchmark + public int t_level10() { + var s = 0; + for (long offset : offsets) { + s += level10(offset); + } + return s; + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + @Benchmark + public int t_level11() { + var s = 0; + for (long offset : offsets) { + s += level11(offset); + } + return s; + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + @Benchmark + public int t_level12() { + var s = 0; + for (long offset : offsets) { + s += level12(offset); + } + return s; + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + @Benchmark + public int t_level13() { + + var s = 0; + for (long offset : offsets) { + s += level13(offset); + } + return s; + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + @Benchmark + public int t_level14() { + var s = 0; + for (long offset : offsets) { + s += level14(offset); + } + return s; + } + + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + @Benchmark + public int t_level15() { + var s = 0; + for (long offset : offsets) { + s += level15(offset); + } + return s; + } + + private static int level15(long offset) { + return level14(offset); + } + + private static int level14(long offset) { + return level13(offset); + } + + private static int level13(long offset) { + return level12(offset); + } + + private static int level12(long offset) { + return level11(offset); + } + + private static int level11(long offset) { + return level10(offset); + } + + private static int level10(long offset) { + return level9(offset); + } + + private static int level9(long offset) { + return level8(offset); + } + + private static int level8(long offset) { + return level7(offset); + } + + private static int level7(long offset) { + return level6(offset); + } + + private static int level6(long offset) { + return level5(offset); + } + + private static int level5(long offset) { + return level4(offset); + } + + private static int level4(long offset) { + return level3(offset); + } + + private static int level3(long offset) { + return level2(offset); + } + + private static int level2(long offset) { + return level1(offset); + } + + private static int level1(long offset) { + return level0(offset); + } + + private static int level0(long offset) { + return (int) JAVA_INT_UNALIGNED.get(offset); + } + +/* private static int level0(long offset) { + return MemorySegment.ofAddress(offset) + .reinterpret(8L) + .get(ValueLayout.JAVA_INT_UNALIGNED, 0L); + }*/ + +} \ No newline at end of file