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]

[BC ABI] gcj-abi-2-dev-branch created


2004-04-16  Andrew Haley  <aph@redhat.com>

	* java/lang/natClassLoader.cc (_Jv_WaitForState): Call
	_Jv_LayoutClass.
	(_Jv_PrepareCompiledClass): Cast address to uaddr for comparison.
	(_Jv_PrepareCompiledClass): If we throw an exception during
	preparation, restore state.
	(ClassLoader::getClassLoader0): New method.

	* java/lang/natClass.cc (get_alignment_from_class): Moved here
	from resolve.cc.
	(ALIGNOF): Use offsetof, not __alignof__.
	(_Jv_ResolveClassRef): Resolve a reference to a class in a
	constant pool.
	(getInterfaces): Emit debug output if interface hasn't been
	resolved.
	(initializeClass): Call _Jv_LayoutClass.
	(_Jv_LinkSymbolTable): Add debugging output.
	(_Jv_LinkSymbolTable): NoClassDefFoundError if target_class isn't
	found.
	(_Jv_LinkSymbolTable): Call _Jv_PrepareClass.
	(_Jv_LinkSymbolTable): Pass the real class loader to
	_Jv_FindClass.
	(_Jv_linkExceptionClassTable): Don't throw if we fail to find an
	exception class.
	(_Jv_LinkSymbolTable): Assert if we find a static field reference
	to an interpreted class.
	(_Jv_LayoutVTableMethods): Use klass->getSuperclass to get the
	superclass.
	(_Jv_LayoutClass): Moved here; it was part of _Jv_PrepareClass in
	resolve.cc.

	* java/lang/VMSecurityManager.java: Check for the system class
	loader as well as loader != null.
	
	* java/lang/SecurityManager.java (checkPermission): Remove
	security check.
	(checkRead): Likewise.
	(checkConnect): Likewise.

	* java/lang/ClassLoader.java (loadClass): Include all class
	loaders in stack trace string.
	Look for class in "gcjlib.so" in the same directory.
	(getSystemClassLoader) Use getClassLoader0.
	(getClassLoader0): New native method.

	* java/lang/Class.h (getSuperclass): New method.
	(getInterface): New method.
	(size): Lay out class if needed.
	(firstMethodIndex): New method.
	(Jv_ResolveClassRef): New declaration.
	(_Jv_LinkSymbolTable): New declaration.

	* java/io/ObjectOutputStream.java: Add DEBUG statements
	everywhere.
	(dumpElementln): New method.
	(depth): New field.
	* java/io/ObjectInputStream.java (MyIOException): new, for
	debugging.
	Everywhere: use MyIOException rather than IOException.
	Indent debugging output to make nesting visible.
	(currentClassLoader): Make native
	(callersClassLoader): New field.
	(depth): New field.
	* java/io/natObjectInputStream.cc (getCallersClassLoader): New
	method.

	(readObject): ENDBLOCKDATA is generated if the class has a write
	method, not if it has a read method.

	* include/jvm.h (_Jv_CallAnyMethodA): Add new arg, iface.

	* gnu/javax/rmi/CORBA/DelegateFactory.java: Use the
	getContextClassLoader form the current thread after our own class
	loader.
 
	* gnu/gcj/runtime/SharedLibHelper.java (findClass): Class loader
	debugging.
	(toString): New method.

	* verify.cc (class _Jv_BytecodeVerifier): Don't directly access
	interfaces array.

	* resolve.cc (_Jv_PrepareMissingMethods): If interface looks like
	a constant pool entry, resolve it now.
	(_Jv_PrepareClass): Break out part of this function to Jv_LayoutClass
	in natClass.cc.
	Move  get_alignment_from_class to natClass.cc.
	
	* prims.cc (_Jv_AllocObjectNoFinalizer): Use size field from class.
	(_Jv_AllocObjectNoInitNoFinalizer): Likewise.

	* defineclass.cc (checkExtends): Don't access superclass field
	directly.

	* Makefile.in: regenerate.

	* gnu/gcj/util/natDebug.cc: New
	* gnu/gcj/util/Debug.java: New.

	* Makefile.am (java/io/ObjectInputStream.lo): Use
	-fno-optimize-sibling-calls.

	* java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Use
	_Jv_LookupInterfaceMethodIdx to calculate the address of a method
	in an interface.
	* include/jvm.h (_Jv_CallAnyMethodA): Add new arg: iface.

Index: libjava/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.368
diff -p -2 -c -w -r1.368 Makefile.am
*** libjava/Makefile.am	20 Mar 2004 20:30:55 -0000	1.368
--- libjava/Makefile.am	16 Apr 2004 12:29:55 -0000
*************** gnu/gcj/runtime/StackTrace.lo: gnu/gcj/r
*** 494,497 ****
--- 494,500 ----
  	$(GCJCOMPILE) -fno-optimize-sibling-calls -o $@ $<
  
+ java/io/ObjectInputStream.lo: java/io/ObjectInputStream.java
+ 	$(GCJCOMPILE) -fno-optimize-sibling-calls -o $@ $<
+ 
  ## Pass the list of object files to libtool in a temporary file to 
  ## avoid tripping platform command line length limits.
*************** gnu/gcj/runtime/StackTrace.java \
*** 2196,2199 ****
--- 2199,2203 ----
  gnu/gcj/runtime/StringBuffer.java \
  gnu/gcj/runtime/VMClassLoader.java \
+ gnu/gcj/util/Debug.java \
  gnu/java/io/ASN1ParsingException.java \
  gnu/java/io/Base64InputStream.java \
*************** gnu/gcj/runtime/natStackTrace.cc \
*** 2866,2869 ****
--- 2870,2874 ----
  gnu/gcj/runtime/natStringBuffer.cc \
  gnu/gcj/runtime/natVMClassLoader.cc \
+ gnu/gcj/util/natDebug.cc \
  gnu/java/awt/natEmbeddedWindow.cc \
  gnu/java/net/natPlainDatagramSocketImpl.cc \
Index: libjava/defineclass.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/defineclass.cc,v
retrieving revision 1.35
diff -p -2 -c -w -r1.35 defineclass.cc
*** libjava/defineclass.cc	24 Oct 2003 09:29:41 -0000	1.35
--- libjava/defineclass.cc	16 Apr 2004 12:29:57 -0000
*************** _Jv_ClassReader::checkExtends (jclass su
*** 968,972 ****
      } 
  
!   for (; super != 0; super = super->superclass)
      {
        if (super == sub)
--- 968,972 ----
      } 
  
