[Vm-dev] VM Maker: VMMaker.oscog-eem.273.mcz

commits at source.squeak.org commits at source.squeak.org
Mon Mar 18 20:23:11 UTC 2013


Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.273.mcz

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

Name: VMMaker.oscog-eem.273
Author: eem
Time: 18 March 2013, 1:20:54.297 pm
UUID: 0a8e74b7-9351-45ea-b8a3-56969530c62e
Ancestors: VMMaker.oscog-eem.272

Integrate VMMaker-dtl.302:
A WordArray parameter in the parameter list of a primitive declaration should be declared as (unsigned *) not (usqInt *) in the generated C code. Fix WordArray class>>ccgDeclareCForVar: code generation and provide a unit test.

Also remove redundant type declaration in HostWindowPlugin>>primitiveShowHostWindow:bits:width:height:depth:left:right:top:bottom: which was an ineffective attempt to work around the code generation bug.

Cogit in-image tests:
Fix the facade now that absent-receiver inline caches are
disassembled prettily.
Allow supplying VM config options to pc-mapping tests.
Put VMClass defaultIntegerBaseInDebugger in a class var for quick
flipping between decimal and hex.

=============== Diff against VMMaker.oscog-eem.272 ===============

Item was changed:
  ----- Method: Cogit class>>testPCMappingFor: (in category 'tests') -----
  testPCMappingFor: aCompiledMethod
+ 	^self testPCMappingFor: aCompiledMethod options: #()!
- 	| tuple |
- 	tuple := self cog: aCompiledMethod selector: aCompiledMethod selector.
- 	tuple second testPCMappingForMethod: tuple last!

Item was added:
+ ----- Method: Cogit class>>testPCMappingFor:options: (in category 'tests') -----
+ testPCMappingFor: aCompiledMethod options: optionsDictionaryOrArray
+ 	| tuple |
+ 	tuple := self cog: aCompiledMethod selector: aCompiledMethod selector options: optionsDictionaryOrArray.
+ 	tuple second testPCMappingForMethod: tuple last!

Item was changed:
  ----- Method: Cogit class>>testPCMappingSelect: (in category 'tests') -----
  testPCMappingSelect: aBlock
  	"Test pc mapping both ways using the methods in the current image"
+ 	self testPCMappingSelect: aBlock options: #()!
- 	| cogit coInterpreter |
- 	self initialize.
- 	cogit := self new.
- 	coInterpreter := CurrentImageCoInterpreterFacade new cogit: cogit; yourself.
- 	[cogit
- 			setInterpreter: coInterpreter;
- 			singleStep: true;
- 			initializeCodeZoneFrom: 1024 upTo: coInterpreter memory size]
- 		on: Notification
- 		do: [:ex|
- 			(ex messageText beginsWith: 'cannot find receiver for') ifTrue:
- 				[ex resume: coInterpreter]].
- 	SystemNavigation new allSelect:
- 		[:m| | cm |
- 		(m isQuick not
- 		 and: [aBlock value: m]) ifTrue:
- 			[Transcript nextPut: $.; flush.
- 			 [cm := cogit
- 						cog: (coInterpreter oopForObject: m)
- 						selector: (coInterpreter oopForObject: m selector).
- 			   cm isNil and: [coInterpreter isCogCompiledCodeCompactionCalledFor]] whileTrue:
- 				[cogit methodZone clearCogCompiledCode.
- 				 coInterpreter clearCogCompiledCodeCompactionCalledFor.
- 				 coInterpreter initializeObjectMap].
- 			 cogit testPCMappingForMethod: cm].
- 		 false]!

Item was added:
+ ----- Method: Cogit class>>testPCMappingSelect:options: (in category 'tests') -----
+ testPCMappingSelect: aBlock options: optionsDictionaryOrArray
+ 	"Test pc mapping both ways using the methods in the current image"
+ 	| cogit coInterpreter |
+ 	self initializeWithOptions: (self asOptionsDictionary: optionsDictionaryOrArray).
+ 	cogit := self new.
+ 	coInterpreter := CurrentImageCoInterpreterFacade new cogit: cogit; yourself.
+ 	[cogit
+ 			setInterpreter: coInterpreter;
+ 			singleStep: true;
+ 			initializeCodeZoneFrom: 1024 upTo: coInterpreter memory size]
+ 		on: Notification
+ 		do: [:ex|
+ 			(ex messageText beginsWith: 'cannot find receiver for') ifTrue:
+ 				[ex resume: coInterpreter]].
+ 	SystemNavigation new allSelect:
+ 		[:m| | cm |
+ 		(m isQuick not
+ 		 and: [aBlock value: m]) ifTrue:
+ 			[Transcript nextPut: $.; flush.
+ 			 [cm := cogit
+ 						cog: (coInterpreter oopForObject: m)
+ 						selector: (coInterpreter oopForObject: m selector).
+ 			   cm isNil and: [coInterpreter isCogCompiledCodeCompactionCalledFor]] whileTrue:
+ 				[cogit methodZone clearCogCompiledCode.
+ 				 coInterpreter clearCogCompiledCodeCompactionCalledFor.
+ 				 coInterpreter initializeObjectMap].
+ 			 cogit testPCMappingForMethod: cm].
+ 		 false]!

