[Vm-dev] VM Maker: VMMaker.oscog-nice.1979.mcz

commits at source.squeak.org commits at source.squeak.org
Fri Nov 4 21:00:10 UTC 2016


Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1979.mcz

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

Name: VMMaker.oscog-nice.1979
Author: nice
Time: 4 November 2016, 9:58:00.806651 pm
UUID: 2abf6236-cd7c-42c2-bf82-515ac9ada054
Ancestors: VMMaker.oscog-nice.1978

Introduce sqIntptr_t and usqIntptr_t in VMMaker (image side) for LLP64 compatibility - but do not yet use them.
These are integers long enough to hold a target machine pointer (BytesPerWord).
These should later replace most usage of #long and #'unsigned long'.
They are already defined in sqMemoryAccess.h.

Add enough machinery for generating and simulating these types, inferring size, converting signedness etc....

Introduce asUnsignedIntegerPtr which will convert to (cast to) a usqIntptr_t.
same for asIntegerPtr -> sqIntptr_t.
They should replace most usage of asUnsignedLong and asLong in the future.
Unless we don't want a machine word, but an oop, in which case we should use asUnsignedInteger (-> usqInt) or asInteger (-> sqInt) (typically to turn a longAt: into an unsignedLongAt: - because longAt: answers a sqInt not a long!)

Restore the size of sqInt/usqInt as BytePerOop.
BytesPerOop matches BytesPerWord for Spur currently, but the CCodeGenerator should be Spur-agnostic if possible.

Move sqInt/usqInt check ahead in simulated sizeof: because most variables are of this type.

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

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>>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 changed:
  ----- Method: CCodeGenerator>>initializeCTranslationDictionary (in category 'C translation support') -----
  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:
  	#abs			#generateAbs: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:
  	#>>>			#generateSignedShiftRight: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		#generateBitInvert:on:indent:
  	#bitInvert64		#generateBitInvert:on:indent:
  	#bitClear:			#generateBitClear:on:indent:
  	#truncateTo:		#generateTruncateTo:on:indent:
  	#rounded			#generateRounded:on:indent:
  
  	#byteSwap32		#generateByteSwap32:on:indent:
  	#byteSwap64		#generateByteSwap64:on:indent:
  	#byteSwapped32IfBigEndian:	generateByteSwap32IfBigEndian:on:indent:
  	#byteSwapped64IfBigEndian:	generateByteSwap64IfBigEndian: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:
  	#timesRepeat:	#generateTimesRepeat:on:indent:
  
  	#ifTrue:			#generateIfTrue:on:indent:
  	#ifFalse:		#generateIfFalse:on:indent:
  	#ifTrue:ifFalse:	#generateIfTrueIfFalse:on:indent:
  	#ifFalse:ifTrue:	#generateIfFalseIfTrue:on:indent:
  
  	#ifNotNil:		#generateIfNotNil:on:indent:
  	#ifNil:			#generateIfNil:on:indent:
  	#ifNotNil:ifNil:	#generateIfNotNilIfNil:on:indent:
  	#ifNil:ifNotNil:	#generateIfNilIfNotNil: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:
  	#cppIf:ifTrue:ifFalse:		#generateInlineCppIfElse:on:indent:
  	#cppIf:ifTrue:				#generateInlineCppIfElse:on:indent:
  	#cCoerce:to:				#generateCCoercion:on:indent:
  	#cCoerceSimple:to:			#generateCCoercion:on:indent:
  	#addressOf:				#generateAddressOf:on:indent:
  	#addressOf:put:			#generateAddressOf:on:indent:
  	#asAddress:put:			#generateAsAddress:on:indent:
  	#signedIntFromLong64		#generateSignedIntFromLong64:on:indent:
  	#signedIntFromLong		#generateSignedIntFromLong:on:indent:
  	#signedIntFromShort		#generateSignedIntFromShort:on:indent:
  	#signedIntToLong64		#generateSignedIntToLong64:on:indent:
  	#signedIntToLong			#generateSignedIntToLong:on:indent:
  	#signedIntToShort			#generateSignedIntToShort:on:indent:
  	#preIncrement				#generatePreIncrement: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:
  	#asSymbol					#generateAsSymbol:on:indent:
  	#flag:						#generateFlag:on:indent:
  	#anyMask:					#generateBitAnd:on:indent:
  	#allMask:					#generateAllMask:on:indent:
  	#noMask:					#generateNoMask:on:indent:
  	#raisedTo:					#generateRaisedTo:on:indent:
  	#touch:						#generateTouch:on:indent:
  
  	#bytesPerOop 				#generateBytesPerOop:on:indent:
  	#bytesPerWord 			#generateBytesPerWord:on:indent:
  	#wordSize		 			#generateBytesPerWord:on:indent:
  	#baseHeaderSize			#generateBaseHeaderSize:on:indent:
  	#minSmallInteger			#generateSmallIntegerConstant:on:indent:
  	#maxSmallInteger			#generateSmallIntegerConstant: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:
  	#value:value:value:					#generateValue:on:indent:
  	#value:value:value:value:			#generateValue:on:indent:
  
  	#deny:								#generateDeny:on:indent:
  
  	#shouldNotImplement				#generateSmalltalkMetaError:on:indent:
  	#shouldBeImplemented			#generateSmalltalkMetaError:on:indent:
  	#subclassResponsibility			#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:
  	#ifNotNil:				#generateIfNotNilAsArgument:on:indent:	
  	#ifNil:					#generateIfNilAsArgument:on:indent:
  	#ifNotNil:ifNil:			#generateIfNotNilIfNilAsArgument:on:indent:
  	#ifNil:ifNotNil:			#generateIfNilIfNotNilAsArgument:on:indent:
  	#cCode:				#generateInlineCCodeAsArgument:on:indent:
  	#cCode:inSmalltalk:		#generateInlineCCodeAsArgument:on:indent:
  	#cppIf:ifTrue:ifFalse:	#generateInlineCppIfElseAsArgument:on:indent:
  	#cppIf:ifTrue:			#generateInlineCppIfElseAsArgument: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 changed:
  ----- Method: CCodeGenerator>>isIntegralCType: (in category 'inlining') -----
  isIntegralCType: aCType "<String>"
