lang.opt (-freduced-reflection): New option.

* lang.opt (-freduced-reflection): New option.
	* lang.c (java_post_options): Generate an error if
	-freduced-reflection used with -fjni or -findirect-dispatch.
	* java-tree.h (flag_reduced_reflection): Declare new variable.
	* boehm.c (get_boehm_type_descriptor): Indicate all pointers
	if bitmap overflows and flag_reduced_reflection set.
	* class.c (uses_jv_markobj_p): New function.
	(make_class_data): Moved generation of vtable to before
	reflection data, generate less reflection data if
	flag_reduced_reflection set.
	* gcj.texi: Document -freduced-reflection.

From-SVN: r112095
This commit is contained in:
David Daney 2006-03-15 19:10:23 +00:00 committed by David Daney
parent 492edb3ac5
commit dba370a829
7 changed files with 125 additions and 24 deletions

View File

@ -1,3 +1,17 @@
2006-03-15 David Daney <ddaney@avtrex.com>
* lang.opt (-freduced-reflection): New option.
* lang.c (java_post_options): Generate an error if
-freduced-reflection used with -fjni or -findirect-dispatch.
* java-tree.h (flag_reduced_reflection): Declare new variable.
* boehm.c (get_boehm_type_descriptor): Indicate all pointers
if bitmap overflows and flag_reduced_reflection set.
* class.c (uses_jv_markobj_p): New function.
(make_class_data): Moved generation of vtable to before
reflection data, generate less reflection data if
flag_reduced_reflection set.
* gcj.texi: Document -freduced-reflection.
2006-03-15 Tom Tromey <tromey@redhat.com>
PR java/26638:

View File

