[Vm-dev] Re: allObjectsDo:

David T. Lewis lewis at mail.msen.com
Tue Jan 14 13:53:38 UTC 2014

On Tue, Jan 14, 2014 at 02:27:11PM +0100, Bert Freudenberg wrote:
> On 14.01.2014, at 01:36, David T. Lewis <lewis at mail.msen.com> wrote:
> > On Mon, Jan 13, 2014 at 12:28:33PM +0100, Bert Freudenberg wrote:
> >> I'd fill the remaining slots with 0 instead of nil. Even
> >> better: allocate the array as object count + 1 and *always* put a 0 last.
> >> That way the image code cannot ever "forget" to check for 0.
> >> 
> > 
> > Attached is an implementation of Bert's proposal. There is at least one integer
> > zero at the end of the result array, or more if the primitive caused a GC.
> > 
> > I sort of like this idea now that I understand the rational for using integer
> > zero as the fill. 
> > 
> > But Eliot is right, it would be better to answer only the objects that still
> > exist after any possible GC.
> > 
> > Dave
> > 
> > <InterpreterPrimitives-primitiveAllObjects-dtl.2.cs>
> Nice. Now we just need the same for allInstances :)
> - Bert -

One more update for primitiveAllObjects to fix a buglet. If garbage collection
occurs during allocation of the result array, then the result array itself was
being included in the result. We want to have self includes: self ==> false for
the result array. This fixes it.

Truncating the array per Eliot's suggestion remains on the to-do list.


-------------- next part --------------
'From Squeak4.5 of 12 January 2014 [latest update: #13621] on 14 January 2014 at 8:43:29 am'!
"Change Set:		InterpreterPrimitives-primitiveAllObjects-dtl
Date:			13 January 2014
Author:			David T. Lewis

InterpreterPrimitives>>primitiveAllObjects is a primitive that answers an array of all accessible objects. The result array will have at least one trailing integer zero, or more if garbage collection occurred as a side effect of the primitive. Sender is responsible for ignoring all trailing zeros in the result array."!

!InterpreterPrimitives methodsFor: 'object access primitives' stamp: 'dtl 1/14/2014 08:38'!
	"Answer an array of all objects that exist when the primitive is called, excluding those
	that may be garbage collected as a side effect of allocating the result array. The array
	will contain at least one trailing integer zero that serves as a marker for end of valid
	object references. Additional trailing zeros represent objects that were garbage
	collected during execution of this primitive. Sender is responsible for ignoring all
	trailing zero marker objects in the result array."

	<export: true>
	| count obj resultArray idx |
	self pop: argumentCount+1.
	"Count the currently accessible objects"
	count := 0.
	obj := objectMemory firstAccessibleObject.
	[obj = nil] whileFalse:
		[count := count + 1.
		obj := objectMemory accessibleObjectAfter: obj].
	"Allocation result array with space for one extra object, a trailing zero marker"
	resultArray := objectMemory instantiateClass: objectMemory classArray indexableSize: count + 1. "can cause GC"
	resultArray = nil ifTrue:
		[^self primitiveFailFor: PrimErrNoMemory].
	"Set the trailing zero marker"
	self stObject: resultArray at: count + 1 put: (objectMemory integerObjectOf: 0).
	"Store all objects in result array, filling any remaining slots with integer zero if garbage
	collection occurred during allocation of the result array."
	obj := objectMemory firstAccessibleObject.
	idx := 1.
	[count = 0] whileFalse:
		[count := count - 1.
		obj = nil
			ifTrue: [ "garbage collection happened, fill remaining slots with nil"
				self stObject: resultArray at: idx put: (objectMemory integerObjectOf: 0).
				idx := idx + 1]
			ifFalse: [ "next accessible object"
				obj == resultArray
					ifFalse: [ "do not store a reference to the result array itself"
						self stObject: resultArray at: idx put: obj.
						idx := idx + 1]
					ifTrue: [ "skipped one, still need to fill all slots in the result object"
						count := count + 1].
				obj := objectMemory accessibleObjectAfter: obj ]].
	self push: resultArray! !

More information about the Vm-dev mailing list