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:
parent
492edb3ac5
commit
dba370a829
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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, "-"))
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user