This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[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);
+ }