[Vm-dev] [Pharo-project] Plan/discussion/communication around new object format

Igor Stasenko siguctua at gmail.com
Fri Jun 15 17:52:27 UTC 2012


On 15 June 2012 17:57, Chris Muller <ma.chris.m at gmail.com> wrote:
>> In terms of implementation, this is quite easy to do: since graph
>> comes from database in serialized form, creating an initial copy is
>> just about materializing same object twice (or materializing and then
>> copying) instead of once.
>> One will be used in working set,
>> and another will be used to detect the changes upon committing transaction.
>
> Magma essentially does this today.  Back in the early 2000's, it made
> shallow copies of each materialized object and identity-mapped them to
> the "working copy" of the object.  It would compare them upon
> transaction commit to see if they should be part of the commit
> package.
>
Ah.. cool.. so even less work.
So, i presume you miss one little primitive which scans the memory
subgraph from the roots which you provide
and gives you back all objects which inside it.
Like that you can very quickly discover what is a new shape of a working set
and then iterate over it and see what objects were changed and which
were added/removed.

> Since then, it was changed to just keep the original buffers that were
> already part of the materialization (so not making copies when just
> reading from the db).  On transaction commit it now compares the
> referenced oids of each to determine if different.
>
> BTW:  I just realized a BIG problem with the WriteBarrier approach to
> change-detection:  If the method which modifies the inst-variable ALSO
> happens to perform the commit, then the commit will not notice the
> changes!
>
> For example, consider a simple setter:
>
>    name: aString
>        myDbSession commit: [ name = aString ]
>
> WB will override this method in its generated anonymous subclass to:
>
>    name: aString
>        | t1 |
>        t1 := name.
>        returnVal := super name: aString.
>        t1 == name ifFalse: [ self writeBarrier modified ].
>        ^ returnVal
>
> Do you see the problem?

yes, i do :)
A correct implementation should modify the existing methods, but
not use subclassing. But that's of course harder to do without decent
support from tools
(btw Opal Compiler will allow to do that easily).

but i think you can easily fix it by implementing #maValue in block
and use
aBlock maValue
in commit method, instead of #value.

A sketch implementaiton of #maValue is something like:

maValue
  | rcvr receiverStateBefore result |
  rcvr := self home receiver.
  receiverStateBefore :=rcrvr copyState.
  result := self value.
  (rcvr isSameAs: receiverStateBefore) ifFalse: [ rcvr writeBarrier modified ].
  ^ result

> Super call already tried the commit before it
> even knew it was changed.  It emphasizes the limitation of WB:  That
> it can only work via method calls, not direct assignments like a
> immutability-bit could.
>
> The only solution is to NEVER co-locate the updating of a persistent
> inst-var in the same method as performing/signaling the commit.  That
> sucks bad enough that I've made Magma sessions now default
> allowWriteBarrier to false.   :-(



-- 
Best regards,
Igor Stasenko.


More information about the Magma mailing list