+ 	^(#('sqLong' 'usqLong' 'sqInt' 'usqInt' 'sqIntptr_t' 'usqIntptr_t'
- 	^(#('sqLong' 'usqLong' 'sqInt' 'usqInt'
  		'long' 'int' 'short' 'char' 'signed char'
  		'size_t' 'pid_t') includes: aCType asString)
  	or: [(aCType beginsWith: 'unsigned') "Accept e.g. 'unsigned long' and also 'unsigned  : 8'"
  		and: [(aCType includesAnyOf: '[*]') not]]!

Item was changed:
  ----- Method: CCodeGenerator>>returnTypeForSend:in:ifNil: (in category 'type inference') -----
  returnTypeForSend: sendNode in: aTMethod ifNil: typeIfNil
  	"Answer the return type for a send.  Unbound sends default to typeIfNil.
  	 Methods with types as yet unknown have a type determined either by the
  	 kernelReturnTypes or the table below, or, if they are in neither set, then nil.
  	 The inferred type should match as closely as possible the C type of
  	 generated expessions so that inlining would not change the expression.
  	 If there is a method for sel but its return type is as yet unknown it mustn't
  	 be defaulted, since on a subsequent pass its type may be computable."
  	| sel methodOrNil |
  	methodOrNil := self anyMethodNamed: (sel := sendNode selector).
  	(methodOrNil notNil and: [methodOrNil returnType notNil]) ifTrue:
  		[^self baseTypeForType: methodOrNil returnType].
  	^kernelReturnTypes
  		at: sel
  		ifAbsent:
  			[sel
  				caseOf: {
  				[#integerValueOf:]		->	[#sqInt].
  				[#isIntegerObject:]		->	[#int].
  				[#negated]				->	[self promoteArithmeticTypes: (self typeFor: sendNode receiver in: aTMethod) and: #int].
  				[#+]					->	[self typeForArithmetic: sendNode in: aTMethod].
  				[#-]						->	[self typeForArithmetic: sendNode in: aTMethod].
  				[#*]					->	[self typeForArithmetic: sendNode in: aTMethod].
  				[#/]						->	[self typeForArithmetic: sendNode in: aTMethod].
  				[#//]					->	[self typeForArithmetic: sendNode in: aTMethod].
  				[#\\]					->	[self typeForArithmetic: sendNode in: aTMethod].
  				[#rem:]					->	[self typeForArithmetic: sendNode in: aTMethod].
  				[#quo:]					->	[self typeForArithmetic: sendNode in: aTMethod].
  				"C99 Sec Bitwise shift operators ... 3 Sematics ...
  				 The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand..."
  				[#>>]					->	[self typeFor: sendNode receiver in: aTMethod].
  				[#<<]					->	[self typeFor: sendNode receiver in: aTMethod].
  				[#addressOf:]			->	[(self typeFor: sendNode receiver in: aTMethod)
  												ifNil: [#sqInt]
  												ifNotNil: [:type| type, (type last isLetter ifTrue: [' *'] ifFalse: ['*'])]].
  				[#at:]					->	[self typeForDereference: sendNode in: aTMethod].
  				[#bitAnd:]				->	[self typeForArithmetic: sendNode in: aTMethod].
  				[#bitOr:]				->	[self typeForArithmetic: sendNode in: aTMethod].
  				[#bitXor:]				->	[self typeForArithmetic: sendNode in: aTMethod].
  				[#bitClear:]				->	[self typeForArithmetic: sendNode in: aTMethod].
  				[#bitInvert32]			->	[#'unsigned int'].
  				[#bitInvert64]			->	[self promoteArithmeticTypes: (self typeFor: sendNode receiver in: aTMethod) and: #int].
  				[#byteSwap32]			->	[#'unsigned int'].
  				[#byteSwap64]			->	[#'unsigned long long'].
  				[#byteSwapped32IfBigEndian:]	->	[#'unsigned int'].
  				[#byteSwapped64IfBigEndian:]	->	[#'unsigned long long'].
  				[#=]					->	[#int].
  				[#~=]					->	[#int].
  				[#==]					->	[#int].
  				[#~~]					->	[#int].
  				[#<]					->	[#int].
  				[#<=]					->	[#int].
  				[#>]					->	[#int].
  				[#>=]					->	[#int].
  				[#between:and:]		->	[#int].
  				[#anyMask:]				->	[#int].
  				[#allMask:]				->	[#int].
  				[#noMask:]				->	[#int].
  				[#isNil]					->	[#int].
  				[#notNil]				->	[#int].
  				[#&]					->	[#int].
  				[#|]						->	[#int].
  				[#not]					->	[#int].
  				[#asFloat]				->	[#double].
  				[#atan]					->	[#double].
  				[#exp]					->	[#double].
  				[#log]					->	[#double].
  				[#sin]					->	[#double].
  				[#sqrt]					->	[#double].
  				[#asLong]				->	[#long].
  				[#asInteger]			->	[#sqInt].
+ 				[#asIntegerPtr]			->	[#'sqIntptr_t'].
  				[#asUnsignedInteger]	->	[#usqInt].
+ 				[#asUnsignedIntegerPtr]->	[#'usqIntptr_t'].
  				[#asUnsignedLong]		->	[#'unsigned long'].
  				[#asUnsignedLongLong]		->	[#'unsigned long long'].
  				[#asVoidPointer]		->	[#'void *'].
  				[#signedIntToLong]		->	[#usqInt]. "c.f. generateSignedIntToLong:on:indent:"
  				[#signedIntToShort]	->	[#usqInt]. "c.f. generateSignedIntToShort:on:indent:"
  				[#cCoerce:to:]			->	[sendNode args last value].
  				[#cCoerceSimple:to:]	->	[sendNode args last value].
  				[#sizeof:]				->	[#'unsigned long']. "Technically it's a size_t but it matches unsigned long on target architectures so far..."
  				[#ifTrue:ifFalse:]		->	[self typeForConditional: sendNode in: aTMethod].
  				[#ifFalse:ifTrue:]		->	[self typeForConditional: sendNode in: aTMethod].
  				[#ifTrue:]				->	[self typeForConditional: sendNode in: aTMethod].
  				[#ifFalse:]				->	[self typeForConditional: sendNode in: aTMethod].
  				[#and:]					->	[#sqInt].
  				[#or:]					->	[#sqInt] }
  				otherwise: "If there /is/ a method for sel but its return type is as yet unknown it /mustn't/ be defaulted,
  							since on a subsequent pass its type may be computable.  Only default unbound selectors."
  					[methodOrNil ifNotNil: [nil] ifNil: [typeIfNil]]]!

Item was changed:
  ----- Method: CCodeGenerator>>signedTypeForIntegralType: (in category 'type inference') -----
  signedTypeForIntegralType: aCTypeString
  	(aCTypeString beginsWith: 'unsigned ') ifTrue:
  		[^aCTypeString allButFirst: 8].
  	
  	(aCTypeString beginsWith: 'usq') ifTrue:
  		[^aCTypeString allButFirst].
  
+ 	aCTypeString = 'size_t' ifTrue: [^#usqIntptr_t].
+ 	
  	self error: 'unknown type'.
  	^#long!

Item was changed:
  ----- Method: CCodeGenerator>>sizeOfIntegralCType: (in category 'inlining') -----
  sizeOfIntegralCType: anIntegralCType "<String>"
  	"N.B. Only works for values for which isIntegralCType: answers true."
  	| prunedCType index |
  	(anIntegralCType beginsWith: 'register ') ifTrue:
  		[^self sizeOfIntegralCType: (anIntegralCType allButFirst: 9)].
  	prunedCType := (anIntegralCType beginsWith: 'unsigned ')
  						ifTrue: [(anIntegralCType allButFirst: 9) withBlanksTrimmed]
  						ifFalse: [(anIntegralCType beginsWith: 'signed ')
  									ifTrue: [(anIntegralCType allButFirst: 7) withBlanksTrimmed]
  									ifFalse: [anIntegralCType]].
+ 	
  	^prunedCType asString caseOf: {
  		['sqLong']	->	[8].
  		['usqLong']	->	[8].
  		['long long']	->	[8].
+ 		['sqInt']		->	[BytesPerOop].
+ 		['usqInt']	->	[BytesPerOop].
+ 		['sqIntptr_t']	->	[BytesPerWord].
+ 		['usqIntptr_t']	->	[BytesPerWord].
- 		['sqInt']		->	[BytesPerWord].
- 		['usqInt']	->	[BytesPerWord].
  		['int']		->	[4].
  		['short']		->	[2].
  		['short int']	->	[2].
  		['char']		->	[1].
+ 		['long']		->	[BytesPerWord]. "It's ambiguous on LLP64 and we'll later remove it"
+ 		['size_t']	->	[BytesPerWord].
- 		['long']		->	[BytesPerWord].
- 		['size_t']		->	[BytesPerWord].
  		['pid_t']		->	[BytesPerWord].
  	}
  	otherwise:
  		[((anIntegralCType beginsWith: 'unsigned') "e.g. 'unsigned  : 8'"
  		  and: [(anIntegralCType includesAnyOf: '[*]') not
  		  and: [(index := anIntegralCType indexOf: $:) > 0]])
  			ifTrue: [(Integer readFrom: (anIntegralCType copyFrom: index + 1 to: anIntegralCType size) withBlanksTrimmed readStream) + 7 // 8]
  			ifFalse: [self error: 'unrecognized integral type']]!

Item was added:
+ ----- Method: CogAbstractInstruction>>asIntegerPtr (in category 'coercion') -----
+ asIntegerPtr
+ 	<doNotGenerate>
+ 	^self!

Item was added:
+ ----- Method: CogAbstractInstruction>>asUnsignedIntegerPtr (in category 'coercion') -----
+ asUnsignedIntegerPtr
+ 	<doNotGenerate>
+ 	^self!

Item was changed:
  ----- Method: CogClass>>cCoerceSimple:to: (in category 'translation support') -----
  cCoerceSimple: value to: cTypeString
  	<doNotGenerate>
  	"Type coercion for translation and simulation.
  	 For simulation answer a suitable surrogate for the struct types"
  	^cTypeString caseOf:
  	   {	[#'unsigned long']							->	[value].
  		[#'unsigned int']							->	[value].
  		[#sqInt]										->	[value].
+ 		[#'sqIntptr_t']								->	[value].
+ 		[#'usqIntptr_t']								->	[value].
  		[#usqInt]									->	[value].
  		[#sqLong]									->	[value].
  		[#usqLong]									->	[value].
  		[#'AbstractInstruction *']					->	[value].
  		[#'BytecodeFixup *']						->	[value].
  		[#'CogMethod *']							->	[value].
  		[#'char *']									->	[value].
  		[#'sqInt *']									->	[value].
  		[#'void *']									->	[value].
  		[#void]										->	[value].
  		[#'void (*)()']								->	[value].
  		[#'void (*)(void)']							->	[value].
  		[#'unsigned long (*)(void)']					->	[value].
  		[#'void (*)(unsigned long,unsigned long)']	->	[value] }!

Item was added:
+ ----- Method: CogMethodSurrogate>>asIntegerPtr (in category 'accessing') -----
+ asIntegerPtr
+ 	"Answer the surrogate's adress. This is equivalent to a C cast to usqIntptr_t,
+ 	 which is precisely what Slang generates for asIntegerPtr"
+ 	^address!

Item was added:
+ ----- Method: CogMethodSurrogate>>asUnsignedIntegerPtr (in category 'accessing') -----
+ asUnsignedIntegerPtr
+ 	"Answer the surrogate's adress. This is equivalent to a C cast to usqIntptr_t,
+ 	 which is precisely what Slang generates for asUnsignedIntegerPtr"
+ 	^address!

Item was added:
+ ----- Method: CogSSBytecodeFixup>>asIntegerPtr (in category 'simulation support') -----
+ asIntegerPtr
+ 	<doNotGenerate>
+ 	^self!

Item was added:
+ ----- Method: CogSSBytecodeFixup>>asUnsignedIntegerPtr (in category 'simulation support') -----
+ asUnsignedIntegerPtr
+ 	<doNotGenerate>
+ 	^self!

Item was added:
+ ----- Method: CogStackPageSurrogate>>asIntegerPtr (in category 'accessing') -----
+ asIntegerPtr
+ 	^address!

Item was added:
+ ----- Method: CogStackPageSurrogate>>asUnsignedIntegerPtr (in category 'accessing') -----
+ asUnsignedIntegerPtr
+ 	^address!

Item was added:
+ ----- Method: Integer>>asIntegerPtr (in category '*VMMaker-interpreter simulator') -----
+ asIntegerPtr
+ 	^self!

Item was added:
+ ----- Method: Integer>>asUnsignedIntegerPtr (in category '*VMMaker-interpreter simulator') -----
+ asUnsignedIntegerPtr
+ 	"Since the simulator deals with positive integers most of the time we assert that the receiver is greater than zero.
+ 	 But one major exception is stack pointers in the StackInterpreterSimulator, which are negative.  So don't fail
+ 	 if the sender is a StackInterpreter and the receiver could be a stack pointer."
+ 	self >= 0 ifFalse:
+ 		[self assert: ((thisContext sender methodClass includesBehavior: StackInterpreter)
+ 					and: [thisContext sender receiver stackPages couldBeFramePointer: self])].
+ 	^self!

Item was changed:
  ----- Method: InterpreterPlugin>>sizeof: (in category 'simulation support') -----
  sizeof: objectSymbolOrClass
  	<doNotGenerate>
  	objectSymbolOrClass isInteger ifTrue:
  		[^interpreterProxy wordSize].
  	objectSymbolOrClass isSymbol ifTrue:
  		["In the simulator file handles are just integer indices into openFiles and so need
  		 only be BytesPerWord big. But in the actual VM they are at least 5 words long."
  		objectSymbolOrClass == #SQFile ifTrue:
  			[^interpreterProxy wordSize * 5].
  		"SQSocket is typedef struct { int sessionID; int socketType; void *privateSocketPtr; } SQSocket"
  		objectSymbolOrClass == #SQSocket ifTrue:
  			[^8 + interpreterProxy wordSize].
  		"We assume the file offset type is always 64-bits."
  		objectSymbolOrClass == #squeakFileOffsetType ifTrue:
  			[^8].
  		(objectSymbolOrClass last == $*
  		 or: [#long == objectSymbolOrClass
+ 		 or: [#'unsigned long' == objectSymbolOrClass
+ 		 or: [#'sqIntptr_t' == objectSymbolOrClass
+ 		 or: [#'usqIntptr_t' == objectSymbolOrClass
+ 		 or: [#'size_t' == objectSymbolOrClass]]]]]) ifTrue:
- 		 or: [#'unsigned long' == objectSymbolOrClass]]) ifTrue:
  			[^interpreterProxy wordSize].
  		(#(usqInt sqInt) includes: objectSymbolOrClass) ifTrue:
  			[^interpreterProxy bytesPerOop]].
  	^super sizeof: objectSymbolOrClass!

Item was changed:
  ----- Method: SistaCogit>>picDataFor:Annotation:Mcpc:Bcpc:Method: (in category 'method introspection') -----
  picDataFor: descriptor Annotation: isBackwardBranchAndAnnotation Mcpc: mcpc Bcpc: bcpc Method: cogMethodArg
  	<var: #descriptor type: #'BytecodeDescriptor *'>
  	<var: #mcpc type: #'char *'>
  	<var: #cogMethodArg type: #'void *'>
  	| annotation entryPoint tuple counter |
+ 	<var: #counter type: #usqInt>
- 	<var: #counter type: #'unsigned long'>
  
  	descriptor ifNil:
  		[^0].
  	descriptor isBranch ifTrue:
  		["it's a branch; conditional?"
  		 (descriptor isBranchTrue or: [descriptor isBranchFalse]) ifTrue:
  			[counter := (self
  							cCoerce: ((self
  											cCoerceSimple: cogMethodArg
  											to: #'CogMethod *') counters)
+ 							to: #'usqInt *')
- 							to: #'unsigned long *')
  								at: counterIndex.
  			 tuple := self picDataForCounter: counter at: bcpc + 1.
  			 tuple = 0 ifTrue: [^PrimErrNoMemory].
  			 objectMemory storePointer: introspectionDataIndex ofObject: introspectionData withValue: tuple.
  			 introspectionDataIndex := introspectionDataIndex + 1.
  			 counterIndex := counterIndex + 1].
  		 ^0].
  	annotation := isBackwardBranchAndAnnotation >> 1.
  	((self isPureSendAnnotation: annotation)
  	 and: [entryPoint := backEnd callTargetFromReturnAddress: mcpc asUnsignedInteger.
  		 entryPoint > methodZoneBase]) ifFalse: "send is not linked, or is not a send"
  		[^0].
  	self targetMethodAndSendTableFor: entryPoint "It's a linked send; find which kind."
  		annotation: annotation
  		into: [:targetMethod :sendTable| | methodClassIfSuper association |
  			methodClassIfSuper := nil.
  			sendTable = superSendTrampolines ifTrue:
  				[methodClassIfSuper := coInterpreter methodClassOf: (self cCoerceSimple: cogMethodArg to: #'CogMethod *') methodObject].
  			sendTable = directedSuperSendTrampolines ifTrue:
  				[association := backEnd literalBeforeInlineCacheTagAt: mcpc asUnsignedInteger.
  				 methodClassIfSuper := objectRepresentation valueOfAssociation: association].
  			tuple := self picDataForSendTo: targetMethod
  						methodClassIfSuper: methodClassIfSuper
  						at: mcpc
  						bcpc: bcpc + 1].
  	tuple = 0 ifTrue: [^PrimErrNoMemory].
  	objectMemory storePointer: introspectionDataIndex ofObject: introspectionData withValue: tuple.
  	introspectionDataIndex := introspectionDataIndex + 1.
  	^0!

Item was changed:
  ----- Method: SistaCogit>>picDataForCounter:at: (in category 'method introspection') -----
  picDataForCounter: counter at: bcpc
  	| executedCount tuple untakenCount |
+ 	<var: #counter type: #usqInt>
- 	<var: #counter type: #'unsigned long'>
  	tuple := objectMemory
  				eeInstantiateClassIndex: ClassArrayCompactIndex
  				format: objectMemory arrayFormat
  				numSlots: 3.
  	tuple = 0 ifTrue:
  		[^0].
  	self assert: CounterBytes = 4.
  	executedCount := initialCounterValue - (counter >> 16).
  	untakenCount := initialCounterValue - (counter bitAnd: 16rFFFF).
  	objectMemory
  		storePointerUnchecked: 0 ofObject: tuple withValue: (objectMemory integerObjectOf: bcpc);
  		storePointerUnchecked: 1 ofObject: tuple withValue: (objectMemory integerObjectOf: executedCount);
  		storePointerUnchecked: 2 ofObject: tuple withValue: (objectMemory integerObjectOf: untakenCount).
  	^tuple!

Item was changed:
  ----- Method: Spur32BitMemoryManager>>integerObjectOfCharacterObject: (in category 'immediates') -----
  integerObjectOfCharacterObject: oop
  	"Immediate characters are unsigned"
+ 	^(self cCoerceSimple: oop to: #usqInt) >> 1!
- 	^(self cCoerceSimple: oop to: #'unsigned long') >> 1!

Item was changed:
  ----- Method: SpurMemoryManager class>>declareCVarsIn: (in category 'translation') -----
  declareCVarsIn: aCCodeGenerator
  	self declareCAsOop: #(	memory freeStart scavengeThreshold newSpaceStart newSpaceLimit pastSpaceStart
  							lowSpaceThreshold freeOldSpaceStart oldSpaceStart endOfMemory firstFreeChunk lastFreeChunk)
  		in: aCCodeGenerator.
  	self declareCAsUSqLong: (self allInstVarNames select: [:ivn| ivn endsWith: 'Usecs'])
  		in: aCCodeGenerator.
  	aCCodeGenerator
  		var: #freeListsMask type: #usqInt;
  		var: #freeLists type: #'sqInt *';
  		var: #objStackInvalidBecause type: #'char *';
  		var: #unscannedEphemerons type: #SpurContiguousObjStack;
  		var: #heapGrowthToSizeGCRatio type: #float;
  		var: #heapSizeAtPreviousGC type: #usqInt;
  		var: #totalFreeOldSpace type: #usqInt;
+ 		var: #maxOldSpaceSize type: #usqInt.
- 		var: #maxOldSpaceSize type: #'unsigned long'.
  	aCCodeGenerator
  		var: #remapBuffer
  		declareC: 'sqInt remapBuffer[RemapBufferSize + 1 /* ', (RemapBufferSize + 1) printString, ' */]'.
  	aCCodeGenerator
  		var: #extraRoots
  		declareC: 'sqInt *extraRoots[ExtraRootsSize + 1 /* ', (ExtraRootsSize + 1) printString, ' */]'!

Item was changed:
  ----- Method: SpurMemoryManager>>setMaxOldSpaceSize: (in category 'accessing') -----
  setMaxOldSpaceSize: limit
+ 	<var: #limit type: #usqInt>
- 	<var: #limit type: #'unsigned long'>
  	maxOldSpaceSize := limit.
  	^0!

Item was changed:
  ----- Method: ThreadedFFIPlugin>>primitiveFFIIntegerAt (in category 'primitives') -----
  primitiveFFIIntegerAt
  	"Answer a (signed or unsigned) n byte integer from the given byte offset
  	 in the receiver, using the platform's endianness."
  	| isSigned byteSize byteOffset rcvr addr value mask valueOop |
  	<var: 'value' type: #usqLong>
  	<var: 'mask' type: #usqLong>
  	<export: true>
  	<inline: false>
  	isSigned := interpreterProxy booleanValueOf: (interpreterProxy stackValue: 0).
  	byteSize := interpreterProxy stackIntegerValue: 1.
  	byteOffset := interpreterProxy stackIntegerValue: 2.
  	rcvr := interpreterProxy stackObjectValue: 3.
  	interpreterProxy failed ifTrue:[^0].
  	(byteOffset > 0
  	 and: [(byteSize between: 1 and: 8)
  	 and: [(byteSize bitAnd: byteSize - 1) = 0 "a.k.a. isPowerOfTwo"]]) ifFalse:
  		[^interpreterProxy primitiveFail].
  	addr := self ffiAddressOf: rcvr startingAt: byteOffset size: byteSize.
  	interpreterProxy failed ifTrue:[^0].
  	byteSize <= 2
  		ifTrue:
  			[byteSize = 1
  				ifTrue: [value := self cCoerceSimple: (interpreterProxy byteAt: addr) to: #'unsigned char']
  				ifFalse: [value := self cCoerceSimple: (interpreterProxy shortAt: addr) to: #'unsigned short']]
  		ifFalse:
  			[byteSize = 4
  				ifTrue: [value := self cCoerceSimple: (interpreterProxy long32At: addr) to: #'unsigned int']
  				ifFalse: [value := interpreterProxy long64At: addr]].
  	byteSize < BytesPerWord
  		ifTrue:
  			[isSigned ifTrue: "sign extend value"
+ 				[mask := 1 asUnsignedLongLong << (byteSize * 8 - 1).
- 				[mask := 1 << (byteSize * 8 - 1).
  				value := (value bitAnd: mask-1) - (value bitAnd: mask)].
  			 "note: byte/short (&long if BytesPerWord=8) never exceed SmallInteger range"
  			 valueOop := interpreterProxy integerObjectOf: value]
  		ifFalse: "general 64 bit integer; note these never fail"
  			[isSigned
  				ifTrue:
  					[byteSize < 8 ifTrue: "sign extend value"
+ 						[mask := 1 asUnsignedLongLong << (byteSize * 8 - 1).
- 						[mask := 1 << (byteSize * 8 - 1).
  						value := (value bitAnd: mask-1) - (value bitAnd: mask)].
  					 valueOop := interpreterProxy signed64BitIntegerFor: value]
  				ifFalse:[valueOop := interpreterProxy positive64BitIntegerFor: value]].
  	^interpreterProxy pop: 4 thenPush: valueOop!

Item was added:
+ ----- Method: UndefinedObject>>asIntegerPtr (in category '*VMMaker-interpreter simulator') -----
+ asIntegerPtr
+ 	^self!

Item was added:
+ ----- Method: UndefinedObject>>asUnsignedIntegerPtr (in category '*VMMaker-interpreter simulator') -----
+ asUnsignedIntegerPtr
+ 	^self!

Item was changed:
  ----- Method: VMClass>>sizeof: (in category 'translation support') -----
  sizeof: objectSymbolOrClass
  	<doNotGenerate>
  	| index |
  	objectSymbolOrClass isInteger ifTrue:
  		[^self class objectMemoryClass wordSize].
+ 	(#(usqInt sqInt) includes: objectSymbolOrClass) ifTrue: [^self class objectMemoryClass bytesPerOop].
  	objectSymbolOrClass isSymbol ifTrue:
  		[(objectSymbolOrClass last == $*
+ 		 or: [#(#long #'unsigned long' #'sqIntptr_t'  #'usqIntptr_t' #'size_t') includes: objectSymbolOrClass]) ifTrue:
- 		 or: [#long == objectSymbolOrClass
- 		 or: [#'unsigned long' == objectSymbolOrClass]]) ifTrue:
  			[^self class objectMemoryClass wordSize].
  		index := #(	#sqLong #usqLong #double
  					#int #'unsigned int' #float
  					#short #'unsigned short'
  					#char #'unsigned char' #'signed char')
  						indexOf: objectSymbolOrClass
  						ifAbsent:
+ 							[self error: 'unrecognized C type name'].
- 							[(#(usqInt sqInt) includes: objectSymbolOrClass) ifTrue: [^self class objectMemoryClass bytesPerOop].
- 							 self error: 'unrecognized C type name'].
  		^#(8 8 8
  			4 4 4
  			2 2
  			1 1 1) at: index].
  	^(objectSymbolOrClass isBehavior
  		ifTrue: [objectSymbolOrClass]
  		ifFalse: [objectSymbolOrClass class])
  			alignedByteSizeOf: objectSymbolOrClass
  			forClient: self!



More information about the Vm-dev mailing list