public static Address getStackRootPointer(Address stackFrame) { int size = stackFrame.getInt(); return stackFrame.add(-size * 4); }
private static Address getExceptionHandlerPtr(Address stackFrame) { int size = stackFrame.getInt(); return stackFrame.add(-size * 4 - 4); }
private static Address contentStart(Address resource) { return resource.add(Address.sizeOf()); }
private static void slowMemoryMove(Address source, Address target, int count) { if (source.toInt() > target.toInt()) { while (count-- > 0) { target.putByte(source.getByte()); target = target.add(1); source = source.add(1); } } else { source = source.add(count); target = target.add(count); while (count-- > 0) { target = target.add(-1); source = source.add(-1); target.putByte(source.getByte()); } } }
private static int hashCode(RuntimeString string) { int hashCode = 0; int length = string.characters.length; Address chars = Address.ofData(string.characters); for (int i = 0; i < length; ++i) { hashCode = 31 * hashCode + chars.getChar(); chars = chars.add(2); } return hashCode; }
public static Address getNextStackFrame(Address stackFrame) { int size = stackFrame.getInt() + 2; Address result = stackFrame.add(-size * 4); if (result == initStack()) { result = null; } return result; }
@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); }
private static boolean equals(RuntimeString first, RuntimeString second) { if (first.characters.length != second.characters.length) { return false; } Address firstChars = Address.ofData(first.characters); Address secondChars = Address.ofData(second.characters); int length = first.characters.length; for (int i = 0; i < length; ++i) { if (firstChars.getChar() != secondChars.getChar()) { return false; } firstChars = firstChars.add(2); secondChars = secondChars.add(2); } return true; }
private static boolean getAvailableChunkIfPossible(int size) { if (freeChunks == 0) { return false; } while (true) { if (currentChunk.toAddress().add(size) == currentChunkLimit) { break; } if (currentChunk.toAddress().add(size + Structure.sizeOf(FreeChunk.class)).isLessThan(currentChunkLimit)) { break; } if (--freeChunks == 0) { return false; } freeMemory -= currentChunk.size; currentChunkPointer = Structure.add(FreeChunkHolder.class, currentChunkPointer, 1); currentChunk = currentChunkPointer.value; currentChunkLimit = currentChunk.toAddress().add(currentChunk.size); } return true; }
private static void fillResourceMapKeys(Address map, String[] target) { int sz = map.getInt(); Address data = contentStart(map); Address targetData = Address.ofData(target); for (int i = 0; i < sz; ++i) { Address entry = data.getAddress(); if (entry != null) { targetData.putAddress(entry); targetData = targetData.add(Address.sizeOf()); } data = data.add(Address.sizeOf()); } }
public static RuntimeObject alloc(int size) { FreeChunk current = currentChunk; Address next = current.toAddress().add(size); if (!next.add(Structure.sizeOf(FreeChunk.class)).isLessThan(currentChunkLimit)) { getAvailableChunk(size); current = currentChunk; next = currentChunk.toAddress().add(size); } int freeSize = current.size; freeSize -= size; if (freeSize > 0) { currentChunk = next.toStructure(); currentChunk.size = freeSize; } else { freeMemory -= size; getAvailableChunkIfPossible(currentChunk.size + 1); } currentChunk.classReference = 0; freeMemory -= size; return current.toAddress().toStructure(); }
private static int resourceMapSize(Address map) { int result = 0; int sz = map.getInt(); Address data = contentStart(map); for (int i = 0; i < sz; ++i) { if (data.getAddress() != null) { result++; } data = data.add(Address.sizeOf() * 2); } return result; }
static void enqueue(RuntimeObject object) { GC.gcStorageAddress().add(Address.sizeOf() * tail).putAddress(object.toAddress()); if (++tail >= limit) { tail = 0; } }
@Unmanaged private static void fillEnumConstantsImpl(RuntimeClass cls, Address[] array) { Address enumValues = cls.enumValues; for (int i = 0; i < array.length; i++) { enumValues = enumValues.add(Address.sizeOf()); array[i] = enumValues.getAddress().getAddress(); } }
static RuntimeObject dequeue() { Address result = GC.gcStorageAddress().add(Address.sizeOf() * head).getAddress(); if (++head >= limit) { head = 0; } return result.toStructure(); }
@Unmanaged public static RuntimeArray allocateMultiArray(RuntimeClass tag, Address dimensions, int dimensionCount) { int size = dimensions.getInt(); RuntimeArray array = allocateArray(tag, dimensions.getInt()).toStructure(); if (dimensionCount > 1) { Address arrayData = Structure.add(RuntimeArray.class, array, 1).toAddress(); arrayData = Address.align(arrayData, Address.sizeOf()); for (int i = 0; i < size; ++i) { RuntimeArray innerArray = allocateMultiArray(tag.itemType, dimensions.add(4), dimensionCount - 1); arrayData.putAddress(innerArray.toAddress()); arrayData = arrayData.add(Address.sizeOf()); } } return array; }
@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; }
public static Address lookupResource(Address map, String string) { RuntimeString runtimeString = Address.ofObject(string).toStructure(); int hashCode = hashCode(runtimeString); int sz = map.getInt(); Address content = contentStart(map); for (int i = 0; i < sz; ++i) { int index = (hashCode + i) % sz; if (index < 0) { index += sz; } Address entry = content.add(index * Address.sizeOf() * 2); Address key = entry.getAddress(); if (key == null) { return null; } if (equals(key.toStructure(), runtimeString)) { return entry; } } return null; }
private static int objectSize(FreeChunk object) { if (object.classReference == 0) { return object.size; } else { RuntimeClass cls = RuntimeClass.getClass(object.toAddress().toStructure()); if (cls.itemType == null) { return cls.size; } else { int itemSize = (cls.itemType.flags & RuntimeClass.PRIMITIVE) == 0 ? Address.sizeOf() : cls.itemType.size; RuntimeArray array = object.toAddress().toStructure(); Address address = Address.fromInt(Structure.sizeOf(RuntimeArray.class)); address = Address.align(address, itemSize); address = address.add(itemSize * array.size); address = Address.align(address, Address.sizeOf()); return address.toInt(); } } }