[Vm-dev] VM Maker: Cog-eem.140.mcz

commits at source.squeak.org commits at source.squeak.org
Tue Mar 4 22:16:05 UTC 2014


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

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

Name: Cog-eem.140
Author: eem
Time: 4 March 2014, 2:15:46.019 pm
UUID: 6f9b2b72-85e2-4166-9d6b-b489cec9cb11
Ancestors: Cog-eem.139

Revise Spur bootstrap to add Behavior>>isEphemeronClass &
isImmediateClass and define immediate class definitions using
immediateSubclass:, and fix ClassBuilder to support immediate
and ephemeron class definition.

Add single method to bootstrap an image and copy its changes file.

Preserve existing change comment in patched Monticello packages.

=============== Diff against Cog-eem.139 ===============

Item was added:
+ ----- Method: SpurBootstrap class>>BehaviorPROTOTYPEisEphemeronClass (in category 'method prototypes') -----
+ BehaviorPROTOTYPEisEphemeronClass
+ 	"Answer whether the receiver has ephemeral instance variables.  The garbage collector will
+ 	 fire (queue for finalization) any ephemeron whose first instance variable is not referenced
+ 	 other than from the transitive closure of references from ephemerons. Hence referring to
+ 	 an object from the first inst var of an ephemeron will cause the ephemeron to fire when
+ 	 the rest of the system does not refer to the object and that object is ready to be collected.
+ 	 Since references from the remaining inst vars of an ephemeron will not prevent the ephemeron
+ 	 from firing, ephemerons may act as the associations in weak dictionaries such that the value
+ 	 (e.g. properties attached to the key) will not prevent firing when the key is no longer referenced
+ 	 other than from ephemerons.  Ephemerons can therefore be used to implement instance-based
+ 	 pre-mortem finalization."
+ 	^self instSpec = 5!

Item was added:
+ ----- Method: SpurBootstrap class>>BehaviorPROTOTYPEisImmediateClass (in category 'method prototypes') -----
+ BehaviorPROTOTYPEisImmediateClass
+ 	"Answer whether the receiver has immediate instances.  Immediate instances
+ 	 store their value in their object pointer, not in an object body.  Hence immediates
+ 	 take no space and are immutable.  The immediates are distinguished by tag bits
+ 	 in the pointer. They include SmallIntegers and Characters.  Hence in the 32-bit
+ 	 system SmallIntegers are 31-bit signed integers and Characters are 30-bit
+ 	 unsigned character codes."
+ 	^self instSpec = 7!

Item was changed:
  ----- Method: SpurBootstrap class>>BehaviorPROTOTYPEisVariable (in category 'method prototypes') -----
  BehaviorPROTOTYPEisVariable
  	"Answer whether the receiver has indexable variables.
  	 Above Cog Spur the class format is
  		<5 bits inst spec><16 bits inst size>
  	 where the 5-bit inst spec is
  			0	= 0 sized objects (UndefinedObject True False et al)
  			1	= non-indexable objects with inst vars (Point et al)
  			2	= indexable objects with no inst vars (Array et al)
  			3	= indexable objects with inst vars (MethodContext AdditionalMethodState et al)
  			4	= weak indexable objects with inst vars (WeakArray et al)
  			5	= weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
  			6	= unused
  			7	= immediates (SmallInteger, Character)
  			8	= unused
  			9	= 64-bit indexable
  		10-11	= 32-bit indexable (Bitmap)
  		12-15	= 16-bit indexable
  		16-23	= 8-bit indexable
  		24-31	= compiled methods (CompiledMethod)"
  	| instSpec |
  	instSpec := self instSpec.
+ 	^instSpec >= 2 and: [instSpec <= 4 or: [instSpec >= 9]]!
- 	^instSpec >= 2 and: [instSpec ~= 5]!

