[Vm-dev] VM Maker: VMMaker-dtl.396.mcz

commits at source.squeak.org commits at source.squeak.org
Mon Apr 16 04:02:11 UTC 2018


David T. Lewis uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker-dtl.396.mcz

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

Name: VMMaker-dtl.396
Author: dtl
Time: 16 April 2018, 12:01:41.565 am
UUID: 4692f226-29a6-4aaf-b6ce-5cb5d5e5fb74
Ancestors: VMMaker-dtl.395

VMMaker 4.16.5
Fix declararations for installPrimitive:at: and installPrimitive:from:at: that may have caused errors in primitive table initialization for old image support.
Resolve missing messages for StackInterpreter (not yet working).
Depends on platform updates for sqMemoryAccess.h, requires SVN 3764 or higher.

=============== Diff against VMMaker-dtl.395 ===============

Item was changed:
  Object subclass: #CCodeGenerator
+ 	instanceVariableNames: 'structClasses translationDict inlineList constants variables variableDeclarations scopeStack methods macros apiMethods preparedMethodList variablesSetCache headerFiles globalVariableUsage useSymbolicConstants generateDeadCode doNotRemoveMethodList asArgumentTranslationDict receiverDict vmClass currentMethod logger declareMethodsStatic permitMethodPruning pools abstractDeclarations uncheckedAbstractMethods selectorTranslations breakSrcInlineSelector breakDestInlineSelector inlineReturnTypes'
- 	instanceVariableNames: 'translationDict inlineList constants variables variableDeclarations scopeStack methods macros apiMethods preparedMethodList variablesSetCache headerFiles globalVariableUsage useSymbolicConstants generateDeadCode doNotRemoveMethodList asArgumentTranslationDict receiverDict vmClass currentMethod logger declareMethodsStatic permitMethodPruning pools abstractDeclarations uncheckedAbstractMethods selectorTranslations breakSrcInlineSelector breakDestInlineSelector inlineReturnTypes'
  	classVariableNames: 'UseRightShiftForDivide'
  	poolDictionaries: ''
  	category: 'VMMaker-Translation to C'!
  
  !CCodeGenerator commentStamp: 'tpr 5/2/2003 14:30' prior: 0!
  This class oversees the translation of a subset of Smalltalk to C, allowing the comforts of Smalltalk during development and the efficiency and portability of C for the resulting interpreter.  
  See VMMaker for more useful info!

Item was changed:
  ----- Method: CCodeGenerator>>emitCTypesOn: (in category 'C code generator') -----
  emitCTypesOn: aStream 
  	"Store local type declarations on the given stream."
+ 	structClasses ifNotNil:
+ 		[structClasses do:
- 	vmClass ifNotNil:
- 		[vmClass ancilliaryStructClasses do:
  			[:structClass|
+ 			(structClass isAbstract not
+ 			 and: [vmClass shouldGenerateTypedefFor: structClass]) ifTrue:
- 			(vmClass shouldGenerateTypedefFor: structClass) ifTrue:
  				[structClass printTypedefOn: aStream.
  				 aStream cr; cr]]]!

Item was added:
+ ----- Method: CCodeGenerator>>extractTypeFor:fromDeclaration: (in category 'utilities') -----
+ extractTypeFor: aVariable fromDeclaration: aVariableDeclaration
+ 	"Eliminate inessentials from aVariableDeclaration to answer a C type without the variable,
+ 	 or initializations etc"
+ 	| decl |
+ 	decl := aVariableDeclaration.
+ 	(decl beginsWith: 'static') ifTrue:
+ 		[decl := decl allButFirst: 6].
+ 	(decl indexOf: $= ifAbsent: []) ifNotNil:
+ 		[:index| decl := decl copyFrom: 1 to: index - 1].
+ 	decl := decl copyReplaceAll: aVariable with: '' tokenish: [:ch| ch = $_ or: [ch isAlphaNumeric]].
+ 	^self baseTypeForType: decl!

Item was added:
+ ----- Method: CCodeGenerator>>generateAsIntegerPtr:on:indent: (in category 'C translation') -----
+ generateAsIntegerPtr: msgNode on: aStream indent: level
+ 	"Generate the C code for this message onto the given stream."
+ 
+ 	aStream nextPutAll:'((sqIntptr_t)'.
+ 	self emitCExpression: msgNode receiver on: aStream.
+ 	aStream nextPut: $)!

