[Vm-dev] [Pharo-dev] About ~= and ~~

Eliot Miranda eliot.miranda at gmail.com
Fri Nov 25 17:54:32 UTC 2016

Hi Clément, Hi All,

On Thu, Nov 24, 2016 at 5:09 AM, Clément Bera <bera.clement at gmail.com>

> Hi,
> Support for primitive 169 for Object>>#~~ has been in the VM for a while.
> The default implementation in Squeak 5 uses this primitive for example.
> I've just added today (VMMaker commit 2003) support for inlined #~~ like
> #== (including JIT support, branch pipelining, etc.). If one puts #~~ in
> the specialObjectsArray at the location of #blockCopy:, the bytecode
> compiler generates the special send bytecode for #~~ leading to improved
> performance and consistency between #== and #~~.
> With today's update, the VM supports 3 inlined operations without any type
> checks: #==, #~~ and #class. It is possible to disable such optimisations
> in the bytecode compiler (In Pharo #class inlining is disabled there for
> example). Eliot would like to add support to disable these operations at VM
> level as a VM command line parameter too, and we may do it in the future.
> Now this is for the VM support. It's up to the Pharo/Squeak/other
> community to decide what behavior they want in their runtime for these 3
> selectors.
> In my opinion, I believe that #~~ should be consistent with #==, hence
> they should be both inlined or both sends to primitives. I don't like the
> current situation in Pharo nor in Squeak.
> Now when we look for solutions, we see that one of #== and #~~ needs to be
> a primitive (it's essential), hence it makes sense to have both Object>>#==
> and Object>>#~~ as primitives (with the primitive pragma in the method
> body). The inlining of #== and #~~ is arguable and I let the community
> decide what they believe is best for their runtime, though I would rather
> have the same behavior for both selectors.

In addition, for proxies, it makes sense to allow the system to not inline
the primitives.  Let me explain.  The primitives for #== and #~~, just like
any other primitives, are found by message sends.  However, a set of 32
"special" selectors, which comprise some arithmetic selectors (#+, #- etc)
and comparison selectors (#< #<= etc) and some frequent selectors #(at:
#next #value #== etc) are subject to inlining with no sends (see Smalltalk
specialSelectoers for the full set).

The first sixteen are arithmetic and comparison, and the interpreter gains
performance by implementing these byte codes to test for SmallIntegers and
Floats, and performing the arithmetic directly without a send, and for the
comparisons, performing the comparison and any immediately following
conditional branch.  The JIT performs these optimisations too.  But these
short-cuts (static type prediction in the official terminology) are safe
because they apply only to SmallInteger and Float.

Of the next sixteen most are there only to save space in a method's literal
frame.  Since the byte code encodes the selector directly there is no need
to store the selector in the method's literals.  The implementation of all
but two (three if we add #~~ to replace #blockCopy: as mentioned above) of
these bytecodes is to fetch the selector from the specialSelectors array
and do a normal send.

#== and #class are handled specially.  These are inlined without doing a
send.  The current Opal compiler in Pharo avoids the inlining of #class by
not generating the #class special selector bytecode.  Squeak's compiler
still issues the special selector bytecode.  Both generate #== by issuing
the #== special selector bytecode, and so #== is never sent.  This is not
what's desired for applications that use proxies.  It is fine for simple
applications that prefer speed.

One simple thing one can do is prevent inlining for anything other than the
arithmetic and comparison operators.  A simple command-line switch, or
perhaps better, a flag in the image header, can control whether the VM
inlines #class, #== & #~~.  This then allows the compilers to generate the
more compact special selector byte codes for these sends, but causes the VM
to treat them like the other 13 non-arithmetic special selectors.  Hence
they become true sends.  I did this for VisualWorks several years ago and
it works well, expect for needing a command-line switch.  The flag in the
image header is much more reliable; whether an image should be run with
inlining or not is a property of the image, not of a particular VM

So I suggest that
a) I implement the switch as an image header flag, allowing the inlining of
#class, #== and #~~ to be turned off (but keeping inlining on by default)
b) Pharo changes Opal to start issuing the #class special selector send
byte code again and turns off inlining of #class, #== and #~~
c) applications that use proxies (in Cuis, Pharo or Squeak) experiment with
the setting and see if logic is improved and report back; Squeak and other
dialects can then decide what they want as the default, and indeed certain
packages could try and set the flag or at least check that the flag is in
the desired state

> Cheers
> On Wed, Nov 23, 2016 at 2:39 PM, Aliaksei Syrel <alex.syrel at gmail.com>
> wrote:
>> Hi
>> It is been a while...
>> So, do we want to replace ~~ with a primitive? :)
>> Cheers
>> Alex
>> --
>> View this message in context: http://forum.world.st/About-an
>> d-tp3898409p4924391.html
>> Sent from the Pharo Smalltalk Developers mailing list archive at
>> Nabble.com.

best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20161125/70cc04ba/attachment-0001.html>

More information about the Vm-dev mailing list