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

commits at source.squeak.org commits at source.squeak.org
Mon Aug 2 05:51:40 UTC 2021


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

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

Name: VMMaker.oscog-eem.3011
Author: eem
Time: 1 August 2021, 10:51:32.195381 pm
UUID: c31b5783-0c4c-472a-a602-4eeb7922c5cb
Ancestors: VMMaker.oscog-eem.3010

Cogit: Get the stack adjustment after primitive success right for FastCPrimitiveFlag primitives, with or without the FastCPrimitiveAlignForFloatsFlag.

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

Item was changed:
  ----- Method: CogAbstractInstruction>>genLoadStackPointersForFastPrimCall: (in category 'smalltalk calling convention') -----
  genLoadStackPointersForFastPrimCall: spareReg
  	"Switch back to the Smalltalk stack where there may be a C return address on top of stack below
  	 the last primitive argument. Assign SPReg first because typically it is used immediately afterwards."
  	self hasLinkRegister
  		ifTrue: [self genLoadStackPointers]
  		ifFalse:
  			[cogit
  				MoveAw: cogit stackPointerAddress R: spareReg;
  				"N.B. dont use SubCq:R:R: since it may generate MoveR:spareRegR:SPReg;SubCq:wordSize R:SPReg
+ 				 which allows for the ret addr to be smashed by an interrupt between the two instructions."
- 				 which allows for the ret addr to be smashed by an interrupt between the two insructions."
  				SubCq: objectMemory wordSize R: spareReg;
  				MoveR: spareReg R: SPReg;
  				MoveAw: cogit framePointerAddress R: FPReg].
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>compileOnStackExternalPrimitive:flags: (in category 'primitive generators') -----
  compileOnStackExternalPrimitive: primitiveRoutine flags: flags
  	"Compile a fast call of a C primitive using the current stack page, avoiding the stack switch except on failure.
  	 This convention still uses stackPointer and argumentCount to access operands.  Push all operands to the stack,
  	 assign stackPointer, argumentCount, and zero primFailCode.  Make the call (saving a LinkReg if required).
  	 Test for failure and return.  On failure on Spur, if there is an accessor depth, assign framePointer and newMethod,
  	 do the stack switch, call checkForAndFollowForwardedPrimitiveState, and loop back if forwarders are found.
  	 Fall through to frame build."
  	 
  	<var: #primitiveRoutine declareC: 'void (*primitiveRoutine)(void)'>
  	| jmp retry calleeSavedReg |
+ 	self assert: (objectRepresentation hasSpurMemoryManagerAPI and: [flags anyMask: PrimCallOnSmalltalkStack]).
- 	self assert: (flags anyMask: PrimCallOnSmalltalkStack).
  
  	"Clear the primFailCode and set argumentCount"
  	self MoveCq: 0 R: TempReg.
  	self MoveR: TempReg Aw: coInterpreter primFailCodeAddress.
  	methodOrBlockNumArgs ~= 0 ifTrue:
  		[self MoveCq: methodOrBlockNumArgs R: TempReg].
  	self MoveR: TempReg Aw: coInterpreter argumentCountAddress.
  	self genExternalizeStackPointerForFastPrimitiveCall.
  	backEnd hasLinkRegister ifTrue:
  		[self PushR: LinkReg].
  	retry := self Label.
  	calleeSavedReg := NoReg.
  	(SPReg ~= NativeSPReg
  	 and: [(self isCalleeSavedReg: SPReg) not]) ifTrue:
  		[calleeSavedReg := self availableRegisterOrNoneIn: ABICalleeSavedRegisterMask.
  		 self deny: calleeSavedReg = NoReg.
  		 self MoveR: SPReg R: calleeSavedReg].
  	(flags anyMask: PrimCallOnSmalltalkStackAlign2x)
  		ifTrue: [self AndCq: (objectMemory wordSize * 2 - 1) bitInvert R: SPReg R: NativeSPReg]
  		ifFalse:
  			[SPReg ~= NativeSPReg ifTrue:
  				[backEnd genLoadNativeSPRegWithAlignedSPReg]].
  	self CallFullRT: primitiveRoutine.
  	self MoveAw: coInterpreter primFailCodeAddress R: TempReg.
  	calleeSavedReg ~= NoReg ifTrue:
  		[self MoveR: calleeSavedReg R: SPReg].
  	self CmpCq: 0 R: TempReg.
  	jmp := self JumpNonZero: 0.
+ 	"At this point the primitive has cut back stackPointer to point to the result.
+ 	 The original retpc is (argumentCount + 1) words beneath it."
+ 	self MoveAw: coInterpreter stackPointerAddress R: TempReg.
+ 	self MoveMw: (methodOrBlockNumArgs + 1 * objectMemory wordSize) negated
+ 		r: TempReg
+ 		R: (backEnd hasLinkRegister ifTrue: [LinkReg] ifFalse: [ClassReg]).
+ 	self MoveR: TempReg R: SPReg.
  	backEnd hasLinkRegister