Item was added:
+ ----- Method: CCodeGenerator>>generateAsLong:on:indent: (in category 'C translation') -----
+ generateAsLong: msgNode on: aStream indent: level
+ 	"Generate the C code for this message onto the given stream."
+ 
+ 	aStream nextPutAll:'((long)'.
+ 	self emitCExpression: msgNode receiver on: aStream.
+ 	aStream nextPut: $)!

Item was added:
+ ----- Method: CCodeGenerator>>generateAsUnsignedIntegerPtr:on:indent: (in category 'C translation') -----
+ generateAsUnsignedIntegerPtr: msgNode on: aStream indent: level
+ 	"Generate the C code for this message onto the given stream."
+ 
+ 	aStream nextPutAll:'((usqIntptr_t)'.
+ 	self emitCExpression: msgNode receiver on: aStream.
+ 	aStream nextPut: $)!

Item was added:
+ ----- Method: CCodeGenerator>>generateAsUnsignedLong:on:indent: (in category 'C translation') -----
+ generateAsUnsignedLong: msgNode on: aStream indent: level
+ 	"Generate the C code for this message onto the given stream."
+ 
+ 	aStream nextPutAll:'((unsigned long)'.
+ 	self emitCExpression: msgNode receiver on: aStream.
+ 	aStream nextPut: $)!

Item was added:
+ ----- Method: CCodeGenerator>>generateAsUnsignedLongLong:on:indent: (in category 'C translation') -----
+ generateAsUnsignedLongLong: msgNode on: aStream indent: level
+ 	"Generate the C code for this message onto the given stream."
+ 
+ 	aStream nextPutAll:'((unsigned long long)'.
+ 	self emitCExpression: msgNode receiver on: aStream.
+ 	aStream nextPut: $)!

Item was added:
+ ----- Method: CCodeGenerator>>generateAsVoidPointer:on:indent: (in category 'C translation') -----
+ generateAsVoidPointer: msgNode on: aStream indent: level
+ 	"Generate the C code for this message onto the given stream."
+ 
+ 	aStream nextPutAll: '((void *)'.
+ 	self emitCExpression: msgNode receiver on: aStream.
+ 	aStream nextPut: $)!

