Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

247
LINES

< > BotCompany Repo | #1031720 // ManagedIntObjects_indirect - with indirect object pointers [dev.]

JavaX fragment (include)

1  
// all sizes+addresses are in ints (4 bytes)
2  
3  
sclass ManagedIntObjects_indirect implements IIntMemory_indirect {
4  
  replace Addr with int.
5  
  replace BoxedAddr with Int.
6  
  
7  
  int[] mem = new int[0];
8  
  new FreeList freeList;
9  
  bool collecting, compacting; // GC phases
10  
11  
  *() {
12  
    assertEquals(0, alloc(reservedSpaceAtBeginning())); // so 0 is usable as the null pointer
13  
  }
14  
  
15  
  *(int[] *mem) {}
16  
  
17  
  // overridable
18  
  public long size() { ret mem.length; }
19  
  public int get(Addr i) { ret mem[i]; }
20  
  public void set(Addr i, int val) { mem[i] = val; }
21  
  
22  
  swappable void onMemorySizeChanged() {}
23  
  
24  
  void ensureCapacity(int size) {
25  
    if (memorySize() < size)
26  
      setMemorySize(roundUpToPowerOfTwo(size));
27  
  }
28  
  
29  
  void setMemorySize(int newSize) {
30  
    int size = memorySize();
31  
    if (newSize == size) ret;
32  
    if (newSize < size) unimplemented("Shrinking memory");
33  
    print("New memory size: " + newSize);
34  
    mem = resizeIntArray(mem, newSize);
35  
    free(size, newSize-size);
36  
    onMemorySizeChanged();
37  
  }
38  
  
39  
  void growMemory() {
40  
    setMemorySize(max(1, memorySize()*2));
41  
  }
42  
  
43  
  // all allocated ranges are filled with zero
44  
  int alloc(int length) {
45  
    IntRange r;
46  
    while ((r = freeList.findFreeSpace(length)) == null) {
47  
      print("No free space for length " + length + " - growing");
48  
      growMemory();
49  
    }
50  
    
51  
    freeList.remove(IntRange(r.start, r.start+length));
52  
    ret r.start;
53  
  }
54  
  
55  
  void free(int start, int length) {
56  
    if (length == 0) ret;
57  
    deb()?.print("Freeing " + start + " (l=" + length + ")");
58  
    freeList.add(IntRange(start, start+length));
59  
    fillMem(start, start+length, 0);
60  
  }
61  
  
62  
  void fillMem(int start, int end, int value) {
63  
    Arrays.fill(mem, start, end, value);
64  
  }
65  
  
66  
  final int memorySize() { ret mem.length; }
67  
  final public int read(Addr i) { ret get(i); }
68  
  final void write(Addr i, int val) { set(i, val); }
69  
  
70  
  // words a pointer requires
71  
  int sizeOfPointer() { ret 1; }
72  
  int wordSizeInBytes() { ret 4; }
73  
  
74  
  public Addr nullPtr() { ret 0; }
75  
  
76  
  // convenience pointer array handling (memory layout: length + data)
77  
  
78  
  L<BoxedAddr> pointerArray(Addr addr) {
79  
    if (addr == 0) null;
80  
    int size = get(addr);
81  
    ret new RandomAccessAbstractList<BoxedAddr>() {
82  
      public int size() { ret size; }
83  
      public BoxedAddr get(int i) { rangeCheck(i, size); ret read(addr+1+i); }
84  
      public Int set(int i, Int val) { rangeCheck(i, size); Int old = get(i); write(addr+1+i, val); ret old; }
85  
    };
86  
  }
87  
  
88  
  Addr newPointerArray(int size) {
89  
    deb()?.printVars("newIntArray", +size);
90  
    Addr a = alloc(size+1);
91  
    set(a, size);
92  
    ret a;
93  
  }
94  
  
95  
  void freePointerArray aka freeIntArray(Addr a) {
96  
    if (a == 0) ret;
97  
    deb()?.print("freePointerArray at " + a);
98  
    free(a, read(a)+1);
99  
  }
100  
  
101  
  Addr newIntArray(int[] array) {
102  
    if (array == null) ret 0;
103  
    int n = l(array);
104  
    deb()?.printVars("newIntArray", +n);
105  
    Addr ptr = alloc(n+1);
106  
    set(ptr, n);
107  
    for i to n:
108  
      set(ptr+1+i, array[i]);
109  
    ret ptr;
110  
  }
111  
  
112  
  // a can be nullPtr(), then we just make a new array
113  
  Addr resizePointerArray(Addr a, int newSize) {
114  
    deb()?.printVars("resizePointerArray", +a, +newSize);
115  
    if (a == 0) ret newPointerArray(newSize);
116  
    int oldSize = get(a);
117  
    if (oldSize == newSize) ret a;
118  
    
119  
    Addr a2 = realloc(a, oldSize+1, newSize+1);
120  
    set(a2, newSize);
121  
    ret a2;
122  
  }
123  
  
124  
  // a can be nullPtr(), then we just make a new array
125  
  Addr realloc(Addr a, int oldSize, int newSize) {
126  
    deb()?.printVars("realloc", +a, +oldSize, +newSize);
127  
    if (a == 0) ret alloc(newSize);
128  
    if (oldSize == newSize) ret a;
129  
    if (oldSize > newSize) {
130  
      free(a+newSize, oldSize-newSize);
131  
      ret a;
132  
    }
133  
    // newSize is bigger than oldSize
134  
    // Try growing.
135  
    
136  
    IntRange r = new(a+oldSize, a+newSize);
137  
    if (freeList.canRemove(r)) {
138  
      // Great! Grow it and we're done
139  
      deb()?.print("Chunk grown");
140  
      freeList.remove(r);
141  
      ret a;
142  
    }
143  
    
144  
    // We have to move the whole thing
145  
    deb()?.printVars("realloc copy", +newSize);
146  
    Addr a2 = alloc(newSize);
147  
    memCopy(a, a2, oldSize);
148  
    deb()?.printVars("realloc free old, returning", +a2);
149  
    free(a, oldSize);
150  
    ret a2;
151  
  }
152  
  
153  
  void memCopy(int src, int dest, int n) {
154  
    arraycopy(mem, src, mem, dest, n);
155  
  }
156  
  
157  
158  
  
159  
  // even more convenient typed object array handling as List
160  
  
161  
  <A extends AbstractManagedObject> L<A> objectArray(Addr addr,
162  
    IF1<BoxedAddr, A> wrapPointer) {
163  
    ret convertListElementsBothWays(
164  
      wrapPointer,
165  
      element -> element.addr,
166  
      pointerArray(addr));
167  
  }
168  
  
169  
  int totalFree() { ret freeList.totalFree(); }
170  
  
171  
  int reservedSpaceAtBeginning() { ret 1; }
172  
  
173  
  void copyReservedArea(int[] newMem) { newMem[0] = get(0); }
174  
  
175  
  void collectAndCompact(IManagedObject rootObject, ManagedIntObjects_v1_Collector collector default new ManagedIntObjects_v1_Collector(this)) {
176  
    collecting = true;
177  
    if (rootObject != null)
178  
      rootObject.scanForCollection(collector);
179  
    compacting = true;
180  
    collector.collectAndCompact();
181  
    compacting = false;
182  
    collecting = false;
183  
  }
184  
  
185  
  bool collecting() { ret collecting; }
186  
  bool compacting() { ret compacting; }
187  
  
188  
  void printStats {
189  
    print("Managed memory size: " + toM(size()*(long) wordSizeInBytes()) + " MB, free: " + ratioToIntPercent(freeList.totalFree(), size()) + "%");
190  
  }
191  
  
192  
  // +1, actually
193  
  int highestUsedWord() {
194  
    IntRange r = freeList.highestFreeRange();
195  
    ret r != null && r.end == size() ? r.start : (int) size();
196  
  }
197  
  
198  
  void saveToFile(File f) {
199  
    // only save used part
200  
    stream2file(IntArrayInputStream_littleEndian(mem, 0, highestUsedWord()), f);
201  
    printFileInfo(f);
202  
  }
203  
  
204  
  // we use the reserved int for a user-defined value to bootstrap
205  
  // the system
206  
  void setRootField(int val) {
207  
    set(0, val);
208  
  }
209  
  
210  
  int getRootField() {
211  
    ret get(0);
212  
  }
213  
  
214  
  int[] readIntArray(BoxedAddr ptr) {
215  
    if (ptr == 0) null;
216  
    int n = mem[ptr++];
217  
    int[] a = new[n];
218  
    arraycopy(mem, ptr, a, 0, n);
219  
    ret a;
220  
  }
221  
  
222  
  Addr newString(S s) {
223  
    if (s == null) ret 0;
224  
    byte[] array = toUtf8(s);
225  
    int[] ints = intArrayFromBytes_littleEndian_flexLength(array);
226  
    Addr ptr = alloc(l(ints)+1);
227  
    for i over ints:
228  
      set(ptr+1+i, ints[i]);
229  
    set(ptr, l(array)^0x80000000);
230  
    ret ptr;
231  
  }
232  
  
233  
  S readString(Addr addr) {
234  
    if (addr == 0) null;
235  
    int n = get(addr) ^ 0x80000000;
236  
    int[] ints = new[(n+3)/4];
237  
    for i over ints:
238  
      ints[i] = get(addr+1+i);
239  
    byte[] bytes = intArrayToBytes_littleEndian_flexLength(ints, n);
240  
    ret fromUtf8(bytes);
241  
  }
242  
  
243  
  // cycle from "disk" (memory)
244  
  selfType rotate() {
245  
    ret new ManagedIntObjects_v1(mem);
246  
  }
247  
}

Author comment

Began life as a copy of #1029226

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt

No comments. add comment

Snippet ID: #1031720
Snippet name: ManagedIntObjects_indirect - with indirect object pointers [dev.]
Eternal ID of this version: #1031720/1
Text MD5: ce123b7cae82cd177ce51eaf4019c7be
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-06-28 21:19:25
Source code size: 6925 bytes / 247 lines
Pitched / IR pitched: No / No
Views / Downloads: 77 / 107
Referenced in: [show references]