[interop] Optimized unmanaged memory alloc/free

This commit is contained in:
Igor Chevdar
2020-11-12 19:10:49 +05:00
committed by Stanislav Erokhin
parent e7ab525213
commit e5f7cef594
8 changed files with 166 additions and 13 deletions
@@ -16,6 +16,7 @@
package kotlinx.cinterop
import org.jetbrains.kotlin.konan.util.nativeMemoryAllocator
import sun.misc.Unsafe
private val NativePointed.address: Long
@@ -95,19 +96,20 @@ internal object nativeMemUtils {
return unsafe.allocateInstance(T::class.java) as T
}
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
)
internal fun allocRaw(size: Long, align: Int): NativePtr {
val address = unsafe.allocateMemory(size)
if (address % align != 0L) TODO(align.toString())
return interpretOpaquePointed(address)
return address
}
fun free(mem: NativePtr) {
internal fun freeRaw(mem: NativePtr) {
unsafe.freeMemory(mem)
}
fun alloc(size: Long, align: Int) = interpretOpaquePointed(nativeMemoryAllocator.alloc(size, align))
fun free(mem: NativePtr) = nativeMemoryAllocator.free(mem)
private val unsafe = with(Unsafe::class.java.getDeclaredField("theUnsafe")) {
isAccessible = true
return@with this.get(null) as Unsafe
@@ -395,7 +395,7 @@ private object EmptyCString: CValues<ByteVar>() {
override val align get() = 1
private val placement =
interpretCPointer<ByteVar>(nativeMemUtils.alloc(1, 1).rawPtr)!!.also {
interpretCPointer<ByteVar>(nativeMemUtils.allocRaw(1, 1))!!.also {
it[0] = 0.toByte()
}
@@ -118,14 +118,22 @@ internal object nativeMemUtils {
}
fun alloc(size: Long, align: Int): NativePointed {
return interpretOpaquePointed(allocRaw(size, align))
}
fun free(mem: NativePtr) {
freeRaw(mem)
}
internal fun allocRaw(size: Long, align: Int): NativePtr {
val ptr = malloc(size, align)
if (ptr == nativeNullPtr) {
throw OutOfMemoryError("unable to allocate native memory")
}
return interpretOpaquePointed(ptr)
return ptr
}
fun free(mem: NativePtr) {
internal fun freeRaw(mem: NativePtr) {
cfree(mem)
}
}