public final class MemoryAegis extends Object
These helpers are intended for use with Chronicle's
assert SKIP_ASSERTIONS || ... idiom so hot-path checks still
compile out in the normal assertions-disabled build while debug builds
keep precise range validation and failure messages.
Public surface:
assertByteArrayRange(byte[], int, int),
assertCharArrayRange(char[], int, int),
assertStringRange(String, int, int) - on-heap slice bounds
against the array/string length. Offset and length are int
because the backing length / String.length() is also
int.assertAddressRange(long, long) - bounded native-address
range against NativeAddressSpace.assertObjectRange(Object, long, long) - object-relative
byte range bounded by NativeAddressSpace.maxAddressExclusive().Unsafe-style on-heap-or-off-heap access: there is no combined
helper because the same offset argument means two different things
depending on whether the caller is passing an object reference. Inline the
dispatch at the call site so the contract is visible to the reader; see the
"Usage patterns" examples below.
Address-space assumption: these guards intentionally model only
ordinary non-negative user-space ranges. They do not attempt to validate
negative or sign-extended special mappings such as the legacy x86-64
[vsyscall] mapping visible in /proc/self/maps. Call sites
that genuinely need to touch those regions should not route through
MemoryAegis until Chronicle has a separate policy for them.
The assertions return true so they chain cleanly into the
assert SKIP_ASSERTIONS || ... idiom; if SKIP_ASSERTIONS is true
the whole line is compiled away and doesn't add to bytecode. if assertions are disabled
(the normal production posture) the JIT elides the whole right-hand side.
The following examples show the intended adoption pattern for low-level
callers such as UnsafeMemory and helpers built on OS.memory().
They document how to wire the checks cleanly without claiming that every
existing caller has already been migrated.
Fixed-width primitive read at a native address. The width is the
TYPE.BYTES constant so the assertion covers exactly the range that
Unsafe.getXxx will touch:
public static long unsafeGetLong(@Address long address) {
assert SKIP_ASSERTIONS || MemoryAegis.assertAddressRange(address, Long.BYTES);
return UNSAFE.getLong(address);
}
Fixed-width primitive write into an on-heap byte array. Use the array variant so the check runs against the array length rather than the native-address ceiling:
public static void putInt(byte[] bytes, @NonNegative int offset, int value) {
assert SKIP_ASSERTIONS || MemoryAegis.assertByteArrayRange(bytes, offset, Integer.BYTES);
UNSAFE.putInt(bytes, ARRAY_BYTE_BASE_OFFSET + offset, value);
}
Native-to-native copy. Each operand has its own assertion because
from and to are independent address ranges:
public static void copyMemory(@Address long from, @Address long to, @NonNegative int length) {
assert SKIP_ASSERTIONS || MemoryAegis.assertAddressRange(from, length);
assert SKIP_ASSERTIONS || MemoryAegis.assertAddressRange(to, length);
MEMORY.copyMemory(from, to, (long) length);
}
Unsafe-style access that may be on-heap or off-heap. When the
object reference is null the offset is an absolute native
address; otherwise it is an object-relative offset (field offset, array
base offset + index, etc.). Inline the dispatch at the call site: the
ternary keeps both contracts visible to the reader and to any static
analyser, which a combined assertObjectOrAddressRange would
obscure behind one ambiguous entry point:
public static void unsafePutBoolean(Object obj, @NonNegative long offset, boolean value) {
assert SKIP_ASSERTIONS || (obj == null
? MemoryAegis.assertAddressRange(offset, Byte.BYTES)
: MemoryAegis.assertObjectRange(obj, offset, Byte.BYTES));
UNSAFE.putBoolean(obj, offset, value);
}
| Modifier and Type | Method and Description |
|---|---|
static boolean |
assertAddressRange(long address,
long length)
Asserts that the byte range
[address, address + length) lies
inside the configured native-address space
[NativeAddressSpace.minAddress(), NativeAddressSpace.maxAddressExclusive()). |
static boolean |
assertByteArrayRange(byte[] bytes,
int offset,
int length)
Asserts that an on-heap byte-array slice is valid.
|
static boolean |
assertCharArrayRange(char[] chars,
int offset,
int length)
Asserts that an on-heap char-array slice is valid.
|
static boolean |
assertObjectRange(@NotNull Object object,
long offset,
long length)
Asserts that the byte range
[offset, offset + length) is a
valid object-relative Unsafe access on object. |
static boolean |
assertStringRange(@NotNull String text,
int start,
int length)
Asserts that a string slice is valid.
|
public static boolean assertByteArrayRange(byte[] bytes,
int offset,
int length)
bytes - the source arrayoffset - the slice startlength - the slice lengthtrueAssertionError - if the slice is invalidpublic static boolean assertCharArrayRange(char[] chars,
int offset,
int length)
chars - the source arrayoffset - the slice startlength - the slice lengthtrueAssertionError - if the slice is invalidpublic static boolean assertStringRange(@NotNull
@NotNull String text,
int start,
int length)
Unit: start and length are counted in
String.length() units (UTF-16 code units), not bytes. Callers
reading bytes from a compact-string backing array (Java 9+) must use a
byte-unit guard such as assertObjectRange(Object, long, long)
against the backing array instead.
text - the source stringstart - the slice start, in String.length() unitslength - the slice length, in String.length() unitstrueAssertionError - if the slice is invalidpublic static boolean assertAddressRange(long address,
long length)
[address, address + length) lies
inside the configured native-address space
[NativeAddressSpace.minAddress(), NativeAddressSpace.maxAddressExclusive()).
Rejects: length < 0; address in the reserved low
guard area (below NativeAddressSpace.minAddress()); address
at or above NativeAddressSpace.maxAddressExclusive(); and ranges
that would wrap past the ceiling. This deliberately excludes negative
special mappings such as the legacy x86-64 [vsyscall] mapping;
MemoryAegis models ordinary user-space addresses only.
address - the native start addresslength - the number of bytes coveredtrueAssertionError - if the range is invalidpublic static boolean assertObjectRange(@NotNull
@NotNull Object object,
long offset,
long length)
[offset, offset + length) is a
valid object-relative Unsafe access on object.
Rejects: object == null; offset < 0; length < 0;
offset at or above NativeAddressSpace.maxAddressExclusive()
(the same ceiling native addresses obey, which keeps object offsets and
native addresses on one consistent bound); and ranges that would wrap
past that ceiling.
On the ceiling's tightness: real object offsets (field offsets,
array base + index) are many orders of magnitude below
NativeAddressSpace.maxAddressExclusive(). The ceiling here is a
symmetry choice with assertAddressRange(long, long), not a tight
backstop against runaway offsets. The checks that catch real bugs in this
method are the non-null, non-negative, and non-overflow guards; do not
rely on the ceiling to flag out-of-bounds object accesses.
object - the target objectoffset - the starting offsetlength - the number of bytes coveredtrueAssertionError - if the range is invalidCopyright © 2026 Chronicle Software Ltd. All rights reserved.