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

commits at source.squeak.org commits at source.squeak.org
Wed Sep 30 03:01:59 UTC 2020


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

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

Name: VMMaker.oscog-eem.2831
Author: eem
Time: 29 September 2020, 8:01:48.222992 pm
UUID: f4fed277-6b62-4e79-9147-c5405589f2b1
Ancestors: VMMaker.oscog-eem.2830

Cogit: (IAAM) correctly implement the fix in VMMaker.oscog-eem.2824.  The previous version of the fix used methodHeaderOf: to get what was intended to be the pointer to the cog method, if newMethod was in fact cogged, but methodHeaderOf: always answers the byetcoded method header.  What is needed here is the actual pointer to the cog method, i.e. rawHeaderOf:.

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

Item was changed:
  ----- Method: CoInterpreterPrimitives>>cloneContext: (in category 'primitive support') -----
  cloneContext: aContext
  	"Copy a Context.  There are complications here.
  	 Fields of married contexts must be mapped to image-level values.
  	 In mapping a machine code pc, a code compaction may occur.
  	 In this case return through machine code is impossible without
  	 updating a C call stack return address, since the machine code
  	 method that invoked this primitive could have moved.  So if this
  	 happens, map to an interpreter frame and return to the interpreter."
  	| cloned couldBeCogMethod |
  	self assert: ((objectMemory isCompiledMethod: newMethod)
  				and: [(self primitiveIndexOf: newMethod) > 0]).
  
+ 	couldBeCogMethod := objectMemory rawHeaderOf: newMethod.
- 	couldBeCogMethod := objectMemory methodHeaderOf: newMethod.
  	cloned := super cloneContext: aContext.
  
  	"If the header has changed in any way then it is most likely that machine code
  	 has been moved or reclaimed for this method and so normal return is impossible."
+ 	couldBeCogMethod ~= (objectMemory rawHeaderOf: newMethod) ifTrue:
- 	couldBeCogMethod ~= (objectMemory methodHeaderOf: newMethod) ifTrue:
  		[self convertToInterpreterFrame: 0.
  		 self push: cloned.
  		 cogit ceInvokeInterpret
  		 "NOTREACHED"].
  
  	^cloned!

Item was changed:
  ----- Method: CoInterpreterPrimitives>>primitiveInstVarAt (in category 'object access primitives') -----
  primitiveInstVarAt
  	"Override to deal with potential code compaction on accessing context pcs"
  	| index rcvr hdr fmt totalLength fixedFields value |
  	self assert: ((objectMemory isCompiledMethod: newMethod)
  				and: [(self primitiveIndexOf: newMethod) > 0]).
  
  	index := self stackTop.
  	rcvr := self stackValue: 1.
  	((objectMemory isNonIntegerObject: index)
  	 or: [argumentCount > 1 "e.g. object:instVarAt:"
  		and: [objectMemory isOopForwarded: rcvr]]) ifTrue:
  		[^self primitiveFailFor: PrimErrBadArgument].
  	(objectMemory isImmediate: rcvr) ifTrue: [^self primitiveFailFor: PrimErrInappropriate].
  	index := objectMemory integerValueOf: index.
  	hdr := objectMemory baseHeader: rcvr.
  	fmt := objectMemory formatOfHeader: hdr.
  	totalLength := objectMemory lengthOf: rcvr baseHeader: hdr format: fmt.
  	fixedFields := objectMemory fixedFieldsOf: rcvr format: fmt length: totalLength.
  	(index >= 1 and: [index <= fixedFields]) ifFalse:
  		[^self primitiveFailFor: PrimErrBadIndex].
  	(fmt = objectMemory indexablePointersFormat
  	 and: [objectMemory isContextHeader: hdr])
  		ifTrue:
+ 			[| couldBeCogMethod |
- 			[| methodHeader |
  			 self externalWriteBackHeadFramePointers.
  			 "Note newMethod's header to check for potential code compaction
  			  in mapping the context's pc from machine code to bytecode."
  			 index = InstructionPointerIndex ifTrue:
+ 				[couldBeCogMethod := objectMemory rawHeaderOf: newMethod].
- 				[methodHeader := objectMemory methodHeaderOf: newMethod].
  			 value := self externalInstVar: index - 1 ofContext: rcvr.
  			"If the header has changed in any way then it is most likely that machine code
  			 has been moved or reclaimed for this method and so normal return is impossible."
  			 (index = InstructionPointerIndex
+ 			  and: [couldBeCogMethod ~= (objectMemory rawHeaderOf: newMethod)]) ifTrue:
- 			  and: [methodHeader ~= (objectMemory methodHeaderOf: newMethod)]) ifTrue:
  					[self pop: argumentCount + 1.
  					 self convertToInterpreterFrame: 0.
  					 self push: value.
  					 cogit ceInvokeInterpret
  					 "NOTREACHED"]]
  		ifFalse: [value := self subscript: rcvr with: index format: fmt].
  	self pop: argumentCount + 1 thenPush: value!