+ 		ifTrue: [self PopR: ReceiverResultReg] "i.e. get result"
+ 		ifFalse:
+ 			[self MoveMw: 0 r: TempReg R: ReceiverResultReg;
+ 				MoveR: ClassReg Mw: 0 r: TempReg]. "i.e. get result and restore retpc"
- 		ifTrue: [self PopR: LinkReg]
- 		ifFalse: [self PopR: TempReg]. "i.e. save retpc"
- 	self MoveAw: coInterpreter stackPointerAddress R: SPReg.
- 	self PopR: ReceiverResultReg.
- 	backEnd hasLinkRegister ifFalse: [self PushR: TempReg]. "i.e. restore retpc"
  	self RetN: 0.
  
  	jmp jmpTarget: self Label.
+ 	(coInterpreter accessorDepthForExternalPrimitiveMethod: methodObj) >= 0
+ 		ifTrue:
+ 			[| skip |
+ 			 "Given that following primitive state to the accessor depth is recursive, we're asking for
+ 			  trouble if we run the fixup on the Smalltalk stack page.  Run it on the full C stack instead.
+ 			 This won't be a performance issue since primitive failure should be very rare."
+ 			self MoveR: FPReg Aw: coInterpreter framePointerAddress.
+ 			self MoveCw: primitiveRoutine asInteger R: TempReg.
+ 			self MoveR: TempReg Aw: coInterpreter primitiveFunctionPointerAddress.
+ 			self genLoadCStackPointersForPrimCall.
+ 			methodLabel addDependent:
+ 				(self annotateAbsolutePCRef:
+ 					(self MoveCw: methodLabel asInteger R: ClassReg)).
+ 			self MoveMw: (self offset: CogMethod of: #methodObject) r: ClassReg R: TempReg.
+ 			self MoveR: TempReg Aw: coInterpreter newMethodAddress.
+ 			self CallFullRT: (self cCode: [#checkForAndFollowForwardedPrimitiveState asUnsignedIntegerPtr]
+ 								   inSmalltalk: [self simulatedTrampolineFor: #checkForAndFollowForwardedPrimitiveState]).
+ 			backEnd genLoadStackPointersForFastPrimCall: ClassReg.
+ 			self CmpCq: 0 R: ABIResultReg.
+ 			skip := self JumpZero: 0.
+ 			self MoveCq: 0 R: TempReg.
+ 			self MoveR: TempReg Aw: coInterpreter primFailCodeAddress.
+ 			self Jump: retry.
+ 			skip jmpTarget: self Label]
+ 		ifFalse: "must reload SPReg to undo any alignment change,"
+ 			[(flags anyMask: PrimCallOnSmalltalkStackAlign2x) ifTrue:
+ 				[backEnd genLoadStackPointersForFastPrimCall: ClassReg]].
- 	(objectRepresentation hasSpurMemoryManagerAPI
- 	 and: [(coInterpreter accessorDepthForExternalPrimitiveMethod: methodObj) >= 0]) ifTrue:
- 		[| skip |
- 		 "Given that following primitive state to the accessor depth is recursive, we're asking for
- 		  trouble if we run the fixup on the Smalltalk stack page.  Run it on the full C stack instead.
- 		 This won't be a performance issue since primitive failure should be very rare."
- 		self MoveR: FPReg Aw: coInterpreter framePointerAddress.
- 		self MoveCw: primitiveRoutine asInteger R: TempReg.
- 		self MoveR: TempReg Aw: coInterpreter primitiveFunctionPointerAddress.
- 		self genLoadCStackPointersForPrimCall.
- 		methodLabel addDependent:
- 			(self annotateAbsolutePCRef:
- 				(self MoveCw: methodLabel asInteger R: ClassReg)).
- 		self MoveMw: (self offset: CogMethod of: #methodObject) r: ClassReg R: TempReg.
- 		self MoveR: TempReg Aw: coInterpreter newMethodAddress.
- 		self CallFullRT: (self cCode: [#checkForAndFollowForwardedPrimitiveState asUnsignedIntegerPtr]
- 							   inSmalltalk: [self simulatedTrampolineFor: #checkForAndFollowForwardedPrimitiveState]).
- 		backEnd genLoadStackPointersForFastPrimCall: ClassReg.
- 		self CmpCq: 0 R: ABIResultReg.
- 		skip := self JumpZero: 0.
- 		self MoveCq: 0 R: TempReg.
- 		self MoveR: TempReg Aw: coInterpreter primFailCodeAddress.
- 		self Jump: retry.
- 		skip jmpTarget: self Label].
  	"Finally remember to reload ReceiverResultReg if required.  Even if
  	 arguments have been pushed, the prolog sequence assumes it is live."
  	(self register: ReceiverResultReg isInMask: ABICallerSavedRegisterMask) ifTrue:
  		[self MoveMw: (backEnd hasLinkRegister ifTrue: [methodOrBlockNumArgs] ifFalse: [methodOrBlockNumArgs + 1]) * objectMemory wordSize
  			r: SPReg
  			R: ReceiverResultReg].
  	^0!



More information about the Vm-dev mailing list