allObjectsDo: (was Re: [squeak-dev] The Inbox: System-cwp.662.mcz)
Eliot Miranda
eliot.miranda at gmail.com
Mon Jan 13 18:31:49 UTC 2014
Hi Nicolas,
On Mon, Jan 13, 2014 at 10:20 AM, Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com> wrote:
>
> 2014/1/13 Eliot Miranda <eliot.miranda at gmail.com>
>
>> Hi David,
>>
>> On Sun, Jan 12, 2014 at 5:13 PM, David T. Lewis <lewis at mail.msen.com>wrote:
>>
>>> On Sun, Jan 12, 2014 at 09:53:27PM +0100, Bert Freudenberg wrote:
>>> >
>>> > On 12.01.2014, at 20:42, David T. Lewis <lewis at mail.msen.com> wrote:
>>> >
>>> > > It is worth noting that allObjectsDo: relies on assumptions about how
>>> > > the objects memory works internally. It requires that #someObject
>>> will
>>> > > always answer the object at the lowest address in the object memory,
>>> and
>>> > > also that a newly allocated object will always be placed at a higher
>>> > > address location than all other objects. Either of these assumptions
>>> is
>>> > > likely to be a problem as new and better object memories and garbage
>>> > > collectors are implemented.
>>> > >
>>> > > Dave
>>> >
>>> > Right (as Eliot's vm-dev post shows).
>>> >
>>> > So IMHO the only sensible semantics of allObjectsDo: is as in
>>> "allObjects do:" -
>>> > which might be implemented as a primitive in some VMs soonish. It
>>> *should not*
>>> > enumerate objects created after calling the method.
>>> >
>>>
>>>
>>> On Sun, Jan 12, 2014 at 12:01:00PM -0800, Eliot Miranda wrote:
>>> >
>>> > The bug is in implementing allObjects in terms of someObject and
>>> nextObject
>>> > in the first place. It's cheap and cheerful but horribly error-prone
>>> and
>>> > restrictive. It's cheap because the collection of objects doesn't
>>> have to
>>> > be created, and on the original 16-bit Smalltalk machines that was
>>> really
>>> > important. It's horribly restrictive because it assumes much about the
>>> > implementation.
>>> >
>>> > Before closures a sentinel wasn't even needed because enumerating the
>>> block
>>> > didn't create a new object (the block context was reused). So the
>>> code had
>>> > to be rewritten just to support closures.
>>> >
>>> > Spur has a generation scavenger operating in a distinct new space and
>>> that
>>> > doesn't jive well with a consistent ordering at all. So far the
>>> system is
>>> > limping along by tenuring all objects on someObject and someInstance
>>> (so
>>> > that newSpace is either empty, or doesn't contain any instances of a
>>> > specific class) and having nextObject enumerate only objects in
>>> oldSpace.
>>> >
>>> > 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."
>>>
>>
>> Instead of filling the unused slots with nil or 0, I think you should
>> shorten the object so that it contains each object only once, and contains
>> only the objects. Cog contains some code for shortening. See
>> [New]ObjectMemory>>shorten:toIndexableSize:.
>>
>> HTH
>> --
>> best,
>> Eliot
>>
>>
>> Oh, I missed this one. I can't check now, could it cleanly address my
> hugly trick of modifying the header like explained at
>
> http://smallissimo.blogspot.fr/2013/04/still-hacking-largeintegerplugins-in.html?
>
It would on SqueakV3. On Spur it could be more difficult as there's no
support for one-double-word free objects, so one can't free a singe 64-bit
pair (objects are rounded up to 64-bits in length). But perhaps you should
inflict this on me to force my hand ;-). The problem is that a single
64-bit word is big enough for an object header but not for an object header
plus an indirection in the first slot, which takes 129 bits, when rounded
up to a 64-bit boundary. So such fragments are only reclaimable if an
object next to them is freed. They can't be compacted because there's no
forwarding pointer. So I expect in Spur I'd just have to disable the code
and always create the copy. However, what *can* be shortened, always, is
the last object in eden. So if the object is newly created it can easily
be shortened; all that needs ot happen is the allocation pointer,
freeStart, is cut-back.
HTH,
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20140113/0de6348e/attachment.htm
More information about the Squeak-dev
mailing list
|