This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


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

ia64 eh, part 20d [libjava]


This is the libjava change.  Except for removing the option frobbing,
it follows from the libstdc++ changes relatively directly.


r~


	IA-64 ABI Exception Handling:
	* Makefile.am (GCC_UNWIND_INCLUDE): Rename from EH_COMMON_INCLUDE.
	(AM_CXXFLAGS): -fnon-call-exceptions not -fasynchronous-exceptions.
	Remove EXCEPTIONSPEC.
	* configure.host (libgcj_sjlj): Remove.
	* configure.in (EXCEPTIONSPEC): Remove.
	(enable-sjlj-exceptions): Detect if not specified.
	(GCC_UNWIND_INCLUDE): Rename from EH_COMMON_INCLUDE; change
	what header we're looking for.
	* libgcj.spec.in (jc1): Remove EXCEPTIONSPEC.
	* Makefile.in, configure: Regenerate.
	* exception.cc: Don't declare libgcc2 stuff.
	(java_eh_info, _Jv_type_matcher, _Jv_exception_info): Remove.
	(_Jv_eh_alloc, _Jv_eh_free, _Jv_setup_eh_info): Remove.
	(win32_get_restart_frame): Remove.
	(struct java_exception_header): New.
	(__gcj_exception_class): New.
	(get_exception_header_from_ue): New.
	(_Jv_Throw): Rewrite for IA-64 ABI unwind routines.
	(size_of_encoded_value, read_encoded_value): New.
	(read_uleb128, read_sleb128, parse_lsda_header): New.
	(get_ttype_entry, __gcj_personality_sj0): New.
	* gcj/javaprims.h (_Jv_Sjlj_Throw): Remove.

Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.135
diff -c -p -d -r1.135 Makefile.am
*** Makefile.am	2001/03/27 00:18:30	1.135
--- Makefile.am	2001/03/28 10:15:29
*************** LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mo
*** 87,104 ****
  
  JAVAC = $(GCJ_WITH_FLAGS) -C
  
! EH_COMMON_INCLUDE = @EH_COMMON_INCLUDE@
  
  WARNINGS = -W -Wall
  ## We need _GNU_SOURCE defined for some Linux builds.  It doesn't hurt
  ## to always define it.
! ## Note that we need -fasynchronous-exceptions because gcc is
! ## currently broken with respect to exception handling in leaf
! ## functions.
! AM_CXXFLAGS = -fno-rtti -fvtable-thunks -fasynchronous-exceptions \
  ## Some systems don't allow `$' in identifiers by default, so we force it.
  	-fdollars-in-identifiers \
! 	@LIBGCJ_CXXFLAGS@ @EXCEPTIONSPEC@ @X_CFLAGS@ $(WARNINGS) -D_GNU_SOURCE
  if USING_GCC
  AM_CFLAGS = @LIBGCJ_CFLAGS@ $(WARNINGS)
  else
--- 87,101 ----
  
  JAVAC = $(GCJ_WITH_FLAGS) -C
  
! GCC_UNWIND_INCLUDE = @GCC_UNWIND_INCLUDE@
  
  WARNINGS = -W -Wall
  ## We need _GNU_SOURCE defined for some Linux builds.  It doesn't hurt
  ## to always define it.
! AM_CXXFLAGS = -fno-rtti -fvtable-thunks -fnon-call-exceptions \
  ## Some systems don't allow `$' in identifiers by default, so we force it.
  	-fdollars-in-identifiers \
! 	@LIBGCJ_CXXFLAGS@ @X_CFLAGS@ $(WARNINGS) -D_GNU_SOURCE
  if USING_GCC
  AM_CFLAGS = @LIBGCJ_CFLAGS@ $(WARNINGS)
  else
*************** LIBFFIINCS = -I$(top_srcdir)/../libffi/i
*** 112,118 ****
  
  INCLUDES = -I$(top_srcdir) -Iinclude -I$(top_srcdir)/include \
  	$(GCINCS) $(THREADINCS) $(INCLTDL) \
! 	$(EH_COMMON_INCLUDE) $(ZINCS) $(LIBFFIINCS)
  
  
  ## ################################################################
--- 109,115 ----
  
  INCLUDES = -I$(top_srcdir) -Iinclude -I$(top_srcdir)/include \
  	$(GCINCS) $(THREADINCS) $(INCLTDL) \
! 	$(GCC_UNWIND_INCLUDE) $(ZINCS) $(LIBFFIINCS)
  
  
  ## ################################################################
Index: configure.host
===================================================================
RCS file: /cvs/gcc/gcc/libjava/configure.host,v
retrieving revision 1.15
diff -c -p -d -r1.15 configure.host
*** configure.host	2001/02/05 05:49:44	1.15
--- configure.host	2001/03/28 10:15:29
*************** libgcj_flags=
*** 23,29 ****
  libgcj_cflags=
  libgcj_cxxflags=
  libgcj_javaflags=
