[Vm-dev] VM Maker: VMMaker.oscog-eem.1888.mcz

commits at source.squeak.org commits at source.squeak.org
Wed Jun 15 16:36:54 UTC 2016


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

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

Name: VMMaker.oscog-eem.1888
Author: eem
Time: 15 June 2016, 9:34:25.090332 am
UUID: 26b2e5b1-5819-45e5-9340-559278c9712c
Ancestors: VMMaker.oscog-eem.1887

Integrate changes proposed by Laura Perez Cerrato

"Working on JPEGReadWriter2 I noticed that both reading and writing primitives include a sanity check that ensures that the source/destination Smalltalk bitmap has the exact size in bytes needed, instead of checking that its size is at least that needed. Some BitBlt primitives perform the same check, thus not allowing operations with forms with associated bitmaps with a size greater than needed. 

When performing operations with images, and specially when such images are large in size, actually processing the images takes a small fraction of the time it takes to perform the whole operation, while allocating and deallocating correctly sized bitmaps takes much longer. If one would wish to process a series of similarly sized images (with a definite maximum size), it would be desirable to allocate a bitmap big enough to hold any of them only once and then reuse it, thus avoiding the aforementioned cost. Checking that source and destination bitmaps are big enough instead of checking that their size is exactly that which is expected would allow that optimization.

A brief exploration of BitBlt and JPEGReadWriter2's code, accompanied with some experimenting of what would happen if such sanity checks were modified as proposed, has lead me to thinking that these changes would be benefitial. I haven't observed any undesirable side effects (meaning, nothing seems to have blown up :))....."

In 1888 in London, Annie Besant organizes the  matchgirls strike of 1888, Handel's Israel in Egypt is recorded onto wax cylinder at The Crystal Palace, the earliest known recording of classical music, and the Oaths Act permits the oath of allegiance taken to the Sovereign by Members of Parliament to be affirmed rather than sworn to God, thus confirming the ability of atheists to sit in the House of Commons.

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

Item was changed:
  ----- Method: BitBltSimulation>>loadBitBltDestForm (in category 'interpreter interface') -----
  loadBitBltDestForm
  	"Load the dest form for BitBlt. Return false if anything is wrong, true otherwise."
  
  	| destBitsSize |
  	<inline: true>
  	destBits := interpreterProxy fetchPointer: FormBitsIndex ofObject: destForm.
  	destWidth := interpreterProxy fetchInteger: FormWidthIndex ofObject: destForm.
  	destHeight := interpreterProxy fetchInteger: FormHeightIndex ofObject: destForm.
  	(destWidth >= 0 and: [destHeight >= 0])
  		ifFalse: [^ false].
  	destDepth := interpreterProxy fetchInteger: FormDepthIndex ofObject: destForm.
  	destMSB := destDepth > 0.
  	destDepth < 0 ifTrue:[destDepth := 0 - destDepth].
  	"Ignore an integer bits handle for Display in which case 
  	the appropriate values will be obtained by calling ioLockSurfaceBits()."
  	(interpreterProxy isIntegerObject: destBits) ifTrue:[
  		"Query for actual surface dimensions"
  		(self queryDestSurface: (interpreterProxy integerValueOf: destBits))
  			ifFalse:[^false].
  		destPPW := 32 // destDepth.
  		destBits := destPitch := 0.
  	] ifFalse:[
  		destPPW := 32 // destDepth.
  		destPitch := destWidth + (destPPW-1) // destPPW * 4.
  		destBitsSize := interpreterProxy byteSizeOf: destBits.
  		((interpreterProxy isWordsOrBytes: destBits)
+ 			and: [destBitsSize >= (destPitch * destHeight)])
- 			and: [destBitsSize = (destPitch * destHeight)])
  			ifFalse: [^ false].
  		"Skip header since external bits don't have one"
  		destBits := self oopForPointer: (interpreterProxy firstIndexableField: destBits).
  	].
  	^true!