Item was changed:
  ----- Method: CCodeGenerator>>initializeCTranslationDictionary (in category 'C translation') -----
  initializeCTranslationDictionary 
  	"Initialize the dictionary mapping message names to actions for C code generation."
  
  	| pairs |
  	translationDict := Dictionary new: 200.
  	pairs := #(
  	#&				#generateAnd:on:indent:
  	#|				#generateOr:on:indent:
  	#and:			#generateSequentialAnd:on:indent:
  	#or:			#generateSequentialOr:on:indent:
  	#not			#generateNot:on:indent:
  
  	#+				#generatePlus:on:indent:
  	#-				#generateMinus:on:indent:
  	#negated		#generateNegated:on:indent:
  	#*				#generateTimes:on:indent:
  	#/				#generateDivide:on:indent:
  	#//				#generateDivide:on:indent:
  	#\\				#generateModulo:on:indent:
  	#<<			#generateShiftLeft:on:indent:
  	#>>			#generateShiftRight:on:indent:
  	#min:			#generateMin:on:indent:
  	#max:			#generateMax:on:indent:
  	#between:and:	#generateBetweenAnd:on:indent:
  
  	#bitAnd:		#generateBitAnd:on:indent:
  	#bitOr:			#generateBitOr:on:indent:
  	#bitXor:		#generateBitXor:on:indent:
  	#bitShift:		#generateBitShift:on:indent:
  	#signedBitShift:	#generateSignedBitShift:on:indent:
  	#bitInvert32		#generateBitInvert32:on:indent:
  	#bitClear:			#generateBitClear:on:indent:
  
  	#<				#generateLessThan:on:indent:
  	#<=			#generateLessThanOrEqual:on:indent:
  	#=				#generateEqual:on:indent:
  	#>				#generateGreaterThan:on:indent:
  	#>=			#generateGreaterThanOrEqual:on:indent:
  	#~=			#generateNotEqual:on:indent:
  	#==			#generateEqual:on:indent:
  	#~~			#generateNotEqual:on:indent:
  	#isNil			#generateIsNil:on:indent:
  	#notNil			#generateNotNil:on:indent:
  
  	#whileTrue: 	#generateWhileTrue:on:indent:
  	#whileFalse:	#generateWhileFalse:on:indent:
  	#whileTrue 		#generateDoWhileTrue:on:indent:
  	#whileFalse		#generateDoWhileFalse:on:indent:
  	#to:do:			#generateToDo:on:indent:
  	#to:by:do:		#generateToByDo:on:indent:
  	#repeat 		#generateRepeat:on:indent:
  
  	#ifTrue:			#generateIfTrue:on:indent:
  	#ifFalse:		#generateIfFalse:on:indent:
  	#ifTrue:ifFalse:	#generateIfTrueIfFalse:on:indent:
  	#ifFalse:ifTrue:	#generateIfFalseIfTrue:on:indent:
  
  	#at:			#generateAt:on:indent:
  	#at:put:			#generateAtPut:on:indent:
  	#basicAt:		#generateAt:on:indent:
  	#basicAt:put:	#generateAtPut:on:indent:
  
  	#integerValueOf:			#generateIntegerValueOf:on:indent:
  	#integerObjectOf:			#generateIntegerObjectOf:on:indent:
  	#isIntegerObject: 			#generateIsIntegerObject:on:indent:
  	#cCode:					#generateInlineCCode:on:indent:
  	#cCode:inSmalltalk:			#generateInlineCCode:on:indent:
  	#cPreprocessorDirective:	#generateInlineCPreprocessorDirective:on:indent:
  	#preprocessorExpression:	#generateInlineCppDirective:on:indent:
  	#isDefined:inSmalltalk:comment:ifTrue:	#generateInlineCppIfDef:on:indent:
  	#isDefined:inSmalltalk:comment:ifTrue:ifFalse:	#generateInlineCppIfDefElse:on:indent:
  	#isDefinedTrueExpression:inSmalltalk:comment:ifTrue:ifFalse:	#generateInlineCppIfElse:on:indent:
  	#cCoerce:to:				#generateCCoercion:on:indent:
  	#cCoerceSimple:to:			#generateCCoercion:on:indent:
  	#addressOf:				#generateAddressOf:on:indent:
  	#signedIntFromLong			#generateSignedIntFromLong:on:indent:
  	#signedIntToLong			#generateSignedIntToLong:on:indent:
  	#signedIntFromShort		#generateSignedIntFromShort:on:indent:
  	#signedIntToShort			#generateSignedIntToShort:on:indent:
  	#preIncrement				#generatePreIncrement:on:indent:
+ 	#preDecrement			#generatePreDecrement:on:indent:
- 	#preDecrement				#generatePreDecrement:on:indent:
  	#inline:						#generateInlineDirective:on:indent:
  	#asFloat					#generateAsFloat:on:indent:
  	#asInteger					#generateAsInteger:on:indent:
