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]

[gcjx] Patch: FYI: fix attribute lengths


I'm checking this in on the gcjx branch.

We were incorrectly computing the size of the Code attribute in some
cases.  To make this simpler in the future, I changed all attributes
to compute their own sizes; this means if we need to add attributes to
the Code attribute in the future, no further changes will need to be
made.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>
	* bytecode/locals.cc (emit): Updated.
	(update): Update 'valid'.
	* bytecode/locals.hh (locals::valid): New field.
	(locals): Updated.
	(locals::size): New method.
	* bytecode/generate.cc (write): Don't emit the size.
	(write_line_table): Likewise.
	(count_exception_handlers): New method.
	* bytecode/outpool.hh (output_constant_pool::size): Declare.
	* bytecode/outpool.cc (size): New method.
	(write_inner_classes): Don't emit the size.
	* bytecode/attribute.cc (size): New methods.
	(emit): Write the size.  Update all other emit methods.
	* bytecode/generate.hh (line_table_attribute::size): New method.
	(local_variable_table_attribute::size): Likewise.
	(bytecode_generator::count_exception_handlers): Declare.
	(bytecode_generator::bytecode_size): New method.
	* bytecode/attribute.hh (bytecode_attribute_list::size): Declare.
	(bytecode_attribute::size): Likewise.
	(simple_name_attribute::size): New method.
	(utf8_attribute::size): New method.
	(inner_classes_attribute::size): Declare.
	(exceptions_attribute::size): New method.
	(code_attribute::size): Declare.
	(field_value_attribute::size): New method.
	(annotation_attribute::size): Likewise.
	(parameter_attribute::size): Likewise.
	(annotation_default_attribute::size): Likewise.

2005-01-15  Tom Tromey  <tromey@redhat.com>

Index: bytecode/attribute.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/attribute.cc,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 attribute.cc
--- bytecode/attribute.cc 13 Jan 2005 03:18:34 -0000 1.1.2.1
+++ bytecode/attribute.cc 16 Jan 2005 04:34:23 -0000
@@ -1,6 +1,6 @@
 // Attribute for bytecode output.
 
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 //
 // This file is part of GCC.
 //
@@ -43,6 +43,7 @@
 bytecode_attribute::emit (bytecode_stream &writer)
 {
   writer.put2 (pool->add_utf (name));
+  writer.put4 (size ());
 }
 
 
@@ -51,7 +52,6 @@
 simple_name_attribute::emit (bytecode_stream &writer)
 {
   bytecode_attribute::emit (writer);
-  writer.put4 (0);
 }
 
 
@@ -70,7 +70,6 @@
 utf8_attribute::emit (bytecode_stream &writer)
 {
   bytecode_attribute::emit (writer);
-  writer.put4 (2);
   writer.put2 (pool->add_utf (value));
 }
 
@@ -89,6 +88,12 @@
   pool->write_inner_classes ();
 }
 
+int
+inner_classes_attribute::size ()
+{
+  return pool->size ();
+}
+
 
 
 exceptions_attribute::exceptions_attribute (output_constant_pool *p,
@@ -107,7 +112,6 @@
 exceptions_attribute::emit (bytecode_stream &writer)
 {
   bytecode_attribute::emit (writer);
-  writer.put4 (2 + 2 * excs.size ());
   writer.put2 (excs.size ());
   for (std::set<model_type *>::const_iterator i = excs.begin ();
        i != excs.end ();
@@ -130,6 +134,12 @@
   gen->write (&writer);
 }
 
+int
+code_attribute::size ()
+{
+  return gen->bytecode_size ();
+}
+
 
 
 field_value_attribute::field_value_attribute (output_constant_pool *p,
@@ -165,7 +175,6 @@
 field_value_attribute::emit (bytecode_stream &writer)
 {
   bytecode_attribute::emit (writer);
-  writer.put4 (2);
   writer.put2 (index);
 }
 
@@ -322,7 +331,6 @@
 annotation_attribute::emit (bytecode_stream &writer)
 {
   bytecode_attribute::emit (writer);
-  writer.put4 (len);
   writer.put2 (annos.size ());
   for (std::list<model_annotation *>::const_iterator i = annos.begin ();
        i != annos.end ();
@@ -356,7 +364,6 @@
 parameter_attribute::emit (bytecode_stream &writer)
 {
   bytecode_attribute::emit (writer);
-  writer.put4 (len);
   writer.put2 (annos.size ());
   for (std::list< std::list<model_annotation *> >::const_iterator j
 	 = annos.begin ();
@@ -385,7 +392,6 @@
 annotation_default_attribute::emit (bytecode_stream &writer)
 {
   bytecode_attribute::emit (writer);
-  writer.put4 (len);
   emit_annotation_value (&writer, pool, expr);
 }
 
@@ -412,3 +418,17 @@
        ++i)
     (*i)->emit (writer);
 }
+
+int
+bytecode_attribute_list::size ()
+{
+  int result = 2;
+  for (std::list<bytecode_attribute *>::const_iterator i = attrs.begin ();
+       i != attrs.end ();
+       ++i)
+    {
+      // '6' is 2 byte for the name and 4 for the length.
+      result += 6 + (*i)->size ();
+    }
+  return result;
+}
Index: bytecode/attribute.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/attribute.hh,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 attribute.hh
--- bytecode/attribute.hh 13 Jan 2005 03:18:34 -0000 1.1.2.1
+++ bytecode/attribute.hh 16 Jan 2005 04:34:23 -0000
@@ -1,6 +1,6 @@
 // Attribute for bytecode output.
 
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 //
 // This file is part of GCC.
 //
@@ -47,6 +47,9 @@
   /// attribute; subclasses must emit the size of the attribute and
   /// its contents.
   virtual void emit (bytecode_stream &);
+
+  /// Compute the size of this attribute.
+  virtual int size () = 0;
 };
 
 /// An attribute which is just a tag.
@@ -60,6 +63,11 @@
   }
 
   void emit (bytecode_stream &);
+
+  int size ()
+  {
+    return 0;
+  }
 };
 
 /// An attribute that consists of a name and a utf8 value.
@@ -74,6 +82,11 @@
 		  const std::string &);
 
   void emit (bytecode_stream &);
+
+  int size ()
+  {
+    return 2;
+  }
 };
 
 /// An attribute that handles InnerClasses for the constant pool.  It