Item was changed:
  ----- Method: BitBltSimulation>>loadBitBltSourceForm (in category 'interpreter interface') -----
  loadBitBltSourceForm
  	"Load the source form for BitBlt. Return false if anything is wrong, true otherwise."
  	| sourceBitsSize |
  	<inline: true>
  	sourceBits := interpreterProxy fetchPointer: FormBitsIndex ofObject: sourceForm.
  	sourceWidth := self fetchIntOrFloat: FormWidthIndex ofObject: sourceForm.
  	sourceHeight := self fetchIntOrFloat: FormHeightIndex ofObject: sourceForm.
  	(sourceWidth >= 0 and: [sourceHeight >= 0])
  		ifFalse: [^ false].
  	sourceDepth := interpreterProxy fetchInteger: FormDepthIndex ofObject: sourceForm.
  	sourceMSB := sourceDepth > 0.
  	sourceDepth < 0 ifTrue:[sourceDepth := 0 - sourceDepth].
  	"Ignore an integer bits handle for Display in which case 
  	the appropriate values will be obtained by calling ioLockSurfaceBits()."
  	(interpreterProxy isIntegerObject: sourceBits) ifTrue:[
  		"Query for actual surface dimensions"
  		(self querySourceSurface: (interpreterProxy integerValueOf: sourceBits))
  			ifFalse:[^false].
  		sourcePPW := 32 // sourceDepth.
  		sourceBits := sourcePitch := 0.
  	] ifFalse:[
  		sourcePPW := 32 // sourceDepth.
  		sourcePitch := sourceWidth + (sourcePPW-1) // sourcePPW * 4.
  		sourceBitsSize := interpreterProxy byteSizeOf: sourceBits.
  		((interpreterProxy isWordsOrBytes: sourceBits)
+ 			and: [sourceBitsSize >= (sourcePitch * sourceHeight)])
- 			and: [sourceBitsSize = (sourcePitch * sourceHeight)])
  			ifFalse: [^ false].
  		"Skip header since external bits don't have one"
  		sourceBits := self oopForPointer: (interpreterProxy firstIndexableField: sourceBits).
  	].
  	^true!

Item was changed:
  ----- Method: JPEGReadWriter2Plugin>>primJPEGReadImage:fromByteArray:onForm:doDithering:errorMgr: (in category 'primitives') -----
  primJPEGReadImage: aJPEGDecompressStruct fromByteArray: source onForm: form doDithering: ditherFlag errorMgr: aJPEGErrorMgr2Struct
  
  	| formBitmap formNativeDepth formDepth formWidth formHeight pixelsPerWord formPitch formBitmapSizeInBytes sourceSize formBitmapOOP formComponentBitSize formComponents wordsPerRow |
  	<export: true>
  	<var: #formBitmap type: 'unsigned int*'>
  
  	self
  		primitive: 'primJPEGReadImagefromByteArrayonFormdoDitheringerrorMgr'
  		parameters: #(ByteArray ByteArray Form Boolean ByteArray).
  
  	formBitmapOOP := interpreterProxy fetchPointer: 0 ofObject: form. 
  	formNativeDepth := interpreterProxy fetchInteger: 3 ofObject: form.
  	formWidth := interpreterProxy fetchInteger: 1 ofObject: form.
  	formHeight := interpreterProxy fetchInteger: 2 ofObject: form.
  	formDepth := formNativeDepth abs.
  	
  	"Various parameter checks"
  	interpreterProxy success:
  		(self cCode: 'interpreterProxy->stSizeOf(interpreterProxy->stackValue(4)) >= (sizeof(struct jpeg_decompress_struct))' inSmalltalk: []).
  	interpreterProxy success:
  		(self cCode: 'interpreterProxy->stSizeOf(interpreterProxy->stackValue(0)) >= (sizeof(struct error_mgr2))' inSmalltalk: []).
  	interpreterProxy failed ifTrue: [ ^ nil ].
  	
  	formComponents := formDepth ~= 8 ifTrue: [4] ifFalse: [1].
  	formComponentBitSize := formDepth ~= 16 ifTrue: [8] ifFalse: [4].
  	pixelsPerWord := 32 // (formComponents * formComponentBitSize).
  	wordsPerRow := (formWidth + pixelsPerWord - 1) // pixelsPerWord.
  	formPitch := formWidth + (pixelsPerWord-1) // pixelsPerWord * 4.
  	formBitmapSizeInBytes := interpreterProxy byteSizeOf: formBitmapOOP.
  	
  	interpreterProxy success: 
  		((interpreterProxy isWordsOrBytes: formBitmapOOP) and: 
+ 		[formBitmapSizeInBytes >= (formPitch * formHeight)]).
- 		[formBitmapSizeInBytes = (formPitch * formHeight)]).
  	interpreterProxy failed ifTrue: [^ nil].
  	
  	sourceSize := interpreterProxy stSizeOf: (interpreterProxy stackValue: 3).
  	
  	interpreterProxy success: (sourceSize ~= 0).
  	interpreterProxy failed ifTrue: [  ^ nil ].
  	
  	formBitmap := interpreterProxy firstIndexableField: formBitmapOOP.
  	
  	self 
  		cCode: 'primJPEGReadImagefromByteArrayonFormdoDitheringerrorMgrReadScanlines(
  			aJPEGDecompressStruct,
      			aJPEGErrorMgr2Struct,
  			source,
      			sourceSize,
      			ditherFlag,
      			formBitmap,
     			pixelsPerWord,
     			wordsPerRow,
      			formNativeDepth);'
  		inSmalltalk: [].!

