private static void getAvailableChunk(int size) { if (getAvailableChunkIfPossible(size)) { return; } collectGarbage(size); getAvailableChunkIfPossible(size); }
private TThrowable fillInStackTraceLowLevel() { int stackSize = ExceptionHandling.callStackSize() - 1; stackTrace = new TStackTraceElement[stackSize]; ExceptionHandling.fillStackTrace((StackTraceElement[]) (Object) stackTrace); return this; }
@SuppressWarnings("unused") private static RuntimeObject cloneLowLevel(RuntimeObject self) { RuntimeClass cls = RuntimeClass.getClass(self); int skip = Structure.sizeOf(RuntimeObject.class); int size; RuntimeObject copy; if (cls.itemType == null) { copy = Allocator.allocate(cls).toStructure(); size = cls.size; } else { RuntimeArray array = (RuntimeArray) self; copy = Allocator.allocateArray(cls, array.size).toStructure(); int itemSize = (cls.itemType.flags & RuntimeClass.PRIMITIVE) == 0 ? Address.sizeOf() : cls.itemType.size; Address headerSize = Address.align(Address.fromInt(Structure.sizeOf(RuntimeArray.class)), itemSize); size = itemSize * array.size + headerSize.toInt(); } if (size > skip) { Allocator.moveMemoryBlock(self.toAddress().add(skip), copy.toAddress().add(skip), size - skip); } return copy; }
@Unmanaged static void doArrayCopyLowLevel(RuntimeArray src, int srcPos, RuntimeArray dest, int destPos, int length) { RuntimeClass type = RuntimeClass.getClass(src); int itemSize = type.itemType.size; if ((type.itemType.flags & RuntimeClass.PRIMITIVE) == 0) { itemSize = Address.sizeOf(); } Address srcAddress = Address.align(src.toAddress().add(RuntimeArray.class, 1), itemSize); srcAddress = srcAddress.add(itemSize * srcPos); Address destAddress = Address.align(dest.toAddress().add(RuntimeArray.class, 1), itemSize); destAddress = destAddress.add(itemSize * destPos); Allocator.moveMemoryBlock(srcAddress, destAddress, length * itemSize); }
@Unmanaged public static void fillStackTrace(StackTraceElement[] target) { Address stackFrame = ShadowStack.getNextStackFrame(ShadowStack.getStackTop()); int index = 0; while (stackFrame != null && index < target.length) { int callSiteId = ShadowStack.getCallSiteId(stackFrame); CallSite callSite = findCallSiteById(callSiteId); CallSiteLocation location = callSite.location; StackTraceElement element = createElement(location != null ? location.className : "", location != null ? location.methodName : "", location != null ? location.fileName : null, location != null ? location.lineNumber : -1); target[index++] = element; stackFrame = ShadowStack.getNextStackFrame(stackFrame); } }
public static boolean collectGarbage(int size) { mark(); sweep(); updateFreeMemory(); return true; }
@SuppressWarnings("unused") @Unmanaged private static boolean isAssignableLowLevel(RuntimeClass from, RuntimeClass to) { return to.isSupertypeOf.apply(from); }
@SuppressWarnings("unused") private static int getLengthLowLevel(RuntimeObject obj) { RuntimeClass cls = RuntimeClass.getClass(obj); if (cls.itemType == null) { throw new TIllegalArgumentException(); } RuntimeArray array = (RuntimeArray) obj; return array.size; }
static void enqueue(RuntimeObject object) { GC.gcStorageAddress().add(Address.sizeOf() * tail).putAddress(object.toAddress()); if (++tail >= limit) { tail = 0; } }
private long totalMemoryLowLevel() { return GC.availableBytes(); } }
private static void gcLowLevel() { GC.collectGarbage(0); }
@Unmanaged public static int callStackSize() { Address stackFrame = ShadowStack.getStackTop(); int size = 0; while (stackFrame != null) { stackFrame = ShadowStack.getNextStackFrame(stackFrame); size++; } return size; }
private long freeMemoryLowLevel() { return GC.getFreeMemory(); }
@Unmanaged private static void initClassLowLevel(RuntimeClass cls) { if (cls.init != null) { cls.init.run(); } }
@Unmanaged public static RuntimeClass getClass(RuntimeObject object) { return unpack(object.classReference); }
static void init() { head = 0; tail = 0; limit = GC.gcStorageSize() / Address.sizeOf(); }
@Unmanaged public int computeCanary() { return computeCanary(size, tag); }
static RuntimeObject dequeue() { Address result = GC.gcStorageAddress().add(Address.sizeOf() * head).getAddress(); if (++head >= limit) { head = 0; } return result.toStructure(); }
public static Address allocateArray(RuntimeClass tag, int size) { int itemSize = (tag.itemType.flags & RuntimeClass.PRIMITIVE) != 0 ? tag.itemType.size : Address.sizeOf(); int sizeInBytes = Address.align(Address.fromInt(Structure.sizeOf(RuntimeArray.class)), itemSize).toInt(); sizeInBytes += itemSize * size; sizeInBytes = Address.align(Address.fromInt(sizeInBytes), Address.sizeOf()).toInt(); Address result = GC.alloc(sizeInBytes).toAddress(); fillZero(result, sizeInBytes); RuntimeArray array = result.toStructure(); array.classReference = tag.pack(); array.size = size; return result; }