[Vm-dev] localIP, instructionPointer, currentBytecode data size

John M McIntosh johnmci at smalltalkconsulting.com
Tue Mar 2 06:16:59 UTC 2010

instructionPointer  is 
usqInt instructionPointer;
you may be looking at obsolete code.

instructionPointer & stackPointer are either globals or elements in a structure depending on how the interp.c is built. 

Now depending on the hardware, the compiler, and the compiler version we want to produce assembler that functions the best. 
To do that we have to cheat. 

So first we want to move the data from the global or structure out of that storage location into a simple variable and hope the compiler 
will produce better code. Historically that has been the case.  We also can supply register hints which may or may not alter the code the compiler produces
yet even cause the compiler to make the wrong code and crash the VM...  All of this can change with just a minor version number change for your compiler.

    char* localSP;
    register char* localIP;

	/* begin internalizeIPandSP */
	localIP = pointerForOop(foo->instructionPointer);
	localSP = pointerForOop(foo->stackPointer);

By defining the values as char* we might take advantage of hardware that used registers for math,  & registers for addresses like the 68030 CPU where Squeak was born. 
Since they are char * then increment/decrement is by one byte so we have 

				longAtPointerput(localSP += BytesPerWord, longAt((foo->receiver + BaseHeaderSize) + ((0 & 15) << ShiftForWord)));
where BytesPerWord could be 4 or could be 8.  The compiler could do something clever with that.. 

Now note the pointerForOop(foo->instructionPointer);   

The foo->instructionPointer is NOT a memory address it's a oops pointer.  So in a 32bit image running in a 64bit address space then the 

static inline char *pointerForOop(usqInt oop)			
	{ return sqMemoryBase + oop; }

converts the 32bit oops into a 64 bit address pointer, which is why that localIP is  a '*' type, and why instructionPointer is usqInt which is mangled the defines below
I note on a 32bit image on a 32bit CPU the sqMemoryBase and a clever compiler optimized the return 0 + oop  into return oop then into thin air.... 

#if defined(SQ_IMAGE32)
  typedef int		sqInt;
  typedef unsigned int	usqInt;
#elif defined(SQ_HOST64)
  typedef long		sqInt;
  typedef unsigned long	usqInt;
# if (SIZEOF_LONG_LONG != 8)
#   error long long integers are not 64-bits wide?
# endif 
  typedef long long		sqInt;
  typedef unsigned long long	usqInt;

#if defined(SQ_HOST64) && defined(SQ_IMAGE32)
  extern char *sqMemoryBase;
# define SQ_FAKE_MEMORY_OFFSET	16 // (1*1024*1024)	/* nonzero to debug addr xlation */
# define sqMemoryBase		((char *)0)

On 2010-03-01, at 9:56 PM, Ang BeePeng wrote:

> Hi.
> In win32 Squeak VM, I saw localIP as char* while instructionPointer is type
> sqInt. Why is it so? Also, currentBytecode is type sqInt, why is it not
> store as a byte? What is the difference between localIP and
> instructionPointer?
> Thanks.
> Ang Beepeng
> -- 
> View this message in context: http://n4.nabble.com/localIP-instructionPointer-currentBytecode-data-size-tp1574626p1574626.html
> Sent from the Squeak - VM mailing list archive at Nabble.com.

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

More information about the Vm-dev mailing list