Item was changed:
  ----- Method: Cogit>>mapFor:bcpc:performUntil:arg: (in category 'method map') -----
  mapFor: cogMethod bcpc: startbcpc performUntil: functionSymbol arg: arg
  	"Machine-code <-> bytecode pc mapping support.  Evaluate functionSymbol
  	 for each mcpc, bcpc pair in the map until the function returns non-zero,
  	 answering that result, or 0 if it fails to.  This works only for frameful methods."
  	<var: #cogMethod type: #'CogBlockMethod *'>
  	<var: #functionSymbol declareC: 'sqInt (*functionSymbol)(char *mcpc, sqInt bcpc, void *arg)'>
  	<var: #arg type: #'void *'>
  	| isInBlock mcpc bcpc endbcpc map mapByte homeMethod aMethodObj result
  	  latestContinuation byte descriptor bsOffset nExts |
  	<var: #descriptor type: #'BytecodeDescriptor *'>
  	<var: #homeMethod type: #'CogMethod *'>
  	self assert: cogMethod stackCheckOffset > 0.
  	"In both CMMethod and CMBlock cases find the start of the map and
  	 skip forward to the bytecode pc map entry for the stack check."
  	cogMethod cmType = CMMethod
  		ifTrue:
  			[isInBlock := false.
  			 homeMethod := self cCoerceSimple: cogMethod to: #'CogMethod *'.
  			 self assert: startbcpc = (coInterpreter startPCOfMethodHeader: homeMethod methodHeader).
  			 map := self mapStartFor: homeMethod.
  			 self assert: ((objectMemory byteAt: map) >> AnnotationShift = IsAbsPCReference
  						 or: [(objectMemory byteAt: map) >> AnnotationShift = IsRelativeCall
  						 or: [(objectMemory byteAt: map) >> AnnotationShift = IsDisplacementX2N]]).
  			 latestContinuation := startbcpc.
  			 aMethodObj := homeMethod methodObject.
  			 endbcpc := (objectMemory byteLengthOf: aMethodObj) - 1.
  			 bsOffset := self bytecodeSetOffsetForHeader: homeMethod methodHeader]
  		ifFalse:
  			[isInBlock := true.
  			 homeMethod := cogMethod cmHomeMethod.
  			 map := self findMapLocationForMcpc: cogMethod asUnsignedInteger + (self sizeof: CogBlockMethod)
  						inMethod: homeMethod.
  			 self assert: map ~= 0.
  			 self assert: ((objectMemory byteAt: map) >> AnnotationShift = HasBytecodePC "fiducial"
  						 or: [(objectMemory byteAt: map) >> AnnotationShift = IsDisplacementX2N]).
  			 [(objectMemory byteAt: map) >> AnnotationShift ~= HasBytecodePC] whileTrue:
  				[map := map - 1].
  			 map := map - 1. "skip fiducial; i.e. the map entry for the pc immediately following the method header."
  			 aMethodObj := homeMethod methodObject.
  			 bcpc := startbcpc - (self blockCreationBytecodeSizeForHeader: homeMethod methodHeader).
  			 bsOffset := self bytecodeSetOffsetForHeader: homeMethod methodHeader.
  			 byte := (objectMemory fetchByte: bcpc ofObject: aMethodObj) + bsOffset.
  			 descriptor := self generatorAt: byte.
  			 endbcpc := self nextBytecodePCFor: descriptor at: bcpc exts: -1 in: aMethodObj].
  	bcpc := startbcpc.
  	mcpc := cogMethod asUnsignedInteger + cogMethod stackCheckOffset.
  	nExts := 0.
  	"The stack check maps to the start of the first bytecode,
  	 the first bytecode being effectively after frame build."
  	result := self perform: functionSymbol
  					with: (self cCoerceSimple: mcpc to: #'char *')
  					with: startbcpc
  					with: arg.
  	result ~= 0 ifTrue:
  		[^result].
  	"Now skip up through the bytecode pc map entry for the stack check." 
  	[(objectMemory byteAt: map) >> AnnotationShift ~= HasBytecodePC] whileTrue:
  		[map := map - 1].
  	map := map - 1.
  	[(mapByte := objectMemory byteAt: map) ~= MapEnd] whileTrue: "defensive; we exit on bcpc"
  		[mapByte >= FirstAnnotation
  			ifTrue:
  				[| annotation nextBcpc |
  				annotation := mapByte >> AnnotationShift.
  				mcpc := mcpc + (mapByte bitAnd: DisplacementMask).
  				(self isPCMappedAnnotation: annotation) ifTrue:
  					[[byte := (objectMemory fetchByte: bcpc ofObject: aMethodObj) + bsOffset.
  					  descriptor := self generatorAt: byte.
  					  isInBlock
  						ifTrue: [bcpc >= endbcpc ifTrue: [^0]]
  						ifFalse:
+ 							[(descriptor isReturn and: [bcpc >= latestContinuation]) ifTrue: [^0].
- 							[(descriptor isReturn and: [bcpc > latestContinuation]) ifTrue: [^0].
  							 (descriptor isBranch or: [descriptor isBlockCreation]) ifTrue:
  								[| targetPC |
  								 targetPC := self latestContinuationPCFor: descriptor at: bcpc exts: nExts in: aMethodObj.
  								 latestContinuation := latestContinuation max: targetPC]].
  					  nextBcpc := self nextBytecodePCFor: descriptor at: bcpc exts: nExts in: aMethodObj.
  					  descriptor isMapped
  					  or: [isInBlock and: [descriptor isMappedInBlock]]] whileFalse:
  						[bcpc := nextBcpc.
  						 nExts := descriptor isExtension ifTrue: [nExts + 1] ifFalse: [0]].
  					"All subsequent bytecodes except backward branches map to the
  					 following bytecode. Backward branches map to themselves other-
  					 wise mapping could cause premature breaking out of loops." 
  					result := self perform: functionSymbol
  									with: (self cCoerceSimple: mcpc to: #'char *')
  									with: ((descriptor isBranch
  										   and: [self isBackwardBranch: descriptor at: bcpc exts: nExts in: aMethodObj])
  											ifTrue: [bcpc]
  											ifFalse: [bcpc + descriptor numBytes])
  									with: arg.
  					 result ~= 0 ifTrue:
  						[^result].
  					 bcpc := nextBcpc.
  					 nExts := descriptor isExtension ifTrue: [nExts + 1] ifFalse: [0]]]
  			ifFalse:
  				[mcpc := mcpc + (mapByte >= DisplacementX2N
  									ifTrue: [mapByte - DisplacementX2N << AnnotationShift]
  									ifFalse: [mapByte])].
  		 map := map - 1].
  	^0!

Item was added:
+ ----- Method: CurrentImageCoInterpreterFacade>>addressCouldBeObj: (in category 'debug support') -----
+ addressCouldBeObj: address
+ 	^(address bitAnd: 3) = 0
+ 	  and: [self addressCouldBeOop: address]!

Item was changed:
  ----- Method: CurrentImageCoInterpreterFacade>>objectForOop: (in category 'private-cacheing') -----
  objectForOop: anOop
  	"This is a keyAtValue: search and so needs speeding up either by a reverse map or a simple cache."
  	^(anOop bitAnd: 3) caseOf: {
  		[0] -> [anOop = cachedOop
  				ifTrue: [cachedObject]
+ 				ifFalse: [cachedObject := objectMap keyAtValue: anOop. "may raise Error"
+ 						cachedOop := anOop. "Dom't assign until accessed without error"
+ 						cachedObject]].
- 				ifFalse: [cachedObject := objectMap keyAtValue: (cachedOop := anOop)]].
  		[1] -> [anOop signedIntFromLong >> 1].
  		[3] -> [anOop signedIntFromLong >> 1] }!

Item was added:
+ ----- Method: CurrentImageCoInterpreterFacade>>unalignedLongAt: (in category 'accessing') -----
+ unalignedLongAt: index 
+ 	^memory unsignedLongAt: index + 1!

Item was changed:
  ----- Method: HostWindowPlugin>>primitiveShowHostWindow:bits:width:height:depth:left:right:top:bottom: (in category 'system primitives') -----
  primitiveShowHostWindow: windowIndex bits: dispBits width: w height: h depth: d
  left: left right: right top: top bottom: bottom
  "Host window analogue of DisplayScreen> primShowRectLeft:right:top:bottom:
  (Interpreter>primitiveShowDisplayRect) which takes the window index, bitmap
  details and the rectangle bounds. Fail if the windowIndex is invalid or the
  platform routine returns false to indicate failure"
  	|ok|
- 	<var: #dispBits type: #'unsigned char *'>
  	self primitive: 'primitiveShowHostWindowRect'
  		parameters: #(SmallInteger WordArray SmallInteger SmallInteger SmallInteger
  SmallInteger SmallInteger SmallInteger SmallInteger).
  
  	"Tell the vm to copy pixel's from dispBits to the screen - this is just
  ioShowDisplay with the extra parameter of the windowIndex integer"
  	ok := self cCode: 'ioShowDisplayOnWindow(dispBits, w, h, d, left, right, top,
  bottom, windowIndex)'.
  	ok ifFalse:[interpreterProxy primitiveFail]!

