Add missing file from gcj-abi-2-dev-branch merge.
From-SVN: r91284
This commit is contained in:
parent
b1df6376dc
commit
e0966a17a3
226
libjava/gnu/gcj/util/Debug.java
Normal file
226
libjava/gnu/gcj/util/Debug.java
Normal file
@ -0,0 +1,226 @@
|
||||
/* 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, boolean printStaticFields)
|
||||
{
|
||||
this(new PrintStream
|
||||
(new FileOutputStream(FileDescriptor.err), true),
|
||||
maxdepth,
|
||||
maxdepth > 0 ? 1000 : 10, printStaticFields);
|
||||
}
|
||||
|
||||
Debug(int maxdepth)
|
||||
{
|
||||
this(maxdepth, false);
|
||||
}
|
||||
|
||||
Debug()
|
||||
{
|
||||
this(0, false);
|
||||
}
|
||||
|
||||
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 ||
|
||||
C == gnu.gcj.RawDataManaged.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 action: 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();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user