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

commits at source.squeak.org commits at source.squeak.org
Tue Aug 3 19:18:27 UTC 2021


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

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

Name: VMMaker.oscog-eem.3020
Author: eem
Time: 3 August 2021, 12:17:53.467431 pm
UUID: 51321827-cf3b-4b5a-b120-04e3634dc699
Ancestors: VMMaker.oscog-eem.3019

Spur CoInterpreter: Improve checkForAndFollowForwardedPrimitiveState. Allow the method's first literal (if an FFI or named primitive) to be forwarded, unfollowing it *before* accessorDepth is fetched.  Follow it to the relevant depth.

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

Item was changed:
  ----- Method: StackInterpreter>>checkForAndFollowForwardedPrimitiveState (in category 'primitive support') -----
  checkForAndFollowForwardedPrimitiveState
+ 	"In Spur a primitive may fail due to encountering a forwarder. On failure, check the accessorDepth for the
+ 	 primitive and if non-negative scan the args to the depth, following any forwarders.  Answer if any are found
+ 	 so the prim can be retried.  The primitive index is derived from newMethod.
- 	"In Spur a primitive may fail due to encountering a forwarder. On failure,
- 	 check the accessorDepth for the primitive and if non-negative scan the
- 	 args to the depth, following any forwarders.  Answer if any are found so
- 	 the prim can be retried.  The primitive index is derived from newMethod.
  
  	 See http://www.mirandabanda.org/cogblog/2014/02/08/primitives-and-the-partial-read-barrier/
  	 and SpurMemoryManager's class comment."
  
  	<option: #SpurObjectMemory>
+ 	| primIndex accessorDepth found |
- 	| primIndex accessorDepth found scannedStackFrame |
  	self assert: self failed.
+ 	found := false.
- 	found := scannedStackFrame := false.
  	primIndex := self primitiveIndexOf: newMethod.
  	self assert: (argumentCount = (self argumentCountOf: newMethod) or: [self isMetaPrimitiveIndex: primIndex]).
+ 	"First things first; make sure the metadata has been followed before it is accessed to derive accessorDepth..."
+ 	((self isCalloutPrimitiveIndex: primIndex)
+ 	 and: [self unfollowFirstLiteralOfMaybeCalloutMethod: newMethod primitiveIndex: primIndex]) ifTrue:
+ 		[found := true].
  	"If the primitive is one of the meta primitives PrimNumberDoPrimitive or PrimNumberDoExternalCall, then
  	 metaAccessorDepth will have been set to nil at the start of the primitive, and to the accessor depth of the
  	 called primitive (or external call) immediately before dispatch.  Hence if primIndex is that of a meta primitive
  	 then if metaAccessorDepth is -2, the accessor depth is that of the meta primitive, and if > -2, then
  	 metaAccessorDepth is the accessor depth of the primitive (or external call).  Similarly, if the primitive is
  	 primitiveExternalCall then the accessor depth is that of primitiveExternalCall until primitiveFunctionPointer
  	 is assigned, at which point the accessor depth is taken from the slot in newMethod's first literal."
  	accessorDepth := ((self isMetaPrimitiveIndex: primIndex)
  						 and: [metaAccessorDepth > -2])
  							ifTrue: [metaAccessorDepth]
  							ifFalse:
  								[(primIndex = PrimNumberExternalCall
  								  and: [primitiveFunctionPointer ~~ #primitiveExternalCall])
  									ifTrue: [self primitiveAccessorDepthForExternalPrimitiveMethod: newMethod]
  									ifFalse: [primitiveAccessorDepthTable at: primIndex]].
  	self assert: (self saneFunctionPointerForFailureOfPrimIndex: primIndex).
  	self assert: (accessorDepth between: -1 and: 5).
  	accessorDepth >= 0 ifTrue:
+ 		[| scannedStackFrame |
+ 		 scannedStackFrame := false.
- 		[(self isCalloutPrimitiveIndex: primIndex) ifTrue:
- 			[(objectMemory
- 				followForwardedObjectFields: (self literal: 0 ofMethod: newMethod)
- 				toDepth: accessorDepth) ifTrue:
- 				[found := true]].
  		 0 to: argumentCount do:
  			[:index| | oop |
  			oop := self stackValue: index.
  			(objectMemory isNonImmediate: oop) ifTrue:
  				[(objectMemory isForwarded: oop) ifTrue:
  					[self assert: index < argumentCount. "receiver should have been caught at send time."
  					 found := true.
  					 oop := objectMemory followForwarded: oop.
  					 self stackValue: index put: oop.
  					 scannedStackFrame ifFalse:
  						[scannedStackFrame := true.
  						 self	"Avoid repeated primitive failures by following all state in the current stack frame."
  							followForwardedFrameContents: framePointer
  							stackPointer: stackPointer + (argumentCount + 1 * objectMemory wordSize)]].
  				(accessorDepth > 0
  			 	 and: [(objectMemory hasPointerFields: oop)
  				 and: [objectMemory followForwardedObjectFields: oop toDepth: accessorDepth]]) ifTrue:
  					[found := true]]]].
  	^found!

Item was added:
+ ----- Method: StackInterpreter>>unfollowFirstLiteralOfMaybeCalloutMethod:primitiveIndex: (in category 'primitive support') -----
+ unfollowFirstLiteralOfMaybeCalloutMethod: methodObj primitiveIndex: primIndex
+ 	"Follow the first literal of either a primitiveCallout or primitiveExternalCall primitive method. This
+ 	 will be an ExternalFunction for primitiveCallout or a four element Array for primitiveExternalCall.
+ 	 This is here to avoid following all the literals in a method, which would be slow.  Remember
+ 	 forwarders are unlikely, so we only want to follow what is necessary, and for an FFI call or
+ 	 external primitive only the first literal is salient."
+ 	<option: #SpurObjectMemory>
+ 	| found firstLiteral |
+ 	found := false.
+ 	"inlined self literal: 0 ofMethod: methodObj for clarity..."
+ 	firstLiteral := objectMemory fetchPointer: LiteralStart ofObject: methodObj.
+ 	(objectMemory isOopForwarded: firstLiteral) ifTrue:
+ 		[found := true.
+ 		 firstLiteral := objectMemory fixFollowedField: LiteralStart ofObject: methodObj withInitialValue: firstLiteral].
+ 	(objectMemory
+ 		followForwardedObjectFields: firstLiteral
+ 		toDepth: (primIndex = PrimNumberFFICall
+ 					ifTrue: [(primitiveAccessorDepthTable at: primIndex) - 1]
+ 					ifFalse: [0])) ifTrue:
+ 		[found := true].
+ 	^found!



More information about the Vm-dev mailing list