On 06/22/2011 06:20 PM, Andrew Haley wrote:
> I've found and fixed the bugs that were stopping gcj from working.

This is really impressive. Thanks for describing the details!

Cheers,
Niels


> Firstly, there was the "libgcc is a symlink instead of a linker
> script" bug that I've explained before.
> 
> 
> Then there was the libgcj/sysdep/arm/locks.h problem that broke
> locking.  I already described that.
> 
> 
> Then I found a locking bug in the boehm garbage collector.
> GC_clear(), which releases a lock, was simply
> 
>        inline static void GC_clear(volatile unsigned int *addr) {
>          /* Try to discourage gcc from moving anything past this. */
>          __asm__ __volatile__(" " : : : "memory");
>          *(addr) = 0;
>        }
> 
> but it needs a memory barrier instruction.  The easiest way to fix
> this is to use a gcc builtin that generates the correct barrier:
> 
>         inline static void GC_clear(volatile unsigned int *addr) {
>         __sync_lock_release(addr);
>       }
> 
> I also replaced GC_test_and_set() with a gcc builtin, although this
> isn't strictly necessary:
> 
>          inline static int GC_test_and_set(volatile unsigned int *addr) {
>         return __sync_lock_test_and_set(addr, 1);
>         }
> 
> 
> There was also a problem in libffi when generating a closure.  The
> code that generates a trampoline looks like this:
> 
> #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX)                            \
> ({ unsigned char *__tramp = (unsigned char*)(TRAMP);                  \
>    unsigned int  __fun = (unsigned int)(FUN);                         \
>    unsigned int  __ctx = (unsigned int)(CTX);                         \
>    *(unsigned int*) &__tramp[0] = 0xe92d000f; /* stmfd sp!, {r0-r3} */        
> \
>    *(unsigned int*) &__tramp[4] = 0xe59f0000; /* ldr r0, [pc] */      \
>    *(unsigned int*) &__tramp[8] = 0xe59ff000; /* ldr pc, [pc] */      \
>    *(unsigned int*) &__tramp[12] = __ctx;                             \
>    *(unsigned int*) &__tramp[16] = __fun;                             \
>    __clear_cache((&__tramp[0]), (&__tramp[19]));                      \
>  })
> 
> Here, three instructions are laid down in memory, followed by some
> data fields.  Once that has been done, __clear_cache() is called on
> the block of memory.  Unfortunately, due to the requirement to placate
> SELinux, the same block of memory is mapped twice, once with RW
> mapping and once with RX mapping.  Therefore, there must be two calls
> to __clear_cache(), one to flush the dcache, and one to flush the
> icache.  Like this:
> 
> #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX)                            \
> ({ unsigned char *__tramp = (unsigned char*)(TRAMP);                  \
>    unsigned int  __fun = (unsigned int)(FUN);                         \
>    unsigned int  __ctx = (unsigned int)(CTX);                         \
>    unsigned char *insns = (unsigned char *)(CTX);                       \
>    *(unsigned int*) &__tramp[0] = 0xe92d000f; /* stmfd sp!, {r0-r3} */        
> \
>    *(unsigned int*) &__tramp[4] = 0xe59f0000; /* ldr r0, [pc] */      \
>    *(unsigned int*) &__tramp[8] = 0xe59ff000; /* ldr pc, [pc] */      \
>    *(unsigned int*) &__tramp[12] = __ctx;                             \
>    *(unsigned int*) &__tramp[16] = __fun;                             \
>    __clear_cache((&__tramp[0]), (&__tramp[19])); /* Clear data mapping.  */ \
>    __clear_cache(insns, insns + 3 * sizeof (unsigned int));             \
>                                                  /* Clear instruction   \
>                                                     mapping.  */        \
>  })
> 
> 
> Finally, libjava was segfaulting when an array class was finalized.
> This has apparently always happened, but on other platforms the
> segfault is caught and turned into a NullPointerException.  All
> finalizers are called from an exception region that traps all
> exceptions and continues, so we never noticed.
> 
> Fixed thusly:
> 
> --- libjava/java/lang/natClass.cc     2010-06-11 05:09:01.000000000 -0400
> +++ prev/libjava/java/lang/natClass.cc        2011-06-21 06:09:22.000000000 
> -0400
> @@ -668,6 +668,8 @@
>  void
>  java::lang::Class::finalize (void)
>  {
> +  // Array classes don't have an engine, and don't need to be finalized.
> +  if (engine)
>    engine->unregister(this);
>  }
> 
> 
> After all this, gcj now seems to work.  I'm now building OpenJDK.
> 
> Andrew.
> _______________________________________________
> arm mailing list
> [email protected]
> https://admin.fedoraproject.org/mailman/listinfo/arm
_______________________________________________
arm mailing list
[email protected]
https://admin.fedoraproject.org/mailman/listinfo/arm

Reply via email to