Conversation

Eniko | Kitsune Tails out now!

things i did not consider when deciding i was going to write a VM to JIT programs inside a custom kernel instead of dealing with virtual memory:

how am i going to actually do load/store memory operations from my JIT compiled machine code when i don't have virtual memory to make that process easier

3
0
0

suppose on risc-v i could designate a register to always hold the heap address and always do something like

li t0, myaddress
add t6, t0

where t6 is the designated heap address register. that's 3 instructions instead of 2 so like, i guess it could be worse? ¯\_(ツ)_/¯

1
0
0

@eniko Could deal with in a similar way to what I think WASM does? Have an allocated region of memory you keep a pointer to, and then load/store basically translates to "add offset to memory pointer & load from resulting address", plus maybe some checks if you wanna ensure the offset lies within the allocated memory?

2
0
0

@glairedaggers yeah i think i'd have to do it that way

0
0
0

@eniko (I think you maybe touched on this a bit when you mentioned keeping your heap address in a register, though frankly you could also just keep that value in memory as a global variable basically, so you don't need to permanently burn a register on a heap address)

1
0
0

@glairedaggers wouldn't the register be way faster than having to read the base address from ram every time?

1
0
0

@eniko On the GameBoy Advance, we had 2 chunks of RAM at different fixed addresses (32k and 256k). For us the logical thing was to hardcore the local variable base pointer and the stack pointer the each end of the 32k region, and make the base pointer for malloc/free use the start of the 256k region.

In your case, you could probably hardcore your base pointers similarly. Decide memory_base is where variables go, memory_base+256k-1 is where your stack pointer goes, and malloc/free starts at memory_base+256k.

In essence, let the compiler do the work, and you live with some hard coded limits

1
0
0

@pawv but doctor, i'm writing the compiler 😭

i suppose i could hardcode where the stack/heap bases are in the JIT, assuming i don't actually ever move any of the process memory. that would work even with multiple processes

but risc-v only allows a +/- 2048 offset to a register when loading/storing

1
0
0

@eniko Oh, the trick to that is you emit a static data region nearby your generated code that contains the full pointer. The +/- 2048 op code is used to load the full 32bit/64bit pointer addresses into a register, then you fetch what you want relative to the address the register is now pointing at.

1
0
0

@eniko You'll often see these static data regions inserted near jumps and returns.

1
0
0

@eniko Again I'm assuming RISC-V code generation is similar to ARM. I know with x86 you can get away with fat opcodes that inline larger values and pointers.

1
0
0

@pawv the problem is i want this to be multi-process and iirc you're not allowed (supposed?) to change the global pointer in risc-v once you've set it for the first time

0
0
0

@eniko Perhaps, but how concerned are you with generating the fastest possible machine code here? Are you expecting this to be such a hot path that a global variable load is going to kill your perf?

1
0
0

@glairedaggers i mean, JIT is generally for hot paths? :'D

1
0
0

@eniko this is sort-of what gp is used for (but static data not heap), but yes you could have a bunch of registers pointing at useful things (just be careful - most will get clobbered when you call a C function)

1
0
0

@lenary yeah. i considered abusing the gp register but apparently risc-v is very adamant you're supposed to assign it once and then never modify it. i don't know where that falls on the rule<->guideline continuum though?

i could stick it in a callee-saved register like s11, then it should be safe

1
0
0

@eniko honestly, at the guideline end. the calling convention iirc won't touch it, so it can be used for __global_pointer$, or for the shadow stack, or for anything else tbh (but you almost certainly want to match whatever the C code you're calling thinks it's used for)

2
0
0

@lenary oh, that's good to know if i ever want to do *shenanigans*

but tbh with DDCG i have so many spare registers in risc-v that i can afford to burn one to store "here is where the heap lives"

0
0
0
@lenary @eniko ya, don't just use GP for other stuff, it'll break (even if the changed the ABI to say it might be OK)
0
0
0