@ -1,5 +1,5 @@
/* Functions related to the Boehm garbage collector.
Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 2000, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of GCC.
@ -184,7 +184,7 @@ get_boehm_type_descriptor (tree type)
/* If the object is all pointers, or if the part with pointers fits
in our bitmap, then we are ok. Otherwise we have to allocate it
a different way. */
if (all_bits_set != -1)
if (all_bits_set != -1 || (pointer_after_end && flag_reduced_reflection))
{
/* In this case the initial part of the object is all reference
fields, and the end of the object is all non-reference
@ -193,7 +193,12 @@ get_boehm_type_descriptor (tree type)
this:
value = DS_LENGTH | WORDS_TO_BYTES (last_set_index + 1);
DS_LENGTH is 0.
WORDS_TO_BYTES shifts by log2(bytes-per-pointer). */
WORDS_TO_BYTES shifts by log2(bytes-per-pointer).
In the case of flag_reduced_reflection and the bitmap would
overflow, we tell the gc that the object is all pointers so
that we don't have to emit reflection data for run time
marking. */
count = 0;
low = 0;
high = 0;

View File

@ -1548,6 +1548,16 @@ supers_all_compiled (tree type)
return 1;
}
/* The forth (index of 3) element in the vtable is the GC descriptor.
A value of 2 indicates that the class uses _Jv_MarkObj. */
static int
uses_jv_markobj_p(tree dtable)
{
tree v;
v = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (dtable), 3)->value;
return (2 == TREE_INT_CST_LOW (v));
}
void
make_class_data (tree type)
{
@ -1570,7 +1580,10 @@ make_class_data (tree type)
tree constant_pool_constructor;
tree interfaces = null_pointer_node;
int interface_len = 0;
int uses_jv_markobj = 0;
tree type_decl = TYPE_NAME (type);
tree id_main = get_identifier("main");
tree id_class = get_identifier("java.lang.Class");
/** Offset from start of virtual function table declaration
to where objects actually point at, following new g++ ABI. */
tree dtable_start_offset = build_int_cst (NULL_TREE,
@ -1579,6 +1592,22 @@ make_class_data (tree type)
this_class_addr = build_class_ref (type);
decl = TREE_OPERAND (this_class_addr, 0);
if (supers_all_compiled (type) && ! CLASS_INTERFACE (type_decl)
&& !flag_indirect_dispatch)
{
tree dtable = get_dispatch_table (type, this_class_addr);
uses_jv_markobj = uses_jv_markobj_p(dtable);
dtable_decl = build_dtable_decl (type);
DECL_INITIAL (dtable_decl) = dtable;
TREE_STATIC (dtable_decl) = 1;
DECL_ARTIFICIAL (dtable_decl) = 1;
DECL_IGNORED_P (dtable_decl) = 1;
TREE_PUBLIC (dtable_decl) = 1;
rest_of_decl_compilation (dtable_decl, 1, 0);
if (type == class_type_node)
class_dtable_decl = dtable_decl;
}
/* Build Field array. */
field = TYPE_FIELDS (type);
while (field && DECL_ARTIFICIAL (field))
@ -1589,9 +1618,11 @@ make_class_data (tree type)
{
if (! DECL_ARTIFICIAL (field))
{
tree init = make_field_value (field);
if (FIELD_STATIC (field))
{
/* We must always create reflection data for static fields
as it is used in the creation of the field itself. */
tree init = make_field_value (field);
tree initial = DECL_INITIAL (field);
static_field_count++;
static_fields = tree_cons (NULL_TREE, init, static_fields);
@ -1603,8 +1634,9 @@ make_class_data (tree type)
rest_of_decl_compilation (field, 1, 1);
DECL_INITIAL (field) = initial;
}
else
else if (uses_jv_markobj || !flag_reduced_reflection)
{
tree init = make_field_value (field);
instance_field_count++;
instance_fields = tree_cons (NULL_TREE, init, instance_fields);
}
@ -1643,9 +1675,35 @@ make_class_data (tree type)
which we don't have a .class file. */
if (METHOD_DUMMY (method))
continue;
init = make_method_value (method);
method_count++;
methods = tree_cons (NULL_TREE, init, methods);
/* Generate method reflection data if:
- !flag_reduced_reflection.
- <clinit> -- The runtime uses reflection to initialize the
class.
- Any method in class java.lang.Class -- Class.forName() and
perhaps other things require it.
- class$ -- It does not work if reflection data missing.
- main -- Reflection is used to find main(String[]) methods.
- public not static -- It is potentially part of an
interface. The runtime uses reflection data to build
interface dispatch tables. */
if (!flag_reduced_reflection
|| DECL_CLINIT_P (method)
|| DECL_NAME (type_decl) == id_class
|| DECL_NAME (method) == id_main
|| (METHOD_PUBLIC (method) && !METHOD_STATIC (method))
|| TYPE_DOT_CLASS (type) == method)
{
init = make_method_value (method);
method_count++;
methods = tree_cons (NULL_TREE, init, methods);
}
}
method_array_type = build_prim_array_type (method_type_node, method_count);
methods_decl = build_decl (VAR_DECL, mangled_classname ("_MT_", type),
@ -1657,21 +1715,6 @@ make_class_data (tree type)
DECL_IGNORED_P (methods_decl) = 1;
rest_of_decl_compilation (methods_decl, 1, 0);
if (supers_all_compiled (type) && ! CLASS_INTERFACE (type_decl)
&& !flag_indirect_dispatch)
{
tree dtable = get_dispatch_table (type, this_class_addr);
dtable_decl = build_dtable_decl (type);
DECL_INITIAL (dtable_decl) = dtable;
TREE_STATIC (dtable_decl) = 1;
DECL_ARTIFICIAL (dtable_decl) = 1;
DECL_IGNORED_P (dtable_decl) = 1;
TREE_PUBLIC (dtable_decl) = 1;
rest_of_decl_compilation (dtable_decl, 1, 0);
if (type == class_type_node)
class_dtable_decl = dtable_decl;
}
if (class_dtable_decl == NULL_TREE)
{
class_dtable_decl = build_dtable_decl (class_type_node);
@ -1781,7 +1824,8 @@ make_class_data (tree type)
CLASS_INTERFACE (type_decl) ? null_pointer_node : super);
PUSH_FIELD_VALUE (cons, "constants", constant_pool_constructor);
PUSH_FIELD_VALUE (cons, "methods",
build1 (ADDR_EXPR, method_ptr_type_node, methods_decl));
methods_decl == NULL_TREE ? null_pointer_node
: build1 (ADDR_EXPR, method_ptr_type_node, methods_decl));
PUSH_FIELD_VALUE (cons, "method_count",
build_int_cst (NULL_TREE, method_count));

View File

@ -546,6 +546,28 @@ This is convenient, as it means that things like
@code{Class.forName()} will search @samp{CLASSPATH} to find the
desired class.
@item -freduced-reflection
This option causes the code generated by @command{gcj} to contain a
reduced amount of the class meta-data used to support runtime
reflection. The cost of this savings is the loss of
the ability to use certain reflection capabilities of the standard
Java runtime environment. When set all meta-data except for that
which is needed to obtain correct runtime semantics is eliminated.
For code that does not use reflection (i.e. the methods in the
@code{java.lang.reflect} package), @code{-freduced-reflection}
will result in proper operation with a savings in executable code size.
JNI (@code{-fjni}) and the binary compatibility ABI
(@code{-findirect-dispatch}) do not work properly without full
reflection meta-data. Because of this, it is an error to use these options
with @code{-freduced-reflection}.
@strong{Caution:} If there is no reflection meta-data, code that uses
a @code{SecurityManager} may not work properly. Also calling
@code{Class.forName()} may fail if the calling method has no
reflection meta-data.
@end table

View File

@ -215,6 +215,9 @@ extern int flag_indirect_dispatch;
/* When zero, don't generate runtime array store checks. */
extern int flag_store_check;
/* When nonzero, generate only a limited set of class meta-data. */
extern int flag_reduced_reflection;
/* Encoding used for source files. */
extern const char *current_encoding;

View File

@ -608,6 +608,15 @@ java_post_options (const char **pfilename)
if (! flag_indirect_dispatch)
flag_verify_invocations = true;
if (flag_reduced_reflection)
{
if (flag_indirect_dispatch)
error ("-findirect-dispatch is incompatible "
"with -freduced-reflection");
if (flag_jni)
error ("-fjni is incompatible with -freduced-reflection");
}
/* Open input file. */
if (filename == 0 || !strcmp (filename, "-"))

View File

@ -164,6 +164,10 @@ Enable optimization of static class initialization code
foutput-class-dir=
Java Joined RejectNegative
freduced-reflection
Java Var(flag_reduced_reflection)
Reduce the amount of reflection meta-data generated
fstore-check
Java Var(flag_store_check) Init(1)
Enable assignability checks for stores into object arrays