Item was added:
+ ----- Method: SpurBootstrap class>>BehaviorPROTOTYPEkindOfSubclass (in category 'method prototypes') -----
+ BehaviorPROTOTYPEkindOfSubclass
+ 	"Answer a String that is the keyword that describes the receiver's kind of subclass,
+ 	 either a regular subclass, a variableSubclass, a variableByteSubclass,
+ 	 a variableWordSubclass, a weakSubclass, an ephemeronSubclass or an immediateSubclass.
+ 	 c.f. typeOfClass"
+ 	^self isVariable
+ 		ifTrue:
+ 			[self isBits
+ 				ifTrue:
+ 					[self isBytes
+ 						ifTrue: [' variableByteSubclass: ']
+ 						ifFalse: [' variableWordSubclass: ']]
+ 				ifFalse:
+ 					[self isWeak
+ 						ifTrue: [' weakSubclass: ']
+ 						ifFalse: [' variableSubclass: ']]]
+ 		ifFalse:
+ 			[self isImmediateClass
+ 				ifTrue: [' immediateSubclass: ']
+ 				ifFalse:
+ 					[self isEphemeronClass
+ 						ifTrue: [' ephemeronSubclass: ']
+ 						ifFalse: [' subclass: ']]]!

Item was added:
+ ----- Method: SpurBootstrap class>>BehaviorPROTOTYPEtypeOfClass (in category 'method prototypes') -----
+ BehaviorPROTOTYPEtypeOfClass
+ 	"Answer a symbol uniquely describing the type of the receiver. c.f. kindOfSubclass"
+ 	self isBytes ifTrue:
+ 		[^self instSpec = CompiledMethod instSpec
+ 			ifTrue: [#compiledMethod] "Very special!!"
+ 			ifFalse: [#bytes]].
+ 	(self isWords and: [self isPointers not]) ifTrue:
+ 		[^self instSpec = SmallInteger instSpec
+ 			ifTrue: [#immediate] "Very special!!"
+ 			ifFalse: [#words]].
+ 	self isWeak ifTrue: [^#weak].
+ 	self isVariable ifTrue: [^#variable].
+ 	self isEphemeronClass ifTrue: [^#ephemeron].
+ 	^#normal!

Item was added:
+ ----- Method: SpurBootstrap class>>ClassBuilderPROTOTYPEcomputeFormat:instSize:forSuper:ccIndex: (in category 'method prototypes') -----
+ ClassBuilderPROTOTYPEcomputeFormat: type instSize: newInstSize forSuper: newSuper ccIndex: ccIndex
+ 	"Compute the new format for making oldClass a subclass of newSuper.
+ 	 Answer the format or nil if there is any problem."
+ 	| instSize isVar isWords isPointers isWeak |
+ 	type == #compiledMethod ifTrue:
+ 		[newInstSize > 0 ifTrue:
+ 			[self error: 'A compiled method class cannot have named instance variables'.
+ 			^nil].
+ 		^CompiledMethod format].
+ 	instSize := newInstSize + (newSuper ifNil:[0] ifNotNil:[newSuper instSize]).
+ 	instSize > 65535 ifTrue:
+ 		[self error: 'Class has too many instance variables (', instSize printString,')'.
+ 		^nil].
+ 	type == #normal ifTrue:[isVar := isWeak := false. isWords := isPointers := true].
+ 	type == #bytes ifTrue:[isVar := true. isWords := isPointers := isWeak := false].
+ 	type == #words ifTrue:[isVar := isWords := true. isPointers := isWeak := false].
+ 	type == #variable ifTrue:[isVar := isPointers := isWords := true. isWeak := false].
+ 	type == #weak ifTrue:[isVar := isWeak := isWords := isPointers := true].
+ 	type == #ephemeron ifTrue:[isVar := false. isWeak := isWords := isPointers := true].
+ 	type == #immediate ifTrue:[isVar := isWeak := isPointers := false. isWords := true].
+ 	(isPointers not and: [instSize > 0]) ifTrue:
+ 		[self error: 'A non-pointer class cannot have named instance variables'.
+ 		^nil].
+ 	^self format: instSize variable: isVar words: isWords pointers: isPointers weak: isWeak!

Item was changed:
  ----- Method: SpurBootstrap class>>ClassBuilderPROTOTYPEformat:variable:words:pointers:weak: (in category 'method prototypes') -----
  ClassBuilderPROTOTYPEformat: nInstVars variable: isVar words: isWords pointers: isPointers weak: isWeak
  	"Compute the format for the given instance specfication.
  	 Above Cog Spur the class format is
  		<5 bits inst spec><16 bits inst size>
  	 where the 5-bit inst spec is
+ 			0	= 0 sized objects (UndefinedObject True False et al)
+ 			1	= non-indexable objects with inst vars (Point et al)
+ 			2	= indexable objects with no inst vars (Array et al)
+ 			3	= indexable objects with inst vars (MethodContext AdditionalMethodState et al)
+ 			4	= weak indexable objects with inst vars (WeakArray et al)
+ 			5	= weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
+ 			6	= unused
+ 			7	= immediates (SmallInteger, Character)
+ 			8	= unused
+ 			9	= reserved for 64-bit indexable
+ 		10-11	= 32-bit indexable (Bitmap)
+ 		12-15	= 16-bit indexable
+ 		16-23	= 8-bit indexable
+ 		24-31	= compiled methods (CompiledMethod)"
- 		 0 = 0 sized objects (UndefinedObject True False et al)
- 		 1 = non-indexable objects with inst vars (Point et al)
- 		 2 = indexable objects with no inst vars (Array et al)
- 		 3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
- 		 4 = weak indexable objects with inst vars (WeakArray et al)
- 		 5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
- 		 6,7,8 unused
- 		 9 (?) 64-bit indexable
- 		 10 - 11 32-bit indexable
- 		 12 - 15 16-bit indexable
- 		 16 - 23 byte indexable
- 		 24 - 31 compiled method"
  	| instSpec |
  	instSpec := isWeak
+ 					ifTrue:
+ 						[isVar
+ 							ifTrue: [4]
+ 							ifFalse: [5]]
- 					ifTrue: [4]
  					ifFalse:
  						[isPointers
  							ifTrue:
  								[isVar
  									ifTrue: [nInstVars > 0 ifTrue: [3] ifFalse: [2]]
  									ifFalse: [nInstVars > 0 ifTrue: [1] ifFalse: [0]]]
+ 							ifFalse:
+ 								[isVar
+ 									ifTrue: [isWords ifTrue: [12] ifFalse: [16]]
+ 									ifFalse: [7]]].
- 							ifFalse: [isWords ifTrue: [12] ifFalse: [16]]].
  	^(instSpec bitShift: 16) + nInstVars!

Item was added:
+ ----- Method: SpurBootstrap class>>ClassBuilderPROTOTYPEsuperclass:immediateSubclass:instanceVariableNames:classVariableNames:poolDictionaries:category: (in category 'method prototypes') -----
+ ClassBuilderPROTOTYPEsuperclass: aClass
+ 	immediateSubclass: t instanceVariableNames: f 
+ 	classVariableNames: d poolDictionaries: s category: cat
+ 	"This is the standard initialization message for creating a
+ 	 new immediate class as a subclass of an existing class."
+ 	| env |
+ 	aClass instSize > 0
+ 		ifTrue: [^self error: 'cannot make an immediate subclass of a class with named fields'].
+ 	aClass isVariable
+ 		ifTrue: [^self error: 'cannot make an immediate subclass of a class with indexed instance variables'].
+ 	aClass isPointers
+ 		ifFalse: [^self error: 'cannot make an immediate subclass of a class without pointer fields'].
+ 	"Cope with pre-environment and environment versions. Simplify asap."
+ 	env := (Smalltalk classNamed: #EnvironmentRequest)
+ 				ifNil: [aClass environment]
+ 				ifNotNil: [:erc| erc signal ifNil: [aClass environment]].
+ 	^self 
+ 		name: t
+ 		inEnvironment: env
+ 		subclassOf: aClass
+ 		type: #immediate
+ 		instanceVariableNames: f
+ 		classVariableNames: d
+ 		poolDictionaries: s
+ 		category: cat!

Item was added:
+ ----- Method: SpurBootstrap class>>ClassPROTOTYPEimmediateSubclass:instanceVariableNames:classVariableNames:poolDictionaries:category: (in category 'method prototypes') -----
+ ClassPROTOTYPEimmediateSubclass: t instanceVariableNames: f classVariableNames: d poolDictionaries: s category: cat 
+ 	"This is the standard initialization message for creating a new
+ 	 immediate class as a subclass of an existing class (the receiver)."
+ 	^ClassBuilder new
+ 		superclass: self
+ 		immediateSubclass: t
+ 		instanceVariableNames: f
+ 		classVariableNames: d
+ 		poolDictionaries: s
+ 		category: cat!

Item was added:
+ ----- Method: SpurBootstrap class>>bootstrapImage: (in category 'utilities') -----
+ bootstrapImage: imageFileBaseName
+ 	"SpurBootstrap bootstrapImage: '/Users/eliot/Squeak/Squeak4.5/Squeak4.5-13680'"
+ 	| imageFormat |
+ 	imageFormat := ImageFormat fromFile: imageFileBaseName, '.image'.
+ 	imageFormat requiresClosureSupport ifFalse:
+ 		[self error: 'Can''t bootstrap this image since Spur assumes closure support.'].
+ 	imageFormat requiresSpurSupport ifTrue:
+ 		[self error: 'This image is already in Spur format.'].
+ 	imageFormat is32Bit ifTrue:
+ 		[^SpurBootstrap32 new bootstrapImage: imageFileBaseName].
+ 	self error: '64-bit support and 64-bit generation as-yet-unimplemented'!

Item was added:
+ ----- Method: SpurBootstrap class>>testComputeFormat (in category 'tests') -----
+ testComputeFormat
+ 	"self testComputeFormat"
+ 	#(	(normal 0)
+ 		(bytes 16)
+ 		(words 12)
+ 		(variable 2)
+ 		(weak 4)
+ 		(ephemeron 5)
+ 		(immediate 7)
+ 		(compiledMethod 24)) do:
+ 		[:tuple|
+ 		 [:type :instSpec| | fmt |
+ 		   fmt := [self ClassBuilderPROTOTYPEcomputeFormat: type instSize: 0 forSuper: Object ccIndex: 0]
+ 					on: MessageNotUnderstood
+ 					do: [:ex|
+ 						ex message selector ~~ #format:variable:words:pointers:weak: ifTrue:
+ 							[ex pass].
+ 						self perform: #ClassBuilderPROTOTYPEformat:variable:words:pointers:weak:
+ 							withArguments: ex message arguments].
+ 		   self assert: (fmt >> 16 = instSpec
+ 						or: [type = #compiledMethod and: [fmt = CompiledMethod format]]).
+ 		 ] valueWithArguments: tuple]!

Item was added:
+ ----- Method: SpurBootstrap>>bootstrapImage: (in category 'public access') -----
+ bootstrapImage: imageName
+ 	| dirName baseName dir |
+ 	dirName := FileDirectory dirPathFor: imageName.
+ 	baseName := (imageName endsWith: '.image')
+ 					ifTrue: [FileDirectory baseNameFor: imageName]
+ 					ifFalse: [FileDirectory localNameFor: imageName].
+ 	dir := FileDirectory on: dirName.
+ 	self on: (dir fullNameFor: baseName, '.image').
+ 	[self transform]
+ 		on: Halt
+ 		do: [:ex|
+ 			"suppress halts from the usual suspects (development time halts)"
+ 			(#(fullGC compactImage) includes: ex signalerContext sender selector)
+ 				ifTrue: [ex resume]
+ 				ifFalse: [ex pass]].
+ 	self writeSnapshot: (dir fullNameFor: baseName, '-spur.image')
+ 		ofTransformedImage: newHeap
+ 		headerFlags: oldInterpreter getImageHeaderFlags
+ 		screenSize: oldInterpreter savedWindowSize.
+ 	dir copyFileNamed: (dir fullNameFor: baseName, '.changes')
+ 		toFileNamed: (dir fullNameFor: baseName, '-spur.changes')!

Item was added:
+ ----- Method: SpurBootstrap>>writeSnapshot:ofTransformedImage:headerFlags:screenSize: (in category 'testing') -----
+ writeSnapshot: imageFileName ofTransformedImage: spurHeap headerFlags: headerFlags screenSize: screenSizeInteger
+ 	"The bootstrapped image typically contains a few big free chunks and one huge free chunk.
+ 	 Test snapshot writing and loading by turning the largest non-huge chunks into segment bridges
+ 	 and saving."
+ 	| penultimate ultimate sizes counts barriers sim |
+ 	sim := StackInterpreterSimulator onObjectMemory: spurHeap.
+ 	sim bootstrapping: true.
+ 	spurHeap coInterpreter: sim.
+ 	sim initializeInterpreter: 0;
+ 		setImageHeaderFlagsFrom: headerFlags;
+ 		setDisplayForm: (Form extent: screenSizeInteger >> 16 @ (screenSizeInteger bitAnd: 16rFFFF)).
+ 	spurHeap allOldSpaceEntitiesDo: [:e| penultimate := ultimate. ultimate := e].
+ 	self assert: (spurHeap isFreeObject: penultimate).
+ 	self assert: (spurHeap isSegmentBridge: ultimate).
+ 	sizes := Bag new.
+ 	spurHeap allObjectsInFreeTree: (spurHeap freeLists at: 0) do:
+ 		[:f|
+ 		sizes add: (spurHeap bytesInObject: f)].
+ 	counts := sizes sortedCounts.
+ 	self assert: counts last key = 1. "1 huge chunk"
+ 	counts size > 1
+ 		ifTrue:
+ 			[self assert: ((counts at: counts size - 1) key > 2
+ 						and: [(counts at: counts size - 1) value > 1024]).
+ 			barriers := (1 to: (counts at: counts size - 1) key) collect:
+ 							[:ign| spurHeap allocateOldSpaceChunkOfExactlyBytes: (counts at: counts size - 1) value].
+ 			barriers := barriers, {spurHeap allocateOldSpaceChunkOfExactlyBytes: (spurHeap bytesInObject: penultimate)}]
+ 		ifFalse:
+ 			[barriers := {spurHeap allocateOldSpaceChunkOfExactlyBytes: (spurHeap bytesInObject: penultimate)}].
+ 	spurHeap setEndOfMemory: barriers last.
+ 	spurHeap allOldSpaceEntitiesDo: [:e| penultimate := ultimate. ultimate := e].
+ 	self assert: (spurHeap addressAfter: ultimate) = barriers last.
+ 	spurHeap checkFreeSpace.
+ 	spurHeap runLeakCheckerForFullGC: true.
+ 	spurHeap segmentManager initializeFromFreeChunks: (barriers sort collect: [:b| spurHeap objectStartingAt: b]).
+ 	spurHeap checkFreeSpace.
+ 	spurHeap runLeakCheckerForFullGC: true.
+ 	sim bereaveAllMarriedContextsForSnapshotFlushingExternalPrimitivesIf: true.
+ 	sim imageName: imageFileName.
+ 	sim writeImageFileIO!

Item was added:
+ ----- Method: SpurBootstrapMonticelloPackagePatcher>>immediateClassDefinitionFor:from: (in category 'private-accessing') -----
+ immediateClassDefinitionFor: className from: definitions
+ 	| classDef |
+ 	classDef := definitions detect: [:d| d isClassDefinition and: [d className = className]].
+ 	classDef variables removeAllSuchThat:
+ 		[:varDef|
+ 		 varDef isInstanceVariable and: [varDef name = 'value']].
+ 	classDef instVarNamed: 'type' put: #immediate.
+ 	^MCAddition of: classDef!

Item was changed:
  ----- Method: SpurBootstrapMonticelloPackagePatcher>>modifiedCharacterDefinitionsIn: (in category 'private-accessing') -----
  modifiedCharacterDefinitionsIn: definitions
  	| rewriter |
  	rewriter := RBParseTreeRewriter new.
  	rewriter
  		replace: 'value' with: 'self asInteger';
  		replace: 'value := ``@args' with: 'DELETEME'.
  	^(((definitions select: [:d| d isMethodDefinition and: [d fullClassName = #Character]])
  		collect: [:d| { d. self patchDefinition: d withRewriter: rewriter} ]
  		thenSelect: [:pair| pair first source ~= pair second source])
+ 			collect: [:pair| pair second])!
- 			collect: [:pair| pair second]),
- 	 (definitions
- 		select: [:d| d isClassDefinition and: [d className = #Character]]
- 		thenCollect:
- 			[:d|
- 			 d variables removeAllSuchThat:
- 				[:varDef|
- 				 varDef isInstanceVariable and: [varDef name = 'value']].
- 			 d])!

Item was changed:
  ----- Method: SpurBootstrapMonticelloPackagePatcher>>patch (in category 'patching') -----
  patch
  	"(SpurBootstrapMonticelloPackagePatcher new
+ 			from: '/Users/eliot/Squeak/Squeak4.5-spur/squeakv3-package-cache'
+ 			to: '/Users/eliot/Squeak/Squeak4.5-spur/package-cache')
- 			from: '/Users/eliot/Glue/repositories/nsboot/smalltalk'
- 			to: '/Users/eliot/Glue/repositories/spurnsboot/smalltalk')
  		patch"
  	"(SpurBootstrapMonticelloPackagePatcher new
  			from: '/Users/eliot/Glue/repositories/nsboot/Squeak4.3/squeak-package-cache'
  			to: '/Users/eliot/Glue/repositories/nsboot/Squeak4.3/package-cache')
  		patch"
+ 	(sourceDir exists and: [destDir exists]) ifFalse:
+ 		[self error: 'one or both of the directories don''t exist'].
  	self packagesAndPatches keysAndValuesDo:
  		[:package :patches|
  		 (self filesForPackage: package in: sourceDir) do:
  			[:packageFile|
  			 self patchPackage: packageFile with: patches for: package]]!

Item was changed:
  ----- Method: SpurBootstrapMonticelloPackagePatcher>>patchForPackage:withPatches:snapshot: (in category 'patching') -----
  patchForPackage: package withPatches: patches snapshot: snapshot
  	(package includesClass: Character) ifTrue:
+ 		[patches
+ 			addAll: ((self modifiedCharacterDefinitionsIn: snapshot definitions)
+ 						select:
+ 							[:def|
+ 							 patches noneSatisfy:
+ 								[:addition|
+ 								def isMethodDefinition
+ 								and: [addition definition selector = def selector
+ 								and: [addition definition className = def className
+ 								and: [addition definition classIsMeta = def classIsMeta]]]]]
+ 						thenCollect:
+ 							[:def|
+ 							 ((def source includesSubString: 'DELETEME')
+ 								ifTrue: [MCRemoval]
+ 								ifFalse: [MCAddition]) of: def]);
+ 			add: (self immediateClassDefinitionFor: #Character from: snapshot definitions)].
+ 	(package includesClass: SmallInteger) ifTrue:
+ 		[patches
+ 			add: (self immediateClassDefinitionFor: #SmallInteger from: snapshot definitions)].
- 		[patches addAll: ((self modifiedCharacterDefinitionsIn: snapshot definitions) 
- 							select:
- 								[:def|
- 								 patches noneSatisfy:
- 									[:addition|
- 									def isMethodDefinition
- 									and: [addition definition selector = def selector
- 									and: [addition definition className = def className
- 									and: [addition definition classIsMeta = def classIsMeta]]]]]
- 							thenCollect:
- 								[:def|
- 								 ((def source includesSubString: 'DELETEME')
- 									ifTrue: [MCRemoval]
- 									ifFalse: [MCAddition]) of: def])].
  	^MCPatch operations: patches!

Item was changed:
  ----- Method: SpurBootstrapMonticelloPackagePatcher>>version:withPatches:for: (in category 'patching') -----
  version: version withPatches: patches for: package
  	| snapshot ancestry |
  	snapshot := MCPatcher
  					apply: (self patchForPackage: package withPatches: patches snapshot: version snapshot)
  					to: version snapshot.
  	ancestry := MCWorkingAncestry new addAncestor: version info.
  	^MCVersion
  		package: version package
  		info: (ancestry
  				infoWithName: version info name
  				message:	version info name,
  							' patched for Spur by ',
+ 							(CCodeGenerator new shortMonticelloDescriptionForClass: self class),
+ 							'\\' withCRs,
+ 							version info message)
- 							(CCodeGenerator new shortMonticelloDescriptionForClass: self class))
  		snapshot: snapshot
  		dependencies: {} "punt on computing dependencies; there are't any so far"
  !



More information about the Vm-dev mailing list