Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2262.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.2262 Author: eem Time: 10 August 2017, 3:43:50.372252 pm UUID: 8b531242-de02-48aa-b418-8d2dde0bec6c Ancestors: VMMaker.oscog-sk.2261 LargeIntegers plugin Fix the crash for 2009 nthRoot: 100000 due to digitDivLarge:with:negative: failing to check if allocations fail. The example produces 600k byet long integers and so provokes plenty of allocation failures. In addition mark some support methods as <inline: #always> to eliminate their unnecessary uninlined versions. =============== Diff against VMMaker.oscog-sk.2261 =============== Item was changed: ----- Method: LargeIntegersPlugin>>byteSizeOfLargeInt: (in category 'util') ----- byteSizeOfLargeInt: bytesOop "Answer the number of bytes required to represent a LargeInteger. Precondition: bytesOop is not a small integer." + <inline: #always> ^ interpreterProxy slotSizeOf: bytesOop! Item was changed: ----- Method: LargeIntegersPlugin>>createLargeIntegerNeg:byteLength: (in category 'util') ----- createLargeIntegerNeg: neg byteLength: byteLength + <inline: #always> - <inline: true> ^interpreterProxy instantiateClass: (neg ifTrue: [interpreterProxy classLargeNegativeInteger] ifFalse: [interpreterProxy classLargePositiveInteger]) indexableSize: byteLength! Item was changed: ----- Method: LargeIntegersPlugin>>createLargeIntegerNeg:digitLength: (in category 'util') ----- createLargeIntegerNeg: neg digitLength: digitLength + <inline: #always> + ^self createLargeIntegerNeg: neg byteLength: digitLength * 4! - <inline: true> - ^self - createLargeIntegerNeg: neg byteLength: digitLength * 4! 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) 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]. + newOop ifNil: + [interpreterProxy primitiveFailFor: PrimErrNoMemory. + ^nil]. - newOop ifNil: [^interpreterProxy primitiveFailFor: PrimErrNoMemory]. newDigitLen := newByteLen + 3 // 4. self cDigitLshift: shiftCount from: (self pointerToFirstDigitOfLargeInt: anOop) len: oldDigitLen to: (self pointerToFirstDigitOfLargeInt: newOop) len: newDigitLen. ^ newOop! 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 ifNotNil: + [interpreterProxy stObject: result at: 1 put: (0 asOop: SmallInteger). + interpreterProxy stObject: result at: 2 put: firstInteger]. - interpreterProxy stObject: result at: 1 put: (0 asOop: SmallInteger). - interpreterProxy stObject: result at: 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" - 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 ifNotNil: + [div := self largeInt: div growTo: (self digitSizeOfLargeInt: div) + 1 * 4]. + div ifNil: [^div]]. - 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. + rem ifNotNil: + [(self digitSizeOfLargeInt: rem) = firstDigitLen ifTrue: + [rem := self largeInt: rem growTo: firstDigitLen + 1 * 4]]. + rem ifNil: [^rem]]. + self remapOop: #(div rem) + in: [quo := self createLargeIntegerNeg: neg digitLength: quoDigitLen]. - 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) len: (self digitSizeOfLargeInt: div) rem: (self pointerToFirstDigitOfLargeInt: rem) len: (self digitSizeOfLargeInt: rem) quo: (self pointerToFirstDigitOfLargeInt: quo) len: (self digitSizeOfLargeInt: quo). + self remapOop: quo + in: [rem := self digit: rem Rshift: d lookfirst: (self digitSizeOfLargeInt: div) - 1]. - 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 ifNotNil: + [interpreterProxy stObject: result at: 1 put: quo. + interpreterProxy stObject: result at: 2 put: rem]. + ^result! - self remapOop: #(quo rem ) in: [result := interpreterProxy instantiateClass: interpreterProxy classArray indexableSize: 2]. - interpreterProxy stObject: result at: 1 put: quo. - interpreterProxy stObject: result at: 2 put: rem. - ^ result! 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. + newBytes ifNil: + [interpreterProxy primitiveFailFor: PrimErrNoMemory. ^nil]]. - indexableSize: newByteLen]. - newBytes ifNil: [^interpreterProxy primitiveFailFor: PrimErrNoMemory]. newDigitLen := newByteLen + 3 // 4. oldDigitLen := self digitSizeOfLargeInt: aBytesObject. copyLen := oldDigitLen < newDigitLen ifTrue: [oldDigitLen] ifFalse: [newDigitLen]. self cDigitCopyFrom: (self pointerToFirstDigitOfLargeInt: aBytesObject) to: (self pointerToFirstDigitOfLargeInt: newBytes) len: copyLen. ^newBytes! Item was changed: ----- Method: LargeIntegersPlugin>>pointerToFirstDigitOfLargeInt: (in category 'util') ----- pointerToFirstDigitOfLargeInt: bytesObject + <inline: #always> - <inline: true> <returnTypeC: #'unsigned int *'> ^interpreterProxy cCoerce: (interpreterProxy firstIndexableField: bytesObject) to: #'unsigned int *'! Item was changed: ----- Method: LargeIntegersPlugin>>unsafeDigitOfLargeInt:at: (in category 'util') ----- unsafeDigitOfLargeInt: anOop at: ix "Argument must not be aSmallInteger!!" + <inline: #always> - <inline: true> <returnTypeC: #'unsigned int'> ^self cDigitOf: (self pointerToFirstDigitOfLargeInt: anOop) at: ix - 1! |
Free forum by Nabble | Edit this page |