diff options
-rw-r--r-- | gcc/java/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/java/boehm.c | 11 | ||||
-rw-r--r-- | gcc/java/class.c | 86 | ||||
-rw-r--r-- | gcc/java/gcj.texi | 22 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 3 | ||||
-rw-r--r-- | gcc/java/lang.c | 9 | ||||
-rw-r--r-- | gcc/java/lang.opt | 4 |
7 files changed, 125 insertions, 24 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 93d439a..6a0afa2 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -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: diff --git a/gcc/java/boehm.c b/gcc/java/boehm.c index 1bfe9e5..6ea5944 100644 --- a/gcc/java/boehm.c +++ b/gcc/java/boehm.c @@ -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; diff --git a/gcc/java/class.c b/gcc/java/class.c index 6d666e3..bce1677 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -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)); diff --git a/gcc/java/gcj.texi b/gcc/java/gcj.texi index 84659a54..ae7bcb7 100644 --- a/gcc/java/gcj.texi +++ b/gcc/java/gcj.texi @@ -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 diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index d421b51..285945c 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -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; diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 5f9a370..e1f822e 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -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, "-")) diff --git a/gcc/java/lang.opt b/gcc/java/lang.opt index 001a4a7..6ffb0aa 100644 --- a/gcc/java/lang.opt +++ b/gcc/java/lang.opt @@ -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 |