-
Notifications
You must be signed in to change notification settings - Fork 0
VM Unsafe
Low-level operations for direct memory access, hardware I/O, and VM introspection in JNode.
org.jnode.vm.Unsafe (often called "VM Unsafe" to distinguish from sun.misc.Unsafe) provides a constrained set of low-level operations unavailable in standard Java. Unlike sun.misc.Unsafe, it is restricted to classes annotated with @MagicPermission and exposes only a carefully curated API. The class is complemented by UnsafeX86 for x86-specific operations like MSR read/write and CPUID.
VM Unsafe is a bridge between Java and the native world without JNI—the JIT compiler recognizes Unsafe calls and emits direct machine instructions.
| Class / File | Role |
|---|---|
core/src/core/org/jnode/vm/Unsafe.java |
Main API: memory access, debug output, CPU operations, port I/O |
core/src/core/org/jnode/vm/x86/UnsafeX86.java |
x86-specific: GDT/TSS, MSR, CPUID, VBE, AP boot code |
core/src/core/org/jnode/vm/compiler/BaseMagicHelper.java |
Base helper recognizing Unsafe calls during compilation |
core/src/core/org/jnode/vm/x86/compiler/l1a/MagicHelper.java |
L1 compiler intrinsic generation for Unsafe operations |
core/src/core/org/jnode/vm/x86/compiler/l2/MagicHelper.java |
L2 compiler intrinsic generation for Unsafe operations |
core/src/native/x86/unsafe.asm |
Assembly helpers (e.g., Unsafe.yieldPoint via INT 0x30) |
@MagicPermission annotation marks classes allowed to use Unsafe. Any class using Unsafe or VmMagic methods must carry this annotation. The JIT compiler checks this at compile time and refuses to compile calls from unmarked classes.
@MagicPermission
public final class Unsafe {
// All public methods are accessible from @MagicPermission classes
}Unsafe provides typed bulk memory operations that map directly to native memset/memcpy equivalents:
Unsafe.setInts(addr, value, count); // memset to int
Unsafe.setLongs(addr, value, count); // memset to long
Unsafe.setObjects(addr, object, count); // set object references
Unsafe.clear(memPtr, size); // zero memory (SLOT_SIZE aligned)
Unsafe.copy(src, dest, size); // memcpy (non-overlapping)Each typed variant includes bitwise AND/OR/XOR operations for atomic modifications without a loop.
Unsafe.debug(...) is the only logging mechanism available before the class library is initialized. Unlike System.out.println, it requires no object allocation or synchronization.
Unsafe.debug("boot: ");
Unsafe.debug(42);
Unsafe.debug(new Address(0x1000));
Unsafe.debugStackTrace(); // print current stack to debug consolex86-specific operations via UnsafeX86:
UnsafeX86.getCR3(); // Read CR3 register (page directory pointer)
UnsafeX86.getCPUID(input, result); // CPU identification
UnsafeX86.readMSR(index); // Read Model Specific Register
UnsafeX86.writeMSR(index, value); // Write Model Specific Register
UnsafeX86.getMultibootMMap(); // Get GRUB memory mapDirect x86 port access for hardware communication:
Unsafe.inPortByte(portNr);
Unsafe.inPortWord(portNr);
Unsafe.inPortDword(portNr);
Unsafe.outPortByte(portNr, value);
Unsafe.outPortWord(portNr, value);
Unsafe.outPortDword(portNr, value);Used by drivers (IDE, serial) to communicate with hardware via standard I/O port ranges.
System memory layout queries:
Unsafe.getMemoryStart()/getMemoryEnd() // Available physical memory
Unsafe.getKernelStart()/getKernelEnd() // Kernel image bounds
Unsafe.getBootHeapStart()/getBootHeapEnd() // Boot-time heap
Unsafe.getInitJarStart()/getInitJarEnd() // Embedded plugin JARUnsafe.getJumpTable() and Unsafe.getJumpTableEntry(index) provide access to the native method dispatch jump table. This requires JNodePermission("getJumpTable") and is used by the JIT to resolve native method addresses.
- No JNI: Unsafe methods are not native in the traditional sense—they have no JNI overhead. The JIT compiler recognizes the class name and emits inline assembly directly.
-
@MagicPermissionrequired: Any class calling Unsafe methods must be annotated. The compiler enforces this. -
32-bit vs 64-bit: Some methods (e.g.,
getJumpTableEntry) use architecture-specificReferenceSizeto compute offsets. -
Alignment for clear:
Unsafe.clear()requiresmemPtrto beVmObject.SLOT_SIZEaligned andsizeto be a multiple ofSLOT_SIZE. -
VBE is deprecated:
Unsafe.callVbeFunctionis explicitly marked bogus and untested—avoid it. -
UnsafeObjectResolver: Inner class extendingObjectResolverfor object-to-address mapping during boot image assembly.
- VM-Magic - Parent framework containing Unsafe, VmMagic, and magic annotations
-
Code-Conventions -
@MagicPermissionusage guidelines - Memory-Management - How Unsafe fits into the memory subsystem
- Unboxed-Types - Address, Word, Offset types used by Unsafe APIs
- JIT-Compilers - How MagicHelper generates code for Unsafe calls
- Resource-Management - Port I/O used by drivers