- libgcj_sjlj=
  libgcj_interpreter=
  
  case "${target_optspace}:${host}" in
--- 23,28 ----
*************** case "${host}" in
*** 67,83 ****
    alpha*-*)
  	libgcj_flags="${libgcj_flags} -mieee"
  	libgcj_interpreter=yes
- 	libgcj_sjlj=yes
  	;;
    sparc-*)
          ;;
    ia64-*)
          libgcj_flags="${libgcj_flags} -funwind-tables"
- 	libgcj_sjlj=yes
  	libgcj_interpreter=yes
- 	;;
-   *)
-         libgcj_sjlj=yes
  	;;
  esac
  
--- 66,77 ----
Index: configure.in
===================================================================
RCS file: /cvs/gcc/gcc/libjava/configure.in,v
retrieving revision 1.75
diff -c -p -d -r1.75 configure.in
*** configure.in	2001/03/21 18:43:03	1.75
--- configure.in	2001/03/28 10:15:29
*************** if test "$libgcj_interpreter" = yes; the
*** 88,106 ****
     AC_DEFINE(INTERPRETER)
  fi
  
! EXCEPTIONSPEC=
! dnl See if we should use setjmp/longjmp exceptions
  AC_ARG_ENABLE(sjlj-exceptions,
! [  --enable-sjlj-exceptions    use setjmp/longjmp exceptions],
!   if test "$enable_sjlj_exceptions" = yes; then
!      # This can be set in configure.host.
!      libgcj_sjlj=yes
!   fi)
! 
! if test "$libgcj_sjlj" = yes; then
!    EXCEPTIONSPEC="-fsjlj-exceptions"
!    AC_DEFINE(SJLJ_EXCEPTIONS)
  fi
  
  AC_MSG_CHECKING([for data_start])
  LIBDATASTARTSPEC=
--- 88,138 ----
     AC_DEFINE(INTERPRETER)
  fi
  
