This is the mail archive of the java-patches@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]

Re: RFA: [PATCH]: MIPS enhancements to libgcj...


Andrew Haley wrote:

This is OK.  However, I'm not a MIPS expert either.  Perhaps you do
need to ask one.  But don't let that stop you checking this in.

I agree you do need "memory" clobbers on the barrier instructions, if
"sync" does what I think it does.

Andrew.


O.K.:

Here is a slightly modified version of the patch.

Tested as before.

Changes to previous version are:

I removed --with-libgcj-mips-xgot and --with-broken-dladdr from to level configure. These are now configured in libjava/configure.host.

sysdeps/mips/locks.h: Reworked so that in theory it should work on more MIPS processor versions.

Can I check it in?

David Daney.
2003-10-22  David Daney  <ddaney@avtrex.com)

	* include/mips-signal.h: New file.
	* sysdep/dwarf2-backtrace.cc: New file.
	* sysdep/mips: New directory.
	* sysdep/mips/locks.h: New file.
	* Makefile.am(extra_cc_files): New, to allow extra c++ files to be
	added to libgcj.
	(extra_cc_source_files): Ditto.
	* configure.host(disable_dladdr):  New shell variable passed to
	configure.
	(mips*-*-linux*): sysdeps_dir=mips,
	can_unwind_signal=yes, disable_dladdr=yes, use -mxgot.
	(mipsel*-linux* | mipsisa32el*-linux*): Enable hash synchronization.
	* configure.in:(mips*-*-linux*): Use sysdep/dwarf2-backtrace.cc to
	generate backtrace, and include/mips-signal.h as SIGNAL_HANDLER
	(HAVE_DLADDR): Make it depend on setting of disable_dladdr.
	(EXTRA_CC_FILES): New, to support conditional addition of
	sysdep/dwarf2-backtrace.cc.
	* configure: Regenerated.
	* Makefile.in: Regenerated.
	* gcj/Makefile.in: Regenerated.
	* include/config.h.in: Regenerated.
	* include/Makefile.in: Regenerated.
	* testsuite/Makefile.in: Regenerated.
	
Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.332
diff -3 -u -p -r1.332 Makefile.am
--- Makefile.am	12 Oct 2003 13:39:06 -0000	1.332
+++ Makefile.am	22 Oct 2003 16:01:32 -0000
@@ -138,6 +138,7 @@ nat_files = $(nat_source_files:.cc=.lo)
 x_nat_files = $(x_nat_source_files:.cc=.lo)
 ## Objects from C sources in subdirs.
 c_files = $(c_source_files:.c=.lo)
+extra_cc_files = $(extra_cc_source_files:.cc=.lo)
 ## Objects from gtk-related C sources in subdirs.
 gtk_c_files = $(gtk_c_source_files:.c=.lo)
 ## Objects from Java sources in subdirs.
@@ -149,13 +150,13 @@ libgcj_la_SOURCES = prims.cc jni.cc exce
 	resolve.cc defineclass.cc interpret.cc verify.cc \
 	$(nat_source_files)
 EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \
-	win32-threads.cc posix.cc win32.cc \
-	$(c_source_files) $(java_source_files) $(built_java_source_files)
+	win32-threads.cc posix.cc win32.cc $(c_source_files) \
+	$(extra_cc_source_files) $(java_source_files) $(built_java_source_files)
 libgcj_la_DEPENDENCIES = libgcj-@gcc_version@.jar $(javao_files) \
-	$(c_files) $(GCOBJS) $(THREADOBJS) $(PLATFORMOBJS) $(LIBLTDL) \
-	$(LIBFFI) $(ZLIBS) $(GCLIBS)
+	$(c_files) $(extra_cc_files) $(GCOBJS) $(THREADOBJS) \
+       $(PLATFORMOBJS) $(LIBLTDL) $(LIBFFI) $(ZLIBS) $(GCLIBS)
 
-libgcj_la_LIBADD = $(javao_files) $(c_files) $(GCOBJS) \
+libgcj_la_LIBADD = $(javao_files) $(c_files) $(extra_cc_files) $(GCOBJS) \
 	$(THREADOBJS) $(PLATFORMOBJS)
 # Include THREADLIBS here to ensure that the correct version of
 # certain linuxthread functions get linked:
@@ -418,6 +419,9 @@ $(nat_files) $(x_nat_files): %.lo: %.cc
 $(c_files): %.lo: %.c
 	$(LTCOMPILE) -c -o $@ $<
 
+$(extra_cc_files): %.lo: %.cc
+	$(LTCXXCOMPILE) -c -o $@ $<
+
 $(c_files): java/lang/fdlibm.h java/lang/ieeefp.h java/lang/mprec.h
 
 ## FIXME: see above