!   for (; super != 0; super = super->getSuperclass ())
      {
        if (super == sub)
Index: libjava/interpret.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/interpret.cc,v
retrieving revision 1.40
diff -p -2 -c -w -r1.40 interpret.cc
*** libjava/interpret.cc	14 Oct 2003 17:53:41 -0000	1.40
--- libjava/interpret.cc	16 Apr 2004 12:29:57 -0000
*************** details.  */
*** 38,42 ****
  #include <java/lang/Thread.h>
  #include <java-insns.h>
! #include <java-signal.h>
  
  #ifdef INTERPRETER
--- 38,42 ----
  #include <java/lang/Thread.h>
  #include <java-insns.h>
! 
  
  #ifdef INTERPRETER
Index: libjava/prims.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/prims.cc,v
retrieving revision 1.87
diff -p -2 -c -w -r1.87 prims.cc
*** libjava/prims.cc	14 Jan 2004 22:49:58 -0000	1.87
--- libjava/prims.cc	16 Apr 2004 12:29:58 -0000
*************** jobject
*** 400,403 ****
--- 400,405 ----
  _Jv_AllocObjectNoInitNoFinalizer (jclass klass, jint size)
  {
+   if (size == 0)
+     size = klass->size ();
    jobject obj = (jobject) _Jv_AllocObj (size, klass);
    jvmpi_notify_alloc (klass, size, obj);
*************** _Jv_AllocObjectNoFinalizer (jclass klass
*** 410,413 ****
--- 412,417 ----
  {
    _Jv_InitClass (klass);
+   if (size == 0)
+     size = klass->size ();
    jobject obj = (jobject) _Jv_AllocObj (size, klass);
    jvmpi_notify_alloc (klass, size, obj);
*************** _Jv_RunMain (jclass klass, const char *n
*** 1018,1021 ****
--- 1022,1026 ----
  
    int status = (int) java::lang::ThreadGroup::had_uncaught_exception;
+   java::lang::Runtime::securityManager = NULL;
    runtime->exit (status);
  }
Index: libjava/resolve.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/resolve.cc,v
retrieving revision 1.44
diff -p -2 -c -w -r1.44 resolve.cc
*** libjava/resolve.cc	1 Apr 2004 17:07:03 -0000	1.44
--- libjava/resolve.cc	16 Apr 2004 12:29:58 -0000
*************** static void throw_class_format_error (ch
*** 58,63 ****
  	__attribute__ ((__noreturn__));
  
- static int get_alignment_from_class (jclass);
- 
  static _Jv_ResolvedMethod* 
  _Jv_BuildResolvedMethod (_Jv_Method*,
--- 58,61 ----
*************** _Jv_PrepareMissingMethods (jclass base2,
*** 373,379 ****
    for (int i = 0; i < iface_class->interface_count; ++i)
      {
!       for (int j = 0; j < iface_class->interfaces[i]->method_count; ++j)
  	{
! 	  _Jv_Method *meth = &iface_class->interfaces[i]->methods[j];
  	  // Don't bother with <clinit>.
  	  if (meth->name->data[0] == '<')
--- 371,399 ----
    for (int i = 0; i < iface_class->interface_count; ++i)
      {
!       jclass interface = iface_class->interfaces[i];
!       
!       typedef unsigned int uaddr __attribute__ ((mode (pointer)));
! 
!       // If interface looks like a constant pool entry,
!       // resolve it now.
!       if (interface && (uaddr)interface < (uaddr)iface_class->constants.size)
! 	{
! 	  if (iface_class->state < JV_STATE_LINKED) // This can't ever happen
! 	    {
! 	      _Jv_Utf8Const *name = iface_class->constants.data[(int)interface].utf8;
! 	      interface = _Jv_FindClass (name, iface_class->loader);
! 	      if (! interface)
! 		{
! 		  jstring str = _Jv_NewStringUTF (name->data);
! 		  throw new java::lang::NoClassDefFoundError (str);
! 		}
! 	    }
! 	  else
! 	    interface = iface_class->constants.data[(int)interface].clazz;
! 	}
! 
!       for (int j = 0; j < interface->method_count; ++j)
  	{
! 	  _Jv_Method *meth = &interface->methods[j];
  	  // Don't bother with <clinit>.
  	  if (meth->name->data[0] == '<')
*************** _Jv_PrepareMissingMethods (jclass base2,
*** 413,417 ****
  	}
  
!       _Jv_PrepareMissingMethods (base, iface_class->interfaces[i]);
      }
  }
--- 433,437 ----
  	}
  
!       _Jv_PrepareMissingMethods (base, interface);
      }
  }
*************** _Jv_PrepareClass(jclass klass)
*** 450,543 ****
    // will unlock it properly, should an exception happen.  If there's
    // no superclass, do nothing -- Object will already have been
!   // resolved.
  
    if (klass->superclass)
!     java::lang::VMClassLoader::resolveClass (klass->superclass);
! 
!   _Jv_InterpClass *clz = (_Jv_InterpClass*)klass;
  
    /************ PART ONE: OBJECT LAYOUT ***************/
- 
-   // Compute the alignment for this type by searching through the
-   // superclasses and finding the maximum required alignment.  We
-   // could consider caching this in the Class.
-   int max_align = __alignof__ (java::lang::Object);
-   jclass super = clz->superclass;
-   while (super != NULL)
-     {
-       int num = JvNumInstanceFields (super);
-       _Jv_Field *field = JvGetFirstInstanceField (super);
-       while (num > 0)
- 	{
- 	  int field_align = get_alignment_from_class (field->type);
- 	  if (field_align > max_align)
- 	    max_align = field_align;
- 	  ++field;
- 	  --num;
- 	}
-       super = super->superclass;
-     }
- 
-   int instance_size;
    int static_size = 0;
  
!   // Although java.lang.Object is never interpreted, an interface can
!   // have a null superclass.  Note that we have to lay out an
!   // interface because it might have static fields.
!   if (clz->superclass)
!     instance_size = clz->superclass->size();
!   else
!     instance_size = java::lang::Object::class$.size();
! 
!   for (int i = 0; i < clz->field_count; i++)
!     {
!       int field_size;
!       int field_align;
! 
!       _Jv_Field *field = &clz->fields[i];
! 
!       if (! field->isRef ())
! 	{
! 	  // it's safe to resolve the field here, since it's 
! 	  // a primitive class, which does not cause loading to happen.
! 	  _Jv_ResolveField (field, clz->loader);
! 
! 	  field_size = field->type->size ();
! 	  field_align = get_alignment_from_class (field->type);
! 	}
!       else 
! 	{
! 	  field_size = sizeof (jobject);
! 	  field_align = __alignof__ (jobject);
! 	}
! 
! #ifndef COMPACT_FIELDS
!       field->bsize = field_size;
! #endif
! 
!       if (field->flags & Modifier::STATIC)
! 	{
! 	  /* this computes an offset into a region we'll allocate 
! 	     shortly, and then add this offset to the start address */
! 
! 	  static_size        = ROUND (static_size, field_align);
! 	  field->u.boffset   = static_size;
! 	  static_size       += field_size;
! 	}
!       else
! 	{
! 	  instance_size      = ROUND (instance_size, field_align);
! 	  field->u.boffset   = instance_size;
! 	  instance_size     += field_size;
! 	  if (field_align > max_align)
! 	    max_align = field_align;
! 	}
!     }
! 
!   // Set the instance size for the class.  Note that first we round it
!   // to the alignment required for this object; this keeps us in sync
!   // with our current ABI.
!   instance_size = ROUND (instance_size, max_align);
!   clz->size_in_bytes = instance_size;
  
    // allocate static memory
--- 470,483 ----
    // will unlock it properly, should an exception happen.  If there's
    // no superclass, do nothing -- Object will already have been
!   // resolved
  
    if (klass->superclass)
!     java::lang::VMClassLoader::resolveClass (klass->getSuperclass());
  
    /************ PART ONE: OBJECT LAYOUT ***************/
    int static_size = 0;
+   _Jv_LayoutClass(klass, &static_size);
  
!   _Jv_InterpClass *clz = (_Jv_InterpClass*)klass;
  
    // allocate static memory
*************** _Jv_InitField (jobject obj, jclass klass
*** 740,779 ****
      }
  }
- 
- template<typename T>
- struct aligner
- {
-   T field;
- };
- 
- #define ALIGNOF(TYPE) (__alignof__ (((aligner<TYPE> *) 0)->field))
- 
- // This returns the alignment of a type as it would appear in a
- // structure.  This can be different from the alignment of the type
- // itself.  For instance on x86 double is 8-aligned but struct{double}
- // is 4-aligned.
- static int
- get_alignment_from_class (jclass klass)
- {
-   if (klass == JvPrimClass (byte))
-     return ALIGNOF (jbyte);
-   else if (klass == JvPrimClass (short))
-     return ALIGNOF (jshort);
-   else if (klass == JvPrimClass (int)) 
-     return ALIGNOF (jint);
-   else if (klass == JvPrimClass (long))
-     return ALIGNOF (jlong);
-   else if (klass == JvPrimClass (boolean))
-     return ALIGNOF (jboolean);
-   else if (klass == JvPrimClass (char))
-     return ALIGNOF (jchar);
-   else if (klass == JvPrimClass (float))
-     return ALIGNOF (jfloat);
-   else if (klass == JvPrimClass (double))
-     return ALIGNOF (jdouble);
-   else
-     return ALIGNOF (jobject);
- }
- 
  
  inline static unsigned char*
--- 680,683 ----
Index: libjava/verify.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/verify.cc,v
retrieving revision 1.62
diff -p -2 -c -w -r1.62 verify.cc
*** libjava/verify.cc	19 Mar 2004 17:38:23 -0000	1.62
--- libjava/verify.cc	16 Apr 2004 12:29:59 -0000
*************** private:
*** 560,564 ****
  		// We use a recursive call because we also need to
  		// check superinterfaces.
! 		if (is_assignable_from_slow (target, source->interfaces[i]))
  		  return true;
  	      }
--- 560,564 ----
  		// We use a recursive call because we also need to
  		// check superinterfaces.
! 		if (is_assignable_from_slow (target, source->getInterface (i)))
  		  return true;
  	      }
Index: libjava/gnu/gcj/runtime/SharedLibHelper.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/runtime/SharedLibHelper.java,v
retrieving revision 1.1
diff -p -2 -c -w -r1.1 SharedLibHelper.java
*** libjava/gnu/gcj/runtime/SharedLibHelper.java	28 Aug 2003 22:17:36 -0000	1.1
--- libjava/gnu/gcj/runtime/SharedLibHelper.java	16 Apr 2004 12:29:59 -0000
*************** import gnu.gcj.Core;
*** 17,20 ****
--- 17,23 ----
  public class SharedLibHelper
  {
+     private final java.util.HashMap h = 
+ 	new java.util.HashMap();
+ 
    /** Load a shared library, and associate a ClassLoader with it.
     * @param libname named of shared library (passed to dlopen)
*************** public class SharedLibHelper
*** 74,78 ****
    {
      ensureInit();
!     return (Class) classMap.get(name);
    }
  
--- 77,93 ----
    {
        ensureInit();
!       Class c = (Class)classMap.get(name);
!       if (c != null)
! 	  {
! 	      String s = System.getProperty("gnu.classpath.verbose");
! 	      if (s != null && s.equals("class"))
! 		  if (h.get(name) == null)
! 		      {
! 			  System.err.println("[Loading class " + name 
! 					     + " from " + this + "]");
! 			  h.put(name,name);
! 		      }		
! 	  }
!       return c;
    }
  
*************** public class SharedLibHelper
*** 107,110 ****
--- 122,130 ----
    native boolean hasResource(String name);
    native void init();
+ 
+   public String toString ()
+   {
+ 	return "shared object " + baseName;
+   }
  
    /** Called during dlopen's processing of the init section. */
Index: libjava/gnu/javax/rmi/CORBA/DelegateFactory.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/javax/rmi/CORBA/DelegateFactory.java,v
retrieving revision 1.2
diff -p -2 -c -w -r1.2 DelegateFactory.java
*** libjava/gnu/javax/rmi/CORBA/DelegateFactory.java	16 Mar 2004 09:41:31 -0000	1.2
--- libjava/gnu/javax/rmi/CORBA/DelegateFactory.java	16 Apr 2004 12:29:59 -0000
*************** public class DelegateFactory
*** 61,67 ****
      try
        {
! 	Class dclass = Class.forName(dcname, 
! 				     true,
! 				     Thread.currentThread().getContextClassLoader());
  	r = dclass.newInstance();
  	cache.put(type, r);
--- 61,77 ----
      try
        {
! 		Class dclass;
! 		try
! 	      {
! 			dclass = Class.forName(dcname);
! 	      }
! 		catch (ClassNotFoundException c)
! 	      {
! 			ClassLoader loader = Thread.currentThread().getContextClassLoader();
! 			if (loader != null)
! 		      dclass = Class.forName(dcname, true, loader);
! 			else
! 		      throw c;
! 	      }
  		r = dclass.newInstance();
  		cache.put(type, r);
Index: libjava/include/jvm.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/jvm.h,v
retrieving revision 1.63
diff -p -2 -c -w -r1.63 jvm.h
*** libjava/include/jvm.h	1 Feb 2004 20:05:03 -0000	1.63
--- libjava/include/jvm.h	16 Apr 2004 12:29:59 -0000
*************** extern jobject _Jv_CallAnyMethodA (jobje
*** 423,427 ****
  				   jmethodID meth, jboolean is_constructor,
  				   JArray<jclass> *parameter_types,
! 				   jobjectArray args);
  
  union jvalue;
--- 423,428 ----
  				   jmethodID meth, jboolean is_constructor,
  				   JArray<jclass> *parameter_types,
! 				   jobjectArray args,
! 				   jclass iface = NULL);
  
  union jvalue;
*************** extern void _Jv_CallAnyMethodA (jobject 
*** 434,438 ****
  				jvalue *args,
  				jvalue *result,
! 				jboolean is_jni_call = true);
  
  extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims)
--- 435,440 ----
  				jvalue *args,
  				jvalue *result,
! 				jboolean is_jni_call = true,
! 				jclass iface = NULL);
  
  extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims)
Index: libjava/java/io/ObjectInputStream.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/io/ObjectInputStream.java,v
retrieving revision 1.30
diff -p -2 -c -w -r1.30 ObjectInputStream.java
*** libjava/java/io/ObjectInputStream.java	28 Feb 2004 21:48:35 -0000	1.30
--- libjava/java/io/ObjectInputStream.java	16 Apr 2004 12:30:00 -0000
*************** import java.lang.reflect.InvocationTarge
*** 57,60 ****
--- 57,74 ----
  import gnu.classpath.Configuration;
  
+ class MyIOException extends IOException
+ {
+     MyIOException (String s)
+     {
+ 	super(s);
+ 	if (Configuration.DEBUG)
+ 	    {
+ 		String val = System.getProperty("gcj.dumpobjects");
+ 		if (val != null && !val.equals(""))
+ 		    System.out.println (this);
+ 	    }
+     }
+ }
+ 
  public class ObjectInputStream extends InputStream
    implements ObjectInput, ObjectStreamConstants
*************** public class ObjectInputStream extends I
*** 125,128 ****
--- 139,151 ----
    public final Object readObject() throws ClassNotFoundException, IOException
    {
+       if (callersClassLoader == null)
+ 	{
+ 	  callersClassLoader = getCallersClassLoader ();
+ 	  if (Configuration.DEBUG)
+ 	    {
+ 	      dumpElementln ("CallersClassLoader = " + callersClassLoader);
+ 	    }
+ 	}
+ 
      if (this.useSubclassMethod)
        return readObjectOverride();
*************** public class ObjectInputStream extends I
*** 139,142 ****
--- 162,168 ----
  
      byte marker = this.realInputStream.readByte();
+ 
+     depth += 2;
+ 
      if(dump) dumpElement("MARKER: 0x" + Integer.toHexString(marker) + " ");
  
*************** public class ObjectInputStream extends I
*** 156,162 ****
  	    {
  	      if (marker == TC_BLOCKDATALONG)
! 		if(dump) dumpElementln("BLOCKDATALONG");
  	      else
! 		if(dump) dumpElementln("BLOCKDATA");
  	      readNextBlock(marker);
  	      throw new StreamCorruptedException("Unexpected blockData");
--- 182,188 ----
  	    {
  	      if (marker == TC_BLOCKDATALONG)
! 		{ if(dump) dumpElementln("BLOCKDATALONG"); }
  	      else
! 		{ if(dump) dumpElementln("BLOCKDATA"); }
  	      readNextBlock(marker);
  	      throw new StreamCorruptedException("Unexpected blockData");
*************** public class ObjectInputStream extends I
*** 212,216 ****
  		  byte b = this.realInputStream.readByte();
  		  if (b != TC_ENDBLOCKDATA)
! 		    throw new IOException("Data annotated to class was not consumed." + b);
  		}
  	      else
--- 238,242 ----
  		  byte b = this.realInputStream.readByte();
  		  if (b != TC_ENDBLOCKDATA)
! 		    throw new MyIOException("Data annotated to class was not consumed." + b);
  		}
  	      else
*************** public class ObjectInputStream extends I
*** 230,234 ****
  		  byte b = this.realInputStream.readByte();
  		  if (b != TC_ENDBLOCKDATA)
! 		    throw new IOException("Data annotated to class was not consumed." + b);
  		}
  	      else
--- 256,260 ----
  		  byte b = this.realInputStream.readByte();
  		  if (b != TC_ENDBLOCKDATA)
! 		    throw new MyIOException("Data annotated to class was not consumed." + b);
  		}
  	      else
*************** public class ObjectInputStream extends I
*** 324,327 ****
--- 350,356 ----
  	      
  	      int handle = assignNewHandle(obj);
+ 	      Object prevObject = this.currentObject;
+ 	      ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
+ 	      
  	      this.currentObject = obj;
  	      ObjectStreamClass[] hierarchy =
*************** public class ObjectInputStream extends I
*** 346,363 ****
  		      callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);
  		      setBlockDataMode(oldmode);
  		      if(dump) dumpElement("ENDBLOCKDATA? ");
  		      try
  			{
! 			  // FIXME: XXX: This try block is to catch EOF which is
! 			  // thrown for some objects.  That indicates a bug in the logic.
  			  if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
! 			    throw new IOException
  			      ("No end of block data seen for class with readObject (ObjectInputStream) method.");
  			  if(dump) dumpElementln("yes");
  			}