+ 	#asIntegerPtr				#generateAsIntegerPtr:on:indent:
+ 	#asUnsignedInteger		#generateAsUnsignedInteger:on:indent:
+ 	#asUnsignedIntegerPtr		#generateAsUnsignedIntegerPtr:on:indent:
+ 	#asLong					#generateAsLong:on:indent:
+ 	#asUnsignedLong			#generateAsUnsignedLong:on:indent:
+ 	#asUnsignedLongLong		#generateAsUnsignedLongLong:on:indent:
+ 	#asVoidPointer				#generateAsVoidPointer:on:indent:
- 	#asUnsignedInteger			#generateAsUnsignedInteger:on:indent:
  	#asSymbol					#generateAsSymbol:on:indent:
  	#flag:						#generateFlag:on:indent:
  	#anyMask:					#generateBitAnd:on:indent:
  	#raisedTo:					#generateRaisedTo:on:indent:
  	#touch:						#generateTouch:on:indent:
  	#bytesPerWord		#generateBytesPerWord:on:indent:
  	#baseHeaderSize		#generateBaseHeaderSize:on:indent:
  
  	#sharedCodeNamed:inCase:		#generateSharedCodeDirective:on:indent:
  
  	#perform:							#generatePerform:on:indent:
  	#perform:with:						#generatePerform:on:indent:
  	#perform:with:with:					#generatePerform:on:indent:
  	#perform:with:with:with:				#generatePerform:on:indent:
  	#perform:with:with:with:with:		#generatePerform:on:indent:
  	#perform:with:with:with:with:with:	#generatePerform:on:indent:
  
  	#value								#generateValue:on:indent:
  	#value:								#generateValue:on:indent:
  	#value:value:						#generateValue:on:indent:
  
  	#shouldNotImplement				#generateSmalltalkMetaError:on:indent:
  	#shouldBeImplemented				#generateSmalltalkMetaError:on:indent:
  	).
  
  	1 to: pairs size by: 2 do: [:i |
  		translationDict at: (pairs at: i) put: (pairs at: i + 1)].
  
  	pairs := #(
  	#ifTrue:				#generateIfTrueAsArgument:on:indent:	
  	#ifFalse:			#generateIfFalseAsArgument:on:indent:
  	#ifTrue:ifFalse:		#generateIfTrueIfFalseAsArgument:on:indent:
  	#ifFalse:ifTrue:		#generateIfFalseIfTrueAsArgument:on:indent:
  	#cCode:			#generateInlineCCodeAsArgument:on:indent:
  	#cCode:inSmalltalk:	#generateInlineCCodeAsArgument:on:indent:
  
  	#value					#generateValueAsArgument:on:indent:
  	#value:					#generateValueAsArgument:on:indent:
  	#value:value:			#generateValueAsArgument:on:indent:
  	).
  
  	asArgumentTranslationDict := Dictionary new: 8.
  	1 to: pairs size by: 2 do: [:i |
  		asArgumentTranslationDict at: (pairs at: i) put: (pairs at: i + 1)].
  !

Item was added:
+ ----- Method: CCodeGenerator>>storeAPIExportHeader:OnFile: (in category 'public') -----
+ storeAPIExportHeader: headerName OnFile: fullHeaderPath
+ 	"Store C header code on the given file. Evaluate
+ 	 aBlock with the stream to generate its contents."
+ 
+ 	| header |
+ 	header := String streamContents:
+ 				[:s|
+ 				 s nextPutAll: (self fileHeaderVersionStampForSourceClass: nil); cr.
+ 				 self emitCAPIExportHeaderOn: s].
+ 	(self needToGenerateHeader: headerName file: fullHeaderPath contents: header) ifTrue:
+ 		[self storeHeaderOnFile: fullHeaderPath contents: header]!

Item was added:
+ ----- Method: CCodeGenerator>>structClasses (in category 'accessing') -----
+ structClasses
+ 	^structClasses!

Item was added:
+ ----- Method: Integer>>asUnsignedLongLong (in category '*VMMaker-interpreter simulator') -----
+ asUnsignedLongLong
+ 	self assert: self >= 0.
+ 	^self!

Item was changed:
  ----- Method: InterpreterPrimitives>>installPrimitive:at: (in category 'primitive table') -----
  installPrimitive: selector at: anInteger
  	"The primitive table is normally initialized at compile time. This allows an entry
  	in the table to be istalled at runtime."
  
  	<inline: false> "for readability"
+ 	<var: 'selector' type: 'void *'>
  	primitiveTable at: anInteger put: selector.
  !

