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 |
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; #else # if (SIZEOF_LONG_LONG != 8) # error long long integers are not 64-bits wide? # endif typedef long long sqInt; typedef unsigned long long usqInt; #endif #if defined(SQ_HOST64) && defined(SQ_IMAGE32) extern char *sqMemoryBase; # define SQ_FAKE_MEMORY_OFFSET 16 // (1*1024*1024) /* nonzero to debug addr xlation */ #else # define sqMemoryBase ((char *)0) #endif 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 <[hidden email]> Twitter: squeaker68882 Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com =========================================================================== |
Hi, Thank you so much for your detail explanation.
I saw the following in win32 VM interp.c, # define pointerForOop(oop) ((char *)(sqMemoryBase + ((usqInt)(oop)))) ... char* localSP; char* localIP; sqInt currentBytecode; browserPluginInitialiseIfNeeded(); /* begin internalizeIPandSP */ localIP = pointerForOop(instructionPointer); //foo->instructionPointer localSP = pointerForOop(stackPointer); Is it true that char* in bold explain difference in both version? localIP = pointerForOop(instructionPointer); instead of localIP = pointerForOop(foo->instructionPointer); In the bluebook, for example pushReceiverVariableBytecode | fieldIndex | fieldIndex := self extractBits: 12 to: 15 of: currentBytecode. I thought bytecode should be one byte, 8 bits. Why extracting from the second byte? Thanks. Ang Beepeng |
On Tue, Mar 02, 2010 at 12:41:34AM -0800, Ang BeePeng wrote: > > I saw the following in win32 VM interp.c, > > # define pointerForOop(oop) ((char *)(sqMemoryBase + ((usqInt)(oop)))) > > ... > > char* localSP; > char* localIP; > sqInt currentBytecode; > > browserPluginInitialiseIfNeeded(); > /* begin internalizeIPandSP */ > localIP = pointerForOop(instructionPointer); > //foo->instructionPointer > localSP = pointerForOop(stackPointer); > > > Is it true that char* in bold explain difference in both version? > localIP = pointerForOop(instructionPointer); instead of > localIP = pointerForOop(foo->instructionPointer); Yes. You can think of an oop as a 32 bit unsigned-int (for 32-bit object memories, the usual case). Its value represents an offset into the object memory, and it is defined as an usqInt so that an oop value can be stored into a "slot" in the object memory. The actual addressing of object memory is done by bytes, hence the cast to (char *) in converting to memory addresses. This allows addressing individual bytes (of course) and also supports the trick used for small integers; if an "oop" has a 1 in the low order bit, then it cannot be pointing to a valid 32-bit location in the object memory, so it is not really an oop. These "oop values" are used to directly represent small integers. Dave |
In reply to this post by Ang BeePeng
On 2010-03-02, at 12:41 AM, Ang BeePeng wrote: > Is it true that char* in bold explain difference in both version? > localIP = pointerForOop(instructionPointer); instead of This moves the global variable instructionPointer OOPS value into localIP and makes it a memory address. > localIP = pointerForOop(foo->instructionPointer); This move the element instructionPointer from foo into localIP, and makes it a memory address. On the PowerPC this form takes one less assembler instruction than referencing a global. On Intel depending on the compiler it may take less assembler instructions. > > > In the bluebook, for example > > pushReceiverVariableBytecode > | fieldIndex | > fieldIndex := self extractBits: 12 to: 15 of: currentBytecode. > > I thought bytecode should be one byte, 8 bits. Why extracting from the > second byte? That is implementation. Take a look at http://ftp.squeak.org/docs/OOPSLA.Squeak.html and http://stephane.ducasse.free.fr/FreeBooks/CollectiveNBlueBook/Rowledge-Final.pdf > > Thanks. > > Ang Beepeng > > -- > View this message in context: http://n4.nabble.com/localIP-instructionPointer-currentBytecode-data-size-tp1574626p1574737.html > Sent from the Squeak - VM mailing list archive at Nabble.com. -- =========================================================================== John M. McIntosh <[hidden email]> Twitter: squeaker68882 Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com =========================================================================== |
Free forum by Nabble | Edit this page |