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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Patch: FYI: Merge BC branch to trunk


Hi,

On Thu, 2004-11-25 at 04:14, Tom Tromey wrote:
> This patch merges the BC branch to the trunk.  After this patch, I
> think the BC branch is dead; I'll submit another patch to update the
> web pages.  I've made a tag on the branch at the merge point.
> [...]
> 2004-04-16  Andrew Haley  <aph@redhat.com>
> [...]
> 	* gnu/gcj/util/natDebug.cc: New
> 	* gnu/gcj/util/Debug.java: New.

You seem to have forgotten to actually add these files on the trunk.
Since this breaks bootstrap I will add these add the versions from the
gcj-abi-2-dev-branch as follows if my bootstrap succeeds:

2004-11-25  Andrew Haley  <aph@redhat.com>

	* gnu/gcj/util/natDebug.cc: New file from gcj-abi-2-dev-branch.
	* gnu/gcj/util/Debug.java: Likewise.

Unless someone beats me to it or yells loudly that there was a good
reason to break the build.

Cheers,

Mark

P.S. I need to do another thing to make bootstrap work (thanks to
Michael Koch for pointing this out):

--- gcc.c       24 Nov 2004 17:33:48 -0000      1.438
+++ gcc.c       25 Nov 2004 11:33:35 -0000
@@ -3677,6 +3677,4 @@
                break;
              verbose_flag++;
-             if (strcmp (linker_name_spec, "collect2") == 0)
-               add_linker_option ("-v", 2);
              break;

Is anyone else having trouble with this?
// 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);
}

extern "C"
void
_Jv_StaticDeepDebug (void *p, int depth)
{
  (new ::gnu::gcj::util::Debug (depth, true))->write ((jobject)p);
}
/*  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();
  }
}

Attachment: signature.asc
Description: This is a digitally signed message part


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