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

commits at source.squeak.org commits at source.squeak.org
Sat Apr 9 02:24:59 UTC 2016


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

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

Name: VMMaker.oscog-nice.1791
Author: nice
Time: 9 April 2016, 4:22:36.058 am
UUID: 25a942c2-9c18-4bcf-a1da-585c313c89a3
Ancestors: VMMaker.oscog-nice.1790

Fix CCode generation of LargeIntegers

Indeed, this method cannot be generated:

InterpreterPlugin>>
firstIndexableField: obj as: cType
       <inline: true>
       ^interpreterProxy cCoerce: (interpreterProxy firstIndexableField: obj) to: cType!

Only the inlined version can work when cType is replaced by a constant String as actual parameter.

Retract it for now since I found no way to avoid generation without eliminating inlining.
Replace it with a specific #pointerToFirstDigitOfLargeInt:

=============== Diff against VMMaker.oscog-nice.1790 ===============

Item was removed:
- ----- Method: InterpreterPlugin>>firstIndexableField:as: (in category 'casting support') -----
- firstIndexableField: obj as: cType
- 	<inline: true>
- 	^interpreterProxy cCoerce: (interpreterProxy firstIndexableField: obj) to: cType!

Item was changed:
  ----- Method: LargeIntegersPlugin>>createLargeFromSmallInteger: (in category 'oop util') -----
  createLargeFromSmallInteger: anOop 
  	"anOop has to be a SmallInteger!!"
  	| val res pDigit byteSize digitSize |
  	<var: #pDigit type: #'unsigned int *'>
  	val := interpreterProxy integerValueOf: anOop.
  	byteSize := self byteSizeOfCSI: val.
  	res := self createLargeIntegerNeg: val < 0 byteLength: byteSize.
+ 	pDigit := self pointerToFirstDigitOfLargeInt: res.
- 	pDigit := self firstIndexableField: res as: #'unsigned int *'.
  	digitSize := byteSize + 3 // 4.
  	1 to: digitSize do: [:ix | self cDigitOf: pDigit at: ix - 1 put: (self digitOfCSI: val at: ix)].
  	^ res!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digit:Lshift: (in category 'oop functions') -----
  digit: anOop Lshift: shiftCount 
  	"Attention: this method invalidates all oop's!! Only newOop is valid at return."
  	"Does not normalize."
  	| newOop highBit newDigitLen newByteLen oldDigitLen |
  	oldDigitLen := self digitSizeOfLargeInt: anOop.
