Thanks for the idea Rick,

there is one detail I do not understand:
JIT code does not have a stack map **at all**, not even an empty one, thus 
(if I remember correctly) calling any Go function from it may trigger a GC 
cycle, which will find on the Go stack the "unknown" return address to the 
JIT function, and panic even though the JIT code itself does not use the Go 
stack. How can I remove such "offending" return address from the Go stack?

On Wednesday, October 23, 2019 at 5:22:35 PM UTC+2, Rick Hudson wrote:
>
> One approach is to maintain a shadow stack holding the pointers in a place 
> the GC already knows about, like an array allocated in the heap. This can 
> be done in Go, the language. Dereferences would use a level of indirection. 
> Perhaps one would pass an index into the array instead of the pointer and 
> somehow know the location of the shadow stack from a VM structures. This 
> way the stack contains no pointers _into the heap_ so the _GC_ is happy. 
> You might still have to deal with pointers to stack allocated objects since 
> stacks can be moved and so forth but that is not the problem being 
> discussed.
>
> Go the implementation, such as the Go 1.13, has a GC that does not move 
> heap objects. This means that to keep a heap object live the GC only needs 
> to know about a single pointer. That’s sort of handy since now you can push 
> the pointer onto the shadow stack and also onto the call stack since as 
> long as the shadow stack is visible the object will not be collected. I 
> note that this involves a barrier on all pointer writes so it is more than 
> just a change to the calling conventions. Reads on the other hand would be 
> full speed and not require a level of indirection or barrier unless and 
> until Go the implementation moved to a moving collector.
>
> I would explore this approach first since all of the pieces are under your 
> control. Developing an ABI for stack maps would include other people with 
> differing agendas and would likely slow you down. Likewise forking would 
> come with the usual maintenance/merge headaches.
>
>
>
> On Wednesday, October 23, 2019 at 1:50:51 PM UTC+1, Max wrote:
>>
>> Hello gophers,
>>
>> My recent attempt at creating a JIT compiler in Go to speed up my 
>> interpreter https://github.com/cosmos72/gomacro hit an early roadblock.
>>
>> In its current status, it can compile integer arithmetic and 
>> struct/array/slice/pointer access for amd64 and arm64, but it cannot 
>> allocate memory or call other functions, which severely limits its 
>> usefulness (and is thus not yet used by gomacro).
>>
>> The reason is: there is a requirement that Go functions must have a 
>> "stack frame descriptors registered with the runtime", in brief a "stack 
>> map" that tells which bits on the stack are pointers and which ones are not.
>> See https://github.com/golang/go/issues/20123 for details.
>>
>> But there is no API to associate a stack map to functions generated at 
>> runtime and running on the Go stack - currently the only supported 
>> mechanism to load Go code at runtime is to open a shared library file with 
>> `plugin.Open()`
>>
>> Thus JIT-generated functions must avoid triggering the garbage collector, 
>> as it would panic as described in the link above.
>> In turn, this means they cannot:
>> * allocate memory
>> * call other functions
>> * grow the stack
>> or do anything else that may start the GC.
>>
>> Now, I understand *why* Go functions must currently have a stack map, and 
>> I see at least two possible solutions:
>>
>> 1. implement an API to associate a stack map to functions generated at 
>> runtime - possibly by forking the Go compiler and/or standard library
>> 2. replace Go GC and allocator with an alternative that does not require 
>> stack maps - for example Boehm GC https://www.hboehm.info/gc/
>>     Here too, forking the Go compiler and/or standard library if needed.
>>
>> My questions are:
>>
>> a. which one of the two solutions above is easier, and how long could it 
>> take to a full-time expert?
>> b. does anyone have an easier solution or workaround to achieve the same 
>> goal?
>>
>> Regards,
>> cosmos72
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/af55e5f9-a4f0-4433-82fc-46dfb324ea59%40googlegroups.com.

Reply via email to