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

commits at source.squeak.org commits at source.squeak.org
Wed Aug 4 18:21:58 UTC 2021


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

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

Name: VMMaker.oscog-eem.3027
Author: eem
Time: 4 August 2021, 11:21:44.122593 am
UUID: d629ca6e-44f2-4103-bb23-e9539e611ab9
Ancestors: VMMaker.oscog-eem.3026

Nuke the longRunningPrimitive sampling support.  it' a poor idea compared to Andreas' accurate primitive profiling.

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

Item was changed:
  ----- Method: CoInterpreter>>forceInterruptCheckFromHeartbeat (in category 'process primitive support') -----
  forceInterruptCheckFromHeartbeat
  	"Force an interrupt check ASAP. This version is the
  	 entry-point to forceInterruptCheck for the heartbeat
  	 timer to allow for repeatable debugging."
  	suppressHeartbeatFlag ifFalse:
+ 		[self sqLowLevelMFence.
- 		[self checkForLongRunningPrimitive.
- 		 self sqLowLevelMFence.
  		 deferSmash
  			ifTrue:
  				[deferredSmash := true.
  				 self sqLowLevelMFence]
  			ifFalse:
  				[self forceInterruptCheck]]!

Item was changed:
  ----- Method: CoInterpreter>>primitivePropertyFlagsForV3: (in category 'cog jit support') -----
  primitivePropertyFlagsForV3: primIndex
  	<inline: true>
  	"Answer any special requirements of the given primitive"
  	| baseFlags |
  	baseFlags := profileSemaphore ~= objectMemory nilObject
  					ifTrue: [PrimCallNeedsNewMethod + PrimCallCollectsProfileSamples]
  					ifFalse: [0].
  
- 	longRunningPrimitiveCheckSemaphore ifNotNil:
- 		[baseFlags := baseFlags bitOr: PrimCallNeedsNewMethod].
- 
  	(self isCalloutPrimitiveIndex: primIndex) ifTrue: "For callbacks & module unloading"
  		[baseFlags := baseFlags bitOr: PrimCallNeedsNewMethod + PrimCallNeedsPrimitiveFunction + PrimCallMayEndureCodeCompaction + PrimCallIsExternalCall].
  	(self isCodeCompactingPrimitiveIndex: primIndex) ifTrue:
  		[baseFlags := baseFlags bitOr: PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction].
  
  	^baseFlags!

Item was changed:
  ----- Method: CoInterpreterMT>>checkForEventsMayContextSwitch: (in category 'process primitive support') -----
  checkForEventsMayContextSwitch: mayContextSwitch
  	"Check for possible interrupts and handle one if necessary.
  	 Answer if a context switch has occurred."
  	| switched sema now |
  	<inline: false>
  	<var: #now type: #usqLong>
  	self assertSaneThreadAndProcess.
  	cogit assertCStackWellAligned.
  	statCheckForEvents := statCheckForEvents + 1.
  
  	"restore the stackLimit if it has been smashed."
  	self restoreStackLimit.
  	self externalWriteBackHeadFramePointers.
  	self assert: stackPage = stackPages mostRecentlyUsedPage.
  
  	"Allow the platform to do anything it needs to do synchronously."
  	self ioSynchronousCheckForEvents.
  
  	self checkCogCompiledCodeCompactionCalledFor.
  
  	objectMemory needGCFlag ifTrue:
  		["sufficientSpaceAfterGC: runs the incremental GC and
  		 then, if not enough space is available, the fullGC."
  		 (objectMemory sufficientSpaceAfterGC: 0) ifFalse:
  			[self setSignalLowSpaceFlagAndSaveProcess]].
  
  	mayContextSwitch ifFalse: [^false].
  
  	switched := false.
  	self assert: deferThreadSwitch not.
  	deferThreadSwitch := true.
  
  	(profileProcess ~= objectMemory nilObject
  	 or: [nextProfileTick > 0 and:[self ioHighResClock >= nextProfileTick]]) ifTrue:
  		[nextProfileTick := 0.
  		 "Take a sample (if not already done so) for the profiler if it is active.  This
  		  must be done before any of the synchronousSignals below or else we will
  		  attribute a pause in ioRelinquishProcessor to the newly activated process."
  		 profileProcess = objectMemory nilObject ifTrue:
  			[profileProcess := self activeProcess.
  			 profileMethod := objectMemory nilObject].
  		 "and signal the profiler semaphore if it is present"
  		 (profileSemaphore ~= objectMemory nilObject
  		  and: [self synchronousSignal: profileSemaphore]) ifTrue:
  			[switched := true]].
  
- 	self checkDeliveryOfLongRunningPrimitiveSignal ifTrue:
- 		[switched := true].
- 
  	objectMemory signalLowSpace ifTrue:
  		[objectMemory signalLowSpace: false. "reset flag"
  		 sema := objectMemory splObj: TheLowSpaceSemaphore.
  		 (sema ~= objectMemory nilObject
  		  and: [self synchronousSignal: sema]) ifTrue:
  			[switched := true]].
  
  	"inIOProcessEvents prevents reentrancy into ioProcessEvents and allows disabling
  	 ioProcessEvents e.g. for native GUIs.  We would like to manage that here but can't
  	 since the platform code may choose to call ioProcessEvents itself in various places."
  	false
  		ifTrue:
  			[((now := self ioUTCMicroseconds) >= nextPollUsecs
  			 and: [inIOProcessEvents = 0]) ifTrue:
  				[statIOProcessEvents := statIOProcessEvents + 1.
  				 inIOProcessEvents := inIOProcessEvents + 1.
  				 self ioProcessEvents. "sets interruptPending if interrupt key pressed; may callback"
  				 inIOProcessEvents > 0 ifTrue:
  					[inIOProcessEvents := inIOProcessEvents - 1].
  				 nextPollUsecs := now + 20000
  				 "msecs to wait before next call to ioProcessEvents.  Note that strictly
  				  speaking we might need to update 'now' at this point since
  				  ioProcessEvents could take a very long time on some platforms"]]
  		ifFalse:
  			[(now := self ioUTCMicroseconds) >= nextPollUsecs ifTrue:
  				[statIOProcessEvents := statIOProcessEvents + 1.
  				 self ioProcessEvents. "sets interruptPending if interrupt key pressed; may callback"
  				 nextPollUsecs := now + 20000
  				 "msecs to wait before next call to ioProcessEvents.  Note that strictly
  				  speaking we might need to update 'now' at this point since
  				  ioProcessEvents could take a very long time on some platforms"]].
  
  	interruptPending ifTrue:
  		[interruptPending := false.
  		 "reset interrupt flag"
  		 sema := objectMemory splObj: TheInterruptSemaphore.
  		 (sema ~= objectMemory nilObject
  		  and: [self synchronousSignal: sema]) ifTrue:
  			[switched := true]].
  
  	nextWakeupUsecs ~= 0 ifTrue:
  		[now >= nextWakeupUsecs ifTrue:
  			[nextWakeupUsecs := 0.
  			 "set timer interrupt to 0 for 'no timer'"
  			 sema := objectMemory splObj: TheTimerSemaphore.
  			 (sema ~= objectMemory nilObject
  			  and: [self synchronousSignal: sema]) ifTrue:
  				[switched := true]]].
  
  	"signal any pending finalizations"
  	pendingFinalizationSignals > 0 ifTrue:
  		[pendingFinalizationSignals := 0.
  		 sema := objectMemory splObj: TheFinalizationSemaphore.
  		 (sema ~= objectMemory nilObject
  		  and: [self synchronousSignal: sema]) ifTrue:
  			[switched := true]].
  
  	"signal all semaphores in semaphoresToSignal"
  	self signalExternalSemaphores ifTrue:
  		[switched := true].
  
  	deferThreadSwitch := false.
  	checkThreadActivation ifTrue:
  		[checkThreadActivation := false.
  		 self cedeToHigherPriorityThreads]. "N.B.  This may not return if we do switch."
  
  	self threadSwitchIfNecessary: self activeProcess from: CSCheckEvents.
  	^switched!

Item was changed:
  ----- Method: CoInterpreterMT>>forceInterruptCheckFromHeartbeat (in category 'process primitive support') -----
  forceInterruptCheckFromHeartbeat
  	"Force an interrupt check ASAP. This version is the
  	 entry-point to forceInterruptCheck for the heartbeat
  	 timer to allow for repeatable debugging.
  
  	 N.B. SYNCHRONIZE WITH deferStackLimitSmashAround:"
  	suppressHeartbeatFlag ifFalse:
+ 		[self sqLowLevelMFence.
- 		[self checkForLongRunningPrimitive.
- 		 self sqLowLevelMFence.
  		 deferSmash
  			ifTrue:
  				[deferredSmash := true.
  				self sqLowLevelMFence]
  			ifFalse:
  				[self forceInterruptCheck.
  				 self checkVMOwnershipFromHeartbeat]]!

Item was removed:
- ----- Method: CoInterpreterPrimitives>>primitiveLongRunningPrimitiveSemaphore (in category 'process primitives') -----
- primitiveLongRunningPrimitiveSemaphore
- 	"Primitive. Install the semaphore to be used for collecting long-running primitives, 
- 	 or nil if no semaphore should be used."
- 	| sema flushState activeContext |
- 	<export: true>
- 	self methodArgumentCount ~= 1 ifTrue:
- 		[^self primitiveFailFor: PrimErrBadNumArgs].
- 	sema := self stackValue: 0.
- 	sema = objectMemory nilObject
- 		ifTrue:
- 			[flushState := longRunningPrimitiveCheckSemaphore notNil.
- 			 longRunningPrimitiveCheckSemaphore := nil]
- 		ifFalse:
- 			[flushState := longRunningPrimitiveCheckSemaphore isNil.
- 			 (objectMemory isSemaphoreOop: sema) ifFalse:
- 				[^self primitiveFailFor: PrimErrBadArgument].
- 			 longRunningPrimitiveCheckSemaphore := sema].
- 	"If we've switched checking on or off we must void machine code
- 	 (and machine code pcs in contexts) since we will start or stop setting
- 	 newMethod in machine code primitive invocations, and so generate
- 	 slightly different code from here on in."
- 	flushState ifTrue:
- 		[self push: instructionPointer.
- 		 activeContext := self voidVMStateForSnapshotFlushingExternalPrimitivesIf: false.
- 		 self marryContextInNewStackPageAndInitializeInterpreterRegisters: activeContext.
- 		 self assert: (((self stackValue: 0) = objectMemory nilObject and: [longRunningPrimitiveCheckSemaphore isNil])
- 				  or: [(self stackValue: 0) = longRunningPrimitiveCheckSemaphore
- 					  and: [objectMemory isSemaphoreOop: sema]])].
- 	self voidLongRunningPrimitive: 'install'.
- 	self pop: 1.
- 	flushState ifTrue:
- 		[cogit ceInvokeInterpret]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveProfilePrimitive (in category 'process primitives') -----
  primitiveProfilePrimitive
  	"Primitive. Answer the last primitive method sampled by the profiler."
+ 	<export: true flags: #FastCPrimitiveFlag>
+ 	self methodReturnValue: profileMethod.
- 	<export: true>
- 	self methodArgumentCount = 0 ifFalse:
- 		[^self primitiveFail].
- 	self pop: 1 thenPush: profileMethod.
  	profileMethod := objectMemory nilObject!

Item was changed:
  InterpreterPrimitives subclass: #StackInterpreter
(excessive size, no diff calculated)

Item was removed:
- ----- Method: StackInterpreter>>checkDeliveryOfLongRunningPrimitiveSignal (in category 'primitive support') -----
- checkDeliveryOfLongRunningPrimitiveSignal
- 	"Check for a hit of the longRunningPrimitive probe and if so attempt to signal the
- 	 longRunningPrimitiveCheckSemaphore.  Answer if a process switch occurred as a result."
- 	<inline: true>
- 	(longRunningPrimitiveStopUsecs > longRunningPrimitiveStartUsecs "a hit"
- 	 and: [longRunningPrimitiveCheckSemaphore notNil "deliverable"
- 	 and: [longRunningPrimitiveSignalUndelivered]]) ifTrue: "but not yet delivered"
- 		[longRunningPrimitiveSignalUndelivered := false.
- 		 longRunningPrimitiveGCUsecs := (objectMemory gcStartUsecs < longRunningPrimitiveStopUsecs
- 										   and: [objectMemory statGCEndUsecs > longRunningPrimitiveStartUsecs])
- 											ifTrue: [objectMemory statGCEndUsecs - objectMemory gcStartUsecs]
- 											ifFalse: [0].
- 		"Signal the LRP check semaphore if it is present"
- 		^self synchronousSignal: longRunningPrimitiveCheckSemaphore].
- 	^false!

Item was changed:
  ----- Method: StackInterpreter>>checkForEventsMayContextSwitch: (in category 'process primitive support') -----
  checkForEventsMayContextSwitch: mayContextSwitch
  	"Check for possible interrupts and handle one if necessary.
  	 Answer if a context switch has occurred."
  	| switched sema now |
  	<inline: false>
  	<var: #now type: #usqLong>
  	statCheckForEvents := statCheckForEvents + 1.
  
  	"restore the stackLimit if it has been smashed."
  	self restoreStackLimit.
  	self externalWriteBackHeadFramePointers.
  	self assert: stackPage = stackPages mostRecentlyUsedPage.
  
  	"Allow the platform to do anything it needs to do synchronously."
  	self ioSynchronousCheckForEvents.
  
  	self checkCogCompiledCodeCompactionCalledFor.
  
  	objectMemory needGCFlag ifTrue:
  		["sufficientSpaceAfterGC: runs the incremental GC and
  		 then, if not enough space is available, the fullGC."
  		 (objectMemory sufficientSpaceAfterGC: 0) ifFalse:
  			[self setSignalLowSpaceFlagAndSaveProcess]].
  
  	mayContextSwitch ifFalse: [^false].
  
  	switched := false.
  
  	(profileProcess ~= objectMemory nilObject
  	 or: [nextProfileTick > 0 and:[self ioHighResClock >= nextProfileTick]]) ifTrue:
  		[nextProfileTick := 0.
  		 "Take a sample (if not already done so) for the profiler if it is active.  This
  		  must be done before any of the synchronousSignals below or else we will
  		  attribute a pause in ioRelinquishProcessor to the newly activated process."
  		 profileProcess = objectMemory nilObject ifTrue:
  			[profileProcess := self activeProcess.
  			 profileMethod := objectMemory nilObject].
  		 "and signal the profiler semaphore if it is present"
  		 (profileSemaphore ~= objectMemory nilObject
  		  and: [self synchronousSignal: profileSemaphore]) ifTrue:
  			[switched := true]].
  
- 	self checkDeliveryOfLongRunningPrimitiveSignal ifTrue:
- 		[switched := true].
- 
  	objectMemory signalLowSpace ifTrue:
  		[objectMemory signalLowSpace: false. "reset flag"
  		 sema := objectMemory splObj: TheLowSpaceSemaphore.
  		 (sema ~= objectMemory nilObject
  		  and: [self synchronousSignal: sema]) ifTrue:
  			[switched := true]].
  
  	"inIOProcessEvents prevents reentrancy into ioProcessEvents and allows disabling
  	 ioProcessEvents e.g. for native GUIs.  We would like to manage that here but can't
  	 since the platform code may choose to call ioProcessEvents itself in various places."
  	false
  		ifTrue:
  			[((now := self ioUTCMicroseconds) >= nextPollUsecs
  			 and: [inIOProcessEvents = 0]) ifTrue:
  				[statIOProcessEvents := statIOProcessEvents + 1.
  				 inIOProcessEvents := inIOProcessEvents + 1.
  				 self ioProcessEvents. "sets interruptPending if interrupt key pressed; may callback"
  				 inIOProcessEvents > 0 ifTrue:
  					[inIOProcessEvents := inIOProcessEvents - 1].
  				 nextPollUsecs := now + 20000
  				 "msecs to wait before next call to ioProcessEvents.  Note that strictly
  				  speaking we might need to update 'now' at this point since
  				  ioProcessEvents could take a very long time on some platforms"]]
  		ifFalse:
  			[(now := self ioUTCMicroseconds) >= nextPollUsecs ifTrue:
  				[statIOProcessEvents := statIOProcessEvents + 1.
  				 self ioProcessEvents. "sets interruptPending if interrupt key pressed; may callback"
  				 nextPollUsecs := now + 20000
  				 "msecs to wait before next call to ioProcessEvents.  Note that strictly
  				  speaking we might need to update 'now' at this point since
  				  ioProcessEvents could take a very long time on some platforms"]].
  
  	interruptPending ifTrue:
  		[interruptPending := false.
  		 "reset interrupt flag"
  		 sema := objectMemory splObj: TheInterruptSemaphore.
  		 (sema ~= objectMemory nilObject
  		  and: [self synchronousSignal: sema]) ifTrue:
  			[switched := true]].
  
  	nextWakeupUsecs ~= 0 ifTrue:
  		[now >= nextWakeupUsecs ifTrue:
  			[nextWakeupUsecs := 0.
  			 "set timer interrupt to 0 for 'no timer'"
  			 sema := objectMemory splObj: TheTimerSemaphore.
  			 (sema ~= objectMemory nilObject
  			  and: [self synchronousSignal: sema]) ifTrue:
  				[switched := true]]].
  
  	"signal any pending finalizations"
  	pendingFinalizationSignals > 0 ifTrue:
  		[pendingFinalizationSignals := 0.
  		 sema := objectMemory splObj: TheFinalizationSemaphore.
  		 (sema ~= objectMemory nilObject
  		  and: [self synchronousSignal: sema]) ifTrue:
  			[switched := true]].
  
  	"signal all semaphores in semaphoresToSignal"
  	self signalExternalSemaphores ifTrue:
  		[switched := true].
  
  	^switched!

Item was removed:
- ----- Method: StackInterpreter>>checkForLongRunningPrimitive (in category 'primitive support') -----
- checkForLongRunningPrimitive
- 	"Called from forceInterruptCheckFromHeartbeat.  If the system has been running
- 	 the same primitive on two successive heartbeats then signal profileMethod."
- 	<inline: true>
- 	longRunningPrimitiveCheckSemaphore isNil ifTrue:
- 		[^nil].
- 	(longRunningPrimitiveStartUsecs > 0
- 	 and: [longRunningPrimitiveCheckMethod = newMethod
- 	 and: [longRunningPrimitiveCheckSequenceNumber = statCheckForEvents]]) ifTrue:
- 		[longRunningPrimitiveStopUsecs := self ioUTCMicroseconds.
- 		self assert: longRunningPrimitiveStopUsecs > longRunningPrimitiveStartUsecs.
- 		^nil].
- 	"See traceProfileState & mapProfileState."
- 	longRunningPrimitiveStopUsecs = 0 ifTrue:
- 		[longRunningPrimitiveCheckSequenceNumber := statCheckForEvents.
- 		 longRunningPrimitiveCheckMethod := newMethod.
- 		 longRunningPrimitiveStartUsecs := self ioUTCMicroseconds.
- 		 self sqLowLevelMFence]!

Item was changed:
  ----- Method: StackInterpreter>>forceInterruptCheckFromHeartbeat (in category 'process primitive support') -----
  forceInterruptCheckFromHeartbeat
  	"Force an interrupt check ASAP. This version is the
  	 entry-point to forceInterruptCheck for the heartbeat
  	 timer to allow for repeatable debugging."
  	suppressHeartbeatFlag ifFalse:
+ 		[self forceInterruptCheck]!
- 		[self checkForLongRunningPrimitive.
- 		 self forceInterruptCheck]!

Item was changed:
  ----- Method: StackInterpreter>>initialize (in category 'initialization') -----
  initialize
  	"Here we can initialize the variables C initializes to zero.  #initialize methods do /not/ get translated."
  	super initialize.
  	primitiveDoMixedArithmetic := true. "whether we authorize primitives to perform mixed arithmetic or not"
  	stackLimit := 0. "This is also the initialization flag for the stack system."
  	stackPage := overflowedPage := 0.
  	extraFramesToMoveOnOverflow := 0.
  	bytecodeSetSelector := 0.
  	highestRunnableProcessPriority := 0.
  	nextPollUsecs := 0.
  	nextWakeupUsecs := 0.
  	tempOop := tempOop2 := theUnknownShort := 0.
  	interruptPending := false.
  	inIOProcessEvents := 0.
  	fullScreenFlag := 0.
  	sendWheelEvents := deferDisplayUpdates := false.
  	displayBits := displayWidth := displayHeight := displayDepth := 0.
  	pendingFinalizationSignals := statPendingFinalizationSignals := 0.
  	globalSessionID := 0.
  	jmpDepth := 0.
- 	longRunningPrimitiveStartUsecs := longRunningPrimitiveStopUsecs := 0.
  	maxExtSemTabSizeSet := false.
  	debugCallbackInvokes := debugCallbackPath := debugCallbackReturns := 0.
  	statForceInterruptCheck := statStackOverflow := statCheckForEvents :=
  	statProcessSwitch := statIOProcessEvents := statStackPageDivorce :=
  	statIdleUsecs := 0!

Item was changed:
  ----- Method: StackInterpreter>>mapProfileState (in category 'object memory support') -----
  mapProfileState
  	(objectMemory shouldRemapObj: profileProcess) ifTrue:
  		[profileProcess := objectMemory remapObj: profileProcess].
  	(objectMemory shouldRemapObj: profileMethod) ifTrue:
  		[profileMethod := objectMemory remapObj: profileMethod].
  	(objectMemory shouldRemapObj: profileSemaphore) ifTrue:
+ 		[profileSemaphore := objectMemory remapObj: profileSemaphore]!
- 		[profileSemaphore := objectMemory remapObj: profileSemaphore].
- 	"The longRunningPrimitiveCheckMethod (LRPCM) is sampled in an interrupt.  Be very careful with it.
- 	  If longRunningPrimitiveCheckSequenceNumber (LRPCSN) = statCheckForEvents then LRPCM has
- 	  been recenty sampled and could be mapped or not, but it must be newMethod and we can simply
- 	  copy newMethod.  If LRPCSN ~= statCheckForEvents then LRPCM must be some extant object and
- 	  needs to be remapped."
- 	self sqLowLevelMFence.
- 	longRunningPrimitiveCheckMethod ifNotNil:
- 		[longRunningPrimitiveCheckSequenceNumber = statCheckForEvents
- 			ifTrue: [longRunningPrimitiveCheckMethod := newMethod]
- 			ifFalse:
- 				[(objectMemory shouldRemapObj: longRunningPrimitiveCheckMethod) ifTrue:
- 					[longRunningPrimitiveCheckMethod := self remapObj: longRunningPrimitiveCheckMethod]].
- 		 self sqLowLevelMFence].
- 	longRunningPrimitiveCheckSemaphore ifNotNil:
- 		[(objectMemory shouldRemapObj: longRunningPrimitiveCheckSemaphore) ifTrue:
- 			[longRunningPrimitiveCheckSemaphore := objectMemory remapObj: longRunningPrimitiveCheckSemaphore]]!

Item was changed:
  ----- Method: StackInterpreter>>traceProfileState (in category 'object memory support') -----
  traceProfileState
  	objectMemory hasSpurMemoryManagerAPI ifTrue:
  		[self followForwardingPointersInProfileState].
  	objectMemory markAndTrace: profileProcess.
  	objectMemory markAndTrace: profileMethod.
+ 	objectMemory markAndTrace: profileSemaphore!
- 	objectMemory markAndTrace: profileSemaphore.
- 
- 	"The longRunningPrimitiveCheckMethod (LRPCM) is sampled in an interrupt.  Be very careful with it.
- 	  If longRunningPrimitiveCheckSequenceNumber (LRPCSN) = statCheckForEvents then LRPCM has
- 	  been recenty sampled, but it must be newMethod and we don't need to trace it twice.  If LRPCSN
- 	  ~= statCheckForEvents then LRPCM must be some extant object and needs to be traced."
- 	self sqLowLevelMFence.
- 	(longRunningPrimitiveCheckMethod ~= nil
- 	 and: [longRunningPrimitiveCheckSequenceNumber ~= statCheckForEvents]) ifTrue:
- 		[(objectMemory isForwarded: longRunningPrimitiveCheckMethod) ifTrue:
- 			[longRunningPrimitiveCheckMethod := objectMemory followForwarded: longRunningPrimitiveCheckMethod].
- 	objectMemory markAndTrace: longRunningPrimitiveCheckMethod].
- 	longRunningPrimitiveCheckSemaphore ~= nil ifTrue:
- 		[(objectMemory isForwarded: longRunningPrimitiveCheckSemaphore) ifTrue:
- 			[longRunningPrimitiveCheckSemaphore := objectMemory followForwarded: longRunningPrimitiveCheckSemaphore].
- 		 objectMemory markAndTrace: longRunningPrimitiveCheckSemaphore]!

Item was removed:
- ----- Method: StackInterpreter>>voidLongRunningPrimitive: (in category 'primitive support') -----
- voidLongRunningPrimitive: reason
- 	"Void the state associated with the long-running primitive check.
- 	 This is done when a new semaphore is installed or when it appears
- 	 that is longRunningPrimitiveCheckMethod is invalid, e.g. because it
- 	 has eben sampled in the middle of a GC."
- 	<var: #reason type: #'char *'>
- 	<inline: #never>
- 	longRunningPrimitiveCheckMethod := nil.
- 	longRunningPrimitiveStartUsecs :=
- 	longRunningPrimitiveStopUsecs := 0.
- 	longRunningPrimitiveSignalUndelivered := true.
- 	self sqLowLevelMFence!

Item was removed:
- ----- Method: StackInterpreterPrimitives>>primitiveLongRunningPrimitive (in category 'process primitives') -----
- primitiveLongRunningPrimitive
- 	"Primitive. Answer an Array with the current long-running primitive method identified by
- 	 the heartbeat, the minimum number of milliseconds it was active for, and the milliseconds
- 	 of GC activity there-in, or nil if none.  Since the longRunningPrimitiveCheckMethod is
- 	 sampled at interrupt time be careful to validate it before returning it."
- 	<export: true>
- 	| lrpcm result primms gcms |
- 	self methodArgumentCount = 0 ifFalse:
- 		[^self primitiveFail].
- 	self sqLowLevelMFence.
- 	(longRunningPrimitiveStopUsecs > longRunningPrimitiveStartUsecs "a hit"
- 	 and: [(lrpcm := longRunningPrimitiveCheckMethod) ~= nil			"there is a method"
- 	 and: [(self addressCouldBeObj: lrpcm)								"method looks valid"
- 	 and: [(self isFreeObject: lrpcm) not
- 	 and: [(self isCompiledMethod: lrpcm)]]]])
- 		ifTrue: [result := objectMemory instantiateClass: (objectMemory splObj: ClassArray) indexableSize: 3.
- 				primms := (longRunningPrimitiveStopUsecs - longRunningPrimitiveStartUsecs) + 500 // 1000.
- 				
- 				gcms := longRunningPrimitiveGCUsecs + 500 // 1000.
- 				objectMemory storePointer: 0 ofObject: result withValue: lrpcm.
- 				objectMemory storePointerUnchecked: 1 ofObject: result withValue: (objectMemory integerObjectOf: primms).
- 				objectMemory storePointerUnchecked: 2 ofObject: result withValue: (objectMemory integerObjectOf: gcms)]
- 		ifFalse: [result := objectMemory nilObject].
- 	self pop: 1 thenPush: result.
- 	self voidLongRunningPrimitive: 'get'!

Item was removed:
- ----- Method: StackInterpreterPrimitives>>primitiveLongRunningPrimitiveSemaphore (in category 'process primitives') -----
- primitiveLongRunningPrimitiveSemaphore
- 	"Primitive. Install the semaphore to be used for collecting long-running primitives, 
- 	 or nil if no semaphore should be used."
- 	| sema |
- 	<export: true>
- 	sema := self stackValue: 0.
- 	((objectMemory isIntegerObject: sema)
- 	or: [self methodArgumentCount ~= 1]) ifTrue:
- 		[^self primitiveFail].
- 	sema = objectMemory nilObject
- 		ifTrue:
- 			[longRunningPrimitiveCheckSemaphore := nil]
- 		ifFalse:
- 			[(objectMemory isSemaphoreOop: sema) ifFalse:
- 				[^self primitiveFail].
- 			 longRunningPrimitiveCheckSemaphore := sema].
- 	self voidLongRunningPrimitive: 'install'.
- 	self pop: 1!



More information about the Vm-dev mailing list