[squeak-dev] Re: allObjectsDo:

David T. Lewis lewis at mail.msen.com
Tue Jan 14 00:36:04 UTC 2014


On Mon, Jan 13, 2014 at 12:28:33PM +0100, Bert Freudenberg wrote:
> On 13.01.2014, at 02:13, David T. Lewis <lewis at mail.msen.com> wrote:
> 
> > On Sun, Jan 12, 2014 at 12:01:00PM -0800, Eliot Miranda wrote:
> >> 
> >> But I think now we can afford a primitive that answers all the objects
> >> (remember that average object size means that such a collection will be ~
> >> 10% of the heap, average object size in Squeak V3 is about 10.6 words).  At
> >> least that's what Spur will do, along with an allInstancesOf: primitive.
> >> And then the become example won't cause any problems at all.  Far more
> >> reliable.  I suppose there are circumstances when enumerating without a
> >> container is the only feasible approach, but VisualWorks has got along with
> >> only an allObjects primitive for a long time now.  I suspect we can too.
> >> 
> > 
> > Implementation attached. Works on interpreter VM, not yet tested on Cog but
> > it should be ok there also. If no objections or better suggestions I will
> > commit it to VMMaker tomorrow.
> > 
> > InterpreterPrimitives>>primitiveAllObjects
> > 	"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. Multiple
> > 	references to nil in the last slots of the array are an indication that garbage collection
> > 	occured, such that some of the unreferenced objects that existed at the time of calling
> > 	the primitive no longer exist. Sender is responsible for handling multiple references to
> > 	nil in the result array."
> > 
> > Dave
> > 
> > <InterpreterPrimitives-primitiveAllObjects-dtl.1.cs>
> 
> Nice, except that 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
 
-------------- next part --------------
'From Squeak4.5 of 12 January 2014 [latest update: #13621] on 13 January 2014 at 7:22:52 pm'!
"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/13/2014 19:10'!
primitiveAllObjects
	"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)]
			ifFalse: [self stObject: resultArray at: idx put: obj.
				obj := objectMemory accessibleObjectAfter: obj].
		idx := idx + 1].
	self push: resultArray! !



More information about the Squeak-dev mailing list