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

commits at source.squeak.org commits at source.squeak.org
Thu May 1 18:33:33 UTC 2014


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

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

Name: VMMaker.oscog-eem.696
Author: eem
Time: 1 May 2014, 11:30:53.842 am
UUID: 5f0bc2e6-b921-48c2-8a95-86858a10bcac
Ancestors: VMMaker.oscog-eem.695

Slang:
Fix generation of expressions in while forever with break
and do while loops.  Hence rescue compilability of Spur VMs.

Spur:
Remove redundant test from
moveARunOfObjectsStartingAt:upTo:

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

Item was changed:
  ----- Method: CCodeGenerator>>generateDoWhileFalse:on:indent: (in category 'C translation') -----
  generateDoWhileFalse: msgNode on: aStream indent: level
  	"Generate do {stmtList} while(!!(cond))"
  
  	| testStmt receiverWithoutTest |
  	testStmt := msgNode receiver statements last.
  	receiverWithoutTest := TStmtListNode new setStatements: msgNode receiver statements allButLast.
  	aStream nextPutAll: 'do {'; cr.
  	receiverWithoutTest emitCCodeOn: aStream level: level + 1 generator: self.
+ 	aStream tab: level.
- 	level timesRepeat: [ aStream tab ].
  	aStream nextPutAll: '} while(!!('.
+ 	testStmt emitCCodeAsExpressionOn: aStream level: 0 generator: self.
+ 	aStream nextPutAll: '))'!
- 	testStmt emitCCodeOn: aStream level: 0 generator: self.
- 	aStream nextPutAll: '))'.!

Item was changed:
  ----- Method: CCodeGenerator>>generateDoWhileTrue:on:indent: (in category 'C translation') -----
  generateDoWhileTrue: msgNode on: aStream indent: level
  	"Generate do {stmtList} while(cond)"
  
  	| testStmt receiverWithoutTest |
  	testStmt := msgNode receiver statements last.
  	receiverWithoutTest := TStmtListNode new setStatements: msgNode receiver statements allButLast.
  	aStream nextPutAll: 'do {'; cr.
  	receiverWithoutTest emitCCodeOn: aStream level: level + 1 generator: self.
+ 	aStream tab: level.
- 	level timesRepeat: [ aStream tab ].
  	aStream nextPutAll: '} while('.
+ 	testStmt emitCCodeAsExpressionOn: aStream level: 0 generator: self.
+ 	aStream nextPut: $)!
- 	testStmt emitCCodeOn: aStream level: 0 generator: self.
- 	aStream nextPutAll: ')'.!

Item was changed:
  ----- Method: CCodeGenerator>>generateWhileForeverBreakIf:loop:on:indent: (in category 'C translation') -----
  generateWhileForeverBreakIf: breakBoolean loop: msgNode on: aStream indent: level
  	"Generate either of
  		while(1) {stmtListA; if(cond) break; stmtListB}
  		while(1) {stmtListA; if(!!(cond)) break; stmtListB}."
  
  	| testStmt receiverWithoutTest |
  	aStream peekLast ~~ Character tab ifTrue:
  		[aStream tab: level - 1].
  	aStream nextPutAll: 'while (1) {'; cr.
  	testStmt := msgNode receiver statements last.
  	receiverWithoutTest := TStmtListNode new setStatements: msgNode receiver statements allButLast.
  	receiverWithoutTest emitCCodeOn: aStream level: level + 1 generator: self.
  	aStream tab: level + 1; nextPutAll: 'if ('.
  	breakBoolean ifFalse: [aStream nextPut: $!!; nextPut: $(].
+ 	testStmt emitCCodeAsExpressionOn: aStream level: 0 generator: self.
- 	testStmt emitCCodeOn: aStream level: 0 generator: self.
  	breakBoolean ifFalse: [aStream nextPut: $)].
  	aStream nextPutAll: ') break;'; cr.
  	msgNode args first emitCCodeOn: aStream level: level + 1 generator: self.
  	aStream tab: level; nextPut: $}!

