[Vm-dev] VM Maker: VMMaker.oscogSPC-eem.2134.mcz

commits at source.squeak.org commits at source.squeak.org
Sat Feb 18 02:11:39 UTC 2017


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

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

Name: VMMaker.oscogSPC-eem.2134
Author: eem
Time: 17 February 2017, 6:10:51.775611 pm
UUID: 06cfcc06-3413-4d67-8701-d97ac0a7dce2
Ancestors: VMMaker.oscogSPC-eem.2133

StackInterpreter:
Fix serious and ancient bug with stack checking and event checking.  The event check piggy backs off the stack check, but the old code would not handle a stack overflow if there was an overflow and an event check at one and the same time, allowing frames to grow down the stack page in cases where there are lots of events (such as profiling).

SpurPlanningCompactor:
Fix bad slip in unmarkObjectsFromFirstFreeObject; it forgot to free the last object in the sequence.

With these two changes the Cadence Glue External Tests run to completion wthout assert fails on 64-bit linux.

=============== Diff against VMMaker.oscogSPC-eem.2133 ===============

Item was removed:
- ----- Method: SpurPlanningCompactor>>findNextMarkedPinnedAfter: (in category 'private') -----
- findNextMarkedPinnedAfter: unpinnedObj
- 	<inline: true>
- 	| nextObj |
- 	self deny: ((manager isPinned: unpinnedObj) and: [manager isMarked: unpinnedObj]).
- 	nextObj := unpinnedObj.
- 	[nextObj := manager oldSpaceObjectAfter: nextObj.
- 	 (self oop: nextObj isGreaterThanOrEqualTo: manager endOfMemory) ifTrue:
- 		[^nil].
- 	 (manager isPinned: nextObj) and: [manager isMarked: nextObj]] whileFalse.
- 	^nextObj!

Item was removed:
- ----- Method: SpurPlanningCompactor>>freeAllUnpinnedObjectsFromObject:toFinger: (in category 'private') -----
- freeAllUnpinnedObjectsFromObject: nextObj toFinger: initialToFinger
- 	"Free all space from toFinger up, preserving only marked pinned objects, clearning their marked bits."
- 	| toFinger nextPinnedObj |
- 	<var: 'toFinger' type: #usqInt>
- 	<var: 'nextPinnedObj' type: #usqInt>
- 	toFinger := initialToFinger.
- 	nextPinnedObj := nextObj.
- 	[[nextPinnedObj >= manager endOfMemory
- 	  or: [(manager isMarked: nextPinnedObj)
- 		  and: [manager isPinned: nextPinnedObj]]] whileFalse:
- 		[nextPinnedObj := manager objectAfter: nextPinnedObj limit: manager endOfMemory].
- 	 nextPinnedObj < manager endOfMemory] whileTrue:
- 		[toFinger < (manager startOfObject: nextPinnedObj) ifTrue:
- 			[manager addFreeChunkWithBytes: (manager startOfObject: nextPinnedObj) - toFinger at: toFinger].
- 		 self unmarkPinned: nextPinnedObj.
- 		 toFinger := manager addressAfter: nextPinnedObj.
- 		 nextPinnedObj := manager oldSpaceObjectAfter: nextPinnedObj].
- 	toFinger < manager endOfMemory ifTrue:
- 		[manager addFreeChunkWithBytes: manager endOfMemory - toFinger at: toFinger]!

Item was removed:
- ----- Method: SpurPlanningCompactor>>unmarkAndScanForFirstUnpinnedObjectFrom: (in category 'compaction') -----
- unmarkAndScanForFirstUnpinnedObjectFrom: initialObject
- 	"Scan from initialObject, unmarking any marked pinned objects, and answering the first mobile or freeable object found, or nil if none."
- 	manager allOldSpaceEntitiesFrom: initialObject do:
- 		[:o|
- 		((manager isMarked: o) and: [manager isPinned: o]) ifFalse:
- 			[^o].
- 		self unmarkPinned: o].
- 	^nil!

Item was removed:
- ----- Method: SpurPlanningCompactor>>unmarkObjectsAfterLastMobileObject (in category 'compaction') -----
- unmarkObjectsAfterLastMobileObject
- 	"Sweep the final immobile heap, freeing and coalescing unmarked and free objects,
- 	 and unmarking all marked objects up to the end of memory."
- 	| startOfFree freeBytes |
- 	freeBytes := 0.
- 	manager allOldSpaceEntitiesFrom: objectAfterLastMobileObject do:
- 		[:o|
- 		self check: o.
- 		(manager isMarked: o)
- 			ifFalse:
- 				[startOfFree ifNil: [startOfFree := manager startOfObject: o].
- 				 freeBytes := freeBytes + (manager bytesInObject: o)]
- 			ifTrue:
- 				[startOfFree ifNotNil:
- 					[manager addFreeChunkWithBytes: freeBytes at: startOfFree.
- 					 startOfFree := nil.
- 					 freeBytes := 0].
- 				 (manager isPinned: o)
- 					ifTrue: [self unmarkPinned: o]
- 					ifFalse: [manager setIsMarkedOf: o to: false]]]!

