[gcjx] Patch: FYI: fix attribute lengths
Tom Tromey
tromey@redhat.com
Sun Jan 16 04:36:00 GMT 2005
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.
More information about the Java-patches
mailing list