Transpiled version (5939L) is out of date.
1 | !include once #1027304 // Eclipse Collections |
2 | |
3 | // Note: Pointers can't point _inside_ of objects |
4 | |
5 | sclass ManagedIntObjects_v1_Collector implements IManagedObjectCollector { |
6 | ManagedIntObjects_v1 mem; |
7 | CompactTreeSet<IntRange> objects = new(intRangeComparatorByStart()); |
8 | new IntHashSet pointers; |
9 | new LongHashSet pointerRanges; // IntRanges as longs |
10 | new IntIntHashMap relocationMap; |
11 | int[] newMem; |
12 | int startAddress; // 1 normally, 0 for PersistentManagedObjects_v1 |
13 | |
14 | // if object at key moves, send new address to the callbacks |
15 | new MultiMap<Int, IVF1<Int>> relocationCallbacks; |
16 | |
17 | bool discardFreeListEarly; // saves memory, but ironically makes original memory unusable when compacting fails because of OOM |
18 | bool verbose = true; |
19 | |
20 | *(ManagedIntObjects_v1 *mem) {} |
21 | |
22 | // notify collector that there is an object in a location |
23 | public void noteObject(int start, int size, IVF1<Int> updateAddress default null) { |
24 | deb()?.printVars("noteObject", +start, +size); |
25 | objects.add(intRange(start, start+size)); |
26 | if (updateAddress != null) |
27 | relocationCallbacks.put(start, updateAddress); |
28 | } |
29 | |
30 | // notify collector that there is a pointer in a location |
31 | public void notePointer(int addr, IVF1<Int> updateAddress) { |
32 | if (addr != 0) { |
33 | pointers.add(addr); |
34 | int target = mem.get(addr); |
35 | if (target != 0 && updateAddress != null) |
36 | relocationCallbacks.put(target, updateAddress); |
37 | } |
38 | } |
39 | |
40 | public void noteRootPointer(int addr) { |
41 | deb()?.printVars("noteRootPointer", +addr, pointingTo := mem.get(addr)); |
42 | pointers.add(addr); |
43 | } |
44 | |
45 | // notify collector that there is a pointer array in a location |
46 | public void notePointerArray(int start) { |
47 | if (start == 0) ret; |
48 | int n = mem.get(start); |
49 | noteObject(start, n+1); |
50 | notePointerRange(IntRange(start+1, start+1+n)); |
51 | } |
52 | |
53 | // notify collector that there is an int array in a location |
54 | public void noteIntArray(int start) { |
55 | if (start == 0) ret; |
56 | int n = mem.get(start); |
57 | noteObject(start, n+1); |
58 | } |
59 | |
60 | void notePointerRange(IntRange r) { |
61 | pointerRanges.add(intRangeToLong(r)); |
62 | } |
63 | |
64 | int sizeNeeded() { |
65 | ret mem.reservedSpaceAtBeginning()+totalIntRangesLength_int(objects); |
66 | } |
67 | |
68 | void collectAndCompact() { |
69 | int sizeNeeded = sizeNeeded(); |
70 | if (mem.size() == sizeNeeded) ret; |
71 | |
72 | if (discardFreeListEarly) mem.freeList.clear(); |
73 | |
74 | // reserve new memory |
75 | print("Reserving " + toM(sizeNeeded*(long) mem.wordSizeInBytes()) + " MB"); |
76 | newMem = new int[sizeNeeded]; |
77 | |
78 | // copy all the objects, fill relocationMap |
79 | print("Copying " + nObjects(objects) + " (" + n2(l(relocationCallbacks), "callback") + ")"); |
80 | int freePtr = startAddress; |
81 | |
82 | for (IntRange r : objects) { |
83 | int oldObjectStart = r.start, newObjectStart = freePtr; |
84 | if (oldObjectStart != newObjectStart) { |
85 | relocationMap.put(oldObjectStart, newObjectStart); |
86 | L<IVF1<Int>> callbacks = relocationCallbacks.get(oldObjectStart); |
87 | deb()?.printVars("Moving object", +r, +oldObjectStart, +newObjectStart, +callbacks); |
88 | callFAll(callbacks, newObjectStart); |
89 | } else { |
90 | //printVars("Keeping object", +r); |
91 | } |
92 | arraycopy(mem.mem, oldObjectStart, newMem, newObjectStart, r.length()); |
93 | freePtr += r.length(); |
94 | } |
95 | relocationCallbacks.clear(); |
96 | |
97 | // update the pointers |
98 | print("Updating " + n2(pointers.size(), "pointer")); |
99 | IntIterator itPointers = pointers.intIterator(); |
100 | while (itPointers.hasNext()) |
101 | movePointer(itPointers.next()); |
102 | |
103 | print("Updating " + n2(pointerRanges.size(), "pointer range")); |
104 | var itPointerRanges = pointerRanges.longIterator(); |
105 | while (itPointerRanges.hasNext()) { |
106 | IntRange r = longToIntRange(itPointerRanges.next()); |
107 | for (int i = r.start; i < r.end; i++) |
108 | movePointer(i); |
109 | } |
110 | |
111 | print("Managed GC done"); |
112 | mem.mem = newMem; |
113 | if (!discardFreeListEarly) mem.freeList.clear(); |
114 | } |
115 | |
116 | // call after collectAndCompact to get new location of objects |
117 | public int getNewLocation(int addr) { |
118 | ret relocationMap.getIfAbsent(addr, addr); |
119 | } |
120 | |
121 | void movePointer(int pointerAddr) { |
122 | // find enclosing object |
123 | IntRange obj = objects.floor(IntRange(pointerAddr, pointerAddr)); |
124 | if (obj == null) ret with print("Pointer without object: " + pointerAddr); |
125 | |
126 | int newObjAddr = relocationMap.getIfAbsent(obj.start, obj.start); |
127 | int newPointerAddr = newObjAddr-obj.start+pointerAddr; |
128 | |
129 | // find target, update pointer |
130 | int target = mem.get(pointerAddr); |
131 | deb()?.printVars("movePointer", +pointerAddr, +obj, +newObjAddr, +newPointerAddr, +target); |
132 | if (target == 0) ret; |
133 | |
134 | int newTarget = relocationMap.getIfAbsent(target, -1); |
135 | deb()?.printVars("movePointer", +newTarget); |
136 | if (newTarget >= 0) |
137 | newMem[newPointerAddr] = newTarget; |
138 | } |
139 | |
140 | public void noteString(int addr, IVF1<Int> updateAddress default null) { |
141 | if (addr == 0) ret; |
142 | int n = ((mem.get(addr)^0x80000000)+3)/4; |
143 | noteObject(addr, n+1, updateAddress); |
144 | } |
145 | } |
Began life as a copy of #1029226
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv
No comments. add comment
Snippet ID: | #1029237 |
Snippet name: | ManagedIntObjects_v1_Collector [compacting collector for managed memory] |
Eternal ID of this version: | #1029237/47 |
Text MD5: | abbaed1a5b92696411abd740d4e097a1 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2021-06-25 13:13:54 |
Source code size: | 5194 bytes / 145 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 347 / 821 |
Version history: | 46 change(s) |
Referenced in: | [show references] |