! AC_MSG_CHECKING([for exception model to use])
! AC_LANG_SAVE
! AC_LANG_CPLUSPLUS
  AC_ARG_ENABLE(sjlj-exceptions,
! [  --enable-sjlj-exceptions  force use of builtin_setjmp for exceptions],
! [:],
! [dnl Botheration.  Now we've got to detect the exception model.
! dnl Link tests against libgcc.a are problematic since -- at least
! dnl as of this writing -- we've not been given proper -L bits for
! dnl single-tree newlib and libgloss.
! dnl
! dnl This is what AC_TRY_COMPILE would do if it didn't delete the
! dnl conftest files before we got a change to grep them first.
! cat > conftest.$ac_ext << EOF
! [#]line __oline__ "configure"
! struct S { ~S(); };
! void bar();
! void foo()
! {
!   S s;
!   bar();
! }
! EOF
! old_CXXFLAGS="$CXXFLAGS"  
! CXXFLAGS=-S
! if AC_TRY_EVAL(ac_compile); then
!   if grep _Unwind_Sjlj_Resume conftest.s >/dev/null 2>&1 ; then
!     enable_sjlj_exceptions=yes
!   elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then
!     enable_sjlj_exceptions=no
!   fi
! fi
! CXXFLAGS="$old_CXXFLAGS"
! rm -f conftest*])
! if test x$enable_sjlj_exceptions = xyes; then
!   AC_DEFINE(SJLJ_EXCEPTIONS, 1,
! 	[Define if the compiler is configured for setjmp/longjmp exceptions.])
!   ac_exception_model_name=sjlj
! elif test x$enable_sjlj_exceptions = xno; then
!   ac_exception_model_name="call frame"
! else
!   AC_MSG_ERROR([unable to detect exception model])
  fi
+ AC_LANG_RESTORE
+ AC_MSG_RESULT($ac_exception_model_name)
  
  AC_MSG_CHECKING([for data_start])
  LIBDATASTARTSPEC=
*************** CANADIAN=no
*** 349,364 ****
  NULL_TARGET=no
  NATIVE=yes
  
! # Find eh-common.h and support headers.  If we're in the tree with
  # gcc, then look there.  Otherwise look in compat-include.  If all else
  # fails, just hope the user has set things up somehow.
! if test -r $srcdir/../gcc/eh-common.h; then
!    EH_COMMON_INCLUDE='-I$(top_srcdir)/../gcc -I$(top_srcdir)/../include'
  else
     if test -d $srcdir/../compat-include; then
!       EH_COMMON_INCLUDE='-I$(top_srcdir)/../compat-include'
     else
!       EH_COMMON_INCLUDE=
     fi
  fi
  
--- 381,397 ----
  NULL_TARGET=no
  NATIVE=yes
  
! # Find unwind.h and support headers.  If we're in the tree with
  # gcc, then look there.  Otherwise look in compat-include.  If all else
  # fails, just hope the user has set things up somehow.
! echo "probing $srcdir/../gcc/unwind.h"
! if test -r $srcdir/../gcc/unwind.h; then
!    GCC_UNWIND_INCLUDE='-I$(top_srcdir)/../gcc'
  else
     if test -d $srcdir/../compat-include; then
!       GCC_UNWIND_INCLUDE='-I$(top_srcdir)/../compat-include'
     else
!       GCC_UNWIND_INCLUDE=
     fi
  fi
  
*************** if test -n "${with_cross_host}"; then
*** 389,395 ****
     # directory.
     if test "$build" != "$with_cross_host"; then
        CANADIAN=yes
!       EH_COMMON_INCLUDE=
        GCJ="${target_alias}-gcj"
     else
        GCJ=
--- 422,428 ----
     # directory.
     if test "$build" != "$with_cross_host"; then
        CANADIAN=yes
!       GCC_UNWIND_INCLUDE=
        GCJ="${target_alias}-gcj"
     else
        GCJ=
*************** AC_SUBST(ZLIBS)
*** 623,636 ****
  AC_SUBST(ZDEPS)
  AC_SUBST(ZINCS)
  AC_SUBST(DIVIDESPEC)
- AC_SUBST(EXCEPTIONSPEC)
  
  AM_CONDITIONAL(CANADIAN, test "$CANADIAN" = yes)
  AM_CONDITIONAL(NULL_TARGET, test "$NULL_TARGET" = yes)
  AM_CONDITIONAL(NATIVE, test "$NATIVE" = yes || test "$NULL_TARGET" = yes)
  AM_CONDITIONAL(USE_LIBDIR, test -z "$with_cross_host")
  AM_CONDITIONAL(NEEDS_DATA_START, test "$NEEDS_DATA_START" = yes && test "$NATIVE" = yes)
! AC_SUBST(EH_COMMON_INCLUDE)
  
  # Determine gcj version number.
  changequote(<<,>>)
--- 656,668 ----
  AC_SUBST(ZDEPS)
  AC_SUBST(ZINCS)
  AC_SUBST(DIVIDESPEC)
  
  AM_CONDITIONAL(CANADIAN, test "$CANADIAN" = yes)
  AM_CONDITIONAL(NULL_TARGET, test "$NULL_TARGET" = yes)
  AM_CONDITIONAL(NATIVE, test "$NATIVE" = yes || test "$NULL_TARGET" = yes)
  AM_CONDITIONAL(USE_LIBDIR, test -z "$with_cross_host")
  AM_CONDITIONAL(NEEDS_DATA_START, test "$NEEDS_DATA_START" = yes && test "$NATIVE" = yes)
! AC_SUBST(GCC_UNWIND_INCLUDE)
  
  # Determine gcj version number.
  changequote(<<,>>)
Index: exception.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/exception.cc,v
retrieving revision 1.11
diff -c -p -d -r1.11 exception.cc
*** exception.cc	2001/03/26 07:05:31	1.11
--- exception.cc	2001/03/28 10:15:29
***************
*** 1,6 ****
  // Functions for Exception Support for Java.
  
! /* Copyright (C) 1998, 1999  Free Software Foundation
  
     This file is part of libgcj.
  
--- 1,6 ----
  // Functions for Exception Support for Java.
  
! /* Copyright (C) 1998, 1999, 2001  Free Software Foundation
  
     This file is part of libgcj.
  
*************** details.  */
*** 18,199 ****
  #include <gcj/cni.h>
  #include <jvm.h>
  
! // eh-common.h needs gansidecl.h.
! #include "gansidecl.h"
! #include "eh-common.h"
  
! typedef struct {
!   __eh_info eh_info;
    jthrowable value;
- } java_eh_info;
  
  
! /* Language-specific EH info pointer, throw routine, and language/version
!    info routines. All defined in libgcc2. */
  
- extern "C" java_eh_info **__get_eh_info (); 
- extern "C" void __throw () __attribute__ ((__noreturn__));
- extern "C" void __sjthrow () __attribute__ ((__noreturn__));
- extern "C" short __get_eh_table_version (void *table);
- extern "C" short __get_eh_table_language (void *table);
- extern "C" void *__get_eh_context ();
  
! extern "C" void *
! _Jv_type_matcher (java_eh_info *info, void* match_info, 
! 		  void *exception_table)
  {
! #ifndef SJLJ_EXCEPTIONS
!   /* No exception table implies the old style mechanism, so don't check. */
!   if (exception_table != NULL
!       && __get_eh_table_language (exception_table) != EH_LANG_Java)
!     return NULL;
  #endif
  
!   /* we don't worry about version info yet, there is only one version! */
!   
!   if (match_info != NULL)
!     {
!       // The match_info is either a (java::lang::Class*) or
!       // match_info is one more than a (Utf8Const*).
!       if (sizeof(void*) != sizeof(size_t))
! 	abort();
!       size_t mi = (size_t) match_info;
!       if ((mi & 1) != 0)
! 	match_info = _Jv_FindClass ((Utf8Const*) (mi - 1), NULL);
!       if (! _Jv_IsInstanceOf (info->value, (jclass) match_info))
! 	return NULL;
!     }
  
!   return info->value;
  }
  
! /* Compiler hook to return a pointer to java exception object. The value
!    is cleared, so if the exception needs to be rethrown, it should be set 
!    again */
  
! extern "C" void *
! _Jv_exception_info (void)
  {
!   java_eh_info *info = *(__get_eh_info ());
!   void *ptr;
  
!   if (info == NULL)
!     abort ();
  
!   ptr = info->value;
  
!   /* clear the value so another throw is an error */
!   info->value = NULL;
  
!   return ptr;
! }
  
  
  
! /* Allocate an exception info structure for java. Called the first time
!    an exception is thrown. */
  
! extern "C" void
! _Jv_eh_alloc ()
! {
!   /* FIXME: we should use _Jv_AllocBytes here.  However, libgcc2
!      apparently can sometimes free() this value itself.  */
!   java_eh_info *p = (java_eh_info *) malloc (sizeof (java_eh_info));
!   if (p == 0)
!     abort ();
  
!   p->value = 0;
!   java_eh_info ** info_ptr = __get_eh_info ();
  
!   /* There should NOT be an exception info pointer already. */
!   if (*info_ptr != NULL)
!     abort ();
  
!   *info_ptr = p;
  }
  
! /* Deallocate the current exception info structure. Called at shutdown time. */
  
! extern "C" void
! _Jv_eh_free ()
  {
!   java_eh_info ** info_ptr = __get_eh_info ();
!   if (*info_ptr == NULL)
!     abort ();
!   
!   /* FIXME: ideally we should just let the GC handle this.  */
!   free (*info_ptr);
!   *info_ptr = NULL;
  }
  
! /* Initialize an __eh_info structure with this libraries matching info. */
  
! extern "C" void
! _Jv_setup_eh_info (__eh_info *)
  {
  }
  
! /* Perform a throw, Java style. Throw will unwind through this call,
!    so there better not be any handlers or exception thrown here. */
  
  #ifdef SJLJ_EXCEPTIONS
! #define _Jv_Throw _Jv_Sjlj_Throw
  #endif
  
! extern "C" void
! _Jv_Throw (jthrowable value)
  {
!   if (value == NULL)
!     value = new java::lang::NullPointerException;
!   java_eh_info *ehinfo = *(__get_eh_info ());
!   if (ehinfo == NULL)
      {
!       _Jv_eh_alloc ();
!       ehinfo = *(__get_eh_info ());
      }
-   ehinfo->eh_info.match_function = (__eh_matcher) _Jv_type_matcher;
-   ehinfo->eh_info.language = EH_LANG_Java;
-   ehinfo->eh_info.version = 1;
-   ehinfo->value = value;
  
! /* We're happy with setjmp/longjmp exceptions or region-based
!    exception handlers: entry points are provided here for both.  */
  #ifdef SJLJ_EXCEPTIONS
!   __sjthrow ();
  #else
!   __throw ();
! #endif
! }
  
! #ifdef USE_WIN32_SIGNALLING
  
! // This is a mangled version of _Jv_Throw and __sjthrow except
! // rather than calling longjmp, it returns a pointer to the jmp buffer
  
! extern "C" int *
! win32_get_restart_frame (void *value)
! {
!   struct eh_context *eh = (struct eh_context *)__get_eh_context ();
!   void ***dhc = &eh->dynamic_handler_chain;
!  
!   java_eh_info *ehinfo = *(__get_eh_info ());
!   if (ehinfo == NULL)
      {
!       _Jv_eh_alloc ();
!       ehinfo = *(__get_eh_info ());
      }
!   ehinfo->eh_info.match_function = (__eh_matcher) _Jv_type_matcher;
!   ehinfo->eh_info.language = EH_LANG_Java;
!   ehinfo->eh_info.version = 1;
!   ehinfo->value = value;
  
!   // FIXME: Run clean ups?
  
!   int *jmpbuf = (int*)&(*dhc)[2];
  
!   *dhc = (void**)(*dhc)[0];
  
!   return  jmpbuf;
! }
  
! #endif /* USE_WIN32_SIGNALLING */
--- 18,563 ----
  #include <gcj/cni.h>
  #include <jvm.h>
  
! #include "unwind.h"
  
! 
! // More nastiness: the GC wants to define TRUE and FALSE.  We don't
! // need the Java definitions (themselves a hack), so we undefine them.
! #undef TRUE
! #undef FALSE
! 
! extern "C"
! {
! #include <gc_priv.h>
! #include <gc_mark.h>
! #include <include/gc_gcj.h>
! };
! 
! 
! struct alignment_test_struct
! {
!   char space;
!   char end[0] __attribute__((aligned));
! };
! 
! struct java_exception_header
! {
!   /* Cache handler details between Phase 1 and Phase 2.  */
!   _Unwind_Ptr landingPad;
!   int handlerSwitchValue;
! 
!   /* The object being thrown.  Compiled code expects this to be immediately
!      before the generic exception header.  Which is complicated by the fact
!      that _Unwind_Exception is ((aligned)).  */
! 
!   char pad[sizeof(jthrowable) < sizeof(alignment_test_struct)
! 	   ? sizeof(alignment_test_struct) - sizeof(jthrowable) : 0]
!     __attribute__((aligned));
! 
    jthrowable value;
  
+   /* The generic exception header.  */
+   _Unwind_Exception unwindHeader;
+ };
  
! // This is the exception class we report -- "GNUCJAVA".
! const _Unwind_Exception_Class __gcj_exception_class
! = ((((((((_Unwind_Exception_Class) 'G' 
!          << 8 | (_Unwind_Exception_Class) 'N')
!         << 8 | (_Unwind_Exception_Class) 'U')
!        << 8 | (_Unwind_Exception_Class) 'C')
!       << 8 | (_Unwind_Exception_Class) 'J')
!      << 8 | (_Unwind_Exception_Class) 'A')
!     << 8 | (_Unwind_Exception_Class) 'V')
!    << 8 | (_Unwind_Exception_Class) 'A');
  
  
! static inline java_exception_header *
! get_exception_header_from_ue (_Unwind_Exception *exc)
  {
!   return reinterpret_cast<java_exception_header *>(exc + 1) - 1;
! }
! 
! /* Perform a throw, Java style. Throw will unwind through this call,
!    so there better not be any handlers or exception thrown here. */
! 
! extern "C" void
! _Jv_Throw (jthrowable value)
! {
!   /* FIXME: Use the proper API to the collector.  */
!   java_exception_header *xh
!     = static_cast<java_exception_header *>(GC_malloc (sizeof (*xh)));
! 
!   if (value == NULL)
!     value = new java::lang::NullPointerException ();
!   xh->value = value;
! 
!   xh->unwindHeader.exception_class = __gcj_exception_class;
!   xh->unwindHeader.exception_cleanup = NULL;
! 
!   /* We're happy with setjmp/longjmp exceptions or region-based
!      exception handlers: entry points are provided here for both.  */
!   _Unwind_Reason_Code code;
! #ifdef SJLJ_EXCEPTIONS
!   code = _Unwind_SjLj_RaiseException (&xh->unwindHeader);
! #else
!   code = _Unwind_RaiseException (&xh->unwindHeader);
  #endif
  
!   /* FIXME: If code == _URC_END_OF_STACK, then we reached top of
!      stack without finding a handler for the exception.  I seem to
!      recall that Java has specific rules to handle this. 
  
!      If code is something else, we encountered some sort of heinous
!      lossage, from which we could not recover.  As is the way of such
!      things we'll almost certainly have crashed before now, rather
!      than actually being able to diagnose the problem.  */
!   abort ();
  }
  
! 
! // ??? These ought to go somewhere else dwarf2 or dwarf2eh related.
  
! // Pointer encodings.
! #define DW_EH_PE_absptr         0x00
! #define DW_EH_PE_omit           0xff
! 
! #define DW_EH_PE_uleb128        0x01
! #define DW_EH_PE_udata2         0x02
! #define DW_EH_PE_udata4         0x03
! #define DW_EH_PE_udata8         0x04
! #define DW_EH_PE_sleb128        0x09
! #define DW_EH_PE_sdata2         0x0A
! #define DW_EH_PE_sdata4         0x0B
! #define DW_EH_PE_sdata8         0x0C
! #define DW_EH_PE_signed         0x08
! 
! #define DW_EH_PE_pcrel          0x10
! #define DW_EH_PE_textrel        0x20
! #define DW_EH_PE_datarel        0x30
! #define DW_EH_PE_funcrel        0x40
! 
! static unsigned int
! size_of_encoded_value (unsigned char encoding)
  {
!   switch (encoding & 0x07)
!     {
!     case DW_EH_PE_absptr:
!       return sizeof (void *);
!     case DW_EH_PE_udata2:
!       return 2;
!     case DW_EH_PE_udata4:
!       return 4;
!     case DW_EH_PE_udata8:
!       return 8;
!     }
!   abort ();
! }
  
! static const unsigned char *
! read_encoded_value (_Unwind_Context *context, unsigned char encoding,
! 		    const unsigned char *p, _Unwind_Ptr *val)
! {
!   union unaligned
!     {
!       void *ptr;
!       unsigned u2 __attribute__ ((mode (HI)));
!       unsigned u4 __attribute__ ((mode (SI)));
!       unsigned u8 __attribute__ ((mode (DI)));
!       signed s2 __attribute__ ((mode (HI)));
!       signed s4 __attribute__ ((mode (SI)));
!       signed s8 __attribute__ ((mode (DI)));
!     } __attribute__((__packed__));
  
!   union unaligned *u = (union unaligned *) p;
!   _Unwind_Ptr result;
  
!   switch (encoding & 0x0f)
!     {
!     case DW_EH_PE_absptr:
!       result = (_Unwind_Ptr) u->ptr;
!       p += sizeof (void *);
!       break;
  
!     case DW_EH_PE_uleb128:
!       {
! 	unsigned int shift = 0;
! 	unsigned char byte;
  
+ 	result = 0;
+ 	do
+ 	  {
+ 	    byte = *p++;
+ 	    result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
+ 	    shift += 7;
+ 	  }
+ 	while (byte & 0x80);
+       }
+       break;
  
+     case DW_EH_PE_sleb128:
+       {
+ 	unsigned int shift = 0;
+ 	unsigned char byte;
  
! 	result = 0;
! 	do
! 	  {
! 	    byte = *p++;
! 	    result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
! 	    shift += 7;
! 	  }
! 	while (byte & 0x80);
  
! 	if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
! 	  result |= -(1L << shift);
!       }
!       break;
  
!     case DW_EH_PE_udata2:
!       result = u->u2;
!       p += 2;
!       break;
!     case DW_EH_PE_udata4:
!       result = u->u4;
!       p += 4;
!       break;
!     case DW_EH_PE_udata8:
!       result = u->u8;
!       p += 8;
!       break;
  
!     case DW_EH_PE_sdata2:
!       result = u->s2;
!       p += 2;
!       break;
!     case DW_EH_PE_sdata4:
!       result = u->s4;
!       p += 4;
!       break;
!     case DW_EH_PE_sdata8:
!       result = u->s8;
!       p += 8;
!       break;
  
!     default:
!       abort ();
!     }
! 
!   if (result != 0)
!     switch (encoding & 0xf0)
!       {
!       case DW_EH_PE_absptr:
! 	break;
! 
!       case DW_EH_PE_pcrel:
! 	// Define as relative to the beginning of the pointer.
! 	result += (_Unwind_Ptr) u;
! 	break;
! 
!       case DW_EH_PE_textrel:
!       case DW_EH_PE_datarel:
! 	// FIXME.
! 	abort ();
! 
!       case DW_EH_PE_funcrel:
! 	result += _Unwind_GetRegionStart (context);
! 	break;
! 
!       default:
! 	abort ();
!       }
! 
!   *val = result;
!   return p;
  }
  
! static inline const unsigned char *
! read_uleb128 (const unsigned char *p, _Unwind_Ptr *val)
! {
!   return read_encoded_value (0, DW_EH_PE_uleb128, p, val);
! }
  
! static inline const unsigned char *
! read_sleb128 (const unsigned char *p, _Unwind_Ptr *val)
  {
!   return read_encoded_value (0, DW_EH_PE_sleb128, p, val);
  }
  
! 
! struct lsda_header_info
! {
!   _Unwind_Ptr Start;
!   _Unwind_Ptr LPStart;
!   const unsigned char *TType;
!   const unsigned char *action_table;
!   unsigned char ttype_encoding;
!   unsigned char call_site_encoding;
! };
  
! static const unsigned char *
! parse_lsda_header (_Unwind_Context *context, const unsigned char *p,
! 		   lsda_header_info *info)
  {
+   _Unwind_Ptr tmp;
+   unsigned char lpstart_encoding;
+ 
+   info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
+ 
+   // Find @LPStart, the base to which landing pad offsets are relative.
+   lpstart_encoding = *p++;
+   if (lpstart_encoding != DW_EH_PE_omit)
+     p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
+   else
+     info->LPStart = info->Start;
+ 
+   // Find @TType, the base of the handler and exception spec type data.
+   info->ttype_encoding = *p++;
+   if (info->ttype_encoding != DW_EH_PE_omit)
+     {
+       p = read_uleb128 (p, &tmp);
+       info->TType = p + tmp;
+     }
+   else
+     info->TType = 0;
+ 
+   // The encoding and length of the call-site table; the action table
+   // immediately follows.
+   info->call_site_encoding = *p++;
+   p = read_uleb128 (p, &tmp);
+   info->action_table = p + tmp;
+ 
+   return p;
  }
  
! static jclass
! get_ttype_entry (_Unwind_Context *context, lsda_header_info *info, long i)
! {
!   _Unwind_Ptr ptr;
  
+   i *= size_of_encoded_value (info->ttype_encoding);
+   read_encoded_value (context, info->ttype_encoding, info->TType - i, &ptr);
+ 
+   return reinterpret_cast<jclass>(ptr);
+ }
+ 
+ 
+ // Using a different personality function name causes link failures
+ // when trying to mix code using different exception handling models.
  #ifdef SJLJ_EXCEPTIONS
! #define PERSONALITY_FUNCTION	__gcj_personality_sj0
! #define __builtin_eh_return_data_regno(x) x
! #else
! #define PERSONALITY_FUNCTION	__gcj_personality_v0
  #endif
  
! extern "C" _Unwind_Reason_Code
! PERSONALITY_FUNCTION (int version,
! 		      _Unwind_Action actions,
! 		      _Unwind_Exception_Class exception_class,
! 		      struct _Unwind_Exception *ue_header,
! 		      struct _Unwind_Context *context)
  {
!   java_exception_header *xh = get_exception_header_from_ue (ue_header);
! 
!   lsda_header_info info;
!   const unsigned char *language_specific_data;
!   const unsigned char *action_record;
!   const unsigned char *p;
!   _Unwind_Ptr landing_pad, ip;
!   int handler_switch_value;
!   bool saw_cleanup;
!   bool saw_handler;
! 
! 
!   // Interface version check.
!   if (version != 1)
!     return _URC_FATAL_PHASE1_ERROR;
! 
!   // Shortcut for phase 2 found handler for domestic exception.
!   if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME)
!       && exception_class == __gcj_exception_class)
      {
!       handler_switch_value = xh->handlerSwitchValue;
!       landing_pad = xh->landingPad;
!       goto install_context;
      }
  