Item was changed:
  ----- Method: JPEGReadWriter2Plugin>>primJPEGWriteImage:onByteArray:form:quality:progressiveJPEG:errorMgr: (in category 'primitives') -----
  primJPEGWriteImage: aJPEGCompressStruct onByteArray: destination form: form quality: quality progressiveJPEG: progressiveFlag errorMgr: aJPEGErrorMgr2Struct
  
  	| formBitmap formWidth formHeight formNativeDepth formDepth destinationSize pixelsPerWord wordsPerRow formPitch formBitmapSizeInBytes formBitmapOOP formComponentBitSize formComponents |
  	<export: true>
  	<var: #formBitmap type: 'unsigned int *'> 
  	<var: #destinationSize type: 'unsigned int'>
  
  	self
  		primitive: 'primJPEGWriteImageonByteArrayformqualityprogressiveJPEGerrorMgr'
  		parameters: #(ByteArray ByteArray Form SmallInteger Boolean ByteArray).
  
  	formBitmapOOP := interpreterProxy fetchPointer: 0 ofObject: form.
  	formWidth := interpreterProxy fetchInteger: 1 ofObject: form.
  	formHeight := interpreterProxy fetchInteger: 2 ofObject: form.
  	formNativeDepth := interpreterProxy fetchInteger: 3 ofObject: form.
  	formDepth := formNativeDepth abs.
  
  	"Various parameter checks"
  	interpreterProxy success:
  		(self cCode: 'interpreterProxy->stSizeOf(interpreterProxy->stackValue(5)) >= (sizeof(struct jpeg_compress_struct))' inSmalltalk: []).
  	interpreterProxy success: 
  		(self cCode: 'interpreterProxy->stSizeOf(interpreterProxy->stackValue(0)) >= (sizeof(struct error_mgr2))' inSmalltalk: []).
  	interpreterProxy failed ifTrue: [ ^ nil ].
  	
  	formComponents := formDepth ~= 8 ifTrue: [4] ifFalse: [1].
  	formComponentBitSize := formDepth ~= 16 ifTrue: [8] ifFalse: [4].
  	pixelsPerWord := 32 // (formComponents * formComponentBitSize).
  	wordsPerRow := (formWidth + pixelsPerWord - 1) // pixelsPerWord.
  	formPitch := wordsPerRow * 4.
  	formBitmapSizeInBytes := interpreterProxy byteSizeOf: formBitmapOOP.
  	interpreterProxy success: 
  		((interpreterProxy isWordsOrBytes: formBitmapOOP) and: 
+ 		[formBitmapSizeInBytes >= (formPitch * formHeight)]).
- 		[formBitmapSizeInBytes = (formPitch * formHeight)]).
  	interpreterProxy failed ifTrue: [ ^ nil ].
  	
  	formBitmap := interpreterProxy firstIndexableField: formBitmapOOP.
  	destinationSize := interpreterProxy stSizeOf: (interpreterProxy stackValue: 4).
  	(destinationSize = 0) 
  		ifFalse: [ self 
  			cCode: ' primJPEGWriteImageonByteArrayformqualityprogressiveJPEGerrorMgrWriteScanlines(
  				formWidth, 
  				formHeight, 
  				formNativeDepth, 
  				formBitmap, 
  				aJPEGCompressStruct,
  				aJPEGErrorMgr2Struct,
  				quality,
  				progressiveFlag,
  				pixelsPerWord, 
  				wordsPerRow, 
  				destination,
  				&destinationSize);'
  			inSmalltalk: []].
  	
  	^(self cCode: 'destinationSize' inSmalltalk: [0])
  		asOop: SmallInteger!



More information about the Vm-dev mailing list