@@ -2631,6 +2635,8 @@ c_source_files = \
   java/lang/e_scalb.c     java/lang/s_rint.c      java/lang/w_sqrt.c      \
   java/lang/e_sqrt.c      java/lang/s_scalbn.c    java/lang/sf_rint.c     \
   java/lang/k_cos.c       java/lang/s_sin.c       java/lang/sf_fabs.c
+
+extra_cc_source_files = $(EXTRA_CC_FILES)
 
 #java/awt/natToolkit.cc
 
Index: configure.host
===================================================================
RCS file: /cvs/gcc/gcc/libjava/configure.host,v
retrieving revision 1.53
diff -3 -u -p -r1.53 configure.host
--- configure.host	10 Sep 2003 18:50:47 -0000	1.53
+++ configure.host	22 Oct 2003 16:01:37 -0000
@@ -28,6 +28,8 @@
 #			pthread_self calls by caching thread IDs in a hashtable
 #   can_unwind_signal   Set to "yes" if the EH unwinder supports throwing
 #			from a signal handler.
+#   disable_dladdr      Set to "yes" if dladdr should not be used
+#                       (i.e it is broken).
 
 libgcj_flags=
 libgcj_cflags=
@@ -39,6 +41,7 @@ enable_hash_synchronization_default=no
 sysdeps_dir=generic
 slow_pthread_self=
 can_unwind_signal=no
+disable_dladdr=
 
 case "${target_optspace}:${host}" in
   yes:*)
@@ -212,6 +215,17 @@ EOF
 	  ./conftest ./conftest && slow_pthread_self=
 	  rm -f conftest conftest.c
 	fi
+	;;
+  mips*-*-linux* )
+  	sysdeps_dir=mips
+  	can_unwind_signal=yes
+	libgcj_flags="${libgcj_flags} -mxgot"
+	case "${host}" in
+	    mipsel*-linux* | mipsisa32el*-linux*)
+		enable_hash_synchronization_default=yes
+		disable_dladdr=yes
+	    ;;
+	esac
 	;;
   *-*-darwin*)
 	enable_hash_synchronization_default=no
Index: configure.in
===================================================================
RCS file: /cvs/gcc/gcc/libjava/configure.in,v
retrieving revision 1.172
diff -3 -u -p -r1.172 configure.in
--- configure.in	22 Sep 2003 16:04:24 -0000	1.172
+++ configure.in	22 Oct 2003 16:01:38 -0000
@@ -232,6 +232,9 @@ AC_ARG_WITH(ecos,
 TARGET_ECOS="$with_ecos"
 )
 
+EXTRA_CC_FILES=
+AC_SUBST(EXTRA_CC_FILES)
+
 PLATFORMOBJS=
 case "$TARGET_ECOS" in
    no) case "$host" in
@@ -600,6 +603,13 @@ else
        ia64-*-linux*)
 	 # Has broken backtrace()
 	 ;;
+       mips*-*-linux*)
+         # Has broken backtrace(), but we supply our own.
+         if test -d sysdep; then true; else mkdir -p sysdep; fi
+         EXTRA_CC_FILES="${EXTRA_CC_FILES} sysdep/dwarf2-backtrace.cc"
+         AC_DEFINE(HAVE_BACKTRACE, 1,
+           [Define if your platform has a working backtrace() function.])
+         ;;
        *)
          AC_DEFINE(HAVE_BACKTRACE, 1,
            [Define if your platform has a working backtrace() function.])
@@ -616,7 +626,13 @@ else
    ])
 
    AC_CHECK_LIB(dl, dladdr, [
-     AC_DEFINE(HAVE_DLADDR, 1, [Define if you have dladdr()])])
+     if test "x${disable_dladdr}" = "xyes"; then
+       #Broken dladdr().
+       true
+     else
+       AC_DEFINE(HAVE_DLADDR, 1, [Define if you have dladdr()])
+     fi
+   ])
    if test x"$build" = x"$host"; then
      AC_CHECK_FILES(/proc/self/exe, [
        AC_DEFINE(HAVE_PROC_SELF_EXE, 1, [Define if you have /proc/self/exe])])
@@ -1106,6 +1122,9 @@ case "${host}" in
     ;;
  *mingw*)
     SIGNAL_HANDLER=include/win32-signal.h
+    ;;
+ mips*-*-linux*)
+    SIGNAL_HANDLER=include/mips-signal.h
     ;;
  *)
     SIGNAL_HANDLER=include/default-signal.h
