// all sizes+addresses are in ints (4 bytes) sclass ManagedIntObjects_v1 { replace Addr with int. replace Addr2 with Int. int[] mem = new int[0]; new FreeList freeList; *() { alloc(1); // so 0 is usable as the null pointer } void ensureCapacity(int size) { if (memorySize() < size) setMemorySize(roundUpToPowerOfTwo(size)); } int memorySize() { ret mem.length; } void setMemorySize(int newSize) { int size = memorySize(); if (newSize == size) ret; if (newSize < size) unimplemented("Shrinking memory"); freeList.add(IntRange(size, newSize)); mem = resizeIntArray(mem, newSize); } void growMemory() { setMemorySize(max(1, memorySize()*2)); } // all allocated ranges are filled with zero int alloc(int length) { IntRange r; while ((r = freeList.findFreeSpace(length)) == null) growMemory(); freeList.remove(IntRange(r.start, r.start+length)); ret r.start; } void free(int start, int length) { if (length == 0) ret; freeList.add(IntRange(start, start+length)); Arrays.fill(mem, start, start+length, 0); } int get(Addr i) { ret mem[i]; } int read(Addr i) { ret mem[i]; } void set(Addr i, int val) { mem[i] = val; } void write(Addr i, int val) { mem[i] = val; } // words a pointer requires int sizeOfPointer() { ret 1; } Addr nullPtr() { ret 0; } // convenience pointer array handling (memory layout: length + data) L pointerArray(Addr addr) { int size = get(addr); ret new RandomAccessAbstractList() { public int size() { ret size; } public Addr2 get(int i) { rangeCheck(i, size); ret read(addr+1+i); } public Int set(int i, Int val) { rangeCheck(i, size); Int old = get(i); write(addr+1+i, val); ret old; } }; } Addr newPointerArray(int size) { Addr a = alloc(size+1); set(a, size); ret a; } void freePointerArray(Addr a) { if (a != 0) free(a, read(a)+1); } // a can be nullPtr(), then we just make a new array Addr resizePointerArray(Addr a, int newSize) { ifdef ManagedIntObjects_v1_debug printFunctionCall resizePointerArray(a, newSize); endifdef if (a == 0) ret newPointerArray(newSize); int oldSize = get(a); if (oldSize == newSize) ret a; Addr a2 = newPointerArray(newSize); arraycopy(mem, a+1, mem, a2+1, min(oldSize, newSize)); ret a2; } }