!   // FIXME: In Phase 1, record _Unwind_GetIP in xh->obj as a part of
!   // the stack trace for this exception.  This will only collect Java
!   // frames, but perhaps that is acceptable.
!   // FIXME2: _Unwind_GetIP is nonsensical for SJLJ, being a call-site
!   // index instead of a PC value.  We could perhaps arrange for
!   // _Unwind_GetRegionStart to return context->fc->jbuf[1], which
!   // is the address of the handler label for __builtin_longjmp, but
!   // there is no solution for DONT_USE_BUILTIN_SETJMP.
! 
!   language_specific_data = (const unsigned char *)
!     _Unwind_GetLanguageSpecificData (context);
! 
!   // If no LSDA, then there are no handlers or cleanups.
!   if (! language_specific_data)
!     return _URC_CONTINUE_UNWIND;
! 
!   // Parse the LSDA header.
!   p = parse_lsda_header (context, language_specific_data, &info);
!   ip = _Unwind_GetIP (context) - 1;
!   landing_pad = 0;
!   action_record = 0;
!   handler_switch_value = 0;
! 
  #ifdef SJLJ_EXCEPTIONS
!   // The given "IP" is an index into the call-site table, with two
!   // exceptions -- -1 means no-action, and 0 means terminate.  But
!   // since we're using uleb128 values, we've not got random access
!   // to the array.
!   if ((int) ip <= 0)
!     return _URC_CONTINUE_UNWIND;
!   else
!     {
!       _Unwind_Ptr cs_lp, cs_action;
!       do
! 	{
! 	  p = read_uleb128 (p, &cs_lp);
! 	  p = read_uleb128 (p, &cs_action);
! 	}
!       while (--ip);
! 
!       // Can never have null landing pad for sjlj -- that would have
!       // been indicated by a -1 call site index.
!       landing_pad = cs_lp + 1;
!       if (cs_action)
! 	action_record = info.action_table + cs_action - 1;
!       goto found_something;
!     }
  #else