Index: include/mips-signal.h
===================================================================
RCS file: include/mips-signal.h
diff -N include/mips-signal.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ include/mips-signal.h	22 Oct 2003 16:01:40 -0000
@@ -0,0 +1,89 @@
+// mips-signal.h - Catch runtime signals and turn them into exceptions
+// on an mips based Linux system. 
+
+/* Copyright (C) 1998, 1999, 2001, 2002, 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+/* Adapted from sparc-signal.h and powerpc-signal.h
+   by David Daney <ddaney@avtrex.com> */
+
+#ifndef JAVA_SIGNAL_H
+#define JAVA_SIGNAL_H 1
+
+#include <signal.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+/* #include <asm/ucontext.h> structures we use are here but clash with
+   sys/ucontext.h included by java-signal.h from prims.cc */
+
+#define HANDLE_SEGV 1
+#undef HANDLE_FPE
+
+/* The third parameter to the signal handler points to something with
+ * this structure defined in asm/ucontext.h, but the name clashes with
+ * struct ucontext from sys/ucontext.h so this private copy is used. */
+typedef struct _sig_ucontext {
+    unsigned long	  uc_flags;
+    struct _sig_ucontext  *uc_link;
+    stack_t		  uc_stack;
+    struct sigcontext uc_mcontext;
+    sigset_t	  uc_sigmask;
+} sig_ucontext_t;
+
+/* We use kernel_sigaction here because we're calling the kernel
+   directly rather than via glibc. The sigaction structure that the
+   syscall uses is a different shape from the one in userland and not
+   visible to us in a header file so we define it here.
+   Additionally we want a proper prototype for the handler function
+   with the struct sigcontext pointer passed by the kernel as the 2nd
+   argument, which isn't there in userland headers. */
+
+struct kernel_sigaction {
+    unsigned int k_sa_flags;
+    void       (*k_sa_handler) (int, siginfo_t *, sig_ucontext_t *);
+    sigset_t     k_sa_mask;
+    void       (*k_sa_restorer)(void);
+    int          k_sa_resv[1];	/* reserved */
+};
+
+
+
+#define SIGNAL_HANDLER(_name) \
+static void _name (int _dummy, siginfo_t *_info, sig_ucontext_t *_arg)
+
+/*
+ *  MIPS leaves pc pointing at the faulting instruction, but the
+ *  unwinder expects it to point to the following instruction
+ */
+
+#define MAKE_THROW_FRAME(_exception) \
+do                                   \
+{                                    \
+  _arg->uc_mcontext.sc_pc += 4;      \
+  (void)_dummy;                      \
+  (void)_info;                       \
+}                                    \
+while (0)
+
+/* For an explanation why we cannot simply use sigaction to
+   install the handlers, see i386-signal.h.  */
+
+#define INIT_SEGV                                    \
+do                                                   \
+  {                                                  \
+    struct kernel_sigaction kact;                    \
+    kact.k_sa_handler = catch_segv;                  \
+    kact.k_sa_flags = SA_SIGINFO | SA_NODEFER;       \
+    sigemptyset (&kact.k_sa_mask);                   \
+    syscall (SYS_sigaction, SIGSEGV, &kact, NULL);   \
+  }                                                  \
+while (0)
+								
+
+#endif /* JAVA_SIGNAL_H */
+  
Index: sysdep/dwarf2-backtrace.cc
===================================================================
RCS file: sysdep/dwarf2-backtrace.cc
diff -N sysdep/dwarf2-backtrace.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sysdep/dwarf2-backtrace.cc	22 Oct 2003 16:01:40 -0000
@@ -0,0 +1,86 @@
+/* dwarf2-backtrac.cc - backtrace implementation driven by the dwarf2
+ exception unwinder.  */
+
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+/* Written by David Daney <ddaney@avtrex.com> */
+
+/*
+  Although this in theory could be 'C' instead of C++, saying that it
+  is C++ and including jvm.h makes it easier to insure that the proper
+  compiler options are used.  There must be unwind tables for
+  backtrace because it is on the stack when _Unwind_Backtrace is
+  called.  Compiling as C++ insures this.
+
+*/
+
+#include <config.h>
+
+#include <unwind.h>
+
+#include <jvm.h>
+
+
+extern "C"
+{
+  int backtrace (void **, int);
+}
+
+struct backtrace_state
+{
+  int skip_count;
+  int current_level;
+  int max_level;
+  void **locations;
+};
+
+static _Unwind_Reason_Code
+my_trace_fn (struct _Unwind_Context *uc, void *arg)
+{
+
+  struct backtrace_state *bs = (struct backtrace_state *) arg;
+
+  if (bs->skip_count)
+    {
+      bs->skip_count--;
+      return _URC_NO_REASON;
+    }
+
+  _Unwind_Ptr loc = _Unwind_GetIP (uc);
+
+  if (bs->current_level < bs->max_level)
+    bs->locations[bs->current_level++] = (void *) loc;
+
+  if (bs->current_level >= bs->max_level)
+    return _URC_END_OF_STACK;
+  else
+    return _URC_NO_REASON;
+}
+
+/*
+ * backtrace is defined in (some versions of) libc.  This definition
+ * must match so that it can replace the libc version at link time.
+ *
+ * Fill the locations array with at most len back trace locations.
+ *
+ * Returns the number of locations actually filled in.
+ *
+ */
+int
+backtrace (void **locations, int len)
+{
+  struct backtrace_state bs;
+  bs.skip_count = 1;		/* Don't log the call to backtrace itself. */
+  bs.current_level = 0;
+  bs.max_level = len;
+  bs.locations = locations;
+
+  _Unwind_Backtrace (my_trace_fn, &bs);
+  return bs.current_level;
+}
--- /dev/null	Thu Apr 11 07:25:15 2002
+++ sysdep/mips/locks.h	Tue Oct 21 15:16:40 2003
@@ -0,0 +1,109 @@
+// locks.h - Thread synchronization primitives. MIPS implementation.
+
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#ifndef __SYSDEP_LOCKS_H__
+#define __SYSDEP_LOCKS_H__
+
+/* Integer type big enough for object address.	*/
+typedef unsigned obj_addr_t __attribute__((__mode__(__pointer__)));
+
+
+// Atomically replace *addr by new_val if it was initially equal to old.
+// Return true if the comparison succeeded.
+// Assumed to have acquire semantics, i.e. later memory operations
+// cannot execute before the compare_and_swap finishes.
+inline static bool
+compare_and_swap(volatile obj_addr_t *addr,
+                 obj_addr_t old,
+                 obj_addr_t new_val) 
+{
+  long result;
+  __asm__ __volatile__(".set\tpush\n\t"
+                       ".set\tnoreorder\n\t"
+                       ".set\tnomacro\n\t"
+                       "1:\n\t"
+#if _MIPS_SIM == _ABIO32
+                       ".set\tmips2\n\t"
+#endif
+                       "ll\t%[result],0(%[addr])\n\t"
+                       "bne\t%[result],%[old],2f\n\t"
+                       "move\t%[result],$0\n\t"        // delay slot
+                       "move\t%[result],%[new_val]\n\t"
+                       "sc\t%[result],0(%[addr])\n\t"
+                       "beq\t%[result],$0,1b\n\t"
+                       "nop\n\t"                       // delay slot
+                       "2:\n\t"
+                       ".set\tpop"
+          : [result] "=&r" (result)
+          : [addr] "r" (addr), [new_val] "r" (new_val), [old] "r"(old)
+          : "memory");
+  return (bool) result;
+}
+
+// Set *addr to new_val with release semantics, i.e. making sure
+// that prior loads and stores complete before this
+// assignment.
+inline static void
+release_set(volatile obj_addr_t *addr, obj_addr_t new_val)
+{
+  __asm__ __volatile__(".set\tpush\n\t"
+#if _MIPS_SIM == _ABIO32
+                       ".set\tmips2\n\t"
+#endif
+                       "sync\n\t"
+                       ".set\tpop" : : : "memory");
+  *(addr) = new_val;
+}
+
+// Compare_and_swap with release semantics instead of acquire semantics.
+// On many architecture, the operation makes both guarantees, so the
+// implementation can be the same.
+inline static bool
+compare_and_swap_release(volatile obj_addr_t *addr,
+		  				     obj_addr_t old,
+						     obj_addr_t new_val)
+{
+  __asm__ __volatile__(".set\tpush\n\t"
+#if _MIPS_SIM == _ABIO32
+                       ".set\tmips2\n\t"
+#endif
+                       "sync\n\t"
+                       ".set\tpop" : : : "memory");
+  return compare_and_swap(addr, old, new_val);
+}
+
+// Ensure that subsequent instructions do not execute on stale
+// data that was loaded from memory before the barrier.
+// On X86, the hardware ensures that reads are properly ordered.
+inline static void
+read_barrier()
+{
+  __asm__ __volatile__(".set\tpush\n\t"
+#if _MIPS_SIM == _ABIO32
+                       ".set\tmips2\n\t"
+#endif
+                       "sync\n\t"
+                       ".set\tpop" : : : "memory");
+}
+
+// Ensure that prior stores to memory are completed with respect to other
+// processors.
+inline static void
+write_barrier()
+{
+  __asm__ __volatile__(".set\tpush\n\t"
+#if _MIPS_SIM == _ABIO32
+                       ".set\tmips2\n\t"
+#endif
+                       "sync\n\t"
+                       ".set\tpop" : : : "memory");
+}
+
+#endif   // __SYSDEP_LOCKS_H__

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