[Vm-dev] Serious inlining problem

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Wed Apr 27 19:47:28 UTC 2016


Hi,
I changed the compiler flag -Wno-unused-value to -Wunused-value because
there's no reason to carry dead code. Dead code should ring a bell.
it seems it uncovers a problem in code generation.
An example is in code generated for sendInvokeCallbackContext:

       if ((argumentCountOfMethodHeader(methodHeaderOf(GIV(newMethod)))) ==
4) {
                /* begin push: */
                value = ((usqInt)((vmCallbackContext->thunkp)));
                /* begin positive32BitIntegerFor: */
                /* begin maybeInlinePositive32BitIntegerFor: */
                assert(!((hasSixtyFourBitImmediates())));
                if ((((unsigned int) value)) <= (MaxSmallInteger)) {
                        ((value << 1) | 1);
                       ^~~~~~~~~~~~~~ PROBLEM HERE: this result should be
stored in variable 'object'
                        goto l4;
                }
                /* begin eeInstantiateSmallClassIndex:format:numSlots: */
...snip...
                object = newLargeInteger;
        l4:     /* end maybeInlinePositive32BitIntegerFor: */;
                goto l5;

        l5:     /* end positive32BitIntegerFor: */;

                longAtput((sp = GIV(stackPointer) - BytesPerWord), object);

The corresponding Slang code is:

    (self argumentCountOf: newMethod) = 4 ifTrue:
        [self push: (self positiveMachineIntegerFor: vmCallbackContext
thunkp asUnsignedInteger).

With push:

    | sp |
    <inline: true>
    <var: #sp type: #'char *'>
    stackPages longAt: (sp := stackPointer - objectMemory wordSize) put:
object.
    stackPointer := sp

With positiveMachineIntegerFor:

    <var: #value type: #'unsigned long'>
    <inline: true>
    ^objectMemory wordSize = 8
        ifTrue: [self positive64BitIntegerFor: value]
        ifFalse: [self positive32BitIntegerFor: value]

With positive32BitIntegerFor:

    <inline: true>
    <var: 'integerValue' type: #'unsigned int'>
    objectMemory hasSixtyFourBitImmediates
        ifTrue:
            [^objectMemory integerObjectOf: (integerValue asUnsignedLong
bitAnd: 16rFFFFFFFF)]
        ifFalse:
            [^self maybeInlinePositive32BitIntegerFor: integerValue]

With maybeInlinePositive32BitIntegerFor:

    <notOption: #Spur64BitMemoryManager>
    <var: 'integerValue' type: #'unsigned int'>
    | newLargeInteger |
    self deny: objectMemory hasSixtyFourBitImmediates.
       "force coercion because slang inliner sometimes incorrectly pass a
signed int without converting to unsigned"
       (self cCode: [self cCoerceSimple: integerValue to: #'unsigned int']
            inSmalltalk: [integerValue bitAnd: 1 << 32 - 1]) <=
objectMemory maxSmallInteger ifTrue:
        [^objectMemory integerObjectOf: integerValue].
    newLargeInteger := objectMemory
                            eeInstantiateSmallClassIndex:
    ...snip...
    ^newLargeInteger
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20160427/f2221740/attachment.htm


More information about the Vm-dev mailing list