[Vm-dev] VM Maker: VMMaker-dtl.266.mcz

commits at source.squeak.org commits at source.squeak.org
Tue Feb 14 05:46:59 UTC 2012


David T. Lewis uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker-dtl.266.mcz

==================== Summary ====================

Name: VMMaker-dtl.266
Author: dtl
Time: 14 February 2012, 12:45:43.869 am
UUID: d868a20c-7741-49cc-a7f6-2403bc1643ed
Ancestors: VMMaker-dtl.265

VMMaker 4.8.2

Several refactorings to eliminate extra intermediate variables in generated code. The extra intermediate variables had been incorrectly attributed to a slang inlining issue (see commit comment for VMMaker-dtl.264), but root cause was unnecessary dispatching to ObjectMemory.

With these changes, the generated code is equivalent to (or trivially better than) that of VMMaker 4.7.20 prior to Interpreter / ObjectMemory refactoring. Remaining differences are due to variable declaration order and variable renaming artifacts (expected variation, no functional impact).

=============== Diff against VMMaker-dtl.265 ===============

Item was removed:
- ----- Method: Interpreter>>allocateMemory:minimum:imageFile:headerSize: (in category 'image save/restore') -----
- allocateMemory: heapSize minimum: minimumMemory imageFile: fileStream headerSize: headerSize
- 
- 	"Translate to C function call with (case sensitive) camelCase. The purpose of this
- 	method is to document the translation.
- 	The default implementation is sqAllocateMemory(minimumMemory, heapSize). This may
- 	be redefined to make use of the image file and header size parameters for efficient
- 	implementation with mmap().
- 	See CCodeGenerator>>emitDefaultMacrosOn: which specifies a default implementation."
- 
- 	<inline: true>
- 	<returnTypeC: 'char *'>
- 	<var: #fileStream type: 'sqImageFile'>
- 	^ self
- 		allocateMemory: heapSize
- 		Minimum: minimumMemory
- 		ImageFile: fileStream
- 		HeaderSize: headerSize!

Item was changed:
  ----- Method: Interpreter>>internalActivateNewMethod (in category 'message sending') -----
  internalActivateNewMethod
  	| methodHeader newContext tempCount argCount2 needsLarge where |
  	<inline: true>
  
  	methodHeader := self headerOf: newMethod.
  	needsLarge := methodHeader bitAnd: LargeContextBit.
  	(needsLarge = 0 and: [objectMemory freeContexts ~= objectMemory nilContext])
  		ifTrue: [newContext := objectMemory freeContexts.
+ 				objectMemory setFreeContextsAfter: newContext]
- 				objectMemory freeContexts: (objectMemory fetchPointer: 0 ofObject: newContext)]
  		ifFalse: ["Slower call for large contexts or empty free list"
  				self externalizeIPandSP.
  				newContext := objectMemory allocateOrRecycleContext: needsLarge.
  				self internalizeIPandSP].
  	tempCount := (methodHeader >> 19) bitAnd: 16r3F.
  
  	"Assume: newContext will be recorded as a root if necessary by the
  	 call to newActiveContext: below, so we can use unchecked stores."
  	where :=   newContext + objectMemory baseHeaderSize.
  	self longAt: where + (SenderIndex << objectMemory shiftForWord) put: activeContext.
  	self longAt: where + (InstructionPointerIndex << objectMemory shiftForWord)
  		put: (objectMemory integerObjectOf: (((LiteralStart + (self literalCountOfHeader: methodHeader)) * objectMemory bytesPerWord) + 1)).
  	self longAt: where + (StackPointerIndex << objectMemory shiftForWord) put: (objectMemory integerObjectOf: tempCount).
  	self longAt: where + (MethodIndex << objectMemory shiftForWord) put: newMethod.
  	self longAt: where + (ClosureIndex << objectMemory shiftForWord) put: objectMemory nilObj.
  
  	"Copy the receiver and arguments..."
  	argCount2 := argumentCount.
  	0 to: argCount2 do:
  		[:i | self longAt: where + ((ReceiverIndex+i) << objectMemory shiftForWord) put: (self internalStackValue: argCount2-i)].
  
  	"clear remaining temps to nil in case it has been recycled"
  	methodHeader := objectMemory nilObj.  "methodHeader here used just as faster (register?) temp"
  	argCount2+1+ReceiverIndex to: tempCount+ReceiverIndex do:
  		[:i | self longAt: where + (i << objectMemory shiftForWord) put: methodHeader].
  
  	self internalPop: argCount2 + 1.
  	reclaimableContextCount := reclaimableContextCount + 1.
  	self internalNewActiveContext: newContext.
   !