Item was changed:
  ----- Method: SistaStackToRegisterMappingCogit>>mapFor:bcpc:performUntil:arg: (in category 'method map') -----
  mapFor: cogMethod bcpc: startbcpc performUntil: functionSymbol arg: arg
  	"Machine-code <-> bytecode pc mapping support.  Evaluate functionSymbol
  	 for each mcpc, bcpc pair in the map until the function returns non-zero,
  	 answering that result, or 0 if it fails to.  This works only for frameful methods.
  
  	 Override to add the descriptor as the first argument to function."
  	<var: #cogMethod type: #'CogBlockMethod *'>
  	<var: #functionSymbol declareC: 'sqInt (*functionSymbol)(BytecodeDescriptor * desc, char *mcpc, sqInt bcpc, void *arg)'>
  	<var: #arg type: #'void *'>
  	| isInBlock mcpc bcpc endbcpc map mapByte homeMethod aMethodObj result
  	  latestContinuation byte descriptor bsOffset nExts |
  	<var: #descriptor type: #'BytecodeDescriptor *'>
  	<var: #homeMethod type: #'CogMethod *'>
  	self assert: cogMethod stackCheckOffset > 0.
  	"In both CMMethod and CMBlock cases find the start of the map and
  	 skip forward to the bytecode pc map entry for the stack check."
  	cogMethod cmType = CMMethod
  		ifTrue:
  			[isInBlock := false.
  			 homeMethod := self cCoerceSimple: cogMethod to: #'CogMethod *'.
  			 self assert: startbcpc = (coInterpreter startPCOfMethodHeader: homeMethod methodHeader).
  			 map := self mapStartFor: homeMethod.
  			 self assert: ((objectMemory byteAt: map) >> AnnotationShift = IsAbsPCReference
  						 or: [(objectMemory byteAt: map) >> AnnotationShift = IsRelativeCall
  						 or: [(objectMemory byteAt: map) >> AnnotationShift = IsDisplacementX2N]]).
  			 latestContinuation := startbcpc.
  			 aMethodObj := homeMethod methodObject.
  			 endbcpc := (objectMemory byteLengthOf: aMethodObj) - 1.
  			 bsOffset := self bytecodeSetOffsetForHeader: homeMethod methodHeader]
  		ifFalse:
  			[isInBlock := true.
  			 homeMethod := cogMethod cmHomeMethod.
  			 map := self findMapLocationForMcpc: cogMethod asUnsignedInteger + (self sizeof: CogBlockMethod)
  						inMethod: homeMethod.
  			 self assert: map ~= 0.
  			 self assert: ((objectMemory byteAt: map) >> AnnotationShift = HasBytecodePC "fiducial"
  						 or: [(objectMemory byteAt: map) >> AnnotationShift = IsDisplacementX2N]).
  			 [(objectMemory byteAt: map) >> AnnotationShift ~= HasBytecodePC] whileTrue:
  				[map := map - 1].
  			 map := map - 1. "skip fiducial; i.e. the map entry for the pc immediately following the method header."
  			 aMethodObj := homeMethod methodObject.
  			 bcpc := startbcpc - (self blockCreationBytecodeSizeForHeader: homeMethod methodHeader).
  			 bsOffset := self bytecodeSetOffsetForHeader: homeMethod methodHeader.
  			 byte := (objectMemory fetchByte: bcpc ofObject: aMethodObj) + bsOffset.
  			 descriptor := self generatorAt: byte.
  			 endbcpc := self nextBytecodePCFor: descriptor at: bcpc exts: -1 in: aMethodObj].
  	bcpc := startbcpc.
  	mcpc := cogMethod asUnsignedInteger + cogMethod stackCheckOffset.
  	nExts := 0.
  	"as a hack for collecting counters, remember the prev mcpc in a static variable."
  	prevMapAbsPCMcpc := 0.
  	"The stack check maps to the start of the first bytecode,
  	 the first bytecode being effectively after frame build."
  	result := self perform: functionSymbol
  					with: nil
  					with: (self cCoerceSimple: mcpc to: #'char *')
  					with: startbcpc
  					with: arg.
  	result ~= 0 ifTrue:
  		[^result].
  	"Now skip up through the bytecode pc map entry for the stack check." 
  	[(objectMemory byteAt: map) >> AnnotationShift ~= HasBytecodePC] whileTrue:
  		[map := map - 1].
  	map := map - 1.
  	[(mapByte := objectMemory byteAt: map) ~= MapEnd] whileTrue: "defensive; we exit on bcpc"
  		[mapByte >= FirstAnnotation
  			ifTrue:
  				[| annotation nextBcpc |
  				annotation := mapByte >> AnnotationShift.
  				mcpc := mcpc + (mapByte bitAnd: DisplacementMask).
  				(self isPCMappedAnnotation: annotation) ifTrue:
  					[[byte := (objectMemory fetchByte: bcpc ofObject: aMethodObj) + bsOffset.
  					  descriptor := self generatorAt: byte.
  					  isInBlock
  						ifTrue: [bcpc >= endbcpc ifTrue: [^0]]
  						ifFalse:
+ 							[(descriptor isReturn and: [bcpc >= latestContinuation]) ifTrue: [^0].
- 							[(descriptor isReturn and: [bcpc > latestContinuation]) ifTrue: [^0].
  							 (descriptor isBranch or: [descriptor isBlockCreation]) ifTrue:
  								[| targetPC |
  								 targetPC := self latestContinuationPCFor: descriptor at: bcpc exts: nExts in: aMethodObj.
  								 latestContinuation := latestContinuation max: targetPC]].
  					  nextBcpc := self nextBytecodePCFor: descriptor at: bcpc exts: nExts in: aMethodObj.
  					  descriptor isMapped
  					  or: [isInBlock and: [descriptor isMappedInBlock]]] whileFalse:
  						[bcpc := nextBcpc.
  						 nExts := descriptor isExtension ifTrue: [nExts + 1] ifFalse: [0]].
  					"All subsequent bytecodes except backward branches map to the
  					 following bytecode. Backward branches map to themselves other-
  					 wise mapping could cause premature breaking out of loops." 
  					result := self perform: functionSymbol
  									with: descriptor
  									with: (self cCoerceSimple: mcpc to: #'char *')
  									with: ((self isBackwardBranch: descriptor at: bcpc exts: nExts in: aMethodObj)
  											ifTrue: [bcpc]
  											ifFalse: [bcpc + descriptor numBytes])
  									with: arg.
  					 result ~= 0 ifTrue:
  						[^result].
  					 bcpc := nextBcpc].
  				annotation = IsAbsPCReference ifTrue:
  					[prevMapAbsPCMcpc := mcpc]]
  			ifFalse:
  				[mcpc := mcpc + (mapByte >= DisplacementX2N
  									ifTrue: [mapByte - DisplacementX2N << AnnotationShift]
  									ifFalse: [mapByte])].
  		 map := map - 1].
  	^0!

Item was changed:
  Object subclass: #VMClass
  	instanceVariableNames: ''
+ 	classVariableNames: 'DefaultBase'
- 	classVariableNames: ''
  	poolDictionaries: 'VMBasicConstants'
  	category: 'VMMaker-Support'!
  VMClass class
  	instanceVariableNames: 'timeStamp'!
  
  !VMClass commentStamp: '<historical>' prior: 0!
  I am an abstract superclass for all classes in the VM that want to maintain a source timeStamp.!
  VMClass class
  	instanceVariableNames: 'timeStamp'!

Item was changed:
  ----- Method: VMClass class>>defaultIntegerBaseInDebugger (in category 'debugger') -----
  defaultIntegerBaseInDebugger
+ 	"DefaultBase := 16."
+ 	"DefaultBase := 10."
+ 	DefaultBase isNil ifTrue: [DefaultBase := 16].
+ 	^DefaultBase!
- 	^16!

Item was changed:
  ----- Method: WordArray class>>ccgDeclareCForVar: (in category '*VMMaker-plugin generation') -----
  ccgDeclareCForVar: aSymbolOrString
+ 	"Address of an unsigned 32 bit value, regardless of Smalltalk wordSize"
  
+ 	^'unsigned *', aSymbolOrString!
- 	^'usqInt *', aSymbolOrString!



More information about the Vm-dev mailing list