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

commits at source.squeak.org commits at source.squeak.org
Wed Oct 30 01:45:34 UTC 2013


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

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

Name: VMMaker.oscog-eem.482
Author: eem
Time: 29 October 2013, 6:42:28.087 pm
UUID: cb608c2f-ceb9-41c7-8785-5b451860535c
Ancestors: VMMaker.oscog-eem.481

Integrate the mark phase of SpurMemMgr's global GC with the
stack page tracing scheme.  Refactor markAndTraceAndMaybeFreeStackPages:
into markAndTraceUntracedReachableStackPages &
freeUntracedStackPages to enable this.

Add purging the remembered table and a final scavenge to
eliminateAndFreeForwarders.  Refactor the core scavenge invocation
into doScavenge: to enable this.

Fix StackInterpreter>>checkStackIntegrity which was tracing the
instruction pointer.

Change printing of leaks in checkStackIntegrity to include the FP.

Add transcript output to the simulators to show global GC progress.

Fix off-by-one bug in findSelectorOfMethod:.

Fix printActivationNameFor:receiver:isBlock:firstTemporary: for
anonymous methods (doits).

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

Item was changed:
  ----- Method: CoInterpreter>>checkStackIntegrity (in category 'object memory support') -----
  checkStackIntegrity
  	"Perform an integrity/leak check using the heapMap.  Assume
  	 clearLeakMapAndMapAccesibleObjects has set a bit at each
  	 object's header.  Scan all objects accessible from the stack
  	 checking that every pointer points to a header.  Answer if no
  	 dangling pointers were detected."
  	| ok |
  	<inline: false>
  	<var: #thePage type: #'StackPage *'>
  	<var: #theSP type: #'char *'>
  	<var: #theFP type: #'char *'>
  	<var: #callerFP type: #'char *'>
  	<var: #frameRcvrOffset type: #'char *'>
  	<var: #cogMethod type: #'CogMethod *'>
  	ok := true.
  	0 to: numStackPages - 1 do:
  		[:i| | thePage theSP theFP frameRcvrOffset callerFP oop |
  		thePage := stackPages stackPageAt: i.
  		(stackPages isFree: thePage) ifFalse:
  			[thePage = stackPage
  				ifTrue:
  					[theSP := stackPointer.
  					 theFP := framePointer]
  				ifFalse:
  					[theSP := thePage headSP.
  					 theFP := thePage  headFP].
  			 "Skip the instruction pointer on top of stack of inactive pages."
  			 thePage = stackPage ifFalse:
  				[theSP := theSP + BytesPerWord].
  			 [frameRcvrOffset := self frameReceiverOffset: theFP.
  			  [theSP <= frameRcvrOffset] whileTrue:
  				[oop := stackPages longAt: theSP.
  				 ((objectMemory isNonImmediate: oop) 
  				   and: [(self heapMapAtWord: (self pointerForOop: oop)) = 0]) ifTrue:
+ 					[self printFrameThing: 'object leak in frame temp' andFrame: theFP at: theSP.
- 					[self printFrameThing: 'object leak in frame temp' at: theSP; cr.
  					 ok := false].
  				 theSP := theSP + BytesPerWord].
  			 (self frameHasContext: theFP) ifTrue:
  				[oop := self frameContext: theFP.
  				 ((objectMemory isImmediate: oop) 
  				   or: [(self heapMapAtWord: (self pointerForOop: oop)) = 0]) ifTrue:
+ 					[self printFrameThing: 'object leak in frame ctxt' andFrame: theFP at: theFP + FoxThisContext.
- 					[self printFrameThing: 'object leak in frame ctxt' at: theFP + FoxThisContext; cr.
  					 ok := false].
  				 (oop = objectMemory nilObject or: [objectMemory isContext: oop]) ifFalse:
+ 					[self printFrameThing: 'frame ctxt should be context' andFrame: theFP at: theFP + FoxThisContext.
- 					[self printFrameThing: 'frame ctxt should be context' at: theFP + FoxThisContext; cr.
  					 ok := false]].
  			 (self isMachineCodeFrame: theFP)
  				ifTrue:
  					[| cogMethod |
  					 cogMethod := self mframeHomeMethod: theFP.
  					 (self heapMapAtWord: (self pointerForOop: cogMethod)) = 0 ifTrue:
+ 						[self printFrameThing: 'object leak in mframe mthd' andFrame: theFP at: theFP + FoxMethod.
- 						[self printFrameThing: 'object leak in mframe mthd' at: theFP + FoxMethod; cr.
  						 ok := false]]
  				ifFalse:
  					[oop := self iframeMethod: theFP.
  					 ((objectMemory isImmediate: oop) 
  					   or: [(self heapMapAtWord: (self pointerForOop: oop)) = 0]) ifTrue:
+ 						[self printFrameThing: 'object leak in iframe mthd' andFrame: theFP at: theFP + FoxMethod.
- 						[self printFrameThing: 'object leak in iframe mthd' at: theFP + FoxMethod; cr.
  						 ok := false]].
  			 (callerFP := self frameCallerFP: theFP) ~= 0] whileTrue:
  				[theSP := theFP + FoxCallerSavedIP + BytesPerWord.
  				 theFP := callerFP].
  			 theSP := theFP + FoxCallerSavedIP + BytesPerWord.
  			 [theSP <= thePage baseAddress] whileTrue:
  				[oop := stackPages longAt: theSP.
  				 ((objectMemory isNonImmediate: oop) 
  				   and: [(self heapMapAtWord: (self pointerForOop: oop)) = 0]) ifTrue:
+ 					[self printFrameThing: 'object leak in frame arg' andFrame: theFP at: theSP.
- 					[self printFrameThing: 'object leak in frame arg' at: theSP; cr.
  					 ok := false].
  				 theSP := theSP + BytesPerWord]]].
  	^ok!

Item was added:
+ ----- Method: CogVMSimulator>>printFrameThing:andFrame:at: (in category 'debug printing') -----
+ printFrameThing: name andFrame: theFP at: address
+ 	<var: #theFP type: #'char *'>
+ 	| it |
+ 	<inline: false>
+ 	<var: #name type: #'char *'>
+ 	<var: #address type: #'char *'>
+ 	it := stackPages longAt: address.
+ 	self printHex: address;
+ 		printChar: $:.
+ 	1 to: 12 - (self strlen: name) do: [:i| self printChar: $ ].
+ 	self print: name;
+ 		print: ': ';
+ 		printHex: it.
+ 	it ~= 0 ifTrue:
+ 		[self printChar: $=; printNum: it.
+ 		 (it between: objectMemory startOfMemory and: objectMemory endOfMemory) ifFalse:
+ 			[(cogit lookupAddress: it) ifNotNil:
+ 				[:label| self space; printChar: $(; print: label; printChar: $)]]].
+ 	self print: ' frame: '; printHex: theFP; cr!

Item was added:
+ ----- Method: Spur32BitMMLECoSimulator>>eliminateAndFreeForwarders (in category 'gc - global') -----
+ eliminateAndFreeForwarders
+ 	coInterpreter transcript nextPutAll: 'eliminating forwarders...'; flush.
+ 	^super eliminateAndFreeForwarders!

Item was added:
+ ----- Method: Spur32BitMMLECoSimulator>>freeUnmarkedObjectsNilUnmarkedWeaklingSlotsAndSortAndCoalesceFreeSpace (in category 'gc - global') -----
+ freeUnmarkedObjectsNilUnmarkedWeaklingSlotsAndSortAndCoalesceFreeSpace
+ 	coInterpreter transcript nextPutAll: 'sweeping...'; flush.
+ 	^super freeUnmarkedObjectsNilUnmarkedWeaklingSlotsAndSortAndCoalesceFreeSpace!

Item was added:
+ ----- Method: Spur32BitMMLECoSimulator>>globalGarbageCollect (in category 'gc - global') -----
+ globalGarbageCollect
+ 	self halt.
+ 	^super globalGarbageCollect!

Item was added:
+ ----- Method: Spur32BitMMLECoSimulator>>markObjects (in category 'gc - global') -----
+ markObjects
+ 	coInterpreter transcript nextPutAll: 'marking...'; flush.
+ 	^super markObjects!

Item was added:
+ ----- Method: Spur32BitMMLESimulator>>bestFitCompact (in category 'compaction') -----
+ bestFitCompact
+ 	coInterpreter transcript nextPutAll: 'compacting...'; flush.
+ 	^super bestFitCompact!

Item was added:
+ ----- Method: Spur32BitMMLESimulator>>eliminateAndFreeForwarders (in category 'gc - global') -----
+ eliminateAndFreeForwarders
+ 	coInterpreter transcript nextPutAll: 'eliminating forwarders...'; flush.
+ 	^super eliminateAndFreeForwarders!

Item was added:
+ ----- Method: Spur32BitMMLESimulator>>freeUnmarkedObjectsNilUnmarkedWeaklingSlotsAndSortAndCoalesceFreeSpace (in category 'gc - global') -----
+ freeUnmarkedObjectsNilUnmarkedWeaklingSlotsAndSortAndCoalesceFreeSpace
+ 	coInterpreter transcript nextPutAll: 'sweeping...'; flush.
+ 	^super freeUnmarkedObjectsNilUnmarkedWeaklingSlotsAndSortAndCoalesceFreeSpace!

Item was added:
+ ----- Method: Spur32BitMMLESimulator>>markObjects (in category 'gc - global') -----
+ markObjects
+ 	coInterpreter transcript nextPutAll: 'marking...'; flush.
+ 	^super markObjects!

Item was added:
+ ----- Method: SpurGenerationScavenger>>followRememberedForwardersAndForgetFreeObjects (in category 'gc - global') -----
+ followRememberedForwardersAndForgetFreeObjects
+ 	"Scan the remembered set. Follow any forwarded objects,
+ 	 and remove free objects.  This is for global scan-mark GC."
+ 	| index obj |
+ 	index := 0.
+ 	[index < rememberedSetSize] whileTrue:
+ 		[obj := rememberedSet at: index.
+ 		 (manager isFreeObject: obj) "free; remove by overwriting with last element"
+ 			ifTrue:
+ 				[rememberedSetSize := rememberedSetSize - 1.
+ 				 rememberedSet at: index put: (rememberedSet at: rememberedSetSize)]
+ 			ifFalse:
+ 				[(manager isForwarded: obj) ifTrue:
+ 					[obj := manager followForwarded: obj.
+ 					 manager setIsRememberedOf: obj to: true.
+ 					 rememberedSet at: index put: obj].
+ 				 index := index + 1]]!

Item was changed:
  ----- Method: SpurMemoryManager>>copyAndForward:withBytes:toFreeChunk: (in category 'compaction') -----
  copyAndForward: objOop withBytes: bytes toFreeChunk: freeChunk
  	"Copy and forward objOop to freeChunk, the inner operation in
  	 exact and best fit compact."
  
  	<inline: true>
  	| startOfObj freeObj |
  	startOfObj := self startOfObject: objOop.
  	self mem: freeChunk cp: startOfObj y: bytes.
  	freeObj := freeChunk + (objOop - startOfObj).
+ 	"leave it to followRememberedForwarders to remember..."
+ 	"(self isRemembered: objOop) ifTrue:
+ 		[scavenger remember: freeObj]."
- 	"wait until the next scavenge to unremember o"
- 	(self isRemembered: objOop) ifTrue:
- 		[scavenger remember: freeObj].
  	self forward: objOop to: freeObj!

Item was added:
+ ----- Method: SpurMemoryManager>>doScavenge: (in category 'gc - scavenging') -----
+ doScavenge: tenuringCriterion
+ 	"The inner shell for scavenge, abstrascted out so globalGarbageCollect can use it."
+ 
+ 	scavengeInProgress := true.
+ 	pastSpaceStart := scavenger scavenge: tenuringCriterion.
+ 	self assert: (self
+ 					oop: pastSpaceStart
+ 					isGreaterThanOrEqualTo: scavenger pastSpace start
+ 					andLessThanOrEqualTo: scavenger pastSpace limit).
+ 	freeStart := scavenger eden start.
+ 	self initSpaceForAllocationCheck: (self addressOf: scavenger eden).
+ 	scavengeInProgress := false!

Item was changed:
  ----- Method: SpurMemoryManager>>eliminateAndFreeForwarders (in category 'gc - global') -----
  eliminateAndFreeForwarders
  	"As the final phase of global garbage collect, sweep
  	 the heap to follow forwarders, then free forwarders"
  	| lowestForwarded firstForwarded lastForwarded |
  	self assert: (self isForwarded: nilObj) not.
  	self assert: (self isForwarded: falseObj) not.
  	self assert: (self isForwarded: trueObj) not.
  	self assert: (self isForwarded: hiddenRootsObj) not.
  	(self isForwarded: specialObjectsOop) ifTrue:
  		[specialObjectsOop := self followForwarded: specialObjectsOop].
+ 	scavenger followRememberedForwardersAndForgetFreeObjects.
+ 	self doScavenge: TenureByAge.
  	lowestForwarded := 0.
+ 	"sweep, following forwarders in all live objects, and finding the first forwarder."
  	self allOldSpaceObjectsDo:
  		[:o|
  		(self isForwarded: o)
  			ifTrue:
  				[lowestForwarded = 0 ifTrue:
  					[lowestForwarded := o]]
  			ifFalse:
  				[0 to: (self numPointerSlotsOf: o) - 1 do:
  					[:i| | f |
  					f := self fetchPointer: i ofObject: o.
  					(self isOopForwarded: f) ifTrue:
  						[f := self followForwarded: f.
  						 self assert: ((self isImmediate: f) or: [self isYoung: f]) not.
  						 self storePointerUnchecked: i ofObject: o withValue: f]]]].
  	firstForwarded := lastForwarded := 0.
+ 	"sweep from lowest forwarder, coalescing runs of forwarders."
  	self allOldSpaceObjectsFrom: lowestForwarded do:
  		[:o|
  		(self isForwarded: o)
  			ifTrue:
  				[firstForwarded = 0 ifTrue:
  					[firstForwarded := o].
  				 lastForwarded := o]
  			ifFalse:
  				[firstForwarded ~= 0 ifTrue:
  					[| start bytes |
  					start := self startOfObject: firstForwarded.
  					bytes := (self addressAfter: lastForwarded) - start.
  					self addFreeChunkWithBytes: bytes at: start].
  				 firstForwarded := 0]]!

Item was changed:
  ----- Method: SpurMemoryManager>>markAccessibleObjects (in category 'gc - global') -----
  markAccessibleObjects
  	self assert: self validClassTableRootPages.
  	self assert: segmentManager allBridgesMarked.
  	marking := true.
  	self cCode: [] "for debugging markAndTrace: set (MarkStackRecord := OrderedCollection new)"
  		inSmalltalk: [MarkStackRecord ifNotNil: [MarkStackRecord resetTo: 1]].
  	self markAndTraceObjStack: self markStack andContents: false.
  	self assert: self validClassTableRootPages.
  	self markAndTraceObjStack: self ephemeronQueue andContents: true.
  	self assert: self validClassTableRootPages.
+ 	coInterpreter markAndTraceInterpreterOops: true.
  	self markAndTrace: self freeListsObj.
  	self markAndTrace: hiddenRootsObj.
  	self markAndTrace: self specialObjectsOop.
- 	coInterpreter markAndTraceInterpreterOops: true.
  	self markAndFireEphemerons.
  	marking := false!

Item was changed:
  ----- Method: SpurMemoryManager>>markAndFireEphemerons (in category 'gc - global') -----
  markAndFireEphemerons
  	<returnTypeC: #void>
  	"After the initial scan-mark is complete ephemerons can be processed."
+ 	[coInterpreter markAndTraceUntracedReachableStackPages.
+ 	 self noUnscannedEphemerons ifTrue:
- 	[self noUnscannedEphemerons ifTrue:
  		[^self].
  	 self markInactiveEphemerons ifFalse:
  		[self fireAllUnscannedEphemerons].
  	 self markAllUnscannedEphemerons]
  		repeat!

Item was changed:
  ----- Method: SpurMemoryManager>>numStrongSlotsOf:ephemeronInactiveIf: (in category 'object access') -----
  numStrongSlotsOf: objOop ephemeronInactiveIf: criterion
  	"Answer the number of strong pointer fields in the given object.
  	 Works with CompiledMethods, as well as ordinary objects."
  	<api>
  	<var: 'criterion' declareC: 'int (*criterion)(sqInt key)'>
  	<inline: true>
  	<asmLabel: false>
  	| fmt numSlots  contextSize numLiterals |
  	fmt := self formatOf: objOop.
  	fmt <= self lastPointerFormat ifTrue:
  		[numSlots := self numSlotsOf: objOop.
  		 fmt <= self arrayFormat ifTrue:
  			[^numSlots].
  		 fmt = self indexablePointersFormat ifTrue:
  			[(self isContextNonImm: objOop) ifTrue:
+ 				[coInterpreter setTraceFlagOnContextsFramesPageIfNeeded: objOop.
+ 				 "contexts end at the stack pointer"
+ 				 contextSize := coInterpreter fetchStackPointerOf: objOop.
+ 				 ^CtxtTempFrameStart + contextSize].
- 				["contexts end at the stack pointer"
- 				contextSize := coInterpreter fetchStackPointerOf: objOop.
- 				^CtxtTempFrameStart + contextSize].
  			 ^numSlots].
  		 fmt = self weakArrayFormat ifTrue:
  			[^self fixedFieldsOfClass: (self fetchClassOfNonImm: objOop)].
  		 self assert: fmt = self ephemeronFormat.
  		 ^(criterion isNil or: [self perform: criterion with: (self keyOfEphemeron: objOop)])
  			ifTrue: [numSlots]
  			ifFalse: [0]].
  	fmt = self forwardedFormat ifTrue: [^1].
  	fmt < self firstCompiledMethodFormat ifTrue: [^0]. "no pointers"
  
  	"CompiledMethod: contains both pointers and bytes"
  	numLiterals := coInterpreter literalCountOf: objOop.
  	^numLiterals + LiteralStart!

Item was changed:
  ----- Method: SpurMemoryManager>>scavengingGCTenuringIf: (in category 'gc - scavenging') -----
  scavengingGCTenuringIf: tenuringCriterion
  	"Run the scavenger."
  
  	self assert: remapBufferCount = 0.
  	self assert: (segmentManager numSegments = 0 "true in the spur image bootstrap"
  				or: [scavenger eden limit - freeStart > coInterpreter interpreterAllocationReserveBytes]).
  	self checkFreeSpace.
  	"coInterpreter printCallStackFP: coInterpreter framePointer"
  
  	self runLeakCheckerForFullGC: false.
  	coInterpreter
  		preGCAction: GCModeScavenge;
  		"would prefer this to be in mapInterpreterOops, but
  		 compatibility with ObjectMemory dictates it goes here."
  		flushMethodCacheFrom: startOfMemory to: newSpaceLimit.
  	needGCFlag := false.
  
  	gcStartUsecs := coInterpreter ioUTCMicrosecondsNow.
  
+ 	self doScavenge: tenuringCriterion.
- 	scavengeInProgress := true.
- 	pastSpaceStart := scavenger scavenge: tenuringCriterion.
- 	self assert: (self
- 					oop: pastSpaceStart
- 					isGreaterThanOrEqualTo: scavenger pastSpace start
- 					andLessThanOrEqualTo: scavenger pastSpace limit).
- 	freeStart := scavenger eden start.
- 	self initSpaceForAllocationCheck: (self addressOf: scavenger eden).
- 	scavengeInProgress := false.
  
  	statScavenges := statScavenges + 1.
  	statGCEndUsecs := coInterpreter ioUTCMicrosecondsNow.
  	statSGCDeltaUsecs := statGCEndUsecs - gcStartUsecs.
  	statScavengeGCUsecs := statScavengeGCUsecs + statSGCDeltaUsecs.
  	statRootTableCount := scavenger rememberedSetSize.
  
  	coInterpreter postGCAction: GCModeScavenge.
  	self runLeakCheckerForFullGC: false.
  
  	self checkFreeSpace!

Item was changed:
  ----- Method: StackInterpreter>>checkStackIntegrity (in category 'object memory support') -----
  checkStackIntegrity
  	"Perform an integrity/leak check using the heapMap.  Assume
  	 clearLeakMapAndMapAccesibleObjects has set a bit at each
  	 object's header.  Scan all objects accessible from the stack
  	 checking that every pointer points to a header.  Answer if no
  	 dangling pointers were detected."
  	| ok |
  	<inline: false>
  	<var: #thePage type: #'StackPage *'>
  	<var: #theSP type: #'char *'>
  	<var: #theFP type: #'char *'>
  	<var: #callerFP type: #'char *'>
  	ok := true.
  	0 to: numStackPages - 1 do:
  		[:i| | thePage theSP theFP callerFP oop |
  		thePage := stackPages stackPageAt: i.
  		(stackPages isFree: thePage) ifFalse:
  			[thePage = stackPage
  				ifTrue:
  					[theSP := stackPointer.
  					 theFP := framePointer]
  				ifFalse:
  					[theSP := thePage headSP.
  					 theFP := thePage  headFP].
  			 "Skip the instruction pointer on top of stack of inactive pages."
  			 thePage = stackPage ifFalse:
  				[theSP := theSP + BytesPerWord].
  			 [[theSP <= (theFP + FoxReceiver)] whileTrue:
  				[oop := stackPages longAt: theSP.
  				 ((objectMemory isNonImmediate: oop) 
  				   and: [(self heapMapAtWord: (self pointerForOop: oop)) = 0]) ifTrue:
+ 					[self printFrameThing: 'object leak in frame temp' andFrame: theFP at: theSP.
- 					[self printFrameThing: 'object leak in frame temp' at: theSP; cr.
  					 ok := false].
  				 theSP := theSP + BytesPerWord].
  			 (self frameHasContext: theFP) ifTrue:
  				[oop := self frameContext: theFP.
  				 ((objectMemory isImmediate: oop) 
  				   or: [(self heapMapAtWord: (self pointerForOop: oop)) = 0]) ifTrue:
+ 					[self printFrameThing: 'object leak in frame ctxt' andFrame: theFP at: theFP + FoxThisContext.
- 					[self printFrameThing: 'object leak in frame ctxt' at: theFP + FoxThisContext; cr.
  					 ok := false].
  				 (objectMemory isContext: oop) ifFalse:
+ 					[self printFrameThing: 'frame ctxt should be context' andFrame: theFP at: theFP + FoxThisContext.
- 					[self printFrameThing: 'frame ctxt should be context' at: theFP + FoxThisContext; cr.
  					 ok := false]].
  			 oop := self frameMethod: theFP.
  			 ((objectMemory isImmediate: oop) 
  			   or: [(self heapMapAtWord: (self pointerForOop: oop)) = 0]) ifTrue:
+ 				[self printFrameThing: 'object leak in frame mthd' andFrame: theFP at: theFP + FoxMethod.
- 				[self printFrameThing: 'object leak in frame mthd' at: theFP + FoxMethod; cr.
  				 ok := false].
  			 (callerFP := self frameCallerFP: theFP) ~= 0] whileTrue:
  				[theSP := theFP + FoxCallerSavedIP + BytesPerWord.
  				 theFP := callerFP].
+ 			 theSP := theFP + FoxCallerSavedIP + BytesPerWord.
- 			 theSP := theFP + FoxCallerContext "a.k.a. FoxCallerSavedIP".
  			 [theSP <= thePage baseAddress] whileTrue:
  				[oop := stackPages longAt: theSP.
  				 ((objectMemory isNonImmediate: oop) 
  				   and: [(self heapMapAtWord: (self pointerForOop: oop)) = 0]) ifTrue:
+ 					[self printFrameThing: 'object leak in frame arg' andFrame: theFP at: theSP.
- 					[self printFrameThing: 'object leak in frame arg' at: theSP; cr.
  					 ok := false].
  				 theSP := theSP + BytesPerWord]]].
  	^ok!

Item was changed:
  ----- Method: StackInterpreter>>findSelectorOfMethod: (in category 'debug support') -----
  findSelectorOfMethod: methArg
  	| meth classObj classDict classDictSize methodArray i |
  	(objectMemory addressCouldBeObj: methArg) ifFalse:
  		[^objectMemory nilObject].
  	(objectMemory isForwarded: methArg)
  		ifTrue: [meth := objectMemory followForwarded: methArg]
  		ifFalse: [meth := methArg].
  	 (objectMemory isOopCompiledMethod: meth) ifFalse:
  		[^objectMemory nilObject].
  	classObj := self methodClassOf: meth.
  	(self addressCouldBeClassObj: classObj) ifTrue:
  		[classDict := objectMemory fetchPointer: MethodDictionaryIndex ofObject: classObj.
  		 classDictSize := objectMemory fetchWordLengthOf: classDict.
  		 methodArray := objectMemory fetchPointer: MethodArrayIndex ofObject: classDict.
  		 i := 0.
+ 		 [i < (classDictSize - SelectorStart)] whileTrue:
- 		 [i <= (classDictSize - SelectorStart)] whileTrue:
  			[meth = (objectMemory fetchPointer: i ofObject: methodArray) ifTrue:
  				[^(objectMemory fetchPointer: i + SelectorStart ofObject: classDict)].
  				 i := i + 1]].
  	^objectMemory nilObject!

Item was added:
+ ----- Method: StackInterpreter>>freeUntracedStackPages (in category 'object memory support') -----
+ freeUntracedStackPages
+ 	"Free any untraced stack pages."
+ 	<var: #thePage type: #'StackPage *'>
+ 	<inline: false>
+ 
+ 	0 to: numStackPages - 1 do:
+ 		[:i| | thePage |
+ 		thePage := stackPages stackPageAt: i.
+ 		((stackPages isFree: thePage) not
+ 		 and: [thePage trace = 0]) ifTrue:
+ 			[self assert: (self noMarkedContextsOnPage: thePage).
+ 			 stackPages freeStackPage: thePage].
+ 		self assert: (thePage trace: -1) ~= 0] "Invalidate the trace state for assertion checks"!

Item was changed:
  ----- Method: StackInterpreter>>markAndTraceAndMaybeFreeStackPages: (in category 'object memory support') -----
  markAndTraceAndMaybeFreeStackPages: fullGCFlag
  	"Read markAndTraceStackPages:'s comment.  Finish tracing to-be-traced pages.
  	 Then free any untraced pages."
- 	| thePage foundToBeTracedPage |
  	<var: #thePage type: #'StackPage *'>
  	<inline: false>
  	fullGCFlag ifFalse:
  		[0 to: numStackPages - 1 do:
+ 			[:i| | thePage |
- 			[:i|
  			thePage := stackPages stackPageAt: i.
  			self assert: (thePage trace: -1) ~= 0]. "Invalidate the trace state for assertion checks"
  		^nil].
- 	[foundToBeTracedPage := false.
- 	0 to: numStackPages - 1 do:
- 		[:i|
- 		thePage := stackPages stackPageAt: i.
- 		((stackPages isFree: thePage) not
- 		 and: [thePage trace = 1]) ifTrue:
- 			[foundToBeTracedPage := true.
- 			 thePage trace: 2.
- 			 self markAndTraceStackPage: thePage]].
- 	foundToBeTracedPage] whileTrue.
  
+ 	self markAndTraceUntracedReachableStackPages.
+ 	self freeUntracedStackPages!
- 	0 to: numStackPages - 1 do:
- 		[:i|
- 		thePage := stackPages stackPageAt: i.
- 		((stackPages isFree: thePage) not
- 		 and: [thePage trace = 0]) ifTrue:
- 			[self assert: (self noMarkedContextsOnPage: thePage).
- 			 stackPages freeStackPage: thePage].
- 		self assert: (thePage trace: -1) ~= 0] "Invalidate the trace state for assertion checks"!

Item was added:
+ ----- Method: StackInterpreter>>markAndTraceUntracedReachableStackPages (in category 'object memory support') -----
+ markAndTraceUntracedReachableStackPages
+ 	"Trace any untraced pages"
+ 	| thePage foundToBeTracedPage |
+ 	<var: #thePage type: #'StackPage *'>
+ 	<inline: false>
+ 
+ 	[foundToBeTracedPage := false.
+ 	0 to: numStackPages - 1 do:
+ 		[:i|
+ 		thePage := stackPages stackPageAt: i.
+ 		((stackPages isFree: thePage) not
+ 		 and: [thePage trace = 1]) ifTrue:
+ 			[foundToBeTracedPage := true.
+ 			 thePage trace: 2.
+ 			 self markAndTraceStackPage: thePage]].
+ 	foundToBeTracedPage] whileTrue!

Item was changed:
  ----- Method: StackInterpreter>>printActivationNameFor:receiver:isBlock:firstTemporary: (in category 'debug printing') -----
  printActivationNameFor: aMethod receiver: anObject isBlock: isBlock firstTemporary: maybeMessage
  	| methClass methodSel classObj |
  	<inline: false>
  	isBlock ifTrue:
  		[self print: '[] in '].
  	methClass := self findClassOfMethod: aMethod forReceiver: anObject.
  	methodSel := self findSelectorOfMethod: aMethod.
  	((objectMemory addressCouldBeOop: anObject)
  	 and: [(objectMemory isOopForwarded: anObject) not
  	 and: [self addressCouldBeClassObj: (classObj := objectMemory fetchClassOf: anObject)]])
  		ifTrue:
+ 			[(classObj = methClass or: [methClass isNil "i.e. doits"])
+ 				ifTrue: [self printNameOfClass: classObj count: 5]
- 			[classObj = methClass
- 				ifTrue: [self printNameOfClass: methClass count: 5]
  				ifFalse:
  					[self printNameOfClass: classObj count: 5.
  					 self print: '('.
  					 self printNameOfClass: methClass count: 5.
  					 self print: ')']]
  		ifFalse:
  			[self cCode: '' inSmalltalk: [self halt].
  			 self print: 'INVALID RECEIVER'].
  	self print: '>'.
  	(objectMemory addressCouldBeOop: methodSel)
  		ifTrue:
  			[methodSel = objectMemory nilObject
  				ifTrue: [self print: '?']
  				ifFalse: [self printStringOf: methodSel]]
  		ifFalse: [self print: 'INVALID SELECTOR'].
  	(methodSel = (objectMemory splObj: SelectorDoesNotUnderstand)
  	and: [(objectMemory addressCouldBeObj: maybeMessage)
+ 	and: [(objectMemory fetchClassOfNonImm: maybeMessage) = (objectMemory splObj: ClassMessage)]]) ifTrue:
- 	and: [(objectMemory fetchClassOf: maybeMessage) = (objectMemory splObj: ClassMessage)]]) ifTrue:
  		["print arg message selector"
  		methodSel := objectMemory fetchPointer: MessageSelectorIndex ofObject: maybeMessage.
  		self print: ' '.
  		self printStringOf: methodSel]!

Item was added:
+ ----- Method: StackInterpreter>>printFrameThing:andFrame:at: (in category 'debug printing') -----
+ printFrameThing: name andFrame: theFP at: address
+ 	<var: #theFP type: #'char *'>
+ 	| it len |
+ 	<inline: false>
+ 	<var: #name type: #'char *'>
+ 	<var: #address type: #'char *'>
+ 	it := stackPages longAt: address.
+ 	self printHexPtr: address;
+ 		printChar: $:.
+ 	len := self strlen: name.
+ 	1 to: 12 - len do: [:i| self space].
+ 	self print: name;
+ 		print: ': ';
+ 		printHex: it.
+ 	it ~= 0 ifTrue:
+ 		[self printChar: $=.
+ 		 it = objectMemory nilObject
+ 			ifTrue: [self print: 'nil']
+ 			ifFalse:
+ 				[self printNum: it]].
+ 	self print: ' frame: '; printHex: theFP; cr!

Item was added:
+ ----- Method: StackInterpreterSimulator>>printFrameThing:andFrame:at: (in category 'debug printing') -----
+ printFrameThing: name andFrame: theFP at: address
+ 	<var: #theFP type: #'char *'>
+ 	| it |
+ 	<inline: false>
+ 	<var: #name type: #'char *'>
+ 	<var: #address type: #'char *'>
+ 	it := stackPages longAt: address.
+ 	self printHex: address;
+ 		printChar: $/;
+ 		printNum: (stackPages memIndexFor: address);
+ 		printChar: $:.
+ 	1 to: 12 - (self strlen: name) do: [:i| self printChar: $ ].
+ 	self print: name;
+ 		print: ': ';
+ 		printHex: it.
+ 	it ~= 0 ifTrue:
+ 		[self printChar: $=; printNum: it].
+ 	self print: ' frame: '; printHex: theFP; cr!



More information about the Vm-dev mailing list