Item was changed:
  ----- Method: Interpreter>>internalJustActivateNewMethod (in category 'message sending') -----
  internalJustActivateNewMethod
+ 	"Activate the new method but *do not* copy receiver or arguments from activeContext."
- 	"Activate the new method but *do not* copy receiver or argumernts from activeContext."
  	| methodHeader initialIP newContext tempCount needsLarge where |
  	<inline: true>
  
  	methodHeader := self headerOf: newMethod.
  	needsLarge := methodHeader bitAnd: LargeContextBit.
  	(needsLarge = 0 and: [objectMemory freeContexts ~= objectMemory  nilContext])
  		ifTrue: [newContext := objectMemory freeContexts.
+ 				objectMemory setFreeContextsAfter: newContext]
- 				objectMemory freeContexts: (objectMemory fetchPointer: 0 ofObject: newContext)]
  		ifFalse: ["Slower call for large contexts or empty free list"
  				newContext := objectMemory allocateOrRecycleContext: needsLarge].
  	initialIP := ((LiteralStart + (self literalCountOfHeader: methodHeader)) * objectMemory bytesPerWord) + 1.
  	tempCount := (methodHeader >> 19) bitAnd: 16r3F.
  
  	"Assume: newContext will be recorded as a root if necessary by the
  	 call to newActiveContext: below, so we can use unchecked stores."
  	where := newContext + objectMemory baseHeaderSize.
  	self longAt: where + (SenderIndex << objectMemory shiftForWord) put: activeContext.
  	self longAt: where + (InstructionPointerIndex << objectMemory shiftForWord) put: (objectMemory integerObjectOf: initialIP).
  	self longAt: where + (StackPointerIndex << objectMemory shiftForWord) put: (objectMemory integerObjectOf: tempCount).
  	self longAt: where + (MethodIndex << objectMemory shiftForWord) put: newMethod.
  
  	"Set the receiver..."
  	self longAt: where + (ReceiverIndex << objectMemory shiftForWord) put: receiver.
  
  	"clear all args and temps to nil in case it has been recycled"
  	needsLarge := objectMemory nilObj.  "needsLarge here used just as faster (register?) temp"
  	ReceiverIndex + 1 to: tempCount + ReceiverIndex do:
  		[:i | self longAt: where + (i << objectMemory shiftForWord) put: needsLarge].
  	reclaimableContextCount := reclaimableContextCount + 1.
  
  	activeContext := newContext.!

Item was changed:
  ----- Method: Interpreter>>mapInterpreterOops (in category 'object memory support') -----
  mapInterpreterOops
  	"Map all oops in the interpreter's state to their new values 
  	during garbage collection or a become: operation."
  	"Assume: All traced variables contain valid oops."
  	| oop |
