mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
work on LaxMalloc
This commit is contained in:
parent
f266d21f58
commit
9181299a6d
|
@ -82,6 +82,9 @@ public final class LaxMalloc {
|
||||||
sizeBytes = MIN_ALLOC_SIZE;
|
sizeBytes = MIN_ALLOC_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure all allocations are at least a multiple of 4 to maintain alignment
|
||||||
|
sizeBytes = (sizeBytes + 3) & 0xFFFFFFFC;
|
||||||
|
|
||||||
// always between 0-63
|
// always between 0-63
|
||||||
int bucket = getListBucket(sizeBytes);
|
int bucket = getListBucket(sizeBytes);
|
||||||
|
|
||||||
|
@ -124,7 +127,7 @@ public final class LaxMalloc {
|
||||||
Address bucketStartAddr = Address.fromInt(ADDR_HEAP_BUCKETS_START).add(availableBucket << SIZEOF_PTR_SH);
|
Address bucketStartAddr = Address.fromInt(ADDR_HEAP_BUCKETS_START).add(availableBucket << SIZEOF_PTR_SH);
|
||||||
Address chunkPtr = bucketStartAddr.getAddress();
|
Address chunkPtr = bucketStartAddr.getAddress();
|
||||||
int chunkSize = readChunkSize(chunkPtr);
|
int chunkSize = readChunkSize(chunkPtr);
|
||||||
boolean bucketHasMultipleChunks = false;
|
Address itrChunkStart = Address.fromInt(0);
|
||||||
|
|
||||||
// check if the first chunk in the bucket is large enough
|
// check if the first chunk in the bucket is large enough
|
||||||
if(chunkSize - 8 < sizeBytes) { // size - 2 ints
|
if(chunkSize - 8 < sizeBytes) { // size - 2 ints
|
||||||
|
@ -136,8 +139,7 @@ public final class LaxMalloc {
|
||||||
Address chunkNextPtr = readChunkNextFreeAddr(chunkPtr);
|
Address chunkNextPtr = readChunkNextFreeAddr(chunkPtr);
|
||||||
if(chunkNextPtr.getInt() != chunkPtr.getInt()) {
|
if(chunkNextPtr.getInt() != chunkPtr.getInt()) {
|
||||||
bucketStartAddr.putAddress(chunkNextPtr);
|
bucketStartAddr.putAddress(chunkNextPtr);
|
||||||
chunkPtr = chunkNextPtr;
|
itrChunkStart = chunkNextPtr;
|
||||||
bucketHasMultipleChunks = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// extend mask to the next bucket
|
// extend mask to the next bucket
|
||||||
|
@ -179,15 +181,15 @@ public final class LaxMalloc {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bucketHasMultipleChunks) {
|
if(itrChunkStart.toInt() != 0) {
|
||||||
|
|
||||||
// if we've reached this point, it means the first chunk in the bucket wasn't large enough
|
// if we've reached this point, it means the first chunk in the bucket wasn't large enough
|
||||||
// and there weren't any chunks in the larger buckets we could split up
|
// and there weren't any chunks in the larger buckets we could split up
|
||||||
// so we need to look closer
|
// so we need to look closer
|
||||||
|
|
||||||
// iterate the (only) bucket of possibly large enough chunks
|
// iterate the (only) bucket of possibly large enough chunks
|
||||||
Address addrIterator = chunkPtr;
|
Address addrIterator = itrChunkStart;
|
||||||
while((addrIterator = readChunkNextFreeAddr(addrIterator)).getInt() != chunkPtr.getInt()) {
|
do {
|
||||||
chunkSize = readChunkSize(addrIterator);
|
chunkSize = readChunkSize(addrIterator);
|
||||||
|
|
||||||
// check if the chunk is large enough
|
// check if the chunk is large enough
|
||||||
|
@ -206,7 +208,7 @@ public final class LaxMalloc {
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}while((addrIterator = readChunkNextFreeAddr(addrIterator)).getInt() != chunkPtr.getInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
// no other options, time to sbrk
|
// no other options, time to sbrk
|
||||||
|
@ -292,11 +294,12 @@ public final class LaxMalloc {
|
||||||
// chunk actually starts 4 bytes before
|
// chunk actually starts 4 bytes before
|
||||||
Address chunkPtr = address.add(-4);
|
Address chunkPtr = address.add(-4);
|
||||||
|
|
||||||
// set the chunk no longer in use
|
|
||||||
setChunkInUse(chunkPtr, false);
|
|
||||||
|
|
||||||
// bring the size of the chunk into the stack
|
// bring the size of the chunk into the stack
|
||||||
int chunkSize = chunkPtr.getInt();
|
int chunkSize = chunkPtr.getInt();
|
||||||
|
boolean sizeChanged = false;
|
||||||
|
|
||||||
|
// set the chunk no longer in use
|
||||||
|
chunkSize &= 0x7FFFFFFF;
|
||||||
|
|
||||||
if(Address.fromInt(ADDR_HEAP_DATA_START).isLessThan(chunkPtr)) {
|
if(Address.fromInt(ADDR_HEAP_DATA_START).isLessThan(chunkPtr)) {
|
||||||
// check if we can merge with the previous chunk, and move it to another bucket
|
// check if we can merge with the previous chunk, and move it to another bucket
|
||||||
|
@ -311,8 +314,7 @@ public final class LaxMalloc {
|
||||||
// resize the current chunk to also contain the previous chunk
|
// resize the current chunk to also contain the previous chunk
|
||||||
chunkPtr = prevChunkPtr;
|
chunkPtr = prevChunkPtr;
|
||||||
chunkSize += prevChunkSize;
|
chunkSize += prevChunkSize;
|
||||||
chunkPtr.putInt(chunkSize);
|
sizeChanged = true;
|
||||||
chunkPtr.add(chunkSize - 4).putInt(chunkSize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,11 +330,18 @@ public final class LaxMalloc {
|
||||||
|
|
||||||
// resize the current chunk to also contain the next chunk
|
// resize the current chunk to also contain the next chunk
|
||||||
chunkSize += nextChunkSize;
|
chunkSize += nextChunkSize;
|
||||||
chunkPtr.putInt(chunkSize);
|
sizeChanged = true;
|
||||||
chunkPtr.add(chunkSize - 4).putInt(chunkSize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// store the final chunk size (also clears the in use flag)
|
||||||
|
chunkPtr.putInt(chunkSize);
|
||||||
|
|
||||||
|
if(sizeChanged) {
|
||||||
|
// if the size of the chunk changed, we also need to update the chunk's second size integer
|
||||||
|
chunkPtr.add(chunkSize - 4).putInt(chunkSize);
|
||||||
|
}
|
||||||
|
|
||||||
// add the final chunk to the free chunks list
|
// add the final chunk to the free chunks list
|
||||||
linkChunkInFreeList(chunkPtr, chunkSize);
|
linkChunkInFreeList(chunkPtr, chunkSize);
|
||||||
}
|
}
|
||||||
|
@ -368,7 +377,7 @@ public final class LaxMalloc {
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
// not large enough to split, just take the entire chunk
|
// not large enough to split, just take the entire chunk
|
||||||
setChunkInUse(chunkPtr, true);
|
chunkPtr.putInt(chunkSize | 0x80000000); // sets the in use flag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,11 +517,6 @@ public final class LaxMalloc {
|
||||||
chunkAddr.putInt(sizeStatus);
|
chunkAddr.putInt(sizeStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setChunkInUse(Address chunkAddr, boolean inUse) {
|
|
||||||
int i = chunkAddr.getInt();
|
|
||||||
chunkAddr.putInt(inUse ? (i | 0x80000000) : (i & 0x7FFFFFFF));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Address readChunkPrevFreeAddr(Address chunkAddr) {
|
private static Address readChunkPrevFreeAddr(Address chunkAddr) {
|
||||||
return chunkAddr.add(4).getAddress();
|
return chunkAddr.add(4).getAddress();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user