@@ -85,6 +98,8 @@
   inner_classes_attribute (output_constant_pool *);
 
   void emit (bytecode_stream &);
+
+  int size ();
 };
 
 /// An attribute that handles exceptions for a method.
@@ -99,6 +114,11 @@
 			const std::set<model_type *> &);
 
   void emit (bytecode_stream &);
+
+  int size ()
+  {
+    return 2 + 2 * excs.size ();
+  }
 };
 
 /// An attribute that handles the code for a method.
@@ -112,6 +132,8 @@
   code_attribute (output_constant_pool *, bytecode_generator *);
 
   void emit (bytecode_stream &);
+
+  int size ();
 };
 
 /// An attribute that handles the constant value of a field.
@@ -125,6 +147,11 @@
   field_value_attribute (output_constant_pool *, model_field *);
 
   void emit (bytecode_stream &);
+
+  int size ()
+  {
+    return 2;
+  }
 };
 
 /// This represents annotations that are attached to a class, field,
@@ -144,6 +171,11 @@
 			const std::list<model_annotation *> &);
 
   void emit (bytecode_stream &);
+
+  int size ()
+  {
+    return len;
+  }
 };
 
 /// This represents annotations attached to method parameters.
@@ -162,6 +194,11 @@
 		       const std::list< std::list<model_annotation *> > &);
 
   void emit (bytecode_stream &);
+
+  int size ()
+  {
+    return len;
+  }
 };
 
 /// This represents an annotation default value.
@@ -178,6 +215,11 @@
   annotation_default_attribute (output_constant_pool *, model_expression *);
 
   void emit (bytecode_stream &);
+
+  int size ()
+  {
+    return len;
+  }
 };
 
 /// This holds a list of attributes.  It owns each attribute object
@@ -199,6 +241,9 @@
   }
 
   void emit (bytecode_stream &);
+
+  // Compute the size needed by all attributes.
+  int size ();
 };
 
 #endif // GCJX_BYTECODE_ATTRIBUTE_HH
Index: bytecode/generate.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/generate.cc,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 generate.cc
--- bytecode/generate.cc 15 Jan 2005 21:27:50 -0000 1.1.2.4
+++ bytecode/generate.cc 16 Jan 2005 04:34:24 -0000
@@ -183,8 +183,8 @@
     }
 }
 
-void
-bytecode_generator::write (bytecode_stream *out)
+int
+bytecode_generator::count_exception_handlers ()
 {
   // Count the number of exception handlers we have.
   int count = 0;
@@ -204,6 +204,13 @@
 				 "past 65535 bytes");
 	}
     }
+  return count;
+}
+
+void
+bytecode_generator::write (bytecode_stream *out)
+{
+  int count = count_exception_handlers ();
 
   if (count > 65535)
     throw method->error ("method requires more than 65535 exception regions");
@@ -214,12 +221,6 @@
   if (vars.get_max () > 65535)
     throw method->error ("bytecode uses more than 65535 local variable slots");
 
-  // Compute the total length of the Code section.
-  int length = 8 + bytecode_length + 2 + 8 * count + 2;
-  if (global->get_compiler ()->target_debug () && line_count > 0)
-    length += 6 + 2 + 4 * line_count;
-
-  out->put4 (length);
   out->put2 (max_stack);
   out->put2 (vars.get_max ());
   out->put4 (bytecode_length);
@@ -295,7 +296,6 @@
 void
 bytecode_generator::write_line_table (bytecode_stream *out)
 {
-  out->put4 (2 + 4 * line_count);
   out->put2 (line_count);
   int last_line = -1;
   for (bytecode_block *work = first_block; work; work = work->next ())
Index: bytecode/generate.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/generate.hh,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 generate.hh
--- bytecode/generate.hh 15 Jan 2005 21:27:51 -0000 1.1.2.3
+++ bytecode/generate.hh 16 Jan 2005 04:34:24 -0000
@@ -179,6 +179,11 @@
       bytecode_attribute::emit (writer);
       gen->write_line_table (&writer);
     }
+
+    int size ()
+    {
+      return 2 + 4 * gen->line_count;
+    }
   };
 
   /// This class is used to handle the LocalVariableTable attribute.