Item was changed:
  ----- Method: CoInterpreterPrimitives>>primitiveSlotAt (in category 'object access primitives') -----
  primitiveSlotAt
  	"Answer a slot in an object.  This numbers all slots from 1, ignoring the distinction between
  	 named and indexed inst vars.  In objects with both named and indexed inst vars, the named
  	 inst vars precede the indexed ones.  In non-object indexed objects (objects that contain
  	 bits, not object references) this primitive answers the raw integral value at each slot. 
  	 e.g. for Strings it answers the character code, not the Character object at each slot."
  
  	"Override to deal with potential code compaction on accessing context pcs"
  	| index rcvr fmt numSlots |
  	self assert: ((objectMemory isCompiledMethod: newMethod)
  				and: [(self primitiveIndexOf: newMethod) > 0]).
  
  	index := self stackTop.
  	rcvr := self stackValue: 1.
  	(objectMemory isIntegerObject: index) ifFalse:
  		[^self primitiveFailFor: PrimErrBadArgument].
  	(objectMemory isImmediate: rcvr) ifTrue:
  		[^self primitiveFailFor: PrimErrBadReceiver].
  	fmt := objectMemory formatOf: rcvr.
  	index := (objectMemory integerValueOf: index) - 1.
  
  	fmt <= objectMemory lastPointerFormat ifTrue:
  		[numSlots := objectMemory numSlotsOf: rcvr.
  		 (self asUnsigned: index) < numSlots ifTrue:
  			[| value numLiveSlots |
  			 (objectMemory isContextNonImm: rcvr)
  				ifTrue:
  					[self externalWriteBackHeadFramePointers.
  					 numLiveSlots := (self stackPointerForMaybeMarriedContext: rcvr) + CtxtTempFrameStart.
  					 (self asUnsigned: index) < numLiveSlots
  						ifTrue:
+ 							[| couldBeCogMethod |
- 							[| methodHeader |
  							 "Note newMethod's header to check for potential code compaction
  							  in mapping the context's pc from machine code to bytecode."
  							 index = InstructionPointerIndex ifTrue:
+ 								[couldBeCogMethod := objectMemory rawHeaderOf: newMethod].
- 								[methodHeader := objectMemory methodHeaderOf: newMethod].
  							 value := self externalInstVar: index ofContext: rcvr.
  							"If the header has changed in any way then it is most likely that machine code
  							 has been moved or reclaimed for this method and so normal return is impossible."
  							 (index = InstructionPointerIndex
+ 							  and: [couldBeCogMethod ~= (objectMemory rawHeaderOf: newMethod)]) ifTrue:
- 							  and: [methodHeader ~= (objectMemory methodHeaderOf: newMethod)]) ifTrue:
  									[self pop: argumentCount + 1.
  									 self convertToInterpreterFrame: 0.
  									 self push: value.
  									 cogit ceInvokeInterpret
  									 "NOTREACHED"]]
  						ifFalse: [value := objectMemory nilObject]]
  				ifFalse:
  					[value := objectMemory fetchPointer: index ofObject: rcvr].
  			 self pop: argumentCount + 1 thenPush: value.
  			 ^0].
  		 ^self primitiveFailFor: PrimErrBadIndex].
  
  	fmt >= objectMemory firstByteFormat ifTrue:
  		[fmt >= objectMemory firstCompiledMethodFormat ifTrue:
  			[^self primitiveFailFor: PrimErrUnsupported].
  		 numSlots := objectMemory numBytesOfBytes: rcvr.
  		 (self asUnsigned: index) < numSlots ifTrue:
  			[self pop: argumentCount + 1 thenPushInteger: (objectMemory fetchByte: index ofObject: rcvr).
  			 ^0].
  		 ^self primitiveFailFor: PrimErrBadIndex].
  
  	(objectMemory hasSpurMemoryManagerAPI
  	 and: [fmt >= objectMemory firstShortFormat]) ifTrue:
  		[numSlots := objectMemory num16BitUnitsOf: rcvr.
  		 (self asUnsigned: index) < numSlots ifTrue:
  			[self pop: argumentCount + 1 thenPushInteger: (objectMemory fetchUnsignedShort16: index ofObject: rcvr).
  			 ^0].
  		 ^self primitiveFailFor: PrimErrBadIndex].
  
  	fmt = objectMemory sixtyFourBitIndexableFormat ifTrue:
  		[numSlots := objectMemory num64BitUnitsOf: rcvr.
  		 (self asUnsigned: index) < numSlots ifTrue:
  			[self pop: argumentCount + 1
  				thenPush: (self positive64BitIntegerFor: (objectMemory fetchLong64: index ofObject: rcvr)).
  			 ^0].
  		 ^self primitiveFailFor: PrimErrBadIndex].
  
  	fmt >= objectMemory firstLongFormat ifTrue:
  		[numSlots := objectMemory num32BitUnitsOf: rcvr.
  		 (self asUnsigned: index) < numSlots ifTrue:
  			[self pop: argumentCount + 1
  				thenPush: (self positive32BitIntegerFor: (objectMemory fetchLong32: index ofObject: rcvr)).
  			 ^0].
  		 ^self primitiveFailFor: PrimErrBadIndex].
  
  	^self primitiveFailFor: PrimErrBadReceiver!



More information about the Vm-dev mailing list