diff options
-rw-r--r-- | gcc/java/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/java/class.c | 47 | ||||
-rw-r--r-- | gcc/java/constants.c | 68 | ||||
-rw-r--r-- | gcc/java/decl.c | 16 | ||||
-rw-r--r-- | gcc/java/expr.c | 28 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 2 |
6 files changed, 126 insertions, 50 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 56ab178..99e629b 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,18 @@ +2007-02-02 Andrew Haley <aph@redhat.com> + + * expr.c (expand_byte_code): Call cache_this_class_ref() and + cache_cpool_data_ref(). + Set TYPE_CPOOL_DATA_REF. + (cache_cpool_data_ref): New function. + * constants.c (build_ref_from_constant_pool): Remove special-case + code for flag_indirect_classes. + (build_constant_data_ref): Move special-case code for + flag_indirect_classes here from build_ref_from_constant_pool. + * decl.c (finish_method): Move class initialization from here to + cache_this_class_ref. + * class.c (cache_this_class_ref): New function. + (build_class_ref): Use this_classdollar for the ouput class. + 2007-02-02 David Daney <ddaney@avtrex.com> * class.c (is_compiled_class): Move check to avoid reloading diff --git a/gcc/java/class.c b/gcc/java/class.c index 7a14aca..ec94a3c 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -110,6 +110,10 @@ static GTY(()) tree class_roots[4]; static GTY(()) VEC(tree,gc) *registered_class; +/* A tree that returns the address of the class$ of the class + currently being compiled. */ +static GTY(()) tree this_classdollar; + /* Return the node that most closely represents the class whose name is IDENT. Start the search from NODE (followed by its siblings). Return NULL if an appropriate node does not exist. */ @@ -1004,6 +1008,45 @@ build_classdollar_field (tree type) return decl; } +/* Create a local variable that holds the the current class$. */ + +void +cache_this_class_ref (tree fndecl) +{ + if (optimize) + { + tree classdollar_field; + if (flag_indirect_classes) + classdollar_field = build_classdollar_field (output_class); + else + classdollar_field = build_static_class_ref (output_class); + + this_classdollar = build_decl (VAR_DECL, NULL_TREE, + TREE_TYPE (classdollar_field)); + + java_add_local_var (this_classdollar); + java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (this_classdollar), + this_classdollar, classdollar_field)); + } + else + this_classdollar = build_classdollar_field (output_class); + + /* Prepend class initialization for static methods reachable from + other classes. */ + if (METHOD_STATIC (fndecl) + && (! METHOD_PRIVATE (fndecl) + || INNER_CLASS_P (DECL_CONTEXT (fndecl))) + && ! DECL_CLINIT_P (fndecl) + && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl)))) + { + tree init = build3 (CALL_EXPR, void_type_node, + build_address_of (soft_initclass_node), + build_tree_list (NULL_TREE, this_classdollar), + NULL_TREE); + java_add_stmt (init); + } +} + /* Build a reference to the class TYPE. Also handles primitive types and array types. */ @@ -1023,7 +1066,7 @@ build_class_ref (tree type) return build_indirect_class_ref (type); if (type == output_class && flag_indirect_classes) - return build_classdollar_field (type); + return this_classdollar; if (TREE_CODE (type) == RECORD_TYPE) return build_static_class_ref (type); @@ -2443,7 +2486,7 @@ layout_class_methods (tree this_class) if (TYPE_NVIRTUALS (this_class)) return; - + super_class = CLASSTYPE_SUPER (this_class); if (super_class) diff --git a/gcc/java/constants.c b/gcc/java/constants.c index 70e5321..ca138f6 100644 --- a/gcc/java/constants.c +++ b/gcc/java/constants.c @@ -36,7 +36,6 @@ static void set_constant_entry (CPool *, int, int, jword); static int find_tree_constant (CPool *, int, tree); static int find_name_and_type_constant (CPool *, tree, tree); static tree get_tag_node (int); -static tree build_constant_data_ref (void); /* Set the INDEX'th constant in CPOOL to have the given TAG and VALUE. */ @@ -424,14 +423,36 @@ alloc_class_constant (tree clas) /* Return the decl of the data array of the current constant pool. */ -static tree -build_constant_data_ref (void) +tree +build_constant_data_ref (bool indirect) { - tree decl = TYPE_CPOOL_DATA_REF (output_class); + if (indirect) + { + tree d; + tree cpool_type = build_array_type (ptr_type_node, NULL_TREE); + tree decl = build_class_ref (output_class); + tree klass = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (decl)), + decl); + tree constants = build3 (COMPONENT_REF, + TREE_TYPE (constants_field_decl_node), klass, + constants_field_decl_node, + NULL_TREE); + tree data = build3 (COMPONENT_REF, + TREE_TYPE (constants_data_field_decl_node), + constants, + constants_data_field_decl_node, + NULL_TREE); - if (decl == NULL_TREE) + TREE_THIS_NOTRAP (klass) = 1; + data = fold_convert (build_pointer_type (cpool_type), data); + d = build1 (INDIRECT_REF, cpool_type, data); + TREE_INVARIANT (d) = 1; + + return d; + } + else { - tree type; + tree type, decl; tree decl_name = mangled_classname ("_CD_", output_class); /* Build a type with unspecified bounds. The will make sure @@ -446,10 +467,9 @@ build_constant_data_ref (void) decl = build_decl (VAR_DECL, decl_name, type); TREE_STATIC (decl) = 1; - TYPE_CPOOL_DATA_REF (output_class) = decl; - } - return decl; + return decl; + } } /* Get the pointer value at the INDEX'th element of the constant pool. */ @@ -457,27 +477,13 @@ build_constant_data_ref (void) tree build_ref_from_constant_pool (int index) { - tree d = build_constant_data_ref (); - tree i = build_int_cst (NULL_TREE, index); - if (flag_indirect_classes) - { - tree decl = build_class_ref (output_class); - tree klass = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (decl)), - decl); - tree constants = build3 (COMPONENT_REF, - TREE_TYPE (constants_field_decl_node), klass, - constants_field_decl_node, - NULL_TREE); - tree data = build3 (COMPONENT_REF, - TREE_TYPE (constants_data_field_decl_node), - constants, - constants_data_field_decl_node, - NULL_TREE); - data = fold_convert (build_pointer_type (TREE_TYPE (d)), data); - d = build1 (INDIRECT_REF, TREE_TYPE (d), data); - /* FIXME: These should be cached. */ - TREE_INVARIANT (d) = 1; - } + tree i; + tree d = TYPE_CPOOL_DATA_REF (output_class); + + if (d == NULL_TREE) + d = build_constant_data_ref (flag_indirect_classes); + + i = build_int_cst (NULL_TREE, index); d = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i, NULL_TREE, NULL_TREE); TREE_INVARIANT (d) = 1; @@ -557,7 +563,7 @@ build_constants_constructor (void) tags_list = tree_cons (NULL_TREE, get_tag_node (0), tags_list); data_list = tree_cons (NULL_TREE, null_pointer_node, data_list); - data_decl = build_constant_data_ref (); + data_decl = build_constant_data_ref (false); TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type); DECL_INITIAL (data_decl) = build_constructor_from_list (TREE_TYPE (data_decl), data_list); diff --git a/gcc/java/decl.c b/gcc/java/decl.c index fcf6353..e38c4bc 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -1876,22 +1876,6 @@ finish_method (tree fndecl) build2 (TRY_FINALLY_EXPR, void_type_node, *tp, exit)); } - /* Prepend class initialization for static methods reachable from - other classes. */ - if (METHOD_STATIC (fndecl) - && (! METHOD_PRIVATE (fndecl) - || INNER_CLASS_P (DECL_CONTEXT (fndecl))) - && ! DECL_CLINIT_P (fndecl) - && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl)))) - { - tree clas = DECL_CONTEXT (fndecl); - tree init = build3 (CALL_EXPR, void_type_node, - build_address_of (soft_initclass_node), - build_tree_list (NULL_TREE, build_class_ref (clas)), - NULL_TREE); - *tp = build2 (COMPOUND_EXPR, TREE_TYPE (*tp), init, *tp); - } - /* Convert function tree to GENERIC prior to inlining. */ java_genericize (fndecl); diff --git a/gcc/java/expr.c b/gcc/java/expr.c index c51b5cd..f7d35c6 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -83,6 +83,7 @@ static tree build_java_throw_out_of_bounds_exception (tree); static tree build_java_check_indexed_type (tree, tree); static unsigned char peek_opcode_at_pc (struct JCF *, int, int); static void promote_arguments (void); +static void cache_cpool_data_ref (void); static GTY(()) tree operand_type[59]; @@ -3151,6 +3152,8 @@ expand_byte_code (JCF *jcf, tree method) return; promote_arguments (); + cache_this_class_ref (method); + cache_cpool_data_ref (); /* Translate bytecodes. */ linenumber_pointer = linenumber_table; @@ -3223,7 +3226,7 @@ expand_byte_code (JCF *jcf, tree method) PC = process_jvm_instruction (PC, byte_ops, length); maybe_poplevels (PC); } /* for */ - + if (dead_code_index != -1) { /* We've just reached the end of a region of dead code. */ @@ -3791,4 +3794,27 @@ promote_arguments (void) } } +/* Create a local variable that points to the constant pool. */ + +static void +cache_cpool_data_ref (void) +{ + if (optimize) + { + tree cpool; + tree d = build_constant_data_ref (flag_indirect_classes); + tree cpool_ptr = build_decl (VAR_DECL, NULL_TREE, + build_pointer_type (TREE_TYPE (d))); + java_add_local_var (cpool_ptr); + TREE_INVARIANT (cpool_ptr) = 1; + TREE_CONSTANT (cpool_ptr) = 1; + + java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (cpool_ptr), + cpool_ptr, build_address_of (d))); + cpool = build1 (INDIRECT_REF, TREE_TYPE (d), cpool_ptr); + TREE_THIS_NOTRAP (cpool) = 1; + TYPE_CPOOL_DATA_REF (output_class) = cpool; + } +} + #include "gt-java-expr.h" diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 1f71764..f564b59 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -1129,10 +1129,12 @@ extern void layout_class (tree); extern int get_interface_method_index (tree, tree); extern tree layout_class_method (tree, tree, tree, tree); extern void layout_class_methods (tree); +extern void cache_this_class_ref (tree); extern tree build_class_ref (tree); extern tree build_dtable_decl (tree); extern tree build_internal_class_name (tree); extern tree build_constants_constructor (void); +extern tree build_constant_data_ref (bool); extern tree build_ref_from_constant_pool (int); extern tree build_utf8_ref (tree); extern tree ident_subst (const char *, int, const char *, int, int, |