[squeak-dev] read-only literals

Eliot Miranda eliot.miranda at gmail.com
Mon Mar 26 14:09:12 UTC 2018


Hi Chris,



_,,,^..^,,,_ (phone)
> On Mar 25, 2018, at 8:26 PM, Chris Muller <asqueaker at gmail.com> wrote:
> 
>> On Sun, Mar 25, 2018 at 6:18 PM, Eliot Miranda <eliot.miranda at gmail.com> wrote:
>> Hi All,
> 
> Hi Eliot,
> 
> Congratulations on the enhancement.  As developer of Magma, I'm
> interested in learning more about it as a possible alternative to the
> WriteBarrier.  How does it work?

There is a per-object flag (a bit in the object header) that if set prevents modification.  The bit is controlled by Object>>#setIsReadOnlyObject: with Object>>#beReadOnlyObject as a convenience.  Object>>#beReadOnlyObject is the getter.  By default the bit is off (new objects are mutable).  The Compiler modification sets the bit for method literals (literal strings, symbols, arrays, byte arrays and boxed floats).  The facility may also be used for 
- an object-to-database mapping system
-debugging
etc

> 
> First, it might help me to understand what _your_ primary motivation
> for proposing to make various entire classes of objects read-only by
> default?

I have proposed no such thing.  You have misunderstood :-)

>  As you found from running the tests, the few cases that
> modified literals were doing it intentionally.  My guess is that more
> read-only objects allows the VM to run a lot faster, is that right?
> But my hope was that this capability would be provided with
> granularity at the object-level, not necessarily the class level.
> 
>>    the VM now has support for read only objects, and the first logical
>> application is for literals, making boxed floats, strings, symbols, arrays
>> and byte arrays read-only.
> 
> Wow, Arrays and ByteArrays too?  Magma's core Buffer classes all use
> ByteArray's internally to represent and update their state.  Ouch!

No, no, no, no :-). Only _literal_ instances of these.

> 
>> Doing so is trivial; only two methods need to be
>> modified (see attached).  AFAIA little or no core code is broken by making
>> literals read-only.  However, when I ran the test suite with read-only
>> literals in place, several tests were broken.  These are things like
>> creating null-terminated strings for testing OSProcess, by replacing spaces
>> in string literals with zeros, etc.
>> 
>> When we added read-only literals to VisualWorks in something like vw7.0 the
>> balance of opinion was that we should not break user code.  Hence we
>> implemented a preference scheme with three states:
>> 
>> - By default, an attempt to modify a read-only literal would silently make
>> the literal mutable temporarily,update it and then reenable read-onlyness.
> 
> Magma uses previously-loaded ByteArray's and replaces their contents,
> field by field, via ByteArray>>#uint:at:put:.  It runs this method
> more than any other in the image -- millions and millions of times.
> The performance of this method is very important for Magma.

And why on earth would I try and introduce something that would break this?


>> - A second state would issue a warning to the transcript, while doing what
>> the default did.
> 
> I'm reading that and imagining a low level primitive like
> Array>>#at:put: having a reference or signal to the Transcript that
> runs *every single time*?  That can't be true.  Surely the "preference
> scheme" you mentioned must've been more sophisticated than global
> Preference values.  Something more dynamic and simple, like "myObject
> beReadOnly: true"...?   Then applications -- including the IDE -- can
> handle AttemptToModifyReadOnlyObject as needed.
> 
>> - The third state would raise an error
> 
> In the process of raising that error, is there any danger of
> encountering a place in the debugger code which attempted to modify
> another Array, thus causing it to re-enter the original error-raising
> code to raise yet another error?  It seems like a pretty low-level
> thing to have to guard against...
> 
>> Remember that all one needs to do to fix code that modifies literals is to
>> send copy to the literal before modifying the copy, since copies of
>> read-only literals are mutable.
> 
> I hope we are not confusing the intermal representation of objects
> being bytes with whether those objects are literals or not.  If a
> program sees fit to modify a "literal", techincally is not a literal,
> but a variable, right?  Dave's case sounds like a true literal, but
> I'm saying I have applications which update bitmap forms in real time.
> Artists paint on SketchMorphs..  I presume you don't mean for _these_
> cases to need to make constant copies...
> 
>> I was on the side of only raising an error, but was overruled :-).  I wonder
>> what this community thinks.  If there are strong views that user code should
>> continue to function unchanged (even though it is modifying literals, which
>> is so so wrong :-) ) I'm happy to implement a scheme similar to that for
>> VisualWorks.  But I'd rather not have to and simply have people fix their
>> code within a system that raises an error whenever an attempt is made to
>> modify a literal, and is as simple as possible, but no simpler ;-)
>> Thoughts, opinions?
> 
> Instead of introducing new assumptions and breaking old code, I
> suggest people writing which explicitly turn ON read-only'ness,  for
> the objects they want preserving legacy expectations about Smalltalk
> as well as the operation of legacy applications.  IMO, any
> introduction of immutability at the class-level should be turned off
> by default.  Make it powerful but not painful.
> 
> It would help tremendously to know what you want to accomplish and how
> the new API works.

We have been discussing this for a while now.  Clément even wrote a paper

https://hal.archives-ouvertes.fr/hal-01356338/document

> 
> Regards,
>  Chris
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20180326/3d9241cf/attachment.html>


More information about the Squeak-dev mailing list