Item was changed:
  ----- Method: SpurMemoryManager>>moveARunOfObjectsStartingAt:upTo: (in category 'compaction') -----
  moveARunOfObjectsStartingAt: startAddress upTo: limit 
  	"Move the sequence of movable objects starting at startAddress.  Answer the start
  	 of the next sequence of movable objects after a possible run of unmovable objects,
  	 or the limit, if there are no more movable objects, or 0 if no more compaction can be
  	 done. Compaction is done when the search through the freeList has reached the
  	 address from which objects are being moved from.
  
  	 There are two broad cases to be dealt with here.  One is a run of smallish objects
  	 that can easily be moved into free chunks.  The other is a large object that is unlikely
  	 to fit in the typical free chunk. This second pig needs careful handling; it needs to be
  	 moved to the lowest place it will fit and not cause the scan to skip lots of smaller
  	 free chunks looking in vain for somewhere to put it."
  	| here prevPrevFreeChunk prevFreeChunk thisFreeChunk maxFreeChunk |
  	here := startAddress.
  	prevPrevFreeChunk := prevFreeChunk := 0.
  	thisFreeChunk := maxFreeChunk := firstFreeChunk.
  	[thisFreeChunk ~= 0] whileTrue:
  		[| freeBytes endOfFree nextFree destination hereObj hereObjHeader there moved |
  
  		 [hereObj := self objectStartingAt: here.
  		  hereObjHeader := self atLeastClassIndexHalfHeader: hereObj.
  		  (self isMobileObjectHeader: hereObjHeader)] whileFalse:
  			[here := self addressAfter: hereObj.
  			 here >= limit ifTrue:
  				[^maxFreeChunk >= startAddress ifTrue: [0] ifFalse: [limit]]].
  
  		 freeBytes		:= self bytesInObject: thisFreeChunk.
  		 nextFree		:= self nextInSortedFreeListLink: thisFreeChunk given: prevFreeChunk.
  		 destination	:= self startOfObject: thisFreeChunk.
  		 endOfFree		:= destination + freeBytes.
  		 moved			:= false.
  		 maxFreeChunk	:= maxFreeChunk max: nextFree.
  
  		"move as many objects as will fit in freeBytes..."
  		 [there := self addressAfter: hereObj.
  		  (self isMobileObjectHeader: hereObjHeader)
  		  and: [there - here < (freeBytes - self allocationUnit)
  			    or: [there - here = freeBytes]]] whileTrue:
  			[moved := true.
  			 self mem: destination cp: here y: there - here.
  			 self forward: hereObj to: destination + (hereObj - here).
  			 destination := destination + (there - here).
  			 freeBytes := freeBytes - (there - here).
  			 hereObj := self objectStartingAt: there.
  			 here := there.
  			 hereObjHeader := self atLeastClassIndexHalfHeader: hereObj].
  
  		 moved
  			ifTrue: "need to repair the free list"
  				[| nextNextFree |
  				 nextFree ~= 0 ifTrue:
  					[nextNextFree  := self nextInSortedFreeListLink: nextFree given: thisFreeChunk].
  				 (destination > thisFreeChunk "if false couldn't move anything"
  				  and: [destination < endOfFree]) "if false, filled entire free chunk"
  					ifTrue:
  						[thisFreeChunk := self initFreeChunkWithBytes: endOfFree - destination at: destination.
  						 self inSortedFreeListLink: prevFreeChunk to: thisFreeChunk given: prevPrevFreeChunk.
  						 self inSortedFreeListLink: thisFreeChunk to: nextFree given: prevFreeChunk.
  						 nextFree ~= 0 ifTrue:
  							[self inSortedFreeListLink: nextFree to: nextNextFree given: thisFreeChunk].
  						 prevPrevFreeChunk := prevFreeChunk.
  						 prevFreeChunk := thisFreeChunk.
  						 thisFreeChunk := nextFree]
  					ifFalse:
  						[self inSortedFreeListLink: prevFreeChunk to: nextFree given: prevPrevFreeChunk.
  						 nextFree ~= 0 ifTrue:
  							[self inSortedFreeListLink: nextFree to: nextNextFree given: prevFreeChunk.
  						 thisFreeChunk := nextFree]].
  				 "self checkTraversableSortedFreeList"]
  			ifFalse: "out of space (or immobile object); move on up the free list..."
  				[prevPrevFreeChunk := prevFreeChunk.
  				 prevFreeChunk := thisFreeChunk.
  				 thisFreeChunk := nextFree].
  
  		 (self isMobileObjectHeader: hereObjHeader) ifFalse:
  			[^maxFreeChunk >= startAddress ifTrue: [0] ifFalse: [there]].
  
  		 "Was the loop stopped by a pig? If so, try and find space for it"
+ 		 there - here >= (self averageObjectSizeInBytes * 8) ifTrue: "256b in 32 bit, 512b in 64 bit"
- 		 (there - here >= (self averageObjectSizeInBytes * 8) "256b in 32 bit, 512b in 64 bit"
- 		  and: [self isMobileObject: hereObj]) ifTrue:
  			[| usedChunk |
  			 usedChunk := self tryToMovePig: hereObj at: here end: there.
  			"if it couldn't be moved we need to advance, so always
  			 set here to there whether the pig was moved or not."
  			 here := there.
  			 "In general it's a bad idea to reset the enumeration; it leads to N^2 behaviour
  			  when encountering pigs.  But if the move affected the enumeration this is
  			  simpler than resetting the list pointers."
  			 (usedChunk = prevPrevFreeChunk
  			  or: [usedChunk = prevFreeChunk
  			  or: [usedChunk = thisFreeChunk]]) ifTrue: "a bad idea; leads to N^2 behaviour when encountering pigs"
  				["reset the scan for free space back to the start of the list"
  				 prevPrevFreeChunk := prevFreeChunk := 0.
  				 thisFreeChunk := firstFreeChunk]].
  
  		(there >= limit
  		 or: [maxFreeChunk >= startAddress]) ifTrue:
  			[^maxFreeChunk >= startAddress ifTrue: [0] ifFalse: [there]]].!



More information about the Vm-dev mailing list