[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: copy-on-write (was: globals considered harmful)



> I don't see the need for the stub object; addSlotsIfAbsent: takes care of
> copying the remainder of the slots while preserving object identity.
> Or perhaps I'm misunderstanding your example.
[...]
> - JJ Larrea (jjl@panix.com)

My understanding of addSlotsIfAbsent: is that it first creates a copy of the 
object with the additional slots added and then walks through all of memory to 
reassign the pointers from the old one to the new one.  I think Urs was 
referring to this point when he said:

> The problem with COW is that there's no straightforward efficient
> implementation.  For example, if an assignment grows an object, the
> implementation has to make up a new object and redirect all pointers
> to the old object.  That's only fast if you use indirect pointers
> (i.e., an object table), which is acceptable for an interpreter but
> slows down a compiled system quite a bit.
>
> However, there may be some clever trick to implement COW efficiently.
> Sounds like a Ph.D. thesis to me... :-)

So my solution (a stub object until you're finished growing, then an 
addSlotsIfAbsent) was a blend of the indirect and the direct methods.

Later, Dave said:

> A Lieberman-style system (with copy-on-write) avoids the
> non-concrete traits problem but makes it harder to express shared state--
> how do you know when NOT to copy-on-write?

If you want per slot selection of COW, then you can do this by using stubs 
with only selected slots added to them.  The other are implicitly copied over. 
 One possible definition (my Self is VERY rusty, so this may have errors):

[assume that there is a primitive called 'smash: a And: b' that concatenates a 
and b into a third object -- maybe there already is such a primitive...]

stub objects have an assignable inheriting slot called 'cow' to hold the new 
slots and a slot called slotsLeft, which holds the number of slots left to 
copy, so that we know when to convert the stub to the real object.

traits for cow objects:

(|
	copySlot: aSlot = (
		cow: smash: cow And: aSlot.
		checkGrowth.
	).
	checkGrowth = (
		(slotsLeft: slotsLeft - 1) isZero ifTrue: [Define: cow].
	).
|)

prototype for a brick:

(|
	color = red.
	color: aValue = (copySlot: (| color <- aValue. |)).
	weight = 1.
	weight: aValue = (copySlot: (| weight <- aValue. |)).
|)

--------------

I think this should do the trick.  I'm pretty sure that inheritence will 'do 
the right thing' with this setup, too..

	-- Bill Burdick
	burdick@ars.rtp.nc.us