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

commits at source.squeak.org commits at source.squeak.org
Fri Oct 11 16:53:11 UTC 2013

Eliot Miranda uploaded a new version of VMMaker to project VM Maker:

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

Name: VMMaker.oscog-eem.450
Author: eem
Time: 11 October 2013, 9:48:56.883 am
UUID: 86e607b5-0e72-4bf7-bda3-064b59b40267
Ancestors: VMMaker.oscog-eem.449

Fix swizzling:
- search the segments in reverse order for the first segment whose
  start is less than or equal to the oop.
- add an assert set in adjustSegmentSwizzlesBy: and cleared in
  collapseSegmentsPostSwizzle that checks that swizzling is done
  only while the swizzle info is valid (numSegments reflects the num
  of segs in the image, not in the loaded system).
- swizzle the freeLists before collapseSegmentsPostSwizzle.

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

Item was added:
+ ----- Method: CObjectAccessor>>first (in category 'accessing') -----
+ first
+ 	^self at: 0!

Item was changed:
  ----- Method: SpurMemoryManager>>initializeObjectMemory: (in category 'initialization') -----
  initializeObjectMemory: bytesToShift
  	"Initialize object memory variables at startup time. Assume endOfMemory is initially set (by the image-reading code) to the end of the last object in the image. Initialization redefines endOfMemory to be the end of the object allocation area based on the total available memory, but reserving some space for forwarding blocks."
  	"Assume: image reader initializes the following variables:
  	<inline: false>
  	| freeListObj |
+ 	self halt.
  	segmentManager adjustSegmentSwizzlesBy: bytesToShift.
  	"image may be at a different address; adjust oops for new location"
  	self adjustAllOopsBy: bytesToShift.
  	segmentManager numSegments > 0 "false if Spur image bootstrap"
  		ifTrue: [specialObjectsOop := segmentManager swizzleObj: specialObjectsOop]
  		ifFalse: [self assert: bytesToShift = 0].
- 	segmentManager collapseSegmentsPostSwizzle.
  	"heavily used special objects"
  	nilObj		:= self splObj: NilObject.
  	falseObj	:= self splObj: FalseObject.
  	trueObj		:= self splObj: TrueObject.
  	"In Cog we insist that nil, true & false are next to each other (Cogit generates tighter
  	 conditional branch code as a result).  In addition, Spur places the free lists and
  	 class table root page immediately following them."
  	self assert: nilObj = newSpaceLimit.
  	self assert: falseObj = (self objectAfter: nilObj).
  	self assert: trueObj = (self objectAfter: falseObj).
  	freeListObj := self objectAfter: trueObj.
  	self classTableRootObj: (self objectAfter: freeListObj).
  	self initializeFreeSpacePostLoad: freeListObj.
+ 	segmentManager collapseSegmentsPostSwizzle.
  	self initializeOldSpaceFirstFree: freeOldSpaceStart. "initializes endOfMemory, freeStart"
  	"lowSpaceThreshold := 0.
  	signalLowSpace := false.
  	remapBufferCount := 0.
  	tenuringThreshold := 2000.  ""tenure all suriving objects if survivor count is over this threshold""
  	growHeadroom := 4*1024*1024. ""four megabytes of headroom when growing""
  	shrinkThreshold := 8*1024*1024. ""eight megabytes of free space before shrinking""
  	""garbage collection statistics""
  	statFullGCs := 0.
  	statFullGCUsecs := 0.
  	statIncrGCs := 0.
  	statIncrGCUsecs := 0.
  	statTenures := 0.
  	statRootTableOverflows := 0.
  	statGrowMemory := 0.
  	statShrinkMemory := 0.
  	forceTenureFlag := 0.
  	gcBiasToGrow := 0.
  	gcBiasToGrowGCLimit := 0.
  	extraRootCount := 0."!

Item was changed:
  ----- Method: SpurMemoryManager>>isValidFreeObject: (in category 'free space') -----
  isValidFreeObject: objOop
  	| chunk |
+ 	^(self addressCouldBeObj: objOop)
+ 	  and: [(self isFreeObject: objOop)
- 	^(self isFreeObject: objOop)
  	  and: [((chunk := (self fetchPointer: self freeChunkNextIndex ofFreeChunk: objOop)) = 0
  		   or: [self isFreeObject: chunk])
  	  and: [(self bytesInObject: objOop) / self allocationUnit < self numFreeLists
  		    or: [((chunk := (self fetchPointer: self freeChunkParentIndex ofFreeChunk: objOop)) = 0
  			   or: [self isFreeObject: chunk])
  			  and: [((chunk := (self fetchPointer: self freeChunkSmallerIndex ofFreeChunk: objOop)) = 0
  				    or: [self isFreeObject: chunk])
  			  and: [(chunk := (self fetchPointer: self freeChunkLargerIndex ofFreeChunk: objOop)) = 0
+ 				    or: [self isFreeObject: chunk]]]]]]]!
- 				    or: [self isFreeObject: chunk]]]]]]!

Item was changed:
  ----- Method: SpurMemoryManager>>unlinkFreeChunk:atIndex: (in category 'free space') -----
  unlinkFreeChunk: chunk atIndex: index
