The compiler I am working on will be moving from using pointers to using integers to hold references to heap objects. The integer is an array offset from a base address determined at run time. In addition, I expect the garbage collector will routinely move objects in memory.
LLVM already provides the
llvm.experimental.gc.* intrinsics to support the notion of on-stack value replacement by the GC, to accommodate relocation of objects by the collector. However these intrinsics seem to assume that reference values are always pointer-typed, using an address space to mark the pointer for RS4GC.
What I want to understand is, can an integer-based scheme work at all with the existing implementation? Since
llvm.experimental.gc.relocate does not support anything other than pointers, it seems like using this mechanism is a non-starter - unless we can somehow change the size of pointers on a per-address space basis. Is this possible?
Otherwise, if we did not use
.relocate for our reference values which nevertheless might be changed by GC, do we risk runtime errors due to violating assumptions about the bit pattern or magnitude of integer values that would be relocated? While some invariants would be preserved - for example, if two values are not equal before GC, they would still not be equal after GC - we would not be able to guarantee that others are preserved - for example, even if
a < b before GC, it is not guaranteed that
a < b afterwards. Is there any way we could tag or wrap an integer type so that this kind of uncertainty can be made known to the compiler?
If it helps, we are not relying much on LLVM’s alias analysis for heap pointers; we’re doing our own alias analysis on the front end (the Java memory model is simpler in many ways than, say, the C memory model).