Item was changed:
  ----- Method: InterpreterPrimitives>>installPrimitive:from:at: (in category 'primitive table') -----
  installPrimitive: selector from: moduleName at: anInteger
  	"The primitive table is normally initialized at compile time. This allows an entry
  	in the table to be istalled at runtime. If the function cannot be loaded from the
  	named module, then let the numbered primitive fail."
  
  	<inline: false> "for readability"
+ 	<var: 'selector' type: 'void *'>
+ 	<var: 'moduleName' type: 'void *'>
  	<var: 'fn' declareC: 'void (*fn)(void)'>
  	| fn |
  	fn := self ioLoadFunction: selector From: moduleName.
  	fn = nil
  		ifTrue: [ primitiveTable at: anInteger put: #primitiveFail ]
  		ifFalse: [ primitiveTable at: anInteger put: fn ].
  !

Item was added:
+ ----- Method: InterpreterPrimitives>>isDirectAlien: (in category 'primitive support') -----
+ isDirectAlien: oop
+ 	^(self sizeFieldOfAlien: oop) > 0!

Item was added:
+ ----- Method: InterpreterPrimitives>>isIndirectAlien: (in category 'primitive support') -----
+ isIndirectAlien: oop
+ 	^(self sizeFieldOfAlien: oop) < 0!

Item was added:
+ ----- Method: InterpreterPrimitives>>isInstanceOfClassByteString: (in category 'primitive support') -----
+ isInstanceOfClassByteString: oop
+ 	<inline: true>
+ 	"N.B.  Because Slang always inlines is:instanceOf:compactClassIndex:
+ 	 (because is:instanceOf:compactClassIndex: has an inline: pragma) the
+ 	 phrase (objectMemory splObj: ClassByteString) is expanded in-place and
+ 	 is _not_ evaluated if oop has a non-zero CompactClassIndex."
+ 	^objectMemory
+ 		is: oop
+ 		instanceOf: (objectMemory splObj: ClassByteString) 
+ 		compactClassIndex: ClassByteStringCompactIndex!

Item was added:
+ ----- Method: InterpreterPrimitives>>isPointerAlien: (in category 'primitive support') -----
+ isPointerAlien: oop
+ 	^(self sizeFieldOfAlien: oop) = 0!

Item was removed:
- ----- Method: InterpreterProxy>>internalIsImutable: (in category 'object access') -----
- internalIsImutable: oop
- 	^oop isImmutable!

Item was removed:
- ----- Method: InterpreterProxy>>internalIsMutable: (in category 'object access') -----
- internalIsMutable: oop
- 	^oop isImmutable not!

Item was added:
+ ----- Method: NewObjectMemory>>byteSwapByteObjectsFrom:to:flipFloatsIf: (in category 'image segment in/out') -----
+ byteSwapByteObjectsFrom: startOop to: stopAddr flipFloatsIf: flipFloatWords
+ 	"Byte-swap the words of all bytes objects in a range of the 
+ 	image, including Strings, ByteArrays, and CompiledMethods. 
+ 	This returns these objects to their original byte ordering 
+ 	after blindly byte-swapping the entire image. For compiled 
+ 	methods, byte-swap only their bytecodes part.  For Floats
+ 	swap their most and least significant words if required."
+ 	| oop fmt temp wordAddr |
+ 	oop := startOop.
+ 	[self oop: oop isLessThan: stopAddr] whileTrue:
+ 		[(self isFreeObject: oop) ifFalse:
+ 			[fmt := self formatOf: oop.
+ 			fmt >= self firstByteFormat ifTrue:
+ 				["oop contains bytes; unswap"
+ 				wordAddr := oop + self baseHeaderSize.
+ 				fmt >= self firstCompiledMethodFormat ifTrue: "compiled method; start after methodHeader and literals"
+ 					[wordAddr := wordAddr + ((self literalCountOf: oop) + LiteralStart * self bytesPerOop)].
+ 				self reverseBytesFrom: wordAddr to: oop + (self sizeBitsOf: oop)].
+ 			fmt = self firstLongFormat  ifTrue: "Bitmap, Float etc"
+ 				[(self compactClassIndexOf: oop) = ClassFloatCompactIndex
+ 					ifTrue:
+ 						[flipFloatWords ifTrue:
+ 							[temp := self longAt: oop + self baseHeaderSize.
+ 							 self longAt: oop + self baseHeaderSize put: (self longAt: oop + self baseHeaderSize + 4).
+ 							 self longAt: oop + self baseHeaderSize + 4 put: temp]]
+ 					ifFalse:
+ 						[self wordSize = 8 ifTrue:
+ 							["Object contains 32-bit half-words packed into 64-bit machine words."
+ 							wordAddr := oop + self baseHeaderSize.
+ 							self reverseWordsFrom: wordAddr to: oop + (self sizeBitsOf: oop)]]]].
+ 			oop := self objectAfter: oop]!

Item was added:
+ ----- Method: NewObjectMemory>>primitiveFailCodeAfterCleanup: (in category 'image segment in/out') -----
+ primitiveFailCodeAfterCleanup: outPointerArray
+ 	"If the storeSegment primitive fails, it must clean up first."
+ 
+ 	| i lastAddr |   "Store nils throughout the outPointer array."
+ 	lastAddr := outPointerArray + (self lastPointerOf: outPointerArray).
+ 	i := outPointerArray + self baseHeaderSize.
+ 	[i <= lastAddr] whileTrue:
+ 		[self longAt: i put: nilObj.
+ 		i := i + self wordSize].
+ 
+ 	DoAssertionChecks ifTrue: [self verifyCleanHeaders].
+ 	^PrimErrGenericFailure!

Item was added:
+ ----- Method: ObjectMemory>>addressCouldBeOop: (in category 'debug support') -----
+ addressCouldBeOop: address
+ 	<api>
+ 	"Answer if address appears to be that of either a SmallInteger or an object.
+ 	 For code disassembly and assertions."
+ 	^(self isIntegerObject: address)
+ 	   or: [self addressCouldBeObj: address]!

Item was added:
+ ----- Method: ObjectMemory>>bytesPerOop (in category 'accessing') -----
+ bytesPerOop
+ 	"N.B. This would appear to hard-code the header size for 32-bit images.  But if generating
+ 	 a 64-bit image, this method could be removed and the relevant one substituted.  We can't
+ 	 mark this method as <doNotGenerate> as we need an actual method to guide code gen."
+ 
+ 	"BYTES_PER_WORD see CCodeGenerator>>generateBytesPerWord:on:indent:"
+ 
+ 	^self bytesPerWord!

Item was added:
+ ----- Method: ObjectMemory>>classMutex (in category 'plugin support') -----
+ classMutex
+ 	"Used by StackInterpreter>>printAllStacks, but see initializeSpecialObjectsArray
+ 	for initialization of CassMutex. Slot 39 in the array is presently used for class
+ 	PseudoContext, which is obsolete but may be needed for running older images."
+ 
+ 	self flag: #FIXME. "ClassMutex is not initialized."
+ 	^self splObj: ClassMutex!

Item was added:
+ ----- Method: ObjectMemory>>fetchLong64:ofObject: (in category 'object access') -----
+ fetchLong64: longIndex ofObject: oop
+ 	<returnTypeC: #sqLong>
+ 	^self bytesPerWord = 8
+ 		ifTrue: [self long64At: oop + self baseHeaderSize + (longIndex << 3)]
+ 		ifFalse:
+ 			["BEWARE OF SIGN EXTENSION ON LEAST SIGNIFICAND LIMB
+ 			'unsigned int) CAST IS THERE TO PREVENT SUCH ERROR"
+ 			self isBigEnder
+ 				ifTrue: [((self long32At: oop + self baseHeaderSize + (longIndex << 3)) asUnsignedLongLong << 32)
+ 					+ (self cCoerceSimple: (self long32At: oop + self baseHeaderSize + (longIndex << 3 + 4)) to: #'unsigned int')]
+ 				ifFalse: [(self cCoerceSimple: (self long32At: oop + self baseHeaderSize + (longIndex << 3)) to: #'unsigned int')
+ 					+ ((self long32At: oop + self baseHeaderSize + (longIndex << 3 + 4)) asUnsignedLongLong << 32)]]!

Item was added:
+ ----- Method: ObjectMemory>>gcStartUsecs (in category 'accessing') -----
+ gcStartUsecs
+ 	^gcStartUsecs!

Item was added:
+ ----- Method: ObjectMemory>>isNonIntegerImmediate: (in category 'interpreter access') -----
+ isNonIntegerImmediate: oop
+ 	"ObjectMemory only has integer immedates"
+ 	<inline: true>
+ 	^false!

Item was added:
+ ----- Method: ObjectMemory>>numBytesOfBytes: (in category 'object access') -----
+ numBytesOfBytes: objOop 
+ 	"Answer the number of indexable bytes in the given non-immediate byte-indexable object."
+ 	<api>
+ 	| header sz fmt |
+ 	header := self baseHeader: objOop.
+ 	sz := (header bitAnd: TypeMask) = HeaderTypeSizeAndClass
+ 			ifTrue: [(self sizeHeader: objOop) bitAnd: self allButTypeMask]
+ 			ifFalse: [header bitAnd: self sizeMask].
+ 	fmt := self formatOfHeader: header.
+ 	self assert: fmt >= self firstByteFormat.
+ 	^(sz - self baseHeaderSize) - (fmt bitAnd: 3)!

Item was added:
+ ----- Method: ObjectMemory>>statFullGCUsecs (in category 'accessing') -----
+ statFullGCUsecs
+ 	^statFullGCUsecs!

Item was added:
+ ----- Method: ObjectMemory>>statIGCDeltaUsecs (in category 'accessing') -----
+ statIGCDeltaUsecs
+ 	^statIGCDeltaUsecs!

Item was added:
+ ----- Method: ObjectMemory>>statIncrGCUsecs (in category 'accessing') -----
+ statIncrGCUsecs
+ 	^statIncrGCUsecs!

Item was removed:
- ----- Method: SmartSyntaxInterpreterPlugin class>>translateDoInlining:locally:debug: (in category 'translation') -----
- translateDoInlining: inlineFlag locally: localFlag debug: debugFlag 
- 	^ self
- 		translate: self moduleFileName
- 		doInlining: inlineFlag
- 		locally: localFlag
- 		debug: debugFlag!

Item was added:
+ ----- Method: StackInterpreter>>classNameIndex (in category 'simulation') -----
+ classNameIndex
+ 	<doNotGenerate>
+ 	^classNameIndex!

Item was changed:
  ----- Method: StackInterpreter>>highBit: (in category 'stack pages') -----
  highBit: anUnsignedValue 
  	"This is a C implementation needed by stackPageByteSize when translated."
  	| shifted bitNo |
  	<var: #anUnsignedValue type: #usqInt>
  	<var: #shifted type: #usqInt>
  	shifted := anUnsignedValue.
  	bitNo := 0.
+ 	objectMemory bytesPerWord > 4
- 	self cppIf: [objectMemory bytesPerWord > 4]
  		ifTrue:
  			[shifted < (1 << 32) ifFalse:
  				[shifted := shifted >> 32.
  				 bitNo := bitNo + 32]].
  	shifted < (1 << 16) ifFalse:
  		[shifted := shifted >> 16.
  		 bitNo := bitNo + 16].
  	shifted < (1 << 8) ifFalse:
  		[shifted := shifted >> 8.
  		 bitNo := bitNo + 8].
  	shifted < (1 << 4) ifFalse:
  		[shifted := shifted >> 4.
  		 bitNo := bitNo + 4].
  	shifted < (1 << 2) ifFalse:
  		[shifted := shifted >> 2.
  		 bitNo := bitNo + 2].
  	shifted < (1 << 1) ifFalse:
  		[shifted := shifted >> 1.
  		 bitNo := bitNo + 1].
  	"shifted 0 or 1 now"
  	^bitNo + shifted!

Item was added:
+ ----- Method: StackInterpreter>>isQuickPrimitiveIndex: (in category 'compiled methods') -----
+ isQuickPrimitiveIndex: anInteger
+ 	<api>
+ 	^anInteger between: 256 and: 519!

Item was removed:
- ----- 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 handleStackOverflow.
- 	self enterSmalltalkExecutiveFromCallback.
- 	"not reached"
- 	^true!

Item was added:
+ ----- Method: StackInterpreter>>stackLimitBytes (in category 'stack pages') -----
+ stackLimitBytes
+ 	"Answer the actual stackLimit offset in a page.  Since stackPageByteSize may have chosen to shrink a page
+ 	 this may be less than stackPageFrameBytes, but it should be no more than stackPageFrameBytes."
+ 	^self stackPageFrameBytes min: self stackPageByteSize - self stackLimitOffset - self stackPageHeadroom.!

Item was changed:
  ----- Method: StackInterpreter>>stackPageByteSize (in category 'stack pages') -----
  stackPageByteSize
+ 	"Answer a page size that is a power-of-two and contains a useful number of frames.
+ 	 Room for 256 slots for frames gives around 40 frames a page which is a
- 	"Room for 512 bytes of frames gives around 40 frames a page which is a
  	 good compromise between overflow rate and latency in divorcing a page."
  	<inline: false>
+ 	| pageBytes largeSize smallSize |
+ 	pageBytes := self stackPageFrameBytes + self stackLimitOffset + self stackPageHeadroom.
+ 	(pageBytes bitAnd: pageBytes - 1) = 0 ifTrue: "= 0 => a power of two"
+ 		[^pageBytes].
+ 	"round up or round down; that is the question.  If rounding down reduces
+ 	 the size by no more than 1/8th round down, otherwise roundup."
+ 	largeSize := 1 << pageBytes highBit.
+ 	smallSize := 1 << (pageBytes highBit - 1).
+ 	self assert: (largeSize > pageBytes and: [pageBytes > smallSize]).
+ 	^(pageBytes - smallSize) <= (smallSize / 8)
+ 		ifTrue: [smallSize]
+ 		ifFalse: [largeSize]!
- 	^1 << (512 + self stackLimitOffset + self stackPageHeadroom - 1) highBit!

Item was added:
+ ----- Method: StackInterpreter>>stackPageFrameBytes (in category 'stack pages') -----
+ stackPageFrameBytes
+ 	"Answer a byte size that accomodates a useful number of frames.  The minimum frame size is
+ 	 7 slots in the StackInterpreter, and 6 slots in the CoInterpreter, and the maximum size is 56 + 7
+ 	 slots in the StackInterpreter and 56 + 8 slots in the CoInterpreter. 256 slots gives from 4 to 36
+ 	 frames in the StackInterpreter and from 4 to 42 in the CoInterpreter. Hence 2048 bytes in 32-bits
+ 	 and 4096 bytes in 64-bits; a compromise between overflow rate and latency in divorcing a page."
+ 	"Defining as a macro simplifies hand editing the C for experiments..."
+ 	<cmacro: '() (256 * BytesPerWord)'>
+ 	^256 * objectMemory wordSize!

Item was added:
+ ----- Method: StackInterpreter>>startPCOfMethod: (in category 'compiled methods') -----
+ startPCOfMethod: aCompiledMethod
+ 	<api>
+ 	"Zero-relative version of CompiledMethod>>startpc."
+ 	^(objectMemory literalCountOf: aCompiledMethod) + LiteralStart * objectMemory bytesPerOop!

Item was added:
+ ----- Method: StackInterpreter>>thisClassIndex (in category 'simulation') -----
+ thisClassIndex
+ 	<doNotGenerate>
+ 	^thisClassIndex!

Item was changed:
  ----- Method: VMMaker class>>versionString (in category 'version testing') -----
  versionString
  
  	"VMMaker versionString"
  
+ 	^'4.16.5'!
- 	^'4.16.4'!

Item was added:
+ ----- Method: VMMaker>>sourceFilePathFor: (in category 'generate sources') -----
+ sourceFilePathFor: sourceFileName
+ 	"Answer the fully-qualified path for the generated source file."
+ 	^self coreVMDirectory fullNameFor: sourceFileName!



More information about the Vm-dev mailing list