Item was changed:
  ----- Method: SpurPlanningCompactor>>unmarkObjectsFromFirstFreeObject (in category 'compaction') -----
  unmarkObjectsFromFirstFreeObject
  	"Sweep the final immobile heap, freeing and coalescing unmarked and free objects,
  	 and unmarking all marked objects up to the end of memory."
  	| startOfFree freeBytes |
  	freeBytes := 0.
  	manager allOldSpaceEntitiesFrom: firstFreeObject do:
  		[:o|
  		self check: o.
  		(manager isMarked: o)
  			ifFalse:
  				[startOfFree ifNil: [startOfFree := manager startOfObject: o].
  				 freeBytes := freeBytes + (manager bytesInObject: o)]
  			ifTrue:
  				[startOfFree ifNotNil:
  					[manager addFreeChunkWithBytes: freeBytes at: startOfFree.
  					 startOfFree := nil.
  					 freeBytes := 0].
  				 (manager isPinned: o)
  					ifTrue: [self unmarkPinned: o]
+ 					ifFalse: [manager setIsMarkedOf: o to: false]]].
+ 	startOfFree ifNotNil:
+ 		[manager addFreeChunkWithBytes: freeBytes at: startOfFree].!
- 					ifFalse: [manager setIsMarkedOf: o to: false]]]!

Item was removed:
- ----- Method: SpurPlanningCompactor>>unmarkPinnedObjectsAndFindFirstUnpinnedOrFreeEntityFollowing: (in category 'private') -----
- unmarkPinnedObjectsAndFindFirstUnpinnedOrFreeEntityFollowing: pinnedObj
- 	<inline: true>
- 	| nextObj |
- 	self assert: ((manager isPinned: pinnedObj) and: [manager isMarked: pinnedObj]).
- 	nextObj := pinnedObj.
- 	[self unmarkPinned: nextObj.
- 	 nextObj := manager oldSpaceObjectAfter: nextObj.
- 	 (self oop: nextObj isGreaterThanOrEqualTo: manager endOfMemory) ifTrue:
- 		[^manager endOfMemory].
- 	 (manager isPinned: nextObj) and: [manager isMarked: nextObj]] whileTrue.
- 	^nextObj!

Item was changed:
  ----- Method: SpurSegmentManager>>shrinkObjectMemory: (in category 'growing/shrinking memory') -----
  shrinkObjectMemory: delta
  	"Answer if any shrinkage was achieved."
  	<inline: false>
  	<var: #delta type: #usqInt>
  	| shrinkage emptySeg |
  	<var: #shrinkage type: #usqInt>
  	<var: #emptySeg type: #'SpurSegmentInfo *'>
+ 	manager checkFreeSpace: GCModeFreeSpace.
  	shrinkage := delta.
  	[emptySeg := self findEmptySegNearestInSizeTo: shrinkage.
+ 	 (emptySeg isNil
+ 	  or: [emptySeg segSize > shrinkage]) ifTrue:
+ 		[manager checkFreeSpace: GCModeFreeSpace.
+ 		 ^shrinkage < delta].
+ 	 shrinkage := shrinkage - emptySeg segSize.
+ 	 manager detachFreeObject: (manager objectStartingAt: emptySeg segStart).
+ 	 self removeSegment: emptySeg] repeat!
- 	 emptySeg notNil] whileTrue:
- 		[emptySeg segSize > shrinkage ifTrue:
- 			[^shrinkage < delta].
- 		 shrinkage := shrinkage - emptySeg segSize.
- 		 manager detachFreeObject: (manager objectStartingAt: emptySeg segStart).
- 		 self removeSegment: emptySeg].
- 	^shrinkage < delta!

Item was changed:
  ----- Method: StackInterpreter>>checkForStackOverflow (in category 'message sending') -----
  checkForStackOverflow
+ 	"Check for stack overflow, moving frames to another stack if so.  Since event checking
+ 	 piggy-backs off the stackLimit by setting it to all ones, the check for overflow must be
+ 	 against the real stack limit to find out if overflow has actually occurred."
- 	"Check for stack overflow, moving frames to another stack if so."
  	<inline: true>
+ 	self externalWriteBackHeadFramePointers.
- 	"After checkForInterrupts another event check may have been forced, setting both
- 	 stackLimit and stackPage stackLimit to all ones.  So here we must check against
- 	 the real stackLimit, not the effective stackLimit."
  	stackPointer < stackPage realStackLimit ifTrue:
  		[self handleStackOverflow]!

Item was changed:
  ----- Method: StackInterpreter>>handleStackOverflowOrEventAllowContextSwitch: (in category 'message sending') -----
  handleStackOverflowOrEventAllowContextSwitch: mayContextSwitch
  	"The stackPointer is below the stackLimit.  This is either because of a
  	 stack overflow or the setting of stackLimit to indicate a possible interrupt.
+ 	 Check for stackOverflow and  interrupts anddeal with each appropriately.
- 	 Check for interrupts and stackOverflow and deal with each appropriately.
  	 Answer if a context switch occurred."