!   // Search the call-site table for the action associated with this IP.
!   while (p < info.action_table)
!     {
!       _Unwind_Ptr cs_start, cs_len, cs_lp, cs_action;
  
!       // Note that all call-site encodings are "absolute" displacements.
!       p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
!       p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
!       p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
!       p = read_uleb128 (p, &cs_action);
  
!       // The table is sorted, so if we've passed the ip, stop.
!       if (ip < info.Start + cs_start)
! 	p = info.action_table;
!       else if (ip < info.Start + cs_start + cs_len)
! 	{
! 	  if (cs_lp)
! 	    landing_pad = info.LPStart + cs_lp;
! 	  if (cs_action)
! 	    action_record = info.action_table + cs_action - 1;
! 	  goto found_something;
! 	}
!     }
! #endif // SJLJ_EXCEPTIONS
  
!   // If ip is not present in the table, C++ would call terminate.
!   // ??? It is perhaps better to tweek the LSDA so that no-action
!   // is mapped to no-entry for Java.
!   return _URC_CONTINUE_UNWIND;
! 
!  found_something:
!   saw_cleanup = false;
!   saw_handler = false;
! 
!   if (landing_pad == 0)
      {
!       // If ip is present, and has a null landing pad, there are
!       // no cleanups or handlers to be run.
      }
