Slang question (was: Re: [squeak-dev] The Trunk:
Collections-ul.685.mcz)
David T. Lewis
lewis at mail.msen.com
Tue Apr 5 23:14:29 UTC 2016
I just got around to checking this for code generation for the interpreter VM
(VMMaker, not VMMaker.oscog). The #ifNil: is not translated at all, so I replaced
it with this:
matchTable = nil ifTrue:
This produces the expected result, and can be compiled.
There are other issues in the resulting VM, but they do not seem to be
related to Collections-ul.685 (I reverted to Collections-ul.684 with the
same results). I don't know the cause of those issues, but I will follow
up in a separate thread as needed.
With respect to Collections-ul.685, replacing the ifNil: test as above
seems like the right thing to do.
Dave
On Sun, Apr 03, 2016 at 06:00:13PM -0400, David T. Lewis wrote:
> Many people will not be familiar with this optimization, so a few words of
> explanation are in order for background:
>
> There is a mechanism for translating certain methods in the image directly
> into primitives for performance. This is normally not noticed, but you will
> find occasional refernces such at this one in the image:
>
> findSubstring: key in: body startingAt: start matchTable: matchTable
> <primitive: 'primitiveFindSubstring' module: 'MiscPrimitivePlugin'>
>
> This is a method that first tries to call a version of itself that has
> been translated to C. If the primitive fails, the normal Smalltalk method
> is executed. The hidden tricky bit is that MiscPrimitivePlugin, which
> lives in the VMMaker package, arranges for the #findSubstring:in:startingAt:matchTable:
> method in the image to be translated to C and installed as a primitive.
> This means that the generated VM is actually governed partly my methods
> in the main image (not in the VMMaker package).
>
> It also means that if one of these methods is changed in the image, it
> might accidentally result in unexpected (and possibly wrong) code being
> generated for the plugin in the VM. That is the reason that Levente is
> asking about the slang code generation in this case.
>
> Dave
>
>
> On Sun, Apr 03, 2016 at 07:45:13PM +0200, Levente Uzonyi wrote:
> > On Sun, 3 Apr 2016, commits at source.squeak.org wrote:
> >
> > >Levente Uzonyi uploaded a new version of Collections to project The Trunk:
> > >http://source.squeak.org/trunk/Collections-ul.685.mcz
> > >
> > >==================== Summary ====================
> > >
> > >Name: Collections-ul.685
> > >Author: ul
> > >Time: 3 April 2016, 3:21:51.035808 am
> > >UUID: db8fd391-2306-4ccc-87d5-b5dee96a78ab
> > >Ancestors: Collections-eem.684
> > >
> > >Use Spur's new character comparison abilities in some String methods.
> > >
> > >=============== Diff against Collections-eem.684 ===============
> > >
> > >Item was changed:
> > > ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in
> > > category 'comparing') -----
> > > findSubstring: key in: body startingAt: start matchTable: matchTable
> > > "Answer the index in the string body at which the substring key
> > > first occurs, at or beyond start. The match is determined using
> > > matchTable, which can be used to effect, eg, case-insensitive
> > > matches. If no match is found, zero will be returned.
> > >
> > > The algorithm below is not optimum -- it is intended to be
> > > translated to C which will go so fast that it wont matter."
> > > | index |
> > > <primitive: 'primitiveFindSubstring' module: 'MiscPrimitivePlugin'>
> > > <var: #key declareC: 'unsigned char *key'>
> > > <var: #body declareC: 'unsigned char *body'>
> > > <var: #matchTable declareC: 'unsigned char *matchTable'>
> > >
> > > key size = 0 ifTrue: [^ 0].
> > >+ matchTable ifNil: [
> > >+ start to: body size - key size + 1 do: [ :startIndex |
> > >+ index := 0.
> > >+ [ (body at: startIndex + index) == (key at: (index
> > >:= index + 1)) ] whileTrue: [
> > >+ index = key size ifTrue: [ ^startIndex ] ] ].
> > >+ ^0 ].
> >
> > I wonder if the #ifNil: check is correct in Slang. The generated code is
> >
> > ...
> > unsigned char *matchTable;
> > ...
> > matchTable = arrayValueOf(stackValue(0));
> > matchTable -= 1;
> > ...
> > if (!(matchTable)) {
> > ...
> >
> > So, will the value of matchTable actually be NULL or not, when nil is
> > passed to the primitive. That -= 1 makes me think that it won't be NULL.
> >
> > Another thing is that the loop condition, while it's order of evaluation
> > is well defined in Smalltalk, will compile to C code containing undefined
> > behavior:
> >
> > while ((body[startIndex + index]) == (key[index +=
> > 1])) {
> >
> > Since in C the evaluation of the left and right side of == can happen in
> > any order, the generated machine code may or may not be correct.
> > Is this is a difference between Smalltalk and Slang, or is it just a slip
> > in the code generator?
> >
> > Levente
> >
> > > (start max: 1) to: body size - key size + 1 do:
> > > [:startIndex |
> > > index := 1.
> > > [(matchTable at: (body at: startIndex+index-1)
> > > asciiValue + 1)
> > > = (matchTable at: (key at: index) asciiValue
> > > + 1)]
> > > whileTrue:
> > > [index = key size ifTrue: [^ startIndex].
> > > index := index+1]].
> > > ^ 0
> > > "
> > > ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable:
> > > CaseSensitiveOrder 1
> > > ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable:
> > > CaseSensitiveOrder 7
> > > ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable:
> > > CaseSensitiveOrder 0
> > > ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable:
> > > CaseSensitiveOrder 0
> > > ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable:
> > > CaseInsensitiveOrder 7
> > > "!
More information about the Squeak-dev
mailing list
|