[squeak-dev] read-only literals

Chris Muller asqueaker at gmail.com
Mon Mar 26 03:26:58 UTC 2018


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?

First, it might help me to understand what _your_ primary motivation
for proposing to make various entire classes of objects read-only by
default?  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!

> 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.

> - 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.

Regards,
  Chris


More information about the Squeak-dev mailing list