! 		      catch (EOFException e)
! 			{
! 			  if(dump) dumpElementln("no, got EOFException");
! 			}
  		      catch (IOException e)
  			{
--- 375,403 ----
  		      callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);
  		      setBlockDataMode(oldmode);
+ 		    }
+ 		  else
+ 		    {
+ 		      readFields(obj, currentObjectStreamClass);
+ 		    }
+ 
+ 		  if (this.currentObjectStreamClass.hasWriteMethod())
+ 		    {
  		      if(dump) dumpElement("ENDBLOCKDATA? ");
  		      try
  			{
! 			  // FIXME: XXX: This try block is to
! 			  // catch EOF which is thrown for some
! 			  // objects.  That indicates a bug in
! 			  // the logic.
! 
  			  if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
! 			    throw new MyIOException
  			      ("No end of block data seen for class with readObject (ObjectInputStream) method.");
  			  if(dump) dumpElementln("yes");
  			}
! // 		      catch (EOFException e)
! // 			{
! // 			  if(dump) dumpElementln("no, got EOFException");
! // 			}
  		      catch (IOException e)
  			{
*************** public class ObjectInputStream extends I
*** 365,377 ****
  			}
  		    }
- 		  else
- 		    {
- 		      readFields(obj, currentObjectStreamClass);
- 		    }
  		}
  
! 	      this.currentObject = null;
! 	      this.currentObjectStreamClass = null;
  	      ret_val = processResolution(osc, obj, handle);
  	      break;
  	    }
--- 405,414 ----
  			}
  		    }
  		}
  
! 	      this.currentObject = prevObject;
! 	      this.currentObjectStreamClass = prevObjectStreamClass;
  	      ret_val = processResolution(osc, obj, handle);
+ 		  
  	      break;
  	    }
*************** public class ObjectInputStream extends I
*** 393,397 ****
  
  	  default:
! 	    throw new IOException("Unknown marker on stream: " + marker);
  	  }
        }
--- 430,434 ----
  
  	  default:
! 	    throw new MyIOException("Unknown marker on stream: " + marker);
  	  }
        }
*************** public class ObjectInputStream extends I
*** 402,405 ****
--- 439,444 ----
  	this.isDeserializing = was_deserializing;
  
+ 	depth -= 2;
+ 	
  	if (! was_deserializing)
  	  {
*************** public class ObjectInputStream extends I
*** 715,719 ****
      throws ClassNotFoundException, IOException
    {
!     return Class.forName(osc.getName(), true, currentLoader());
    }
  
--- 754,758 ----
      throws ClassNotFoundException, IOException
    {
!     return Class.forName(osc.getName(), true, callersClassLoader);
    }
  
*************** public class ObjectInputStream extends I
*** 1807,1815 ****
     * @return The current class loader in the calling stack.
     */
!   private static ClassLoader currentClassLoader (SecurityManager sm)
!   {
!     // FIXME: This is too simple.
!     return ClassLoader.getSystemClassLoader ();
!   }
  
    private void callReadMethod (Method readObject, Class klass, Object obj) throws IOException
--- 1846,1852 ----
     * @return The current class loader in the calling stack.
     */
!     private static native ClassLoader currentClassLoader (SecurityManager sm);
! 
!     private native ClassLoader getCallersClassLoader();
  
    private void callReadMethod (Method readObject, Class klass, Object obj) throws IOException
*************** public class ObjectInputStream extends I
*** 1869,1872 ****
--- 1906,1913 ----
    private static boolean dump = false && Configuration.DEBUG;
  
+   private ClassLoader callersClassLoader;
+ 
+   private int depth = 0;
+ 
    private void dumpElement (String msg)
    {	
*************** public class ObjectInputStream extends I
*** 1877,1880 ****
--- 1918,1924 ----
    {
      System.out.println(msg);
+     for (int i = 0; i < depth; i++)
+       System.out.print (" ");
+     System.out.print (Thread.currentThread() + ": ");
    }
  
Index: libjava/java/io/ObjectOutputStream.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/io/ObjectOutputStream.java,v
retrieving revision 1.24
diff -p -2 -c -w -r1.24 ObjectOutputStream.java
*** libjava/java/io/ObjectOutputStream.java	31 Dec 2003 11:04:21 -0000	1.24
--- libjava/java/io/ObjectOutputStream.java	16 Apr 2004 12:30:00 -0000
*************** public class ObjectOutputStream extends 
*** 173,180 ****
--- 173,196 ----
      if (useSubclassMethod)
        {
+ 	if (Configuration.DEBUG)
+ 	  {
+ 	    String val = System.getProperty("gcj.dumpobjects");
+ 	    if (val != null && !val.equals(""))
+ 	      dumpElementln ("WRITE OVERRIDE: " + obj);
+ 	  }
+ 	  
  	writeObjectOverride(obj);
  	return;
        }
  
+     if (Configuration.DEBUG)
+       {
+ 	String val = System.getProperty("gcj.dumpobjects");
+ 	if (val != null && !val.equals(""))
+ 	  dumpElementln ("WRITE: " + obj);
+       }
+     
+     depth += 2;    
+ 
      boolean was_serializing = isSerializing;
      boolean old_mode = setBlockDataMode(false);
*************** public class ObjectOutputStream extends 
*** 319,322 ****
--- 335,340 ----
  	    if (obj instanceof Serializable)
  	      {
+ 		Object prevObject = this.currentObject;
+ 		ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
  		currentObject = obj;
  		ObjectStreamClass[] hierarchy =
*************** public class ObjectOutputStream extends 
*** 330,344 ****
  		    if (currentObjectStreamClass.hasWriteMethod())
  		      {
  			setBlockDataMode(true);
  			callWriteMethod(obj, currentObjectStreamClass);
  			setBlockDataMode(false);
  			realOutput.writeByte(TC_ENDBLOCKDATA);
  		      }
  		    else
  		      writeFields(obj, currentObjectStreamClass);
  		  }
  
! 		currentObject = null;
! 		currentObjectStreamClass = null;
  		currentPutField = null;
  		break;
--- 348,367 ----
  		    if (currentObjectStreamClass.hasWriteMethod())
  		      {
+ 			dumpElementln ("WRITE METHOD CALLED FOR: " + obj);
  			setBlockDataMode(true);
  			callWriteMethod(obj, currentObjectStreamClass);
  			setBlockDataMode(false);
  			realOutput.writeByte(TC_ENDBLOCKDATA);
+ 			dumpElementln ("WRITE ENDBLOCKDATA FOR: " + obj);
  		      }
  		    else
+ 		      {
+ 			dumpElementln ("WRITE FIELDS CALLED FOR: " + obj);
  			writeFields(obj, currentObjectStreamClass);
  		      }
+ 		  }
  
! 		this.currentObject = prevObject;
! 		this.currentObjectStreamClass = prevObjectStreamClass;
  		currentPutField = null;
  		break;
*************** public class ObjectOutputStream extends 
*** 361,370 ****
  	try
  	  {
  	    writeObject(e);
  	  }
  	catch (IOException ioe)
  	  {
! 	    throw new StreamCorruptedException
! 	      ("Exception " + ioe + " thrown while exception was being written to stream.");
  	  }
  
--- 384,403 ----
  	try
  	  {
+ 	    if (Configuration.DEBUG)
+ 	      {
+ 		e.printStackTrace(System.out);
+ 	      }
  	    writeObject(e);
  	  }
  	catch (IOException ioe)
  	  {
! 	    StreamCorruptedException ex = 
! 	      new StreamCorruptedException
! 	      (ioe + " thrown while exception was being written to stream.");
! 	    if (Configuration.DEBUG)
! 	      {
! 		ex.printStackTrace(System.out);
! 	      }
! 	    throw ex;
  	  }
  
*************** public class ObjectOutputStream extends 
*** 376,379 ****
--- 409,421 ----
  	isSerializing = was_serializing;
  	setBlockDataMode(old_mode);
+ 	depth -= 2;
+ 
+ 	if (Configuration.DEBUG)
+ 	  {
+ 	    String val = System.getProperty("gcj.dumpobjects");
+ 	    if (val != null && !val.equals(""))
+ 	      dumpElementln ("END: " + obj);
+ 	  }
+     
        }
    }