+ 	(highBit := self cDigitHighBit: (self pointerToFirstDigitOfLargeInt: anOop)
- 	(highBit := self cDigitHighBit: (self firstIndexableField: anOop as: #'unsigned int *')
  				len: oldDigitLen) = 0 ifTrue: [^  interpreterProxy instantiateClass: (interpreterProxy fetchClassOf: anOop) indexableSize: 1].
  	newByteLen := highBit + shiftCount + 7 // 8.
  	self remapOop: anOop in: [newOop := interpreterProxy instantiateClass: (interpreterProxy fetchClassOf: anOop)
  					indexableSize: newByteLen].
  	newDigitLen := newByteLen + 3 // 4.
  	self
  		cDigitLshift: shiftCount
+ 		from: (self pointerToFirstDigitOfLargeInt: anOop)
- 		from: (self firstIndexableField: anOop as: #'unsigned int *')
  		len: oldDigitLen
+ 		to: (self pointerToFirstDigitOfLargeInt: newOop)
- 		to: (self firstIndexableField: newOop as: #'unsigned int *')
  		len: newDigitLen.
  	^ newOop!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digit:Rshift:lookfirst: (in category 'oop functions') -----
  digit: anOop Rshift: shiftCount lookfirst: a 
  	"Attention: this method invalidates all oop's!! Only newBytes is valid at return."
  	"Shift right 32*digitShift+bitShift bits, 0<=bitShift<32.         
  	Discard all digits beyond a, and all zeroes at or below a."
  	"Does not normalize."
  	| newByteLen newOop oldBitLen newBitLen oldDigitLen newDigitLen |
+ 	oldBitLen := self cDigitHighBit: (self pointerToFirstDigitOfLargeInt: anOop) len: a.
- 	oldBitLen := self cDigitHighBit: (self firstIndexableField: anOop as: #'unsigned int *') len: a.
  	oldDigitLen := oldBitLen + 31 // 32.
  	newBitLen := oldBitLen - shiftCount.
  	newBitLen <= 0 ifTrue: ["All bits lost"
  		^ interpreterProxy
  			instantiateClass: (interpreterProxy fetchClassOf: anOop)
  			indexableSize: 0].
  	newByteLen := newBitLen + 7 // 8.
  	newDigitLen := newByteLen + 3 // 4.
  	self remapOop: anOop in: [newOop := interpreterProxy instantiateClass: (interpreterProxy fetchClassOf: anOop)
  					indexableSize: newByteLen].
  	self
  		cDigitRshift: shiftCount
+ 		from: (self pointerToFirstDigitOfLargeInt: anOop)
- 		from: (self firstIndexableField: anOop as: #'unsigned int *')
  		len: oldDigitLen
+ 		to: (self pointerToFirstDigitOfLargeInt: newOop)
- 		to: (self firstIndexableField: newOop as: #'unsigned int *')
  		len: newDigitLen.
  	^ newOop!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitAddLarge:with: (in category 'oop functions') -----
  digitAddLarge: firstInteger with: secondInteger 
  	"Does not need to normalize!!"
  	| over firstDigitLen secondDigitLen shortInt shortDigitLen longInt longDigitLen sum newSum neg |
  	<var: #over type: #'unsigned int'>
  	firstDigitLen := self digitSizeOfLargeInt: firstInteger.
  	secondDigitLen := self digitSizeOfLargeInt: secondInteger.
  	neg := (interpreterProxy fetchClassOf: firstInteger)
  		= interpreterProxy classLargeNegativeInteger.
  	firstDigitLen <= secondDigitLen
  		ifTrue: 
  			[shortInt := firstInteger.
  			shortDigitLen := firstDigitLen.
  			longInt := secondInteger.
  			longDigitLen := secondDigitLen]
  		ifFalse: 
  			[shortInt := secondInteger.
  			shortDigitLen := secondDigitLen.
  			longInt := firstInteger.
  			longDigitLen := firstDigitLen].
  	"	sum := Integer new: len neg: firstInteger negative."
  	self remapOop: #(shortInt longInt ) in: [sum := self createLargeIntegerNeg: neg digitLength: longDigitLen].
  	over := self
+ 				cDigitAdd: (self pointerToFirstDigitOfLargeInt: shortInt)
- 				cDigitAdd: (self firstIndexableField: shortInt as: #'unsigned int *')
  				len: shortDigitLen
+ 				with: (self pointerToFirstDigitOfLargeInt: longInt)
- 				with: (self firstIndexableField: longInt as: #'unsigned int *')
  				len: longDigitLen
+ 				into: (self pointerToFirstDigitOfLargeInt: sum).
- 				into: (self firstIndexableField: sum as: #'unsigned int *').
  	over > 0
  		ifTrue: 
  			["sum := sum growby: 1."
  			self remapOop: sum in: [newSum := self createLargeIntegerNeg: neg byteLength: longDigitLen * 4 + 1].
  			self
+ 				cDigitCopyFrom: (self pointerToFirstDigitOfLargeInt: sum)
+ 				to: (self pointerToFirstDigitOfLargeInt: newSum)
- 				cDigitCopyFrom: (self firstIndexableField: sum as: #'unsigned int *')
- 				to: (self firstIndexableField: newSum as: #'unsigned int *')
  				len: longDigitLen.
  			sum := newSum.
  			"C index!!"
+ 			self cDigitOf: (self pointerToFirstDigitOfLargeInt: sum)
- 			self cDigitOf: (self firstIndexableField: sum as: #'unsigned int *')
  				at: longDigitLen put: over]
  		ifFalse:
  			[sum := neg 
  				ifTrue: [self normalizeNegative: sum]
  				ifFalse: [self normalizePositive: sum]].
  	^ sum!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitBitLogic:with:opIndex: (in category 'oop functions') -----
  digitBitLogic: firstInteger with: secondInteger opIndex: opIx 
  	"Bit logic here is only implemented for positive integers or Zero;
  	if rec or arg is negative, it fails."
  	| firstLarge secondLarge firstLen secondLen shortLen shortLarge longLen longLarge result |
  	(interpreterProxy isIntegerObject: firstInteger)
  		ifTrue: 
  			[(interpreterProxy integerValueOf: firstInteger)
  				< 0 ifTrue: [^ interpreterProxy primitiveFail].
  			"convert it to a not normalized LargeInteger"
  			self remapOop: secondInteger in: [firstLarge := self createLargeFromSmallInteger: firstInteger]]
  		ifFalse: 
  			[(interpreterProxy fetchClassOf: firstInteger)
  				= interpreterProxy classLargeNegativeInteger ifTrue: [^ interpreterProxy primitiveFail].
  			firstLarge := firstInteger].
  	(interpreterProxy isIntegerObject: secondInteger)
  		ifTrue: 
  			[(interpreterProxy integerValueOf: secondInteger)
  				< 0 ifTrue: [^ interpreterProxy primitiveFail].
  			"convert it to a not normalized LargeInteger"
  			self remapOop: firstLarge in: [secondLarge := self createLargeFromSmallInteger: secondInteger]]
  		ifFalse: 
  			[(interpreterProxy fetchClassOf: secondInteger)
  				= interpreterProxy classLargeNegativeInteger ifTrue: [^ interpreterProxy primitiveFail].
  			secondLarge := secondInteger].
  	firstLen := self byteSizeOfLargeInt: firstLarge.
  	secondLen := self byteSizeOfLargeInt: secondLarge.
  	firstLen < secondLen
  		ifTrue: 
  			[shortLen := firstLen.
  			shortLarge := firstLarge.
  			longLen := secondLen.
  			longLarge := secondLarge]
  		ifFalse: 
  			[shortLen := secondLen.
  			shortLarge := secondLarge.
  			longLen := firstLen.
  			longLarge := firstLarge].
  	self remapOop: #(shortLarge longLarge ) in: [result := interpreterProxy instantiateClass: interpreterProxy classLargePositiveInteger indexableSize: longLen].
  	self
  		cDigitOp: opIx
+ 		short: (self pointerToFirstDigitOfLargeInt: shortLarge)
- 		short: (self firstIndexableField: shortLarge as: #'unsigned int *')
  		len: shortLen + 3 // 4
+ 		long: (self pointerToFirstDigitOfLargeInt: longLarge)
- 		long: (self firstIndexableField: longLarge as: #'unsigned int *')
  		len: longLen + 3 // 4
+ 		into: (self pointerToFirstDigitOfLargeInt: result).
- 		into: (self firstIndexableField: result as: #'unsigned int *').
  	interpreterProxy failed ifTrue: [^ 0].
  	^ self normalizePositive: result!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitCompareLarge:with: (in category 'oop functions') -----
  digitCompareLarge: firstInteger with: secondInteger 
  	"Compare the magnitude of firstInteger with that of secondInteger.      
  	Return a code of 1, 0, -1 for firstInteger >, = , < secondInteger"
  	| firstDigitLen secondDigitLen |
  	firstDigitLen := self digitSizeOfLargeInt: firstInteger.
  	secondDigitLen := self digitSizeOfLargeInt: secondInteger.
  	secondDigitLen ~= firstDigitLen
  		ifTrue: [secondDigitLen > firstDigitLen
  				ifTrue: [^ -1 asOop: SmallInteger]
  				ifFalse: [^ 1 asOop: SmallInteger]].
  	^ (self
+ 		cDigitCompare: (self pointerToFirstDigitOfLargeInt: firstInteger)
+ 		with: (self pointerToFirstDigitOfLargeInt: secondInteger)
- 		cDigitCompare: (self firstIndexableField: firstInteger as: #'unsigned int *')
- 		with: (self firstIndexableField: secondInteger as: #'unsigned int *')
  		len: firstDigitLen)
  		asOop: SmallInteger!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitDivLarge:with:negative: (in category 'oop functions') -----
  digitDivLarge: firstInteger with: secondInteger negative: neg 
  	"Does not normalize."
  	"Division by zero has to be checked in caller."
  	| firstDigitLen secondDigitLen quoDigitLen d div rem quo result |
  	firstDigitLen := self digitSizeOfLargeInt: firstInteger.
  	secondDigitLen := self digitSizeOfLargeInt: secondInteger.
  	quoDigitLen := firstDigitLen - secondDigitLen + 1.
  	quoDigitLen <= 0
  		ifTrue: 
  			[self remapOop: firstInteger in: [result := interpreterProxy instantiateClass: interpreterProxy classArray indexableSize: 2].
  			result stAt: 1 put: (0 asOop: SmallInteger).
  			result stAt: 2 put: firstInteger.
  			^ result].
  	"set rem and div to copies of firstInteger and secondInteger, respectively. 
  	  However,  
  	 to facilitate use of Knuth's algorithm, multiply rem and div by 2 (that 
  	 is, shift)   
  	 until the high word of div is >=16r80000000"
  	d := 32 - (self cHighBit32: (self unsafeDigitOfLargeInt: secondInteger at: secondDigitLen)).
  	self remapOop: firstInteger
  		in: 
  			[div := self digit: secondInteger Lshift: d.
  			div := self largeInt: div growTo: (self digitSizeOfLargeInt: div) + 1 * 4].
  	self remapOop: div
  		in: 
  			[rem := self digit: firstInteger Lshift: d.
  			(self digitSizeOfLargeInt: rem) = firstDigitLen
  				ifTrue: [rem := self largeInt: rem growTo: firstDigitLen + 1 * 4]].
  	self remapOop: #(div rem ) in: [quo := self createLargeIntegerNeg: neg digitLength: quoDigitLen].
  	self
+ 		cDigitDiv: (self pointerToFirstDigitOfLargeInt: div)
- 		cDigitDiv: (self firstIndexableField: div as: #'unsigned int *')
  		len: (self digitSizeOfLargeInt: div)
+ 		rem: (self pointerToFirstDigitOfLargeInt: rem)
- 		rem: (self firstIndexableField: rem as: #'unsigned int *')
  		len: (self digitSizeOfLargeInt: rem)
+ 		quo: (self pointerToFirstDigitOfLargeInt: quo)
- 		quo: (self firstIndexableField: quo as: #'unsigned int *')
  		len: (self digitSizeOfLargeInt: quo).
  	self remapOop: #(quo ) in: [rem := self
  					digit: rem
  					Rshift: d
  					lookfirst: (self digitSizeOfLargeInt: div)
  							- 1].
  	"^ Array with: quo with: rem"
  	self remapOop: #(quo rem ) in: [result := interpreterProxy instantiateClass: interpreterProxy classArray indexableSize: 2].
  	result stAt: 1 put: quo.
  	result stAt: 2 put: rem.
  	^ result!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitMontgomery:times:modulo:mInvModB: (in category 'oop functions') -----
  digitMontgomery: firstLarge times: secondLarge modulo: thirdLarge mInvModB: mInv
  	<var: #mInv type: #'unsigned int'>
  	| firstLen secondLen thirdLen prod |
  	firstLen := self digitSizeOfLargeInt: firstLarge.
  	secondLen := self digitSizeOfLargeInt: secondLarge.
  	thirdLen := self digitSizeOfLargeInt: thirdLarge.
  	(firstLen <= thirdLen and: [secondLen <= thirdLen]) ifFalse: [^interpreterProxy primitiveFail].
  
  	self remapOop: #(firstLarge secondLarge thirdLarge)
  		in: [prod := interpreterProxy instantiateClass: interpreterProxy classLargePositiveInteger indexableSize: thirdLen * 4].
  	self
+ 		cDigitMontgomery: (self pointerToFirstDigitOfLargeInt: firstLarge)
- 		cDigitMontgomery: (self firstIndexableField: firstLarge as: #'unsigned int *')
  		len: firstLen
+ 		times: (self pointerToFirstDigitOfLargeInt: secondLarge)
- 		times: (self firstIndexableField: secondLarge as: #'unsigned int *')
  		len: secondLen
+ 		modulo: (self pointerToFirstDigitOfLargeInt: thirdLarge)
- 		modulo: (self firstIndexableField: thirdLarge as: #'unsigned int *')
  		len: thirdLen
  		mInvModB: mInv
+ 		into: (self pointerToFirstDigitOfLargeInt: prod).
- 		into: (self firstIndexableField: prod as: #'unsigned int *').
  	^self normalizePositive: prod!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitMultiplyLarge:with:negative: (in category 'oop functions') -----
  digitMultiplyLarge: firstInteger with: secondInteger negative: neg 
  	"Normalizes."
  	| firstLen secondLen shortInt shortLen longInt longLen prod |
  	firstLen := self byteSizeOfLargeInt: firstInteger.
  	secondLen := self byteSizeOfLargeInt: secondInteger.
  	firstLen <= secondLen
  		ifTrue: 
  			[shortInt := firstInteger.
  			shortLen := firstLen.
  			longInt := secondInteger.
  			longLen := secondLen]
  		ifFalse: 
  			[shortInt := secondInteger.
  			shortLen := secondLen.
  			longInt := firstInteger.
  			longLen := firstLen].
  	self remapOop: #(shortInt longInt) in: [prod := self createLargeIntegerNeg: neg byteLength: longLen + shortLen].
  	self
+ 		cDigitMultiply: (self pointerToFirstDigitOfLargeInt: shortInt)
- 		cDigitMultiply: (self firstIndexableField: shortInt as: #'unsigned int *')
  		len: shortLen + 3 // 4
+ 		with: (self pointerToFirstDigitOfLargeInt: longInt)
- 		with: (self firstIndexableField: longInt as: #'unsigned int *')
  		len: longLen + 3 // 4
+ 		into: (self pointerToFirstDigitOfLargeInt: prod)
- 		into: (self firstIndexableField: prod as: #'unsigned int *')
  		len: longLen + shortLen + 3 // 4.
  	^neg 
  		ifTrue: [self normalizeNegative: prod]
  		ifFalse: [self normalizePositive: prod]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>digitSubLarge:with: (in category 'oop functions') -----
  digitSubLarge: firstInteger with: secondInteger 
  	"Normalizes."
  	| firstDigitLen secondDigitLen larger largeDigitLen smaller smallerDigitLen neg resDigitLen res firstNeg |
  	firstNeg := (interpreterProxy fetchClassOf: firstInteger)
  				= interpreterProxy classLargeNegativeInteger.
  	firstDigitLen := self digitSizeOfLargeInt: firstInteger.
  	secondDigitLen := self digitSizeOfLargeInt: secondInteger.
  	firstDigitLen = secondDigitLen ifTrue: 
  		[[firstDigitLen > 1
  		  and: [(self unsafeDigitOfLargeInt: firstInteger at: firstDigitLen) = (self unsafeDigitOfLargeInt: secondInteger at: firstDigitLen)]]
  			whileTrue: [firstDigitLen := firstDigitLen - 1].
  		secondDigitLen := firstDigitLen].
  	(firstDigitLen < secondDigitLen
  	 or: [firstDigitLen = secondDigitLen
  		 and: [(self unsafeDigitOfLargeInt: firstInteger at: firstDigitLen) < (self unsafeDigitOfLargeInt: secondInteger at: firstDigitLen)]])
  		ifTrue: 
  			[larger := secondInteger.
  			largeDigitLen := secondDigitLen.
  			smaller := firstInteger.
  			smallerDigitLen := firstDigitLen.
  			neg := firstNeg == false]
  		ifFalse: 
  			[larger := firstInteger.
  			largeDigitLen := firstDigitLen.
  			smaller := secondInteger.
  			smallerDigitLen := secondDigitLen.
  			neg := firstNeg].
  	resDigitLen := largeDigitLen.
  	self remapOop: #(smaller larger)
  		in: [res := self createLargeIntegerNeg: neg digitLength: resDigitLen].
  	self
+ 		cDigitSub: (self pointerToFirstDigitOfLargeInt: smaller)
- 		cDigitSub: (self firstIndexableField: smaller as: #'unsigned int *')
  		len: smallerDigitLen
+ 		with: (self pointerToFirstDigitOfLargeInt: larger)
- 		with: (self firstIndexableField: larger as: #'unsigned int *')
  		len: largeDigitLen
+ 		into: (self pointerToFirstDigitOfLargeInt: res).
- 		into: (self firstIndexableField: res as: #'unsigned int *').
  	^neg 
  		ifTrue: [self normalizeNegative: res]
  		ifFalse: [self normalizePositive: res]!

Item was changed:
  ----- Method: LargeIntegersPlugin>>highBitOfLargeInt: (in category 'util') -----
  highBitOfLargeInt: anOop 
  	<inline: true>
  	^ self
+ 		cDigitHighBit: (self pointerToFirstDigitOfLargeInt: anOop)
- 		cDigitHighBit: (self firstIndexableField: anOop as: #'unsigned int *')
  		len: (self digitSizeOfLargeInt: anOop)!

Item was changed:
  ----- Method: LargeIntegersPlugin>>largeInt:growTo: (in category 'oop util') -----
  largeInt: aBytesObject growTo: newByteLen 
  	"Attention: this method invalidates all oop's!! Only newBytes is valid at return."
  	"Does not normalize."
  	| newBytes oldDigitLen newDigitLen copyLen |
  	self remapOop: aBytesObject in: [newBytes := interpreterProxy instantiateClass: (interpreterProxy fetchClassOf: aBytesObject)
  					indexableSize: newByteLen].
  	newDigitLen := newByteLen + 3 // 4.
  	oldDigitLen := self digitSizeOfLargeInt: aBytesObject.
  	copyLen := oldDigitLen < newDigitLen
  					ifTrue: [oldDigitLen]
  					ifFalse: [newDigitLen].
  	self
+ 		cDigitCopyFrom: (self pointerToFirstDigitOfLargeInt: aBytesObject)
+ 		to: (self pointerToFirstDigitOfLargeInt: newBytes)
- 		cDigitCopyFrom: (self firstIndexableField: aBytesObject as: #'unsigned int *')
- 		to: (self firstIndexableField: newBytes as: #'unsigned int *')
  		len: copyLen.
  	^newBytes!

Item was added:
+ ----- Method: LargeIntegersPlugin>>pointerToFirstDigitOfLargeInt: (in category 'util') -----
+ pointerToFirstDigitOfLargeInt: bytesObject
+ 	<inline: true>
+ 	<returnTypeC: #'unsigned int'>
+ 	^interpreterProxy cCoerce: (interpreterProxy firstIndexableField: bytesObject) to: #'unsigned int *'!

Item was changed:
  ----- Method: LargeIntegersPlugin>>unsafeByteOfLargeInt:at: (in category 'util') -----
  unsafeByteOfLargeInt: bytesObj at: ix
  	"Argument bytesObj must not be aSmallInteger!!"
  	<inline: true>
  	<returnTypeC: #'unsigned char'>
+ 	^(interpreterProxy cCoerce: (interpreterProxy firstIndexableField: bytesObj) to: #'unsigned char *') at: ix - 1!
- 	^(self firstIndexableField: bytesObj as: #'unsigned char *') at: ix - 1!

Item was changed:
  ----- Method: LargeIntegersPlugin>>unsafeDigitOfLargeInt:at: (in category 'util') -----
  unsafeDigitOfLargeInt: anOop at: ix
  	"Argument must not be aSmallInteger!!"
  	<inline: true>
  	<returnTypeC: #'unsigned int'>
+ 	^self cDigitOf: (self pointerToFirstDigitOfLargeInt: anOop) at: ix - 1!
- 	^self cDigitOf: (self firstIndexableField: anOop as: #'unsigned int *') at: ix - 1!



More information about the Vm-dev mailing list