+ 	"Unlink and answer a small chunk from one of the fixed size freeLists"
  	<inline: true>
  	self assert: ((self bytesInObject: chunk) = (index * self allocationUnit)
+ 				and: [index > 1 "a.k.a. (self bytesInObject: chunk) > self allocationUnit"
+ 				and: [(self startOfObject: chunk) = chunk]]).
- 				and: [index > 1 "a.k.a. (self bytesInObject: chunk) > self allocationUnit"]).
  		at: index
  		put: (self
  				fetchPointer: self freeChunkNextIndex
  				ofFreeChunk: chunk).

Item was changed:
  CogClass subclass: #SpurSegmentManager
+ 	instanceVariableNames: 'manager numSegments numSegInfos segments firstSegmentSize canSwizzle'
- 	instanceVariableNames: 'manager numSegments numSegInfos segments firstSegmentSize'
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'VMMaker-SpurMemoryManager'!
  !SpurSegmentManager commentStamp: 'eem 10/6/2013 10:32' prior: 0!
  Instances of SpurSegmentManager manage oldSpace, which is organized as a sequence of segments.  Segments can be obtained from the operating system and returned to the operating system when empty and shrinkage is required.  Segments are kept invisible from the SpurMemoryManager by using "bridge" objects, "fake" pinned objects to bridge the gaps between segments.  A pinned object header occupies the last 16 bytes of each segment, and the pinned object's size is the distance to the start of the next segment.  So when the memory manager enumerates objects it skips over these bridges and memory appears linear.  The constraint is that segments obtained from the operating system must be at a higher address than the first segment.  The maximum size of large objects, being an overflow slot size, should be big enough to bridge the gaps, because in 32-bits the maximum size is 2^32 slots.  In 64-bits the maximum size of large objects is 2^56 slots, or 2^59 bits, which we hope will suffice.
  When an image is written to a snapshot file the second word of the header of the bridge at the end of each segment is replaced by the size of the following segment, the segments are written to the file, and the second word of each bridge is restored.  Hence the length of each segment is derived from the bridge at the end of the preceeding segment.  The length of the first segment is stored in the image header as firstSegmentBytes.  The start of each segment is also derived from the bridge as a delta from the start of the previous segment.  The start of The first segment is stored in the image header as startOfMemory.
  On load all segments are read into one single segment, eliminating the bridge objects, and computing the swizzle distance for each segment, based on where the segments were in memory when the image file was written, and where the coallesced segment ends up on load.  Then the segment is traversed, swizzling pointers by selecting the relevant swizzle for each oop's segment.
  Instance Variables
  	numSegments:		<Integer>
  	segments:			<Array of SpurSegmentInfo>
  	manager:			<SpurMemoryManager>
  	- the number of segments
  	- the start addresses, lengths and offsets to adjust oops on image load, for each segment
  	- the SpurMemoryManager whose oldSpace is managed (simulation only).!

Item was changed:
  ----- Method: SpurSegmentManager>>adjustSegmentSwizzlesBy: (in category 'snapshot') -----
  adjustSegmentSwizzlesBy: firstSegmentShift
  	"Adjust swizzles by firstSegmentShift."
  	<var: 'segInfo' type: 'SpurSegmentInfo *'>
  	| oldBaseAddr |
  	oldBaseAddr := manager memoryBaseForImageRead - firstSegmentShift.
  	0 to: numSegments - 1 do:
  		[:i| | segInfo |
  		 segInfo := self addressOf: (segments at: i).
  			start: segInfo start + oldBaseAddr;
+ 			swizzle: segInfo swizzle - oldBaseAddr].
+ 	canSwizzle := true!
- 			swizzle: segInfo swizzle  - oldBaseAddr"+ firstSegmentShift"]!

Item was changed:
  ----- Method: SpurSegmentManager>>collapseSegmentsPostSwizzle (in category 'snapshot') -----
  	"The image has been loaded, old segments reconstructed, and the
  	  loaded image swizzled into a single contiguous segment.  Collapse
  	  the segments intio one."
  	| bridge |
+ 	canSwizzle := false.
  	firstSegmentSize ifNil: "true when used by SpurBootstrap to transform an image"
  	numSegments := 1.
  	(segments at: 0)
  		start: manager newSpaceLimit;
  		segSize: manager endOfMemory.
  	"finally plant a bridge at the end of the coallesced segment and cut back the
  	 manager's ntion of the end of memory to immediately before the bridge."
  	bridge := manager endOfMemory - manager bridgeSize.
  		initSegmentBridgeWithBytes: manager bridgeSize at: bridge;
  		setEndOfMemory: bridge!

Item was changed:
  ----- Method: SpurSegmentManager>>initialize (in category 'initialization') -----
+ 	numSegments := numSegInfos := 0.
+ 	canSwizzle := false!
- 	numSegments := numSegInfos := 0!

Item was changed:
  ----- Method: SpurSegmentManager>>swizzleObj: (in category 'snapshot') -----
  swizzleObj: objOop
+ 	self assert: canSwizzle.
+ 	numSegments - 1 to: 1 by: -1 do:
- 	1 to: numSegments - 1 do:
+ 		objOop >= (segments at: i) start ifTrue:
+ 			[^objOop + (segments at: i) swizzle]].
+ 	^objOop + (segments at: 0) swizzle!
- 		objOop < (segments at: i) start ifTrue:
- 			[^objOop + (segments at: i - 1) swizzle]].
- 	^objOop + (segments at: numSegments - 1) swizzle!

More information about the Vm-dev mailing list