sclass PersistentManagedObjects_v1 { replace Addr with int. ManagedIntObjects_v1 objectManager; IF1 makeUserObject; // user needs to fill this final static TYPE_STRING = -1, TYPE_INTARRAY = -2, TYPE_ROOT = -3; class Root extends AbstractManagedObject { final static int ofs_type = 0, ofs_version = 1, ofs_freeListPtr = 2, ofs_userDataPtr = 3; final static int objectSize = ofs_userDataPtr+1; // initialize as wrapper for existing object *(Addr addr) { super(addr); } // initialize as new object *() { addr = mem.alloc(objectSize); type(TYPE_ROOT); version(1); } // getters + setters int type() { ret mem.get(addr+ofs_type); } void type(int x) { mem.set(addr+ofs_type, x); } int version() { ret mem.get(addr+ofs_version); } void version(int x) { mem.set(addr+ofs_version, x); } Addr freeListPtr() { ret mem.get(addr+ofs_freeListPtr); } void freeListPtr(Addr x) { mem.set(addr+ofs_freeListPtr, x); } Addr userDataPtr() { ret mem.get(addr+ofs_userDataPtr); } void userDataPtr(Addr x) { mem.set(addr+ofs_userDataPtr, x); } // GC handling public void scanForCollection(IManagedObjectCollector gc) { gc.noteObject(addr, objectSize, newAddr -> { addr = newAddr; }); gc.notePointer(addr+ofs_freeListPtr); gc.notePointer(addr+ofs_freeDataPtr); gc.noteIntArray(freeListPtr()); if (userDataPtr() != 0) makeUserObject.get(userDataPtr()).scanForCollection(gc); } } }