!   else if (action_record == 0)
!     {
!       // If ip is present, has a non-null landing pad, and a null
!       // action table offset, then there are only cleanups present.
!       // Cleanups use a zero switch value, as set above.
!       saw_cleanup = true;
!     }
!   else
!     {
!       // Otherwise we have a catch handler.
!       signed long ar_filter, ar_disp;
  
!       while (1)
! 	{
! 	  _Unwind_Ptr tmp;
  
! 	  p = action_record;
! 	  p = read_sleb128 (p, &tmp); ar_filter = tmp;
! 	  read_sleb128 (p, &tmp); ar_disp = tmp;
  
! 	  if (ar_filter == 0)
! 	    {
! 	      // Zero filter values are cleanups.
! 	      saw_cleanup = true;
! 	    }
  
! 	  // During forced unwinding, we only run cleanups.  With a
! 	  // foreign exception class, we have no class info to match.
! 	  else if ((actions & _UA_FORCE_UNWIND)
! 	      || exception_class != __gcj_exception_class)
! 	    ;
  
! 	  else if (ar_filter > 0)
! 	    {
! 	      // Positive filter values are handlers.
! 
! 	      jclass catch_type = get_ttype_entry (context, &info, ar_filter);
! 
! 	      // The catch_type is either a (java::lang::Class*) or
! 	      // is one more than a (Utf8Const*).
! 	      if ((size_t)catch_type & 1)
! 		catch_type = _Jv_FindClass ((Utf8Const*)catch_type - 1, NULL);
! 
! 	      if (_Jv_IsInstanceOf (xh->value, catch_type))
! 		{
! 		  handler_switch_value = ar_filter;
! 		  saw_handler = true;
! 		  break;
! 		}
! 	    }
! 	  else
! 	    {
! 	      // Negative filter values are exception specifications,
! 	      // which Java does not use.
! 	      // ??? Perhaps better to make them an index into a table
! 	      // of null-terminated strings instead of playing games
! 	      // with Utf8Const+1 as above.
! 	      abort ();
! 	    }
! 
! 	  if (ar_disp == 0)
! 	    break;
! 	  action_record = p + ar_disp;
! 	}
!     }
! 
!   if (! saw_handler && ! saw_cleanup)
!     return _URC_CONTINUE_UNWIND;
! 
!   if (actions & _UA_SEARCH_PHASE)
!     {
!       if (! saw_handler)
! 	return _URC_CONTINUE_UNWIND;
! 
!       // For domestic exceptions, we cache data from phase 1 for phase 2.
!       if (exception_class == __gcj_exception_class)
!         {
!           xh->handlerSwitchValue = handler_switch_value;
!           xh->landingPad = landing_pad;
! 	}
!       return _URC_HANDLER_FOUND;
!     }
! 
!  install_context:
!   _Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
! 		 (_Unwind_Ptr) &xh->unwindHeader);
!   _Unwind_SetGR (context, __builtin_eh_return_data_regno (1),
! 		 handler_switch_value);
!   _Unwind_SetIP (context, landing_pad);
!   return _URC_INSTALL_CONTEXT;
! }
Index: libgcj.spec.in
===================================================================
RCS file: /cvs/gcc/gcc/libjava/libgcj.spec.in,v
retrieving revision 1.14
diff -c -p -d -r1.14 libgcj.spec.in
*** libgcj.spec.in	2001/02/27 09:41:21	1.14
--- libgcj.spec.in	2001/03/28 10:15:29
***************
*** 6,12 ****
  %rename lib liborig
  *lib: -lgcj -lm @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(libgcc) %(liborig)
  
