[kaffe] Release 1.0.7: Deadlock in JIT3 (Amiga m68k)

Tony Wyatt wyattaw@optushome.com.au
Sat Jun 21 04:20:02 2003


Hi all,

While I can't get Release 1.1.0 to compile, I just had a little play with
1.0.7-JIT3. I have a test program that causes a deadlock when run, due to a
corrupted Lock address.

The program is:
"import java.io.*;

class FloatTest
{
    public static void main(String[] args)
    {
        System.out.println("=" + (fmeth() / fmeth()) );
    }

    public static float fmeth()
    {
        return 0.0f;
    }
}
"
The temporary result for the division within the println call causes the
problem.
The translated Method code for FloatTest.main generates the following code
which over-writes the address of the Lock variable (my comments):

 L0:  1
@0:    getstatic 12
@3:    new 15
@6:    dup
@7:    ldc1 17
@9:    invokespecial 22
@12:    invokestatic 26
@15:    invokestatic 26
@18:    fdiv
@19:    invokevirtual 30
@22:    invokevirtual 34
@25:    invokevirtual 37
@28:    return
            0000:    linkw %fp, #0
            - - -
            002a:    jsr +0                // soft_new
            0030:    addql #4, %sp
            0032:    movel %d0, -12(%fp)    // save result
            - - -
            009a:    fsmoves -8(%fp), %fp1
            00a0:    fsdivx %fp0, %fp1
            00a4:    fmoved %fp1, -12(%fp)    // destroys saved Lock
            - - -
            00ce:    movel 12(%fp), -(%sp)
            00d2:    movel -8(%fp), -(%sp)
            00d6:    movel -12(%fp), -(%sp)
            00da:    moveal #0x8e0713e, %a0    // "append"
            00e0:    moveal (%a0), %a0
            00e2:    jsr (%a0)


If I alter the source to write the floating result into a local variable,
the deadlock does not occur:
"import java.io.*;

class FloatTest
{
    public static void main(String[] args)
    {
        float    result = (fmeth() / fmeth());
        
        System.out.println("=" + result );
    }

    public static float fmeth()
    {
        return 0.0f;
    }
}

"

The new resulting code is:

 L0:  1 L1:  1
@0:    invokestatic 12
@3:    invokestatic 12
@6:    fdiv
@7:    fstore 1
@8:    getstatic 16
@11:    new 19
@14:    dup
@15:    ldc1 21
@17:    invokespecial 26
@20:    fload 1
@21:    invokevirtual 30
@24:    invokevirtual 34
@27:    invokevirtual 37
@30:    return
            0000:    linkw %fp, #0
            - - -
            0046:    fsdivx %fp0, %fp1            // do the division
            004a:    fsmovex %fp1, %fp0
            - - -
            005a:    fmoves %fp0, -4(%fp)        // save FP result
            - - -
            0066:    jsr +0                            // soft_new
            006c:    addql #4, %sp
            006e:    movel %d0, -16(%fp)        // save result
            - - -
            00ac:    fsmoves -4(%fp), %fp0        // a little nonsense
            00b2:    fsmovex %fp0, %fp1            // to keep the
            00b6:    fmoves %fp1, -12(%fp)        // FPU warm
            - - -
            00e0:    movel 12(%fp), -(%sp)
            00e4:    movel -12(%fp), -(%sp)
            00e8:    movel -16(%fp), -(%sp)
            00ec:    moveal #0x938313e, %a0    // "append"
            00f2:    moveal (%a0), %a0
            00f4:    jsr (%a0)

Needless to say, this version runs without deadlocking. My question is,
where should I start looking for the problem in the first version? In the area 
of "register spillage"? In the area of "save temporary variables"? I could 
do with a hint, please.

cheers
tony