[squeak-dev] Re: [Pharo-project] A small idea how to get closer to hardware with small efforts :)

Igor Stasenko siguctua at gmail.com
Thu Apr 8 16:38:25 UTC 2010

Okay, here the small snippet of code, which does the trick! :)

Compile it with:

 gcc calltest.c callgate.s -o calltest

Here, a fn1() and fn2()
is equal functions (almost), which imitating the native code, which
moved during the VM call.

And fnCallGate() is a special function, which needs to be called
instead of actual function,
which potentially could move our code.

extern void fnCallGate(void* fn, ...);

it take a first argument - a function which needs to be called, and
then rest of arguments (if any),
which belong to that function.

This gate function using another function, which returns a current
value of a method oop.
In terms of Squeak VM, this is a method oop, which it retrieving
before calling a VM function
and after calling it (interpreterProxy->primitiveMethod).
So, in case if method oop is moved during GC, it will change the
return address by the same offset
as a difference between old method oop value and new one.

And so, with this trick, a native code could safely call any VM
function (through a gate function)
without the risk that if native code is moved during GC, it will
return to wrong address and cause a system crash.

On 6 April 2010 23:49, Igor Stasenko <siguctua at gmail.com> wrote:
> On 6 April 2010 14:46, Marcus Denker <marcus.denker at inria.fr> wrote:
>> Hi,
>> I always liked how Smalltalk X did it... they have
>>        -> an ivar in CompiledMethod that is the "native code pointer".
>>        -> Primitive methods are just methods that have this pointer set
>>             to the primitive in the vm.
>>        -> Methods with embedded C-code are compiled and linked with
>>             the Smtk->C cross-compiler, the pointer than points to that function
>>        -> the JIT just put a pointer to the code it generates.
>> So they merge primitives / static compiling(+embedded c-code) *and* the JIT
>> into one not that ugly mechanism. In STX, the memory is managed by the VM, though (the
>> code is not allocated in the GCed object memory by the JIT).
>> So: Yes, I like this :-) and your mechanism is a nice way to get it easily integrated into the current
>> system.
>> Q: what happens when code is moved by the GC?
> Yeah, it will break the whole thing :)
> To avoid that, a native code should not issue any memory allocation,
> which may cause GC.
> Perhaps, there is a way to counter this , while still being able to
> move the code.
> A primitive could set a flag that its going to call a native code,
> embedded into compiled method,
> so, then, after GC, if this flag is set, VM knows, that memory
> allocation is issued from native code,
> and should fix the return address (1) on stack, before returning to
> native code, which moved to the new code location:
> primitive -> native code --(1)-> VM allocation procedure -> GC
> (1) - a return address , which should be fixed.
>> --
>> Marcus Denker  -- http://www.marcusdenker.de
>> INRIA Lille -- Nord Europe. Team RMoD.
>> _______________________________________________
>> Pharo-project mailing list
>> Pharo-project at lists.gforge.inria.fr
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
> --
> Best regards,
> Igor Stasenko AKA sig.

Best regards,
Igor Stasenko AKA sig.
-------------- next part --------------
	.file	"callgate.s"
	.p2align 4,,15
.globl _fnCallGate
	.def	_fnCallGate;	.scl	2;	.type	32;	.endef
	call	*(_getCurrentAddressFn)  /* retrieve a primitive method oop */
	movl	%eax, _savedAddress
	popl	_returnAddress  /* save return address */
	popl	%eax
	call	*%eax  /* call the function */
	pushl	_returnAddress 
	pushl	%eax  /* save return value */
	pushl	%edx
	call	*(_getCurrentAddressFn)  /* retrieve a primitive method oop */
	subl	_savedAddress, %eax
	addl	%eax, 8(%esp)  /* current - old + returnAddress */
	popl	%edx
	popl	%eax
	.comm	_returnAddress, 16	 # 4
	.comm	_savedAddress, 16	 # 4
-------------- next part --------------
A non-text attachment was scrubbed...
Name: calltest.c
Type: text/x-c
Size: 800 bytes
Desc: not available
Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20100408/1a439cb1/calltest.bin

More information about the Squeak-dev mailing list