! *jc1:  @DIVIDESPEC@ @EXCEPTIONSPEC@ @JC1GCSPEC@ -fasynchronous-exceptions
  
  #
  # On some systems we force in a data_start symbol so that the GC will work
--- 6,12 ----
  %rename lib liborig
  *lib: -lgcj -lm @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(libgcc) %(liborig)
  
! *jc1:  @DIVIDESPEC@ @JC1GCSPEC@
  
  #
  # On some systems we force in a data_start symbol so that the GC will work
Index: gcj/javaprims.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gcj/javaprims.h,v
retrieving revision 1.16
diff -c -p -d -r1.16 javaprims.h
*** javaprims.h	2001/03/26 07:05:31	1.16
--- javaprims.h	2001/03/28 10:15:29
*************** extern "C" jsize _Jv_GetStringUTFLength 
*** 369,375 ****
  extern "C" jsize _Jv_GetStringUTFRegion (jstring, jsize, jsize, char *);
  
  extern "C" void _Jv_Throw (jthrowable) __attribute__ ((__noreturn__));
- extern "C" void _Jv_Sjlj_Throw (jthrowable) __attribute__ ((__noreturn__));
  extern "C" void* _Jv_Malloc (jsize) __attribute__((__malloc__));
  extern "C" void* _Jv_Realloc (void *, jsize);
  extern "C" void _Jv_Free (void*);
--- 369,374 ----


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