- 	| switched |
  	<inline: false>
+ 	self checkForStackOverflow.
  	"If the stackLimit differs from the realStackLimit then the stackLimit
  	 has been set to indicate an event or interrupt that needs servicing."
+ 	stackLimit = stackPage realStackLimit ifTrue:
+ 		[^false].
+ 	^self checkForEventsMayContextSwitch: mayContextSwitch!
- 	stackLimit = stackPage realStackLimit
- 		ifTrue:
- 			[self externalWriteBackHeadFramePointers.
- 			 switched := false]
- 		ifFalse: [switched := self checkForEventsMayContextSwitch: mayContextSwitch].
- 
- 	self checkForStackOverflow.
- 	^switched!

Item was changed:
  ----- Method: StackInterpreter>>sendInvokeCallback:Stack:Registers:Jmpbuf: (in category 'callback support') -----
  sendInvokeCallback: thunkPtr Stack: stackPtr Registers: regsPtr Jmpbuf: jmpBufPtr
  	"Send the 4 argument callback message invokeCallback:stack:registers:jmpbuf:
  	 to Alien class with the supplied args.  The arguments are raw C addresses
  	 and are converted to integer objects on the way."
  	<export: true>
  	| classTag |
  	classTag := self fetchClassTagOfNonImm: (self splObj: ClassAlien).
  	messageSelector := self splObj: SelectorInvokeCallback.
  	argumentCount := 4.
  	(self lookupInMethodCacheSel: messageSelector classTag: classTag) ifFalse:
  	 	[(self lookupOrdinaryNoMNUEtcInClass: (objectMemory classForClassTag: classTag)) ~= 0 ifTrue:
  			[^false]].
  	((self argumentCountOf: newMethod) = 4
  	and: [primitiveFunctionPointer = 0]) ifFalse:
  		[^false].
  	self push: (self splObj: ClassAlien). "receiver"
  	self push: (self positiveMachineIntegerFor: thunkPtr).
  	self push: (self positiveMachineIntegerFor: stackPtr).
  	self push: (self positiveMachineIntegerFor: regsPtr).
  	self push: (self positiveMachineIntegerFor: jmpBufPtr).
  	self ifAppropriateCompileToNativeCode: newMethod selector: messageSelector.
  	self justActivateNewMethod.
  	(self isMachineCodeFrame: framePointer) ifFalse:
  		[self maybeFlagMethodAsInterpreted: newMethod].
- 	self externalWriteBackHeadFramePointers.
  	self checkForStackOverflow.
  	self enterSmalltalkExecutiveFromCallback.
  	"not reached"
  	^true!

Item was changed:
  ----- Method: StackInterpreter>>sendInvokeCallbackContext: (in category 'callback support') -----
  sendInvokeCallbackContext: vmCallbackContext
  	"Send the calllback message to Alien class with the supplied arg(s).  Use either the
  	 1 arg invokeCallbackContext: or the 4 arg invokeCallback:stack:registers:jmpbuf:
  	 message, depending on what selector is installed in the specialObjectsArray.
  	 Note that if invoking the legacy invokeCallback:stack:registers:jmpbuf: we pass the
  	 vmCallbackContext as the jmpbuf argument (see reestablishContextPriorToCallback:).
  	 The arguments are raw C addresses and are converted to integer objects on the way."
  	<export: true>
  	<var: #vmCallbackContext type: #'VMCallbackContext *'>
  	| classTag |
  	classTag := self fetchClassTagOfNonImm: (self splObj: ClassAlien).
  	messageSelector := self splObj: SelectorInvokeCallback.
  	(self lookupInMethodCacheSel: messageSelector classTag: classTag) ifFalse:
  	 	[(self lookupOrdinaryNoMNUEtcInClass: (objectMemory classForClassTag: classTag)) ~= 0 ifTrue:
  			[^false]].
  	primitiveFunctionPointer ~= 0 ifTrue:
  		[^false].
  	self saveCStackStateForCallbackContext: vmCallbackContext.
  	self push: (self splObj: ClassAlien). "receiver"
  	(self argumentCountOf: newMethod) = 4 ifTrue:
  		[self push: (self positiveMachineIntegerFor: vmCallbackContext thunkp asUnsignedInteger).
  		 self push: (self positiveMachineIntegerFor: vmCallbackContext stackp asUnsignedInteger).
  		 self push: (self positiveMachineIntegerFor: vmCallbackContext intregargsp asUnsignedInteger)].
  	self push: (self positiveMachineIntegerFor: vmCallbackContext asUnsignedInteger).
  	self ifAppropriateCompileToNativeCode: newMethod selector: messageSelector.
  	self justActivateNewMethod.
  	(self isMachineCodeFrame: framePointer) ifFalse:
  		[self maybeFlagMethodAsInterpreted: newMethod].
- 	self externalWriteBackHeadFramePointers.
  	self checkForStackOverflow.
  	self enterSmalltalkExecutiveFromCallback.
  	"not reached"
  	^true!



More information about the Vm-dev mailing list