Optimize Arena and memScoped

Also do minor refactoring.
This commit is contained in:
Svyatoslav Scherbina
2017-09-19 12:23:25 +03:00
committed by SvyatoslavScherbina
parent 2217be4003
commit a3721f857c
4 changed files with 20 additions and 20 deletions
@@ -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) {