*************** public class ObjectOutputStream extends 
*** 1172,1175 ****
--- 1214,1225 ----
  	type = fields[i].getType();
  
+ 	if (Configuration.DEBUG)
+ 	  {
+ 	    String val = System.getProperty("gcj.dumpobjects");
+ 	    if (val != null && !val.equals(""))
+ 	      dumpElementln ("WRITE FIELD: " + field_name + " type=" + type);
+ 	  }
+ 
+ 
  	if (type == Boolean.TYPE)
  	  realOutput.writeBoolean(getBooleanField(obj, osc.forClass(), field_name));
*************** public class ObjectOutputStream extends 
*** 1513,1516 ****
--- 1563,1574 ----
    }
  
+    private void dumpElementln (String msg)
+   {
+     for (int i = 0; i < depth; i++)
+       System.out.print (" ");
+     System.out.print (Thread.currentThread() + ": ");
+     System.out.println(msg);
+   }
+ 
    // this value comes from 1.2 spec, but is used in 1.1 as well
    private final static int BUFFER_SIZE = 1024;
*************** public class ObjectOutputStream extends 
*** 1534,1537 ****
--- 1592,1597 ----
    private int protocolVersion;
    private boolean useSubclassMethod;
+ 
+   private int depth = 0;
  
    static
Index: libjava/java/io/natObjectInputStream.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/io/natObjectInputStream.cc,v
retrieving revision 1.6
diff -p -2 -c -w -r1.6 natObjectInputStream.cc
*** libjava/java/io/natObjectInputStream.cc	28 Feb 2003 11:38:56 -0000	1.6
--- libjava/java/io/natObjectInputStream.cc	16 Apr 2004 12:30:00 -0000
*************** details.  */
*** 20,23 ****
--- 20,25 ----
  #include <java/lang/reflect/Modifier.h>
  #include <java/lang/reflect/Method.h>
+ #include <java/lang/ArrayIndexOutOfBoundsException.h>
+ #include <java/lang/SecurityManager.h>
  
  #ifdef DEBUG
*************** java::io::ObjectInputStream::callConstru
*** 70,71 ****
--- 72,103 ----
    _Jv_CallAnyMethodA (obj, JvPrimClass (void), meth, false, arg_types, NULL);
  }
+ 
+ java::lang::ClassLoader* 
+ java::io::ObjectInputStream::getCallersClassLoader ()
+ {
+   java::lang::ClassLoader *loader = NULL;
+   gnu::gcj::runtime::StackTrace *t 
+     = new gnu::gcj::runtime::StackTrace(4);
+   java::lang::Class *klass = NULL;
+   try
+     {
+       for (int i = 2; !klass; i++)
+ 	{
+ 	  klass = t->classAt (i);
+ 	}
+       loader = klass->getClassLoaderInternal();
+     }
+   catch (::java::lang::ArrayIndexOutOfBoundsException *e)
+     {
+       // FIXME: RuntimeError
+     }
+ 
+   return loader;
+ }
+ 
+ java::lang::ClassLoader*
+ java::io::ObjectInputStream::currentClassLoader (::java::lang::SecurityManager *sm)
+ {
+   return sm->currentClassLoader ();
+ }
+ 
Index: libjava/java/lang/Class.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/Class.h,v
retrieving revision 1.63
diff -p -2 -c -w -r1.63 Class.h
*** libjava/java/lang/Class.h	3 Dec 2003 21:26:59 -0000	1.63
--- libjava/java/lang/Class.h	16 Apr 2004 12:30:00 -0000
*************** details.  */
*** 15,18 ****
--- 15,19 ----
  #pragma interface
  
+ #include <cstddef>
  #include <java/lang/Object.h>
  #include <java/lang/String.h>
*************** public:
*** 209,215 ****
--- 210,227 ----
    inline jclass getSuperclass (void)
      {
+       if (state < JV_STATE_LINKED)
+ 	superclass =_Jv_ResolveClassRef (this, superclass);
+       
        return superclass;
      }
  
+   inline jclass getInterface (jint n)
+     {
+       if (state < JV_STATE_LINKED)
+ 	interfaces[n] =_Jv_ResolveClassRef (this, interfaces[n]);
+       
+       return interfaces[n];
+     }
+ 
    inline jboolean isArray (void)
      {
*************** public:
*** 244,250 ****
--- 256,276 ----
    jint size (void)
      {
+       // FIXME size_in_bytes == -1 is an evil way to test for BC compiled programs
+       if (size_in_bytes == (jint)-1)
+ 	{
+ 	  int static_size;
+ 	  _Jv_LayoutClass(this, &static_size);
+ 	}
+ 
        return size_in_bytes;
      }
  
+   // The index of the first method we declare ourself (as opposed to
+   // inheriting).
+   inline jint firstMethodIndex (void)
+   {
+     return vtable_method_count - method_count;
+   }
+     
    // finalization
    void finalize ();
*************** private:   
*** 272,275 ****
--- 298,303 ----
  					     int method_idx);
  
+   friend jclass _Jv_ResolveClassRef (jclass, jclass);
+ 
    inline friend void 
    _Jv_InitClass (jclass klass)
*************** private:   
*** 280,283 ****
--- 308,313 ----
    }
    
+   friend void _Jv_LayoutClass(jclass, int*);
+ 
    friend _Jv_Method* _Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *, 
  					       _Jv_Utf8Const*);
*************** private:   
*** 339,343 ****
    friend jshort _Jv_AppendPartialITable (jclass, jclass, void **, jshort);
    friend jshort _Jv_FindIIndex (jclass *, jshort *, jshort);
!   friend void _Jv_LinkSymbolTable (jclass);
    friend void _Jv_LayoutVTableMethods (jclass klass);
    friend void _Jv_SetVTableEntries (jclass, _Jv_VTable *, jboolean *);
--- 369,373 ----
    friend jshort _Jv_AppendPartialITable (jclass, jclass, void **, jshort);
    friend jshort _Jv_FindIIndex (jclass *, jshort *, jshort);
!   friend void _Jv_LinkSymbolTable (jclass, const char* foo=NULL);
    friend void _Jv_LayoutVTableMethods (jclass klass);
    friend void _Jv_SetVTableEntries (jclass, _Jv_VTable *, jboolean *);
Index: libjava/java/lang/ClassLoader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/ClassLoader.java,v
retrieving revision 1.31
diff -p -2 -c -w -r1.31 ClassLoader.java
*** libjava/java/lang/ClassLoader.java	9 Oct 2003 16:24:55 -0000	1.31
--- libjava/java/lang/ClassLoader.java	16 Apr 2004 12:30:01 -0000
*************** package java.lang;
*** 40,43 ****
--- 40,44 ----
  
  import java.io.InputStream;
+ import java.io.File;
  import java.io.IOException;
  import java.lang.reflect.Constructor;
*************** import java.util.Map;
*** 52,55 ****
--- 53,57 ----
  import gnu.java.util.DoubleEnumeration;
  import gnu.java.util.EmptyEnumeration;
