From b4e18eee4b56ed8d4003d1fb92acb5f7dbf43748 Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Fri, 2 Feb 2007 16:34:17 +0000 Subject: [PATCH] expr.c (expand_byte_code): Call cache_this_class_ref() and cache_cpool_data_ref(). 2007-02-02 Andrew Haley * 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. From-SVN: r121508 --- gcc/java/ChangeLog | 15 ++++++++++ gcc/java/class.c | 47 ++++++++++++++++++++++++++++-- gcc/java/constants.c | 68 ++++++++++++++++++++++++-------------------- gcc/java/decl.c | 16 ----------- gcc/java/expr.c | 28 +++++++++++++++++- gcc/java/java-tree.h | 2 ++ 6 files changed, 126 insertions(+), 50 deletions(-) diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 56ab178a1ef..99e629b4a57 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,18 @@ +2007-02-02 Andrew Haley + + * 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 * class.c (is_compiled_class): Move check to avoid reloading diff --git a/gcc/java/class.c b/gcc/java/class.c index 7a14aca6496..ec94a3c9534 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 70e5321de00..ca138f62130 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 fcf63539092..e38c4bcbdd1 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 c51b5cd0b04..f7d35c68a25 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 1f717646473..f564b5918fd 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, -- 2.30.2