diff options
author | Andrew Haley <aph@redhat.com> | 2003-10-01 16:22:13 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2003-10-01 16:22:13 +0000 |
commit | 9dfc2ec225a5a8f0a5d2a9b5853d0a19d728e129 (patch) | |
tree | 2dba069aa1abbb8cef2f212c67ca484cf5f8a674 /gcc/java/expr.c | |
parent | 530ce5517ce00a43761d303a614b25d3371dd030 (diff) | |
download | gcc-9dfc2ec225a5a8f0a5d2a9b5853d0a19d728e129.zip gcc-9dfc2ec225a5a8f0a5d2a9b5853d0a19d728e129.tar.gz gcc-9dfc2ec225a5a8f0a5d2a9b5853d0a19d728e129.tar.bz2 |
jcf-parse.c (java_parse_file): Write otable and atable.
2003-10-01 Andrew Haley <aph@redhat.com>
* jcf-parse.c (java_parse_file): Write otable and atable.
* java-tree.h (atable_methods): New.
(atable_decl): New.
(atable_syms_decl): New.
(enum java_tree_index): Add JTI_ATABLE_METHODS, JTI_ATABLE_DECL,
JTI_ATABLE_SYMS_DECL. Rename JTI_METHOD_SYMBOL* to JTI_SYMBOL*.
(symbol_*type): Rename method_symbol* to symbol*type.
(emit_offset_symbol_table): Delete.
(emit_symbol_table): New.
(get_symbol_table_index): New.
(atable_type): New.
* expr.c (build_field_ref): Handle flag_indirect_dispatch.
(build_known_method_ref): Likewise.
(get_symbol_table_index): Rename from get_offset_table_index.
Parameterize to allow re-use by differing types of symbol table.
(build_invokevirtual): Pass table to get_offset_table_index.
* decl.c (java_init_decl_processing): Push types and decls for
atable and atable_syyms.
* class.c (build_static_field_ref): Handle flag_indirect_dispatch.
(make_class_data): Add new fields atable and atable_syms.
(emit_symbol_table): Rename from emit_offset_symbol_table.
Parameterize to allow re-use by different types of symbol table.
(build_symbol_entry): Renamed from build_method_symbols_entry.
2003-10-01 Andrew Haley <aph@redhat.com>
* java/lang/natClass.cc (initializeClass): Check for otable and
atable.
(_Jv_LinkOffsetTable): Check for existence of atable. Rewrite
loops using for(). Search superinterfaces. Check for fields as
well as methods. Initialize atable as well as otable: check for
static methods as well as virtual methods.
* java/lang/Class.h (struct _Jv_AddressTable): New.
(atable): New.
(atable_syms): New.
* include/jvm.h (_Jv_equalUtf8Consts): constify.
* prims.cc (_Jv_equalUtf8Consts): constify.
From-SVN: r71979
Diffstat (limited to 'gcc/java/expr.c')
-rw-r--r-- | gcc/java/expr.c | 65 |
1 files changed, 49 insertions, 16 deletions
diff --git a/gcc/java/expr.c b/gcc/java/expr.c index 994a8c5..2c9ac09 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -84,7 +84,6 @@ static tree build_java_check_indexed_type (tree, tree); static tree case_identity (tree, tree); static unsigned char peek_opcode_at_pc (struct JCF *, int, int); static int emit_init_test_initialization (void **entry, void * ptr); -static int get_offset_table_index (tree); static GTY(()) tree operand_type[59]; @@ -1510,6 +1509,25 @@ build_field_ref (tree self_value, tree self_class, tree name) tree base_type = promote_type (base_class); if (base_type != TREE_TYPE (self_value)) self_value = fold (build1 (NOP_EXPR, base_type, self_value)); + if (flag_indirect_dispatch + && current_class != self_class) + /* FIXME: current_class != self_class is not exactly the right + test. What we really want to know is whether self_class is + in the same translation unit as current_class. If it is, + we can make a direct reference. */ + { + tree otable_index + = build_int_2 + (get_symbol_table_index (field_decl, &otable_methods), 0); + tree field_offset = build (ARRAY_REF, integer_type_node, otable_decl, + otable_index); + tree address + = fold (build (PLUS_EXPR, + build_pointer_type (TREE_TYPE (field_decl)), + self_value, field_offset)); + return fold (build1 (INDIRECT_REF, TREE_TYPE (field_decl), address)); + } + self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)), self_value, check); return fold (build (COMPONENT_REF, TREE_TYPE (field_decl), @@ -1744,8 +1762,19 @@ build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED, tree func; if (is_compiled_class (self_type)) { - make_decl_rtl (method, NULL); - func = build1 (ADDR_EXPR, method_ptr_type_node, method); + if (!flag_indirect_dispatch + || (!TREE_PUBLIC (method) && DECL_CONTEXT (method))) + { + make_decl_rtl (method, NULL); + func = build1 (ADDR_EXPR, method_ptr_type_node, method); + } + else + { + tree table_index = build_int_2 (get_symbol_table_index + (method, &atable_methods), 0); + func = build (ARRAY_REF, method_ptr_type_node, atable_decl, + table_index); + } } else { @@ -1816,27 +1845,29 @@ invoke_build_dtable (int is_invoke_interface, tree arg_list) return dtable; } -/* Determine the index in the virtual offset table (otable) for a call to - METHOD. If this method has not been seen before, it will be added to the - otable_methods. If it has, the existing otable slot will be reused. */ +/* Determine the index in SYMBOL_TABLE for a reference to the decl + T. If this decl has not been seen before, it will be added to the + otable_methods. If it has, the existing table slot will be + reused. */ -static int -get_offset_table_index (tree method) +int +get_symbol_table_index (tree t, tree *symbol_table) { int i = 1; tree method_list; - - if (otable_methods == NULL_TREE) + + if (*symbol_table == NULL_TREE) { - otable_methods = build_tree_list (method, method); + *symbol_table = build_tree_list (t, t); return 1; } - method_list = otable_methods; + method_list = *symbol_table; while (1) { - if (TREE_VALUE (method_list) == method) + tree value = TREE_VALUE (method_list); + if (value == t) return i; i++; if (TREE_CHAIN (method_list) == NULL_TREE) @@ -1845,7 +1876,7 @@ get_offset_table_index (tree method) method_list = TREE_CHAIN (method_list); } - TREE_CHAIN (method_list) = build_tree_list (method, method); + TREE_CHAIN (method_list) = build_tree_list (t, t); return i; } @@ -1860,7 +1891,8 @@ build_invokevirtual (tree dtable, tree method) if (flag_indirect_dispatch) { - otable_index = build_int_2 (get_offset_table_index (method), 0); + otable_index + = build_int_2 (get_symbol_table_index (method, &otable_methods), 0); method_index = build (ARRAY_REF, integer_type_node, otable_decl, otable_index); } @@ -1924,7 +1956,8 @@ build_invokeinterface (tree dtable, tree method) if (flag_indirect_dispatch) { - otable_index = build_int_2 (get_offset_table_index (method), 0); + otable_index + = build_int_2 (get_symbol_table_index (method, &otable_methods), 0); idx = build (ARRAY_REF, integer_type_node, otable_decl, otable_index); } else |