This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Linker name conflicts due to optimization in gjavah


When linking an executable that users java/util/logging/Logger, I get
a a linkage error:

------------  Linkage error ------------
l:/gcc_native/i686-pc-mingw32/bin/../lib/gcc/i686-pc-mingw32/4.1.0/../../../libgcj.a(natLogger.o)(.text$_ZN4java4util7logging6Logger7getNameEPNS_4lang6StringEv[java::util::logging::Logger::getName(java::lang::String*,
void)]+0x0):natLogger.cc: multiple definition of
`java::util::logging::Logger::getName(java::lang::String*, void)'
l:/gcc_native/i686-pc-mingw32/bin/../lib/gcc/i686-pc-mingw32/4.1.0/../../../libgcj.a(Logger.o)(.text+0x950):Logger.java:
first defined here
collect2: ld returned 1 exit status
------------ End linkage error --------

I traced this down to a problem in gjavah.c.  For simple getter
methods it generates code like this (extracted from generated
Logger.h):
     virtual ::java::lang::String *getName () { return name; }

Note that this is a virtual inline method declaration, which means
that if you declare a CNI class that includes the generated header, it
will errantly create a virtual method in the object file that can
conflict with the method declared in the corresponding Java class.

It looks like gjavah is trying to be too smart, as is seen in the
following snippet from the decompile_method function in gjavah.c:
---------------- Code Snippet ---------------
  /* If the method is synchronized, don't touch it.  */
  if ((method_access & ACC_SYNCHRONIZED))
    return;

  if (code_len == 5
      && codes[0] == OPCODE_aload_0
      && codes[1] == OPCODE_getfield
      && (codes[4] == OPCODE_areturn
          || codes[4] == OPCODE_dreturn
          || codes[4] == OPCODE_freturn
          || codes[4] == OPCODE_ireturn
          || codes[4] == OPCODE_lreturn))
    {
      /* Found code like `return FIELD'.  */
      index = (codes[2] << 8) | codes[3];
      /* FIXME: ensure that tag is CONSTANT_Fieldref.  */
      name_and_type = JPOOL_USHORT2 (jcf, index);
      /* FIXME: ensure that tag is CONSTANT_NameAndType.  */
      name = JPOOL_USHORT1 (jcf, name_and_type);
      if (codes[4] == OPCODE_areturn)
        decompile_return_statement (out, jcf, method_signature,
                                    name, JPOOL_USHORT2 (jcf, name_and_type));
      else
        {
          fputs (" { return ", out);
          /* FIXME: flags.  */
          print_field_name (out, jcf, name, 0);
          fputs ("; }", out);
        }
      decompiled = 1;
    }
---------------------------------------------------------

Note that it is decompiling the method and if it finds a simple
getter-style method, just emitting the corresponding C++ inline
definition.  Is it really worth the trouble to be doing this?  Maybe
some platforms are merging the duplicated methods or something (or
maybe no one has seen this problem before) but mine isn't.

At the risk of offending the person who wrote the optimization code, I
suggest that it be taken out.  I found this in CVS head and the
5/15/2005 snapshort.  Any objections?  Should a bug be opened?

TJ


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]