+ import gnu.gcj.runtime.SharedLibHelper;
  
  /**
*************** public abstract class ClassLoader
*** 289,292 ****
--- 291,296 ----
        return c;
  
+     ClassNotFoundException ex = null;
+ 
      // Can the class be loaded by a parent?
      try
*************** public abstract class ClassLoader
*** 305,311 ****
--- 309,326 ----
      catch (ClassNotFoundException e)
        {
+ 	ex = e;
        }
      // Still not found, we have to do it ourself.
+     try
+       {
  	c = findClass(name);
+       }
+     catch (ClassNotFoundException cause)
+       {
+ 	if (ex != null)
+ 	  throw new ClassNotFoundException(ex.toString(), cause);
+ 	else
+ 	  throw cause;
+       }
      if (resolve)
        resolveClass(c);
*************** public abstract class ClassLoader
*** 436,441 ****
--- 451,504 ----
      if (! initialized)
        throw new SecurityException("attempt to define class from uninitialized class loader");
+ 
      Class retval = VMClassLoader.defineClass(this, name, data,
  					     offset, len, domain);
+ 
+     // FIXME: This is a temporary hack that allows you to compile some
+     // class files into a .so called "gcjlib.so" in the same
+     // directory.  To be removed as soon as gcj-JIT is ready.
+     java.security.CodeSource source = domain.getCodeSource();
+     java.net.URL url = source != null ? source.getLocation() : null;
+     String filename = url.getFile();
+     if (filename != null)
+       {
+ 	File f = new File(filename);
+ 	if (f.isDirectory())
+ 	  {
+ 	    try
+ 	      {
+ 		Class c = null;
+ 		String libname = filename + "gcjlib.so";
+ 		File soFile = new File (libname);
+ 		if (soFile.isFile())
+ 		  {
+ 		    SharedLibHelper helper 
+ 		      = SharedLibHelper.findHelper (this, libname, source);
+ 		    c = helper.findClass (retval.getName());
+ 		  }
+ 		if (c != null)
+ 		  retval = c;
+ 	      }
+ 	    catch (UnknownError _)
+ 	      {
+ 	      }
+ 	  }
+       }
+     
+     {	    
+       String s = System.getProperty("gnu.classpath.verbose");
+       if (s != null && s.equals("class"))
+ 	{
+ // 		java.security.CodeSource source = domain.getCodeSource();
+ // 		java.net.URL url = source != null ? source.getLocation() : null;
+ 	  String URLname = url != null ? url.toString() : null;
+ 	  if (URLname == null)
+ 	    URLname = "unknown location";
+ 	  System.err.println("[Loading class " + retval.getName()
+ 			     + " from  " + URLname + "]");
+ 	}
+ 		
+     }
+ 
      loadedClasses.put(retval.getName(), retval);
      return retval;
*************** public abstract class ClassLoader
*** 729,733 ****
        {
  	Class c = VMSecurityManager.getClassContext()[1];
! 	ClassLoader cl = c.getClassLoader();
  	if (cl != null && cl != systemClassLoader)
  	  sm.checkPermission(new RuntimePermission("getClassLoader"));
--- 792,796 ----
        {
  	Class c = VMSecurityManager.getClassContext()[1];
! 	ClassLoader cl = getClassLoader0(c);
  	if (cl != null && cl != systemClassLoader)
  	  sm.checkPermission(new RuntimePermission("getClassLoader"));
*************** public abstract class ClassLoader
*** 950,952 ****
--- 1013,1017 ----
      return false;
    }
+ 
+     static private final native ClassLoader getClassLoader0(Class c);
  }
Index: libjava/java/lang/SecurityManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/SecurityManager.java,v
retrieving revision 1.10
diff -p -2 -c -w -r1.10 SecurityManager.java
*** libjava/java/lang/SecurityManager.java	1 Apr 2004 19:15:05 -0000	1.10
--- libjava/java/lang/SecurityManager.java	16 Apr 2004 12:30:01 -0000
*************** public class SecurityManager
*** 319,323 ****
    {
      // XXX Should be: AccessController.checkPermission(perm);
!     throw new SecurityException("Operation not allowed");
    }
  
--- 319,323 ----
    {
      // XXX Should be: AccessController.checkPermission(perm);
!     //.throw new SecurityException("Operation not allowed");
    }
  
*************** public class SecurityManager
*** 547,551 ****
      // AccessControlContext ac = (AccessControlContext) context;
      // ac.checkPermission(new FilePermission(filename, "read"));
!     throw new SecurityException("Cannot read files via file names.");
    }
  
--- 547,551 ----
      // AccessControlContext ac = (AccessControlContext) context;
      // ac.checkPermission(new FilePermission(filename, "read"));
!     // throw new SecurityException("Cannot read files via file names.");
    }
  
*************** public class SecurityManager
*** 669,673 ****
      //   ac.checkPermission(new SocketPermission(host.toString + ":" +port,
      //                                           "connect"));
!     throw new SecurityException("Cannot make network connections.");
    }
  
--- 669,673 ----
      //   ac.checkPermission(new SocketPermission(host.toString + ":" +port,
      //                                           "connect"));
!     // throw new SecurityException("Cannot make network connections.");
    }
  
Index: libjava/java/lang/Thread.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/Thread.java,v
retrieving revision 1.32
diff -p -2 -c -w -r1.32 Thread.java
*** libjava/java/lang/Thread.java	9 Mar 2004 21:02:52 -0000	1.32
--- libjava/java/lang/Thread.java	16 Apr 2004 12:30:01 -0000
*************** public class Thread implements Runnable
*** 903,908 ****
    public String toString()
    {
!     return ("Thread[" + name + "," + priority + ","
! 	    + (group == null ? "" : group.getName()) + "]");
    }
  
--- 903,908 ----
    public String toString()
    {
!     return ("Thread[" + name + ","
! 	    + (group == null ? "" : group.getName()) + "] (PID " + getpid() + ")");
    }
  
*************** public class Thread implements Runnable
*** 910,912 ****
--- 910,914 ----
  
    private final native static String gen_name();
+ 
+   private final native static long getpid ();
  }
Index: libjava/java/lang/VMSecurityManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/VMSecurityManager.java,v
retrieving revision 1.2
diff -p -2 -c -w -r1.2 VMSecurityManager.java
*** libjava/java/lang/VMSecurityManager.java	5 Dec 2002 00:49:29 -0000	1.2
--- libjava/java/lang/VMSecurityManager.java	16 Apr 2004 12:30:01 -0000
*************** class VMSecurityManager
*** 55,63 ****
      // FIXME this implementation is a bit wrong too -- the docs say we
      // must also consider ancestors of the system class loader.
      Class[] classStack = getClassContext ();
      for (int i = 0; i < classStack.length; i++)
        {
  	ClassLoader loader = classStack[i].getClassLoader();
! 	if (loader != null)
  	  return loader;
        }
--- 55,64 ----
      // FIXME this implementation is a bit wrong too -- the docs say we
      // must also consider ancestors of the system class loader.
+     ClassLoader systemClassLoader = VMClassLoader.getSystemClassLoader();
      Class[] classStack = getClassContext ();
      for (int i = 0; i < classStack.length; i++)
        {
  	ClassLoader loader = classStack[i].getClassLoader();
! 	if (loader != null && loader != systemClassLoader)
  	  return loader;
        }
Index: libjava/java/lang/natClass.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClass.cc,v
retrieving revision 1.75
diff -p -2 -c -w -r1.75 natClass.cc
*** libjava/java/lang/natClass.cc	23 Mar 2004 19:24:07 -0000	1.75
--- libjava/java/lang/natClass.cc	16 Apr 2004 12:30:02 -0000
*************** details.  */
*** 15,18 ****
--- 15,19 ----
  #include <string.h>
  #include <stddef.h>
+ #include <stdio.h>
  
  #pragma implementation "Class.h"
*************** details.  */
*** 60,67 ****
--- 61,133 ----
  #include <java-cpool.h>
  #include <java-interp.h>
+ #include <java-assert.h>
  
  
  using namespace gcj;
  
+ template<typename T>
+ struct aligner
+ {
+   char c;
+   T field;
+ };
+ 
+ #define ALIGNOF(TYPE) (offsetof (aligner<TYPE>, field))
+ 
+ // This returns the alignment of a type as it would appear in a
+ // structure.  This can be different from the alignment of the type
+ // itself.  For instance on x86 double is 8-aligned but struct{double}
+ // is 4-aligned.
+ static int
+ get_alignment_from_class (jclass klass)
+ {
+   if (klass == JvPrimClass (byte))
+     return ALIGNOF (jbyte);
+   else if (klass == JvPrimClass (short))
+     return ALIGNOF (jshort);
+   else if (klass == JvPrimClass (int)) 
+     return ALIGNOF (jint);
+   else if (klass == JvPrimClass (long))
+     return ALIGNOF (jlong);
+   else if (klass == JvPrimClass (boolean))
+     return ALIGNOF (jboolean);
+   else if (klass == JvPrimClass (char))
+     return ALIGNOF (jchar);
+   else if (klass == JvPrimClass (float))
+     return ALIGNOF (jfloat);
+   else if (klass == JvPrimClass (double))
+     return ALIGNOF (jdouble);
+   else
+     return ALIGNOF (jobject);
+ }
+ 
+ jclass
+ _Jv_ResolveClassRef (jclass klass, jclass classref)
+ {
+   jclass ret = classref;
+ 
+   typedef unsigned int uaddr __attribute__ ((mode (pointer)));
+ 
+   // If superclass looks like a constant pool entry,
+   // resolve it now.
+   if (classref && (uaddr)classref < (uaddr)klass->constants.size)
+     {
+       if (klass->state < JV_STATE_LINKED)
+ 	{
+ 	  _Jv_Utf8Const *name = klass->constants.data[(uaddr)classref].utf8;
+ 	  ret = _Jv_FindClass (name, klass->loader);
+ 	  if (! ret)
+ 	    {
+ 	      jstring str = _Jv_NewStringUTF (name->data);
+ 	      throw new java::lang::NoClassDefFoundError (str);
+ 	    }
+ 	}
+       else
+ 	ret = klass->constants.data[(uaddr)classref].clazz;
+     }
+ 
+   return ret;
+ }
+ 
  jclass
  java::lang::Class::forName (jstring className, jboolean initialize,
*************** java::lang::Class::getInterfaces (void)
*** 486,490 ****
--- 552,561 ----
    jobject *data = elements (r);
    for (int i = 0; i < interface_count; ++i)
+     {
+       typedef unsigned int uaddr __attribute__ ((mode (pointer)));
        data[i] = interfaces[i];
+       if ((uaddr)data[i] < (uaddr)constants.size)
+ 	fprintf (stderr, "ERROR !!!\n");
+     }
    return reinterpret_cast<JArray<jclass> *> (r);
  }