+ 	objectMemory mapRootObjects.
- 	objectMemory nilObj: (objectMemory remap: objectMemory nilObj).
- 	objectMemory falseObj: (objectMemory remap: objectMemory falseObj).
- 	objectMemory trueObj: (objectMemory remap: objectMemory trueObj).
- 	objectMemory specialObjectsOop: (objectMemory remap: objectMemory specialObjectsOop).
  	compilerInitialized
  		ifFalse: [stackPointer := stackPointer - activeContext. "*rel to active"
  			activeContext := objectMemory remap: activeContext.
  			stackPointer := stackPointer + activeContext. "*rel to active"
  			theHomeContext := objectMemory remap: theHomeContext].
  	instructionPointer := instructionPointer - method. "*rel to method"
  	method := objectMemory remap: method.
  	instructionPointer := instructionPointer + method. "*rel to method"
  	receiver := objectMemory remap: receiver.
  	messageSelector := objectMemory remap: messageSelector.
  	newMethod := objectMemory remap: newMethod.
  	methodClass := objectMemory remap: methodClass.
  	lkupClass := objectMemory remap: lkupClass.
  	receiverClass := objectMemory remap: receiverClass.
  	1 to: objectMemory remapBufferCount do: [:i | 
  			oop := objectMemory remapBuffer at: i.
  			(objectMemory isIntegerObject: oop)
  				ifFalse: [objectMemory remapBuffer at: i put: (objectMemory remap: oop)]].
  
  	"Callback support - trace suspended callback list"
  	1 to: jmpDepth do:[:i|
  		oop := suspendedCallbacks at: i.
  		(objectMemory isIntegerObject: oop) 
  			ifFalse:[suspendedCallbacks at: i put: (objectMemory remap: oop)].
  		oop := suspendedMethods at: i.
  		(objectMemory isIntegerObject: oop) 
  			ifFalse:[suspendedMethods at: i put: (objectMemory remap: oop)].
  	].
  !

Item was changed:
  ----- Method: Interpreter>>readImageFromFile:HeapSize:StartingAt: (in category 'image save/restore') -----
  readImageFromFile: f HeapSize: desiredHeapSize StartingAt: imageOffset
  	"Read an image from the given file stream, allocating the given amount of memory to its object heap. Fail if the image has an unknown format or requires more than the given amount of memory."
  	"Details: This method detects when the image was stored on a machine with the opposite byte ordering from this machine and swaps the bytes automatically. Furthermore, it allows the header information to start 512 bytes into the file, since some file transfer programs for the Macintosh apparently prepend a Mac-specific header of this size. Note that this same 512 bytes of prefix area could also be used to store an exec command on Unix systems, allowing one to launch Smalltalk by invoking the image name as a command."
  	"This code is based on C code by Ian Piumarta and Smalltalk code by Tim Rowledge. Many thanks to both of you!!!!"
  
  	| swapBytes headerStart headerSize dataSize oldBaseAddr minimumMemory memStart bytesRead bytesToShift heapSize |
  	<var: #f type: 'sqImageFile '>
  	<var: #desiredHeapSize type: 'usqInt'>
  	<var: #headerStart type: 'squeakFileOffsetType '>
  	<var: #dataSize type: 'size_t '>
  	<var: #imageOffset type: 'squeakFileOffsetType '>
  
  	swapBytes := self checkImageVersionFrom: f startingAt: imageOffset.
  	headerStart := (self sqImageFilePosition: f) - objectMemory bytesPerWord.  "record header start position"
  
  	headerSize			:= self getLongFromFile: f swap: swapBytes.
  	dataSize			:= self getLongFromFile: f swap: swapBytes.
  	oldBaseAddr		:= self getLongFromFile: f swap: swapBytes.
  	objectMemory specialObjectsOop: (self getLongFromFile: f swap: swapBytes).
  	objectMemory lastHash: (self getLongFromFile: f swap: swapBytes).
  	savedWindowSize	:= self getLongFromFile: f swap: swapBytes.
  	fullScreenFlag		:= self oldFormatFullScreenFlag: (self getLongFromFile: f swap: swapBytes).
  	extraVMMemory	:= self getLongFromFile: f swap: swapBytes.
  
  	objectMemory lastHash = 0 ifTrue: [
  		"lastHash wasn't stored (e.g. by the cloner); use 999 as the seed"
  		objectMemory lastHash: 999].
  
  	"decrease Squeak object heap to leave extra memory for the VM"
  	heapSize := self cCode: 'reserveExtraCHeapBytes(desiredHeapSize, extraVMMemory)'.
  
  	"compare memory requirements with availability".
  	minimumMemory := dataSize + 100000.  "need at least 100K of breathing room"
  	heapSize < minimumMemory ifTrue: [
  		self insufficientMemorySpecifiedError].
  
  	"allocate a contiguous block of memory for the Squeak heap"
