Optimize Arena and memScoped
Also do minor refactoring.
This commit is contained in:
committed by
SvyatoslavScherbina
parent
2217be4003
commit
a3721f857c
@@ -98,15 +98,13 @@ internal object nativeMemUtils {
|
||||
return unsafe.allocateInstance(T::class.java) as T
|
||||
}
|
||||
|
||||
internal class NativeAllocated(rawPtr: NativePtr) : NativePointed(rawPtr)
|
||||
|
||||
fun alloc(size: Long, align: Int): NativePointed {
|
||||
val address = unsafe.allocateMemory(
|
||||
if (size == 0L) 1L else size // It is a hack: `sun.misc.Unsafe` can't allocate zero bytes
|
||||
)
|
||||
|
||||
if (address % align != 0L) TODO(align.toString())
|
||||
return interpretPointed<NativeAllocated>(address)
|
||||
return interpretOpaquePointed(address)
|
||||
}
|
||||
|
||||
fun free(mem: NativePtr) {
|
||||
|
||||
@@ -40,6 +40,11 @@ val NativePointed?.rawPtr: NativePtr
|
||||
*/
|
||||
inline fun <reified T : NativePointed> interpretPointed(ptr: NativePtr): T = interpretNullablePointed<T>(ptr)!!
|
||||
|
||||
private class OpaqueNativePointed(rawPtr: NativePtr) : NativePointed(rawPtr)
|
||||
|
||||
fun interpretOpaquePointed(ptr: NativePtr): NativePointed = interpretPointed<OpaqueNativePointed>(ptr)
|
||||
fun interpretNullableOpaquePointed(ptr: NativePtr): NativePointed? = interpretNullablePointed<OpaqueNativePointed>(ptr)
|
||||
|
||||
/**
|
||||
* Changes the interpretation of the pointed data or code.
|
||||
*/
|
||||
|
||||
@@ -65,31 +65,30 @@ open class DeferScope {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement optimally
|
||||
open class ArenaBase(private val parent: NativeFreeablePlacement = nativeHeap) : NativePlacement, DeferScope() {
|
||||
|
||||
private val allocatedChunks = ArrayList<NativePointed>()
|
||||
private var lastChunk: NativePointed? = null
|
||||
|
||||
final override fun alloc(size: Long, align: Int): NativePointed {
|
||||
val res = parent.alloc(size, align)
|
||||
try {
|
||||
allocatedChunks.add(res)
|
||||
return res
|
||||
} catch (e: Throwable) {
|
||||
parent.free(res)
|
||||
throw e
|
||||
}
|
||||
// Reserve space for a pointer:
|
||||
val gapForPointer = maxOf(pointerSize, align)
|
||||
|
||||
val chunk = parent.alloc(size = gapForPointer + size, align = gapForPointer)
|
||||
nativeMemUtils.putNativePtr(chunk, lastChunk.rawPtr)
|
||||
lastChunk = chunk
|
||||
return interpretOpaquePointed(chunk.rawPtr + gapForPointer.toLong())
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal fun clearImpl() {
|
||||
this.executeAllDeferred()
|
||||
|
||||
allocatedChunks.forEach {
|
||||
parent.free(it)
|
||||
var chunk = lastChunk
|
||||
while (chunk != null) {
|
||||
val nextChunk = nativeMemUtils.getNativePtr(chunk)
|
||||
parent.free(chunk)
|
||||
chunk = interpretNullableOpaquePointed(nextChunk)
|
||||
}
|
||||
|
||||
allocatedChunks.clear()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -83,14 +83,12 @@ internal object nativeMemUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private class NativeAllocated(rawPtr: NativePtr) : NativePointed(rawPtr)
|
||||
|
||||
fun alloc(size: Long, align: Int): NativePointed {
|
||||
val ptr = malloc(size, align)
|
||||
if (ptr == nativeNullPtr) {
|
||||
throw OutOfMemoryError("unable to allocate native memory")
|
||||
}
|
||||
return interpretPointed<NativeAllocated>(ptr)
|
||||
return interpretOpaquePointed(ptr)
|
||||
}
|
||||
|
||||
fun free(mem: NativePtr) {
|
||||
|
||||
Reference in New Issue
Block a user