From 90c8609f542f394716ca41ef251c230044953916 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Thu, 27 Feb 2020 17:54:35 +0900 Subject: [PATCH] determining array base offset: replaced trick code with proper code --- src/net/torvald/UnsafePtr.kt | 24 ++++++++++++------ src/net/torvald/random/XXHash32.java | 4 +-- .../virtualcomputer/computer/BLIT.kt | 2 +- src/net/torvald/terrarum/tests/RNGTest.kt | 4 ++- src/net/torvald/terrarum/tests/UnsafeTest.kt | 25 +++---------------- 5 files changed, 25 insertions(+), 34 deletions(-) diff --git a/src/net/torvald/UnsafePtr.kt b/src/net/torvald/UnsafePtr.kt index d6b4a625a..c87af48b7 100644 --- a/src/net/torvald/UnsafePtr.kt +++ b/src/net/torvald/UnsafePtr.kt @@ -24,14 +24,24 @@ internal object UnsafeHelper { return UnsafePtr(ptr, size) } - fun memcpy(src: UnsafePtr, fromIndex: Long, dest: UnsafePtr, toIndex: Long, copyLength: Long) { - // unsafe.copyMemory(srcAddress, destAddress, bytes); in case no src for the sun.misc.Unsafe is available :D - unsafe.copyMemory(src.ptr + fromIndex, dest.ptr + toIndex, copyLength) - } + fun memcpy(src: UnsafePtr, fromIndex: Long, dest: UnsafePtr, toIndex: Long, copyLength: Long) = + unsafe.copyMemory(src.ptr + fromIndex, dest.ptr + toIndex, copyLength) + fun memcpy(srcAddress: Long, destAddress: Long, copyLength: Long) = + unsafe.copyMemory(srcAddress, destAddress, copyLength) + fun memcpyRaw(srcObj: Any?, srcPos: Long, destObj: Any?, destPos: Long, len: Long) = + unsafe.copyMemory(srcObj, srcPos, destObj, destPos, len) - fun memcpy(srcAddress: Long, destAddress: Long, copyLength: Long) = unsafe.copyMemory(srcAddress, destAddress, copyLength) - - fun memcpyRaw(srcObj: Any?, srcPos: Long, destObj: Any?, destPos: Long, len: Long) = unsafe.copyMemory(srcObj, srcPos, destObj, destPos, len) + /** + * The array object in JVM is stored in this memory map: + * + * 0 w 2w * + * | Some identifier | Other identifier | the actual data ... | + * + * (where w = 4 for 32-bit JVM and 8 for 64-bit JVM. If Compressed-OOP is involved, things may get complicated) + * + * @return offset from the array's base memory address (aka pointer) that the actual data begins. + */ + fun getArrayOffset(obj: Any) = unsafe.arrayBaseOffset(obj.javaClass) } /** diff --git a/src/net/torvald/random/XXHash32.java b/src/net/torvald/random/XXHash32.java index ba6a8b1c2..d1bf7963f 100644 --- a/src/net/torvald/random/XXHash32.java +++ b/src/net/torvald/random/XXHash32.java @@ -17,8 +17,6 @@ public class XXHash32 { static final int PRIME4 = 0x27D4EB2F; static final int PRIME5 = 0x165667B1; - static final int ARRAY_ELEM_OFFSET = (AppLoader.is32BitJVM) ? 8 : 16; - public static int hash(byte[] data, int seed) { int end = data.length; int offset = 0; @@ -74,6 +72,6 @@ public class XXHash32 { } protected static int getInt(byte[] data, int offset) { - return UnsafeHelper.INSTANCE.getUnsafe().getInt(data, offset + ARRAY_ELEM_OFFSET); + return UnsafeHelper.INSTANCE.getUnsafe().getInt(data, offset + UnsafeHelper.INSTANCE.getArrayOffset(data)); } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/BLIT.kt b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/BLIT.kt index d3dfd0f5f..c250682c7 100644 --- a/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/BLIT.kt +++ b/src/net/torvald/terrarum/modulecomputers/virtualcomputer/computer/BLIT.kt @@ -35,7 +35,7 @@ class BLIT { val writeAddr = toAddr(x, y) UnsafeHelper.memcpyRaw( - bytes, (if (AppLoader.is32BitJVM) 8 else 16) + yy * width, + bytes, UnsafeHelper.getArrayOffset(bytes) + yy * width, null, framebuffer.ptr + writeAddr, width.toLong() ) diff --git a/src/net/torvald/terrarum/tests/RNGTest.kt b/src/net/torvald/terrarum/tests/RNGTest.kt index 47d03ea41..0bcf64309 100644 --- a/src/net/torvald/terrarum/tests/RNGTest.kt +++ b/src/net/torvald/terrarum/tests/RNGTest.kt @@ -39,6 +39,8 @@ fun main(args: Array) { + val rangeSize = 64 + val textLen = (rangeSize - 1).toString().length for (tries in 0 until 16) { repeat(BlockCodex.DYNAMIC_RANDOM_CASES + 12) { repeats -> val x = 349 + repeats @@ -48,7 +50,7 @@ fun main(args: Array) { val offset = XXHash32.hash(((x and 0xFFFF).shl(16) or (y and 0xFFFF)).toLittle(), 10000) //print("${offset.toString().padStart(2, '0')} ") - print("${offset.fmod(BlockCodex.DYNAMIC_RANDOM_CASES).toString().padStart(2, '0')} ") + print("${offset.fmod(rangeSize).toString().padStart(textLen, '0')} ") } println() println() diff --git a/src/net/torvald/terrarum/tests/UnsafeTest.kt b/src/net/torvald/terrarum/tests/UnsafeTest.kt index 7f237439f..cbb79ac44 100644 --- a/src/net/torvald/terrarum/tests/UnsafeTest.kt +++ b/src/net/torvald/terrarum/tests/UnsafeTest.kt @@ -19,30 +19,11 @@ class UnsafeTest { private val memsize = 512L // must be big enough value so that your OS won't always return zero-filled pieces fun main() { - var ptr = unsafe.allocateMemory(memsize) - printDump(ptr) + val intarray = intArrayOf(5,4,3,2,1) - unsafe.setMemory(ptr, memsize, 0x00.toByte()) - printDump(ptr) + val arrayBaseOffset = UnsafeHelper.getArrayOffset(intarray) // should be 16 or 12 on 64-bit JVM - for (k in 0 until 13) { - unsafe.putByte(ptr + k, (-1 - k).toByte()) - } - printDump(ptr) - - // test shingled memory copy -- how would it work out? - UnsafeHelper.memcpy(ptr, ptr + 3L, 13L) - - printDump(ptr) - - - println(ptr) - ptr = unsafe.reallocateMemory(ptr, 256L) - println(ptr) - - - // that's all for today! - unsafe.freeMemory(ptr) + println(arrayBaseOffset) }