*************** java::lang::Class::_getMethod (jstring n
*** 496,499 ****
--- 567,571 ----
    jint p_len = partial_sig->length();
    _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
+ 
     for (Class *klass = this; klass; klass = klass->getSuperclass())
      {
*************** java::lang::Class::initializeClass (void
*** 793,801 ****
    _Jv_PrepareConstantTimeTables (this);
  
    if (vtable == NULL)
      _Jv_MakeVTable(this);
  
    if (otable || atable)
!     _Jv_LinkSymbolTable(this);
  
    _Jv_linkExceptionClassTable (this);
--- 865,881 ----
    _Jv_PrepareConstantTimeTables (this);
    
+   // Assign storage to fields
+   // FIXME size_in_bytes == -1 is an evil way to test for BC compiled programs
+   if (size_in_bytes == (jint)-1)
+     {
+       int static_size;
+       _Jv_LayoutClass(this, &static_size);
+     }
+ 
    if (vtable == NULL)
      _Jv_MakeVTable(this);
  
    if (otable || atable)
!     _Jv_LinkSymbolTable(this, NULL);
  
    _Jv_linkExceptionClassTable (this);
*************** java::lang::Class::setSigners(JArray<job
*** 1532,1536 ****
  
  void
! _Jv_LinkSymbolTable(jclass klass)
  {
    //// FIXME: Need to lock the tables ////
--- 1612,1616 ----
  
  void
! _Jv_LinkSymbolTable(jclass klass, const char *foobar)
  {
    //// FIXME: Need to lock the tables ////
*************** _Jv_LinkSymbolTable(jclass klass)
*** 1544,1551 ****
    klass->otable->state = 1;
  
    for (index = 0; sym = klass->otable_syms[index], sym.name != NULL; index++)
      {
!       // FIXME: Why are we passing NULL as the class loader?
!       jclass target_class = _Jv_FindClass (sym.class_name, NULL);
        _Jv_Method *meth = NULL;            
  
--- 1624,1632 ----
    klass->otable->state = 1;
  
+   if (foobar)
+     fprintf (stderr, "Fixing up otable in %s@%p:\n", foobar, klass);
    for (index = 0; sym = klass->otable_syms[index], sym.name != NULL; index++)
      {
!       jclass target_class = _Jv_FindClass (sym.class_name, klass->loader);
        _Jv_Method *meth = NULL;            
  
*************** _Jv_LinkSymbolTable(jclass klass)
*** 1559,1563 ****
  
        if (target_class == NULL)
! 	continue;
  
        if (target_class->isInterface())
--- 1640,1645 ----
  
        if (target_class == NULL)
! 	throw new java::lang::NoClassDefFoundError 
! 	  (_Jv_NewStringUTF (sym.class_name->data));
  
        if (target_class->isInterface())
*************** _Jv_LinkSymbolTable(jclass klass)
*** 1575,1578 ****
--- 1657,1668 ----
  		    {
  		      klass->otable->offsets[index] = i + 1;
+ 		      if (foobar)
+ 			fprintf (stderr, "  offsets[%d] = %d (interface %s@%p : %s(%s))\n",
+ 				 index,
+ 				 klass->otable->offsets[index],
+ 				 (const char*)cls->name->data,
+ 				 klass,
+ 				 (const char*)sym.name->data,
+ 				 (const char*)signature->data);
  		      goto found;
  		    }
*************** _Jv_LinkSymbolTable(jclass klass)
*** 1592,1595 ****
--- 1682,1689 ----
  	  // then we can't tell the offsets for its methods, so we must lay 
  	  // it out now.
+ 	  {
+ 	    JvSynchronize sync (target_class);
+ 	    _Jv_PrepareClass(target_class);
+ 	  }
  	  if (target_class->vtable_method_count == -1)
  	    {
*************** _Jv_LinkSymbolTable(jclass klass)
*** 1606,1610 ****
  		_Jv_VTable::idx_to_offset (meth->index);	      
  	    }
! 
  	  continue;
  	}
--- 1700,1711 ----
  		_Jv_VTable::idx_to_offset (meth->index);	      
  	    }
! 	  if (foobar)
! 	    fprintf (stderr, "  offsets[%d] = %d (class %s@%p : %s(%s))\n",
! 		     index,
! 		     klass->otable->offsets[index],
! 		     (const char*)target_class->name->data,
! 		     target_class,
! 		     (const char*)sym.name->data,
! 		     (const char*)signature->data);
  	  continue;
  	}
*************** _Jv_LinkSymbolTable(jclass klass)
*** 1667,1672 ****
    for (index = 0; sym = klass->atable_syms[index], sym.name != NULL; index++)
      {
!       // FIXME: Why are we passing NULL as the class loader?
!       jclass target_class = _Jv_FindClass (sym.class_name, NULL);
        _Jv_Method *meth = NULL;            
        const _Jv_Utf8Const *signature = sym.signature;
--- 1768,1772 ----
    for (index = 0; sym = klass->atable_syms[index], sym.name != NULL; index++)
      {
!       jclass target_class = _Jv_FindClass (sym.class_name, klass->loader);
        _Jv_Method *meth = NULL;            
        const _Jv_Utf8Const *signature = sym.signature;
*************** _Jv_LinkSymbolTable(jclass klass)
*** 1677,1681 ****
        
        if (target_class == NULL)
! 	continue;
        
        // We're looking for a static field or a static method, and we
--- 1777,1782 ----
        
        if (target_class == NULL)
! 	throw new java::lang::NoClassDefFoundError 
! 	  (_Jv_NewStringUTF (sym.class_name->data));
        
        // We're looking for a static field or a static method, and we
*************** _Jv_LinkSymbolTable(jclass klass)
*** 1699,1707 ****
--- 1800,1829 ----
  	    {
  	      if (meth->ncode) // Maybe abstract?
+ 		{
  		  klass->atable->addresses[index] = meth->ncode;
+ 		  if (foobar)
+ 		    fprintf (stderr, "  addresses[%d] = %p (class %s@%p : %s(%s))\n",
+ 			     index,
+ 			     &klass->atable->addresses[index],
+ 			     (const char*)target_class->name->data,
+ 			     klass,
+ 			     (const char*)sym.name->data,
+ 			     (const char*)signature->data);
+ 		}
  #ifdef INTERPRETER
  	      else if (_Jv_IsInterpretedClass (target_class))
+ 		{
  		  _Jv_Defer_Resolution (target_class, meth, 
  					&klass->atable->addresses[index]);
+ 		  if (foobar)
+ 		    fprintf (stderr, "  addresses[%d] = DEFERRED@%p (class %s@%p : %s(%s))\n",
+ 			     index,
+ 			     klass->atable->addresses[index],
+ 			     (const char*)target_class->name->data,
+ 			     klass,
+ 			     (const char*)sym.name->data,
+ 			     (const char*)signature->data);
+ 		
+ 		}
  #endif
  	    }
*************** _Jv_LinkSymbolTable(jclass klass)
*** 1731,1734 ****
--- 1853,1859 ----
  		  _Jv_ResolveField (field, cls->loader);
  
+ 		if (_Jv_IsInterpretedClass (target_class))
+ 		  _Jv_AssertDoCall ("can't fixup reference to static field in interpreted class");
+ 		
  // 		if (field_type != 0 && field->type != field_type)
  // 		  throw new java::lang::LinkageError
*************** _Jv_linkExceptionClassTable (jclass self
*** 1773,1779 ****
--- 1898,1912 ----
    while (catch_record->classname)
      {
+       try
+ 	{
  	  jclass target_class = _Jv_FindClass (catch_record->classname,  
  					       self->getClassLoaderInternal ());
  	  *catch_record->address = target_class;
+ 	}
+       catch (::java::lang::Throwable *t)
+ 	{
+ 	  // FIXME: We need to do something better here.
+ 	  *catch_record->address = 0;
+ 	}
        catch_record++;
      }
*************** _Jv_LayoutVTableMethods (jclass klass)
*** 1799,1823 ****
      return;
  
!   jclass superclass = klass->superclass;
! 
!   typedef unsigned int uaddr __attribute__ ((mode (pointer)));
! 
!   // If superclass looks like a constant pool entry,
!   // resolve it now.
!   if ((uaddr)superclass < (uaddr)klass->constants.size)
!     {
!       if (klass->state < JV_STATE_LINKED)
! 	{
! 	  _Jv_Utf8Const *name = klass->constants.data[(int)superclass].utf8;
! 	  superclass = _Jv_FindClass (name, klass->loader);
! 	  if (! superclass)
! 	    {
! 	      jstring str = _Jv_NewStringUTF (name->data);
! 	      throw new java::lang::NoClassDefFoundError (str);
! 	    }
! 	}
!       else
! 	superclass = klass->constants.data[(int)superclass].clazz;
!     }
  
    if (superclass != NULL && superclass->vtable_method_count == -1)
--- 1932,1936 ----
      return;
  
!   jclass superclass = klass->getSuperclass();
  
    if (superclass != NULL && superclass->vtable_method_count == -1)
*************** _Jv_MakeVTable (jclass klass)
*** 1970,1971 ****
--- 2083,2182 ----
      }
  }
+ 
+ void 
+ _Jv_LayoutClass(jclass klass, int *static_size)
+ {  
+   // Compute the alignment for this type by searching through the
+   // superclasses and finding the maximum required alignment.  We
+   // could consider caching this in the Class.
+   int max_align = __alignof__ (java::lang::Object);
+   jclass super = klass->superclass;
+   while (super != NULL)
+     {
+       // FIXME size_in_bytes == -1 is an evil way to test for BC compiled programs
+       if (super->size_in_bytes == (jint)-1)
+ 	_Jv_LayoutClass(super, static_size);
+       int num = JvNumInstanceFields (super);
+       _Jv_Field *field = JvGetFirstInstanceField (super);
+       while (num > 0)
+ 	{
+ 	  int field_align = get_alignment_from_class (field->type);
+ 	  if (field_align > max_align)
+ 	    max_align = field_align;
+ 	  ++field;
+ 	  --num;
+ 	}
+       super = super->superclass;
+     }
+ 
+   int instance_size;
+ 
+   // Although java.lang.Object is never interpreted, an interface can
+   // have a null superclass.  Note that we have to lay out an
+   // interface because it might have static fields.
+   if (klass->superclass)
+     instance_size = klass->superclass->size();
+   else
+     instance_size = java::lang::Object::class$.size();
+ 
+   for (int i = 0; i < klass->field_count; i++)
+     {
+       int field_size;
+       int field_align;
+ 
+       _Jv_Field *field = &klass->fields[i];
+ 
+       if (! field->isRef ())
+ 	{
+ 	  // it's safe to resolve the field here, since it's 
+ 	  // a primitive class, which does not cause loading to happen.
+ 	  _Jv_ResolveField (field, klass->loader);
+ 
+ 	  field_size = field->type->size ();
+ 	  field_align = get_alignment_from_class (field->type);
+ 	}
+       else 
+ 	{
+ 	  field_size = sizeof (jobject);
+ 	  field_align = __alignof__ (jobject);
+ 	}
+ 
+ #ifndef COMPACT_FIELDS
+       field->bsize = field_size;
+ #endif
+ 
+       if (field->flags & java::lang::reflect::Modifier::STATIC)
+ 	{
+ 	  if (_Jv_IsInterpretedClass (klass))
+ 	    {
+ 	      /* this computes an offset into a region we'll allocate
+ 		 shortly, and then add this offset to the start
+ 		 address */
+ 
+ 	      *static_size       = ROUND (*static_size, field_align);
+ 	      field->u.boffset   = *static_size;
+ 	      *static_size       += field_size;
+ 	    }
+ 	}
+       else
+ 	{
+ 	  instance_size      = ROUND (instance_size, field_align);
+ 	  if (field->u.boffset != instance_size)
+ 	    fprintf (stderr, "change to %s.%s: old = %d new=%d\n",
+ 		     (const char*)(klass->name->data), 
+ 		     (const char*)(field->name->data), 
+ 		     field->u.boffset, instance_size);
+ 	  field->u.boffset   = instance_size;
+ 	  instance_size     += field_size;
+ 	  if (field_align > max_align)
+ 	    max_align = field_align;
+ 	}
+     }
+ 
+   // Set the instance size for the class.  Note that first we round it
+   // to the alignment required for this object; this keeps us in sync
+   // with our current ABI.
+   instance_size = ROUND (instance_size, max_align);
+   klass->size_in_bytes = instance_size;
+ }
+ 
Index: libjava/java/lang/natClassLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClassLoader.cc,v
retrieving revision 1.64
diff -p -2 -c -w -r1.64 natClassLoader.cc
*** libjava/java/lang/natClassLoader.cc	16 Jan 2004 23:54:22 -0000	1.64
--- libjava/java/lang/natClassLoader.cc	16 Apr 2004 12:30:02 -0000
*************** details.  */
*** 33,36 ****
--- 33,37 ----
  #include <java/lang/ClassCircularityError.h>
  #include <java/lang/IncompatibleClassChangeError.h>
+ #include <java/lang/ClassFormatError.h>
  #include <java/lang/VirtualMachineError.h>
  #include <java/lang/VMClassLoader.h>
*************** _Jv_WaitForState (jclass klass, int stat
*** 56,60 ****
--- 57,69 ----
        if (_Jv_IsInterpretedClass (klass))
  	_Jv_PrepareClass (klass);
+       else
  #endif
+ 	// Assign storage to fields
+ 	// FIXME size_in_bytes == -1 is an evil way to test for BC compiled programs
+ 	if (klass->size_in_bytes == (jint)-1)
+ 	  {   
+ 	    int static_size;
+ 	    _Jv_LayoutClass(klass, &static_size);
+ 	  }
        _Jv_PrepareCompiledClass (klass);
        _Jv_MonitorExit (klass);
*************** _Jv_PrepareCompiledClass (jclass klass)
*** 90,93 ****
--- 99,105 ----
      return;
  
+   int state = klass->state;
+   try
+     {
        // Short-circuit, so that mutually dependent classes are ok.
        klass->state = JV_STATE_LINKED;
*************** _Jv_PrepareCompiledClass (jclass klass)
*** 123,132 ****
    // If superclass looks like a constant pool entry,
    // resolve it now.
!   if ((uaddr) klass->superclass < pool->size)
      klass->superclass = pool->data[(int) klass->superclass].clazz;
! 
    // Likewise for interfaces.
    for (int i = 0; i < klass->interface_count; i++)
!     if ((uaddr) klass->interfaces[i] < pool->size)
        klass->interfaces[i] = pool->data[(int) klass->interfaces[i]].clazz;
  
--- 135,145 ----
        // If superclass looks like a constant pool entry,
        // resolve it now.
!       if ((uaddr) klass->superclass < (uaddr)pool->size)
! 	{
  	  klass->superclass = pool->data[(int) klass->superclass].clazz;
! 	}
        // Likewise for interfaces.
        for (int i = 0; i < klass->interface_count; i++)
! 	if ((uaddr) klass->interfaces[i] < (uaddr)pool->size)
  	  klass->interfaces[i] = pool->data[(int) klass->interfaces[i]].clazz;
  
*************** _Jv_PrepareCompiledClass (jclass klass)
*** 175,178 ****
--- 188,197 ----
        _Jv_PushClass (klass);
      }
+   catch (java::lang::Throwable *t)
+     {
+       klass->state = state;
+       throw t;
+     }
+ }
  
  
*************** _Jv_NewArrayClass (jclass element, java:
*** 557,560 ****
--- 576,586 ----
  
    element->arrayclass = array_class;
+ }
+ 
+ // Return the true ClassLoader for a class, without doing security checks
+ ::java::lang::ClassLoader *
+ ::java::lang::ClassLoader::getClassLoader0 (::java::lang::Class *c)
+ {
+   return c->loader;
  }
  
Index: libjava/java/lang/natThread.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natThread.cc,v
retrieving revision 1.26
diff -p -2 -c -w -r1.26 natThread.cc
*** libjava/java/lang/natThread.cc	9 Mar 2004 21:02:52 -0000	1.26
--- libjava/java/lang/natThread.cc	16 Apr 2004 12:30:02 -0000
*************** java::lang::Thread::resume (void)
*** 148,151 ****
--- 148,160 ----
  }
  
+ #include <sys/types.h>
+ #include <unistd.h>
+ 
+ jlong
+ java::lang::Thread::getpid (void)
+ {
+   return ::getpid ();
+ }
+ 
  void
  java::lang::Thread::setPriority (jint newPriority)
Index: libjava/java/lang/natVMClassLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natVMClassLoader.cc,v
retrieving revision 1.1
diff -p -2 -c -w -r1.1 natVMClassLoader.cc
*** libjava/java/lang/natVMClassLoader.cc	16 Jan 2004 23:54:22 -0000	1.1
--- libjava/java/lang/natVMClassLoader.cc	16 Apr 2004 12:30:02 -0000
*************** java::lang::VMClassLoader::loadClass(jst
*** 131,133 ****
--- 131,134 ----
      _Jv_InitClass (klass);
    return klass;
+ 
  }
Index: libjava/java/lang/reflect/natMethod.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/reflect/natMethod.cc,v
retrieving revision 1.37
diff -p -2 -c -w -r1.37 natMethod.cc
*** libjava/java/lang/reflect/natMethod.cc	26 Feb 2004 15:22:20 -0000	1.37
--- libjava/java/lang/reflect/natMethod.cc	16 Apr 2004 12:30:02 -0000
*************** java::lang::reflect::Method::invoke (job
*** 144,147 ****
--- 144,148 ----
  {
    using namespace java::lang::reflect;
+   jclass iface = NULL;
    
    if (parameter_types == NULL)
*************** java::lang::reflect::Method::invoke (job
*** 149,153 ****
      
    jmethodID meth = _Jv_FromReflectedMethod (this);
- 
    jclass objClass;
    
--- 150,153 ----
*************** java::lang::reflect::Method::invoke (job
*** 189,194 ****
      }
  
    return _Jv_CallAnyMethodA (obj, return_type, meth, false,
! 			     parameter_types, args);
  }
  
--- 189,197 ----
      }
  
+   if (declaringClass->isInterface())
+     iface = declaringClass;
+   
    return _Jv_CallAnyMethodA (obj, return_type, meth, false,
! 			     parameter_types, args, iface);
  }
  
*************** _Jv_CallAnyMethodA (jobject obj,
*** 342,346 ****
  		    jvalue *args,
  		    jvalue *result,
! 		    jboolean is_jni_call)
  {
    using namespace java::lang::reflect;
--- 345,350 ----
  		    jvalue *args,
  		    jvalue *result,
! 		    jboolean is_jni_call,
! 		    jclass iface)
  {
    using namespace java::lang::reflect;
*************** _Jv_CallAnyMethodA (jobject obj,
*** 479,483 ****
--- 483,500 ----
      {
        _Jv_VTable *vtable = *(_Jv_VTable **) obj;
+       if (iface == NULL)
  	ncode = vtable->get_method (meth->index);
+       else
+ 	{
+ 	  /* Okay, here's how it goes.  We want to know the method
+ 	     offset in the list of methods declared by an interface,
+ 	     starting at 1.  The offset in the method is the vtable
+ 	     offset, not the offset in the interface, so we subtract
+ 	     that.  We add 1 because we count interface methods
+ 	     beginning at 1.  I think this is because of the initial
+ 	     gc descriptor in the vtable.  */
+ 	  jint offset = meth->index - JvGetFirstMethod (iface)->index + 1;
+ 	  ncode = _Jv_LookupInterfaceMethodIdx (vtable->clas, iface, offset);
+ 	}
      }
    else
*************** _Jv_CallAnyMethodA (jobject obj,
*** 554,558 ****
  		    jboolean is_constructor,
  		    JArray<jclass> *parameter_types,
! 		    jobjectArray args)
  {
    if (parameter_types->length == 0 && args == NULL)
--- 571,576 ----
  		    jboolean is_constructor,
  		    JArray<jclass> *parameter_types,
! 		    jobjectArray args,
! 		    jclass iface)
  {
    if (parameter_types->length == 0 && args == NULL)
*************** _Jv_CallAnyMethodA (jobject obj,
*** 622,626 ****
    		      _Jv_isVirtualMethod (meth),
  		      parameter_types, argvals, &ret_value,
! 		      false);
  
    jobject r;
--- 640,644 ----
    		      _Jv_isVirtualMethod (meth),
  		      parameter_types, argvals, &ret_value,
! 		      false, iface);
  
    jobject r;
Index: libjava/java/net/URLClassLoader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/net/URLClassLoader.java,v
retrieving revision 1.16
diff -p -2 -c -w -r1.16 URLClassLoader.java
*** libjava/java/net/URLClassLoader.java	28 Aug 2003 22:17:37 -0000	1.16
--- libjava/java/net/URLClassLoader.java	16 Apr 2004 12:30:03 -0000
*************** public class URLClassLoader extends Secu
*** 291,294 ****
--- 291,296 ----
      final URL baseJarURL;  // Base jar: url for all resources loaded from jar
  
+     SoURLLoader soURLLoader;
+ 
      public JarURLLoader(URLClassLoader classloader, URL baseURL)
      {
*************** public class URLClassLoader extends Secu
*** 303,306 ****
--- 305,309 ----
        String jarURL = sb.toString();
  
+       this.soURLLoader = null;
        URL baseJarURL = null;
        JarFile jarfile = null;
*************** public class URLClassLoader extends Secu
*** 311,314 ****
--- 314,339 ----
  	  jarfile
  	    = ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
+ 
+ 	  if (jarfile != null)
+ 	    {
+ 	      String fileName = baseURL.getFile();
+ 	      if (fileName != null)
+ 		{
+ 		  File f = new File(fileName);
+ 		  String libDirName = f.getCanonicalFile().getParent()
+ 		    + File.separator + "GCJLIBS";
+ 		  File libDir = new File(libDirName);
+ 		  if (libDir != null && (libDir.isDirectory()))
+ 		    {
+ 		      File soFile = new File (libDirName + File.separator + f.getName() 
+ 					      + ".so");
+ 		      if (soFile != null && soFile.isFile())
+ 			this.soURLLoader = 
+ 			  new SoURLLoader
+ 			  (classloader, 
+ 			   new URL ("file", null, soFile.getCanonicalPath()));
+ 		    }
+ 		}
+ 	    }
  	}
        catch (IOException ioe) { /* ignored */ }
*************** public class URLClassLoader extends Secu
*** 318,321 ****
--- 343,353 ----
      }
  
+     Class getClass(String className)
+     {
+       if (soURLLoader != null)
+ 	return soURLLoader.getClass(className);
+       return null;
+     }
+ 
      /** get resource with the name "name" in the jar url */
      Resource getResource(String name)
*************** public class URLClassLoader extends Secu
*** 334,337 ****
--- 366,374 ----
      }
  
+     public String toString ()
+     {
+ 	return "jarfile " + jarfile.getName();
+     }
+ 
      Manifest getManifest()
      {
*************** public class URLClassLoader extends Secu
*** 490,494 ****
      Class getClass(String className)
      {
!       return helper.findClass(className);
      }
  
--- 527,532 ----
      Class getClass(String className)
      {
! 	Class c = helper.findClass(className);
! 	return c;
      }
  
*************** public class URLClassLoader extends Secu
*** 574,577 ****
--- 612,620 ----
      }
  
+     public String toString ()
+     {
+ 	return "file " +file.getAbsolutePath();
+     }
+ 
      public URL getURL()
      {
*************** public class URLClassLoader extends Secu
*** 745,749 ****
  	    String protocol = newUrl.getProtocol();
  	    // Check that it is not a directory
! 	    if ("gcjlib".equals(protocol))
  	      loader = new SoURLLoader(this, newUrl);
  	    else if (! (file.endsWith("/") || file.endsWith(File.separator)))
--- 788,792 ----
  	    String protocol = newUrl.getProtocol();
  	    // Check that it is not a directory
! 	    if ("gcjlib".equals(protocol)) // || file.endsWith(".so"))
  	      loader = new SoURLLoader(this, newUrl);
Index: libjava/gnu/gcj/util//Debug.java
===================================================================
RCS file: libjava/gnu/gcj/util//Debug.java
diff -N libjava/gnu/gcj/util//Debug.java
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- libjava/gnu/gcj/util//Debug.java	16 Apr 2004 12:42:19 -0000
***************
*** 0 ****
--- 1,220 ----
+ /*  Copyright (C) 2004  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.  */
+ 
+ /* Utility methods that allow an object to be converted to a textual
+    representation on an OutputStream.  The intention here is that this
+    class be used for debugging, so we provide information about all
+    fields, public or otherwise. */
+ 
+ package gnu.gcj.util;
+ 
+ import java.lang.reflect.*;
+ import java.io.*;
+ import java.util.*;
+ 
+ class Debug 
+ {
+     private final PrintStream p;
+     private final int maxdepth;
+     private final int maxArrayLength;
+     private final boolean printStaticFields;
+     private int depth; 
+ 
+     Debug(PrintStream writer, int maxdepth, int maxArrayLength, boolean printStaticFields)
+     {
+ 	p = writer;
+ 	this.maxdepth = maxdepth;
+ 	this.maxArrayLength = maxArrayLength;
+ 	this.printStaticFields = printStaticFields;
+     }
+ 
+     Debug(PrintStream writer)
+     {
+ 	this(writer, 0, 10, false);
+     }
+ 
+     Debug(int maxdepth)
+     {
+ 	this(new PrintStream
+ 	     (new FileOutputStream(FileDescriptor.err), true), 
+ 	     maxdepth, 
+ 	     maxdepth > 0 ? 1000 : 10, false);
+     }
+ 
+     Debug()
+     {
+ 	this(0);
+     }
+   
+     private final void indent()
+     {
+ 	for (int i = 0; i < depth; i++)
+ 	    p.print("  ");
+     }
+ 
+     private final java.util.IdentityHashMap h = 
+ 	new java.util.IdentityHashMap();
+ 
+     private static native Field[] getDeclaredFields(Class c);
+     private static native Object getField(Object o, Field f);
+     private static native long getAddr(Object o);
+ 
+     // Return an array containing all the fields of a class and its
+     // superclasses.
+     private Field[] internalGetFields(Class c)
+     {
+ 	HashSet set = new HashSet();
+ 	set.addAll(Arrays.asList(getDeclaredFields(c)));
+ 	Class[] interfaces = c.getInterfaces();
+ 	for (int i = 0; i < interfaces.length; i++)
+ 	    set.addAll(Arrays.asList(internalGetFields(interfaces[i])));
+ 	Class superClass = c.getSuperclass();
+ 	if (superClass != null)
+ 	    set.addAll(Arrays.asList(internalGetFields(superClass)));
+ 	return (Field[])set.toArray(new Field[set.size()]);
+     }
+ 
+     // FIXME: We could just use getClass() here, but this is a
+     // workaround for a C++ bug that is causing getClass() to be
+     // miscompiled.
+     static private Class getItsClass(Object O)
+     {
+ 	return O.getClass();
+     }
+ 
+     // Print a reasonably readable textual representation of an object
+     // on our OutputStream.  Objects are only printed once, no matter
+     // how many references point to them.
+     private void print(Object O)
+     {
+ 	int savedDepth = depth;
+ 	h.put(O, O);
+ 	try
+ 	    {
+ 		Class C = getItsClass(O);
+ 		p.print(C.getName() + "@");
+ 		p.println(Long.toHexString(getAddr(O)));
+ 
+ 		if (C.isArray())
+ 		    {
+ 			indent(); p.println("{");
+ 			depth++;
+ 			indent();
+ 			C = C.getComponentType();
+ 
+ 			int len = Array.getLength(O);
+ 			for (int i = 0; i < len; i++)
+ 			    {
+ 				Object thing = Array.get(O, i);
+ 				print0(thing, C);
+ 				p.print(", ");
+ 				if (i > maxArrayLength)
+ 				    {
+ 					p.print("...");
+ 					break;
+ 				    }
+ 			    }
+ 			depth--;
+ 			p.println();
+ 			indent(); p.print("}");
+ 			return;
+ 		    }
+ 
+ 		indent(); p.println("{");
+ 		depth++;
+ 		if (C == java.lang.Class.class)
+ 		    {
+ 			indent();
+ 			p.println ("class = " + O.toString() + ",");
+ 		    }
+ 		else if (C == java.lang.reflect.Field.class)
+ 		    {
+ 			indent();
+ 			p.println ("<field> = \"" + O.toString() + "\",");
+ 		    }
+ 		else if (C == java.lang.String.class)
+ 		    {
+ 			indent();
+ 			p.println ("<string> = \"" + O.toString() + "\",");
+ 		    }
+ 		Field[] f = internalGetFields(C);
+ 		for (int i = 0; i < f.length; i++)
+ 		    {
+ 			Class type = f[i].getType();
+ 			boolean isStatic = (f[i].getModifiers() & Modifier.STATIC) != 0;
+  
+ 			if (isStatic && ! printStaticFields)
+ 			    continue;
+ 
+ 			indent();
+ 			if (isStatic)
+ 			    p.print("static ");
+ 			p.print(type.getName() +" " +f[i].getName() + " = ");
+ 			Object thing = getField(O, f[i]);
+ 			print0(thing, type);
+ 			p.println(",");
+ 		    }
+ 		depth--;
+ 		indent(); p.print("}");
+ 	    }
+ 	catch (Throwable t)
+ 	    {
+ 		p.print("error: 0x" + Long.toHexString(getAddr(O)) + ";");
+ 		depth = savedDepth;
+ 	    }
+     }
+ 
+     private void print0(Object thing, Class C)
+     {
+ 	try
+ 	    {
+ 		if (thing == null)
+ 		    {
+ 			p.print("null");
+ 			return;
+ 		    }
+ 		else if (C == gnu.gcj.RawData.class)
+ 		    {
+ 		    }
+ 		else if (C.isPrimitive())
+ 		    {
+ 			if (getItsClass(thing) == Character.class)				
+ 			    p.print("'" + thing + "'");
+ 			else
+ 			    p.print(thing);
+ 			return;
+ 		    }
+ 		else if (getItsClass(thing) == String.class)
+ 		    {			  
+ 			p.print("\"" + thing + "\"");
+ 			return;
+ 		    }
+ 		else if (depth < maxdepth && h.get(thing) == null)
+ 		    {
+ 			depth++;
+ 			print(thing);
+ 			depth--;
+ 			return;
+ 		    }
+ 	    }
+ 	catch (Throwable t)
+ 	    {
+ 	    }
+     
+ 	// The default cation: just print the address.
+ 	p.print("0x"+ Long.toHexString(getAddr(thing)));    
+     }
+ 
+     // Print the textual representation of an object on System.err.
+     public void write(Object O)
+     {
+ 	depth = 0;
+ 	print(O);
+ 	p.flush();
+     }
+ }
Index: libjava/gnu/gcj/util//natDebug.cc
===================================================================
RCS file: libjava/gnu/gcj/util//natDebug.cc
diff -N libjava/gnu/gcj/util//natDebug.cc
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- libjava/gnu/gcj/util//natDebug.cc	16 Apr 2004 12:42:19 -0000
***************
*** 0 ****
--- 1,111 ----
+ // natDebug -- C++ side of Debug
+ 
+ /* Copyright (C) 2004  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.  */
+ 
+ #include <config.h>
+ #include <stddef.h>
+ #include <gcj/cni.h>
+ #include <gcj/field.h>
+ #include <gcj/javaprims.h>
+ #include <java/lang/reflect/Field.h>
+ #include <java/lang/Class.h>
+ #include <java/lang/Byte.h>
+ #include <java/lang/Short.h>
+ #include <java/lang/Integer.h>
+ #include <java/lang/Long.h>
+ #include <java/lang/Float.h>
+ #include <java/lang/Double.h>
+ #include <java/lang/Boolean.h>
+ #include <java/lang/Character.h>
+ #include <java/lang/IllegalArgumentException.h>
+ 
+ #include <gnu/gcj/util/Debug.h>
+ 
+ jlong 
+ gnu::gcj::util::Debug::getAddr (::java::lang::Object *o)
+ {
+   return (jlong)(size_t)o;
+ }
+ 
+ JArray< ::java::lang::reflect::Field *> *
+ gnu::gcj::util::Debug::getDeclaredFields (::java::lang::Class *c)
+ {
+   return c->getDeclaredFields (false);
+ }
+ 
+ static void *
+ ::getField (::java::lang::Object *obj, 
+ 	    ::java::lang::reflect::Field *field)
+ {
+   using namespace java::lang::reflect;
+   
+   jfieldID fld = _Jv_FromReflectedField (field);
+   _Jv_ushort flags = fld->getModifiers();
+ 
+   if (flags & Modifier::STATIC)
+     {
+       jclass fldClass = field->getDeclaringClass ();
+       JvInitClass(fldClass);
+       return (void*) fld->u.addr;
+     }
+   else
+     {
+       return (void*) ((char*) obj + fld->getOffset ());
+     }
+ }
+ 
+ ::java::lang::Object *
+ gnu::gcj::util::Debug::getField (::java::lang::Object *o, 
+ 				   ::java::lang::reflect::Field *field)
+ {
+   void *addr = ::getField (o, field);
+ 
+   jclass type = field->getType();
+   if (! type->isPrimitive ())
+     return * (jobject*) addr;
+   if (type == JvPrimClass (double))
+     return new java::lang::Double (* (jdouble*) addr);
+   if (type == JvPrimClass (float))
+     return new java::lang::Float (* (jfloat*) addr);
+   if (type == JvPrimClass (long))
+     return new java::lang::Long (* (jlong*) addr);
+   if (type == JvPrimClass (int))
+     return new java::lang::Integer (* (jint*) addr);
+   if (type == JvPrimClass (short))
+     return new java::lang::Short (* (jshort*) addr);
+   if (type == JvPrimClass (byte))
+     return new java::lang::Byte (* (jbyte*) addr);
+   if (type == JvPrimClass (char))
+     return new java::lang::Character (* (jchar*) addr);
+   if (type == JvPrimClass (boolean))
+     {
+       _Jv_InitClass (&java::lang::Boolean::class$);
+       if (* (jboolean*) addr)
+ 	return java::lang::Boolean::TRUE;
+       else
+ 	return java::lang::Boolean::FALSE;
+     }
+   throw new java::lang::IllegalArgumentException;
+ }
+ 
+ /* A simple method of printing an object that can be called from a
+    debugger.  */
+ extern "C"
+ void
+ _Jv_Debug (void *p)
+ {
+   (new ::gnu::gcj::util::Debug ())->write ((jobject)p);
+ }
+ 
+ extern "C"
+ void
+ _Jv_DeepDebug (void *p, int depth)
+ {
+   (new ::gnu::gcj::util::Debug (depth))->write ((jobject)p);
+ }


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