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

145
LINES

< > BotCompany Repo | #1029237 // ManagedIntObjects_v1_Collector [compacting collector for managed memory]

JavaX fragment (include) [tags: use-pretranspiled]

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  
}

Author comment

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]