@@ -201,6 +206,11 @@
       bytecode_attribute::emit (writer);
       vars->emit (pool, &writer);
     }
+
+    int size ()
+    {
+      return vars->size ();
+    }
   };
 
   void write_line_table (bytecode_stream *);
@@ -283,6 +293,8 @@
   bytecode_block *new_bytecode_block ();
   void note_line (model_element *);
 
+  int count_exception_handlers ();
+
   // Used to push a new expression target.
   class push_expr_target
   {
@@ -351,6 +363,13 @@
   /// Write the bytecode for this method.
   void write (bytecode_stream *);
 
+  /// Compute the overall length used by the Code attribute.
+  int bytecode_size ()
+  {
+    int count = count_exception_handlers ();
+    return 8 + bytecode_length + 2 + 8 * count + attributes.size ();
+  }
+
   /// Used to keep track of lifetimes of local variables.
   bytecode_block *get_current () const
   {
Index: bytecode/locals.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/locals.cc,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 locals.cc
--- bytecode/locals.cc 15 Jan 2005 21:27:51 -0000 1.1.2.2
+++ bytecode/locals.cc 16 Jan 2005 04:34:24 -0000
@@ -139,7 +139,7 @@
 bool
 locals::update ()
 {
-  bool any = false;
+  valid = 0;
   for (std::list<debug_info>::iterator i = var_descriptions.begin ();
        i != var_descriptions.end ();
        ++i)
@@ -153,10 +153,10 @@
 	  assert (info.end->live_p ());
 	  // Don't emit debug info for a zero-length range.
 	  if (info.start != info.end)
-	    any = true;
+	    ++valid;
 	}
     }
-  return any;
+  return valid > 0;
 }
 
 void
@@ -180,10 +180,12 @@
 	}
     }
 
+  assert (count == valid);
+  assert (count > 0);
+
   if (! out)
     return;
 
-  out->put4 (2 + 10 * count);
   out->put2 (count);
   for (std::list<debug_info>::const_iterator i = var_descriptions.begin ();
        i != var_descriptions.end ();
Index: bytecode/locals.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/locals.hh,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 locals.hh
--- bytecode/locals.hh 15 Jan 2005 21:27:51 -0000 1.1.2.2
+++ bytecode/locals.hh 16 Jan 2005 04:34:24 -0000
@@ -66,11 +66,15 @@
   // appear several times here, due to how we emit 'finally' clauses.
   std::list<debug_info> var_descriptions;
 
+  // Number of variables that survived updating.
+  int valid;
+
 public:
 
   locals (bytecode_generator *g)
     : gen (g),
-      max (0)
+      max (0),
+      valid (-1)
   {
     scope.push_back (NULL);
   }
@@ -115,6 +119,12 @@
   /// information.  If the writer is NULL, just enter information into
   /// the constant pool.
   void emit (output_constant_pool *, bytecode_stream *);
+
+  /// Return the size of the local variable table attribute.
+  int size ()
+  {
+    return 2 + 10 * valid;
+  }
 };
 
 /// This is an class for allocating a temporary local variable.  Usage
Index: bytecode/outpool.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/outpool.cc,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 outpool.cc
--- bytecode/outpool.cc 13 Jan 2005 03:18:34 -0000 1.1.2.1
+++ bytecode/outpool.cc 16 Jan 2005 04:34:24 -0000
@@ -1,6 +1,6 @@
 // A constant pool being generated.
 
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 //
 // This file is part of GCC.
 //
@@ -333,7 +333,6 @@
 {
   // Here we freely use 'add', assuming that the entries have all been
   // added already.
-  bytes.put4 (2 + 8 * nested_classes.size ());
   bytes.put2 (nested_classes.size ());
 
   for (std::set<model_class *>::const_iterator i = nested_classes.begin ();
@@ -356,6 +355,12 @@
     }
 }
 
+int
+output_constant_pool::size ()
+{
+  return 2 + 8 * nested_classes.size ();
+}
+
 void
 output_constant_pool::update_descriptor (std::map<std::string, model_class *> &desc_map,
 					 model_type *t)
Index: bytecode/outpool.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/outpool.hh,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 outpool.hh
--- bytecode/outpool.hh 13 Jan 2005 03:18:34 -0000 1.1.2.1
+++ bytecode/outpool.hh 16 Jan 2005 04:34:24 -0000
@@ -1,6 +1,6 @@
 // A constant pool being generated.
 
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 //
 // This file is part of GCC.
 //
@@ -109,6 +109,9 @@
   /// Write the inner classes attribute.
   void write_inner_classes ();
 
+  /// Return the number of bytes used by this attribute.
+  int size ();
+
   /// Create a fake compilation unit object from this outgoing
   /// constant pool.  This can only be called after finish().  This is
   /// used when verifying bytecode after creating it.


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