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.

!include once #1027304 // Eclipse Collections

// Note: Pointers can't point _inside_ of objects

sclass ManagedIntObjects_v1_Collector implements IManagedObjectCollector {
  ManagedIntObjects_v1 mem;
  CompactTreeSet<IntRange> objects = new(intRangeComparatorByStart());
  new IntHashSet pointers;
  new LongHashSet pointerRanges; // IntRanges as longs
  new IntIntHashMap relocationMap;
  int[] newMem;
  int startAddress; // 1 normally, 0 for PersistentManagedObjects_v1
  
  // if object at key moves, send new address to the callbacks
  new MultiMap<Int, IVF1<Int>> relocationCallbacks;

  bool discardFreeListEarly; // saves memory, but ironically makes original memory unusable when compacting fails because of OOM
  bool verbose = true;
  
  *(ManagedIntObjects_v1 *mem) {}
  
  // notify collector that there is an object in a location
  public void noteObject(int start, int size, IVF1<Int> updateAddress default null) {
    deb()?.printVars("noteObject", +start, +size);
    objects.add(intRange(start, start+size));
    if (updateAddress != null)
      relocationCallbacks.put(start, updateAddress);
  }
  
  // notify collector that there is a pointer in a location
  public void notePointer(int addr, IVF1<Int> updateAddress) {
    if (addr != 0) {
      pointers.add(addr);
      int target = mem.get(addr);
      if (target != 0 && updateAddress != null)
        relocationCallbacks.put(target, updateAddress);
    }
  }
  
  public void noteRootPointer(int addr) {
    deb()?.printVars("noteRootPointer", +addr, pointingTo := mem.get(addr));
    pointers.add(addr);
  }
  
  // notify collector that there is a pointer array in a location
  public void notePointerArray(int start) {
    if (start == 0) ret;
    int n = mem.get(start);
    noteObject(start, n+1);
    notePointerRange(IntRange(start+1, start+1+n));
  }
  
  // notify collector that there is an int array in a location
  public void noteIntArray(int start) {
    if (start == 0) ret;
    int n = mem.get(start);
    noteObject(start, n+1);
  }
  
  void notePointerRange(IntRange r) {
    pointerRanges.add(intRangeToLong(r));
  }
  
  int sizeNeeded() {
    ret mem.reservedSpaceAtBeginning()+totalIntRangesLength_int(objects);
  }
  
  void collectAndCompact() {
    int sizeNeeded = sizeNeeded();
    if (mem.size() == sizeNeeded) ret;
    
    if (discardFreeListEarly) mem.freeList.clear();
    
    // reserve new memory
    print("Reserving " + toM(sizeNeeded*(long) mem.wordSizeInBytes()) + " MB");
    newMem = new int[sizeNeeded];

    // copy all the objects, fill relocationMap
    print("Copying " + nObjects(objects) + " (" + n2(l(relocationCallbacks), "callback") + ")");
    int freePtr = startAddress;
    
    for (IntRange r : objects) {
      int oldObjectStart = r.start, newObjectStart = freePtr;
      if (oldObjectStart != newObjectStart) {
        relocationMap.put(oldObjectStart, newObjectStart);
        L<IVF1<Int>> callbacks = relocationCallbacks.get(oldObjectStart);
        deb()?.printVars("Moving object", +r, +oldObjectStart, +newObjectStart, +callbacks);
        callFAll(callbacks, newObjectStart);
      } else {
        //printVars("Keeping object", +r);
      }
      arraycopy(mem.mem, oldObjectStart, newMem, newObjectStart, r.length());
      freePtr += r.length();
    }
    relocationCallbacks.clear();
    
    // update the pointers
    print("Updating " + n2(pointers.size(), "pointer"));
    IntIterator itPointers = pointers.intIterator();
    while (itPointers.hasNext())
      movePointer(itPointers.next());
      
    print("Updating " + n2(pointerRanges.size(), "pointer range"));
    var itPointerRanges = pointerRanges.longIterator();
    while (itPointerRanges.hasNext()) {
      IntRange r = longToIntRange(itPointerRanges.next());
      for (int i = r.start; i < r.end; i++)
        movePointer(i);
    }

    print("Managed GC done");
    mem.mem = newMem;
    if (!discardFreeListEarly) mem.freeList.clear();
  }
  
  // call after collectAndCompact to get new location of objects
  public int getNewLocation(int addr) {
    ret relocationMap.getIfAbsent(addr, addr);
  }
  
  void movePointer(int pointerAddr) {
    // find enclosing object
    IntRange obj = objects.floor(IntRange(pointerAddr, pointerAddr));
    if (obj == null) ret with print("Pointer without object: " + pointerAddr);
    
    int newObjAddr = relocationMap.getIfAbsent(obj.start, obj.start);
    int newPointerAddr = newObjAddr-obj.start+pointerAddr;
    
    // find target, update pointer
    int target = mem.get(pointerAddr);
    deb()?.printVars("movePointer", +pointerAddr, +obj, +newObjAddr, +newPointerAddr, +target);
    if (target == 0) ret;
    
    int newTarget = relocationMap.getIfAbsent(target, -1);
    deb()?.printVars("movePointer", +newTarget);
    if (newTarget >= 0)
      newMem[newPointerAddr] = newTarget;
  }
  
  public void noteString(int addr, IVF1<Int> updateAddress default null) {
    if (addr == 0) ret;
    int n = ((mem.get(addr)^0x80000000)+3)/4;
    noteObject(addr, n+1, updateAddress);
  }
}

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: 346 / 820
Version history: 46 change(s)
Referenced in: #1029239 - IManagedObjectCollector
#1029336 - ManagedIntObjects64_Collector [dev., compacting collector for managed memory]
#1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674)