Charlie Tapping
12/17/2024, 7:40 PMephemient
12/17/2024, 7:48 PMsun.misc.Unsafe::compareAndSwap*
like older desktop JVMs should work on AndroidCharlie Tapping
12/17/2024, 7:52 PMMichael Paus
12/31/2024, 1:42 PMephemient
12/31/2024, 6:14 PMMichael Paus
01/01/2025, 12:28 AMephemient
01/01/2025, 7:56 AMephemient
01/01/2025, 7:56 AMMichael Paus
01/01/2025, 10:22 AMephemient
01/01/2025, 4:16 PMCharlie Tapping
01/06/2025, 5:49 PMMichael Paus
01/06/2025, 7:06 PMephemient
01/06/2025, 7:45 PMThe first tier is always an interpreternot always; V8 didn't have one before https://v8.dev/docs/ignition, its lowest tier was the baseline JIT. and as WASM was designed for compilation, most implementations (https://v8.dev/docs/wasm-compilation-pipeline https://firefox-source-docs.mozilla.org/js/index.html#wasm-baseline-rabaldrmonkey) don't have an interpreter either, they only have tiers of compilers. as far as I know, of the major implementations, only wasmtime is working on an interpreter https://github.com/bytecodealliance/rfcs/blob/main/accepted/pulley.md
ephemient
01/06/2025, 7:48 PMephemient
01/06/2025, 8:04 PMAOT would also be possible if done at build timeAOT to what? Chasm doesn't produce code, it's an interpreter
ephemient
01/06/2025, 8:44 PMByteArray
for linear memory on JVM. I'm not seeing what parts of the WASM threading spec you can't implement with Unsafe
? they should all be implementable by Unsafe.compareAndSwap
even if you have to use a wider type, e.g.
private val unsafe = Unsafe::class.java.getDeclaredField("theUnsafe").apply { isAccessible = true }.get(null) as Unsafe
private val baseOffset = unsafe.arrayBaseOffset(ByteArray::class.java)
.also { check(unsafe.arrayIndexScale(ByteArray::class.java) == Byte.SIZE_BYTES) }
fun ByteArray.getAndAdd(index: Int, arg: Byte): Byte {
val offset = baseOffset + index.and(3.inv())
var value: Byte
do {
val expected = unsafe.getIntVolatile(this, offset.toLong())
value = expected.shr(index.and(3) * Byte.SIZE_BITS).toByte()
val desired = expected.and(0xFF.inv() shl index.and(3) * Byte.SIZE_BITS) or
(value + arg).and(0xFF).shl(index.and(3) * Byte.SIZE_BITS)
} while (!unsafe.compareAndSwapInt(this, offset.toLong(), expected, desired))
return value
}
ephemient
01/06/2025, 8:46 PMByteBuffer
- you can get IntBuffer
etc. views, and they can be either array-backed or direct (off-heap memory)Michael Paus
01/06/2025, 8:53 PMCharlie Tapping
01/06/2025, 9:45 PMnot always; V8 didnât have one before https://v8.dev/docs/ignition, its lowest tier was the baseline JIT. and as WASM was designed for compilation, most implementations (https://v8.dev/docs/wasm-compilation-pipeline https://firefox-source-docs.mozilla.org/js/index.html#wasm-baseline-rabaldrmonkey) donât have an interpreter either, they only have tiers of compilers. as far as I know, of the major implementations, only wasmtime is working on an interpreter https://github.com/bytecodealliance/rfcs/blob/main/accepted/pulley.mdSo wasms a bit of a weird exception as it wasnât designed for its bytecode to be interpreted (because originally it was for the web and thus V8 w JIT), but broadly when building a VM an interpreter is the first thing you build. This is because its the fastest way to verify your decoding is correct, in fact if you check any of the wasm proposals youâll notice they all include a reference interpreter for this reason.
I see that you are usingThe instructions I need to support are here if youâre interested. When I looked at the unsafe docs I could see that it didnât have 1:1 equivalents and some instructions would require a CAS or more than one instruction which deterred me. But i guess more important unsafe if being removed from java in the coming versions as there are now safe equivalents.for linear memory on JVM. Iâm not seeing what parts of the WASM threading spec you canât implement withByteArray
? they should all be implementable byUnsafe
even if you have to use a wider type, e.g.Unsafe.compareAndSwap
but perhaps it would be better to switch toOriginally I used ByteArray as ByteBuffer isnât KMP friendly, but now I have implemented the native memory impl with rust I should be able to specialise this. ByteBuffer also has a 2GB limit which is annoying as I would have to stitch multiple together to make it work. Which then means more indirection on memory access, if ART gets a move on I might be able to use this in the future- you can getByteBuffer
etc. views, and they can be either array-backed or direct (off-heap memory)IntBuffer
ephemient
01/06/2025, 10:34 PMephemient
01/06/2025, 10:36 PM