+ 	(objectMemory allocateMemory: heapSize
- 	objectMemory memory: (self
- 		allocateMemory: heapSize
  		minimum: minimumMemory
  		imageFile: f
+ 		headerSize: headerSize) = nil ifTrue: [self insufficientMemoryAvailableError].
- 		headerSize: headerSize).
- 	objectMemory memory = nil ifTrue: [self insufficientMemoryAvailableError].
  
  	memStart := objectMemory startOfMemory.
  	objectMemory memoryLimit: (memStart + heapSize) - 24.  "decrease memoryLimit a tad for safety"
  	objectMemory endOfMemory: memStart + dataSize.
  
  	"position file after the header"
  	self sqImageFile: f Seek: headerStart + headerSize.
  
  	"read in the image in bulk, then swap the bytes if necessary"
  	bytesRead := self
  		sqImage: (self pointerForOop: objectMemory memory)
  		read: f
  		size: (self cCode: 'sizeof(unsigned char)')
  		length: dataSize.
  	bytesRead ~= dataSize ifTrue: [self unableToReadImageError].
  
  	objectMemory headerTypeBytes at: 0 put: objectMemory bytesPerWord * 2.	"3-word header (type 0)"	
  	objectMemory headerTypeBytes at: 1 put: objectMemory bytesPerWord.		"2-word header (type 1)"
  	objectMemory headerTypeBytes at: 2 put: 0.					"free chunk (type 2)"	
  	objectMemory headerTypeBytes at: 3 put: 0.					"1-word header (type 3)"
  
  	swapBytes ifTrue: [self reverseBytesInImage].
  
  	"compute difference between old and new memory base addresses"
  	bytesToShift := memStart - oldBaseAddr.
  	self initializeInterpreter: bytesToShift.  "adjusts all oops to new location"
  	self isBigEnder. "work out the machine endianness and cache the answer"
  	
  	(self imageFormatInitialVersion bitAnd: 1) = 1
  		ifTrue: ["Low order bit set, indicating that the image was saved from
  			a StackInterpreter (Cog) VM. Storage of all Float objects must be
  			returned to older object memory format."
  			self normalizeFloatOrderingInImage].
   
  	^ dataSize
  !

Item was added:
+ ----- Method: ObjectMemory>>allocateMemory:minimum:imageFile:headerSize: (in category 'image save/restore') -----
+ allocateMemory: heapSize minimum: minimumMemory imageFile: fileStream headerSize: headerSize
+ 
+ 	"Translate to C function call with (case sensitive) camelCase. The purpose of this
+ 	method is to document the translation.
+ 	The default implementation is sqAllocateMemory(minimumMemory, heapSize). This may
+ 	be redefined to make use of the image file and header size parameters for efficient
+ 	implementation with mmap().
+ 	See CCodeGenerator>>emitDefaultMacrosOn: which specifies a default implementation."
+ 
+ 	<inline: true>
+ 	<returnTypeC: 'char *'>
+ 	<var: #fileStream type: 'sqImageFile'>
+ 	^ memory := self
+ 		allocateMemory: heapSize
+ 		Minimum: minimumMemory
+ 		ImageFile: fileStream
+ 		HeaderSize: headerSize!

Item was added:
+ ----- Method: ObjectMemory>>mapRootObjects (in category 'gc -- compaction') -----
+ mapRootObjects
+ 	"Remap pointers for root objects that may contains pointers to a remapped memory range"
+ 	nilObj := self remap: nilObj.
+ 	falseObj := self remap: falseObj.
+ 	trueObj := self remap: trueObj.
+ 	specialObjectsOop := self remap: specialObjectsOop.
+ !

Item was added:
+ ----- Method: ObjectMemory>>setFreeContextsAfter: (in category 'allocation') -----
+ setFreeContextsAfter: newContext
+ 	freeContexts := self fetchPointer: 0 ofObject: newContext
+ !

Item was changed:
  ----- Method: VMMaker class>>versionString (in category 'version testing') -----
  versionString
  
  	"VMMaker versionString"
  
+ 	^'4.8.2'!
- 	^'4.8.1'!



More information about the Vm-dev mailing list