[Vm-dev] Re: [squeak-dev] VM performance discrepancy on Linux and Windows

John M McIntosh johnmci at smalltalkconsulting.com
Fri Apr 11 07:42:59 UTC 2008


The sqGnu.h I have reads

#if defined(__i386__)
# define IP_REG asm("%esi")
# define SP_REG asm("%edi")
//# if (__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 95))
#   define CB_REG asm("%ebx")
//# else
//#   define CB_REG /* avoid undue register pressure */
//# endif
#endif


The first two byte codes assemble to this when done right.

L10161:
	addl	$1, %esi
	movzbl	(%esi), %ebx
	addl	$4, %edi
	movl	_foo, %eax
	movl	84(%eax), %eax
	movl	4(%eax), %eax
	movl	%eax, (%edi)
	movl	512(%esp,%ebx,4), %eax
L10421:
	jmp	*%eax

L10162:
	addl	$1, %esi
	movzbl	(%esi), %ebx
	addl	$4, %edi
	movl	_foo, %eax
	movl	84(%eax), %eax
	movl	8(%eax), %eax
	movl	%eax, (%edi)
	movl	512(%esp,%ebx,4), %eax
	jmp	*%eax



sqInt interpret(void) {
#ifdef FOO_REG
     register struct foo * foo FOO_REG = &fum;
#endif
     sqInt localReturnValue;
     sqInt localReturnContext;
     sqInt localHomeContext;
     char* localSP;
     char* localIP;
     sqInt currentBytecode;
     JUMP_TABLE;


Plus use of  -DUSE_INLINE_MEMORY_ACCESSORS

However much of this also relies on GCC version, in this case 4.01,  
usage of SP_REG, etc produced dreadful code with GCC 4.x, but was  
required for earlier versions.

I noted for PowerPC
(Note building with GCC 3.3 PowerPC produces better code than gcc 4.0,  
gcc 3.1 or gcc 2.95, FYI gcc 3.1 produces lousy code
But since you are building on Intel your milage will vary (lots)

On Apr 11, 2008, at 12:22 AM, Andreas Raab wrote:

> Yoshiki Ohshima wrote:
>> Apparently, %esi is used (exclusively) for IP, and %ebx keeps the  
>> next
>> byte, and "jmp *" takes you to the next location stored in the table
>> starts at 0x2780.
>
> All of that comes straight out of sqGnu.h:
>
> #define BC_CASE(N)		case N: _##N:
> #define BC_BREAK		goto *jumpTable[currentBytecode]
>
> #if defined(__i386__)
> # define IP_REG asm("%esi")
> # define SP_REG asm("%edi")
> # define CB_REG asm("%ebx")
> #endif
>
> You might want to check if the gnuifier got confused over time - I  
> had to update it to deal correctly with sqInt etc. gnu-interp.c  
> should look like here:
>
> sqInt interpret(void) {
>    sqInt localReturnValue;
>    sqInt localReturnContext;
>    sqInt localHomeContext;
>    register char* localSP SP_REG;
>    register char* localIP IP_REG;
>    register sqInt currentBytecode CB_REG;
>    BC_JUMP_TABLE;
>
> 		switch (currentBytecode) {
> 		BC_CASE(0)
> 			/* pushReceiverVariableBytecode */
> 			BC_BREAK;
>
>> %esi is almost used for IP but use %eax for fetching the next byte,
>> jmp also seems to use %eax so right before it is spilled and the
>> destination address is brought into %eax.
>
> Sounds more like the static register assignments get ignored.
>
> Cheers,
>  - Andreas
>

--
= 
= 
= 
========================================================================
John M. McIntosh <johnmci at smalltalkconsulting.com>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
= 
= 
= 
========================================================================




More information about the Vm-dev mailing list