[squeak-dev] enabling read-only literals...
eliot.miranda at gmail.com
Wed Mar 11 23:37:49 UTC 2020
On Wed, Mar 11, 2020 at 4:03 PM Chris Muller <asqueaker at gmail.com> wrote:
> Hi Eliot,
> Can ModificationForbidden be resumed? I certainly hope so.
Indeed its can. Use in database write barriers is one major use case.
However, the framework for convenient use has yet to be designed and
implemented. We have lots of experience with this barrier in VisualWorks
and some experience in Pharo, so designing the right support should not be
hard at all.
> Magma's own WriteBarrier has one place where it dynamically compiles a
> literal in a method for the sole purpose of providing one extra reference
> slot needed for the framework. This is a useful feature in a general
> sense, something I'd hate to see lost. Yes, I understand it's "bad code"
> to modify a literal, just like using "become:" (which it also uses), but
> for frameworks that need to work slightly under the hood, these hacks can
> be very useful when one knows what they're doing.
If you *do* have to modify a literal, then all you have to do is send
beWritableObject to the literal in question and you'll be able to modify it
(there is no recursive protection against setting read-only objects to
Unfortunately, I don't think the VM-based WriteBarrier can work for Magma
> due to its "global" nature.
I'm willing to bet you that it can. For example,e, it works in Gemstone on
VisualWorks. The solution is to provide a policy registry hat on a
per-object basis specifies how modifications to objects are to be handled.
This registry typically/best exists in the exception class
(ModificationForbidden), and maps an object to a MessageSend or block.
This registry tags specific instances with a retry policy, so e.g. Magma
can put all objects it fetches from the database that it wants to be
write-through into the registry and sets them to be read-only. Then on an
attempted modification the ModificationForbidden exception looks up the
object in the registry, and if its there runs whatever code the registry
specifies. This would be some method in Magma that would
- set the object as writable
- ask the exception to retry the modification
- write the changed object through to the database
- set the object back to read-only
- resume the exception with a suitable value
Specific classes might implement a message the exception could send rather
than require the registry is used. But that's a space-saving optimization.
Such a framework allows several orthogonal clients to share the framework,
potentially on the same objects because the registry can be engineered to
have more than one action per object.
(BTW, this is how VisualWorks does things, IIRC)
Does that instill more confidence?
When we added read-only object support to VisualWorks some of the
>> engineering staff were of the opinion that insulating customers from the
>> change was a necessary thing, and so we implemented a preference to allow
>> automatic mutating of read-only literals so that customers whose code did
>> modify literals could set the preference rather than fix their code. I
>> *really* don't ant to do this. It is a lot of complication for little
>> gain; the right fix is just to rewrite the code not to write to literals.
>> Note that that's as easy as:
> I don't think we need a global preference as much as just let it be
> #isResumable. Can we do that?
Yes, it is, but doing so loses the modification:
| l |
[(l := #(1 2 3)) at: 2 put: 'nevermore']
do: [:ex| ex resume].
l => #(1 2 3)
whereas one often wants to do something more like this:
| lit result |
result := [(lit := #(1 2 3)) at: 2 put: 'nevermore']
do: [:ex| ex object beWritableObject. ex retryModification].
lit -> result #(1 'nevermore' 3)->'nevermore'
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Squeak-dev