diff options
author | aph <aph@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-04-24 15:33:16 +0000 |
---|---|---|
committer | aph <aph@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-04-24 15:33:16 +0000 |
commit | 2934c6b590ded021f96a83dbb8b1100acedde68c (patch) | |
tree | 843ad6f8c55847b78d8168eb919c303e362e94d6 /gcc/java/class.c | |
parent | 2770736a425f430981ababc76e39565b28599ec4 (diff) | |
download | gcc-2934c6b590ded021f96a83dbb8b1100acedde68c.tar.gz |
2006-04-21 Andrew Haley <aph@redhat.com>
* lang.c (java_init): Handle flag_indirect_classes.
* jvgenmain.c: Use "class$$" instead of "class$".
* mangle.c (java_mangle_decl): Accept RECORD_TYPEs sw well as
DECLs.
(mangle_class_field): Special case "class$$" as well as "class$".
* constants.c (build_ref_from_constant_pool): If
flag_indirect_classes, generate a ref into the heap.
* decl.c (constants_field_decl_node,
constants_data_field_decl_node): New.
* class.c (build_static_class_ref): New.
(build_classdollar_field): Factor out from build_class_ref().
(make_field_value): Handle static fields in heap.
(make_class_data): Make sure we get a static ref to class.
Make class initializer const if flag_indirect_classes.
(register_class): Build a class_ref for initialization if
flag_indirect_classes.
(emit_indirect_register_classes): New.
2006-04-21 Andrew Haley <aph@redhat.com>
* include/execution.h (struct _Jv_CompiledEngine): Define for
compiled classes.
* java/lang/natClassLoader.cc (_Jv_RegisterClasses): Call
_Jv_RegisterLibForGc.
(_Jv_RegisterClasses_Counted): Likewise.
(_Jv_NewClassFromInitializer): New.
(_Jv_RegisterNewClasses): New.
* sources.am: Regenerate.
* boehm.cc (_Jv_GC_has_static_roots): new.
(_Jv_InitGC): Call GC_register_has_static_roots_callback.
(filename_node, find_file, _Jv_print_gc_store, new_node,
_Jv_GC_has_static_roots, _Jv_RegisterLibForGc): New.
* scripts/makemake.tcl: Add -fno-indirect-classes.
* Makefile.in: Regenerate.
* link.cc (resolve_pool_entry): Allocate constant pool.
Allocate fields.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@113224 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java/class.c')
-rw-r--r-- | gcc/java/class.c | 203 |
1 files changed, 165 insertions, 38 deletions
diff --git a/gcc/java/class.c b/gcc/java/class.c index a6074518f59..fe52e67d4ac 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -953,6 +953,71 @@ build_indirect_class_ref (tree type) return convert (promote_type (class_ptr_type), cl); } +static tree +build_static_class_ref (tree type) +{ + tree decl_name, decl, ref; + + if (TYPE_SIZE (type) == error_mark_node) + return null_pointer_node; + decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)), + "", '/', '/', ".class$$"); + decl = IDENTIFIER_GLOBAL_VALUE (decl_name); + if (decl == NULL_TREE) + { + decl = build_decl (VAR_DECL, decl_name, class_type_node); + TREE_STATIC (decl) = 1; + if (! flag_indirect_classes) + TREE_PUBLIC (decl) = 1; + DECL_IGNORED_P (decl) = 1; + DECL_ARTIFICIAL (decl) = 1; + if (is_compiled_class (type) == 1) + DECL_EXTERNAL (decl) = 1; + MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl); + DECL_CLASS_FIELD_P (decl) = 1; + DECL_CONTEXT (decl) = type; + + /* ??? We want to preserve the DECL_CONTEXT we set just above, + that that means not calling pushdecl_top_level. */ + IDENTIFIER_GLOBAL_VALUE (decl_name) = decl; + } + + ref = build1 (ADDR_EXPR, class_ptr_type, decl); + return ref; +} + +static tree +build_classdollar_field (tree type) +{ + tree decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)), + "", '/', '/', ".class$"); + tree decl = IDENTIFIER_GLOBAL_VALUE (decl_name); + + if (decl == NULL_TREE) + { + decl + = build_decl (VAR_DECL, decl_name, + (build_type_variant + (build_pointer_type + (build_type_variant (class_type_node, + /* const */ 1, 0)), + /* const */ 1, 0))); + TREE_STATIC (decl) = 1; + TREE_INVARIANT (decl) = 1; + TREE_CONSTANT (decl) = 1; + TREE_READONLY (decl) = 1; + TREE_PUBLIC (decl) = 1; + DECL_IGNORED_P (decl) = 1; + DECL_ARTIFICIAL (decl) = 1; + MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl); + IDENTIFIER_GLOBAL_VALUE (decl_name) = decl; + DECL_CLASS_FIELD_P (decl) = 1; + DECL_CONTEXT (decl) = type; + } + + return decl; +} + /* Build a reference to the class TYPE. Also handles primitive types and array types. */ @@ -962,7 +1027,7 @@ build_class_ref (tree type) int is_compiled = is_compiled_class (type); if (is_compiled) { - tree ref, decl_name, decl; + tree ref, decl; if (TREE_CODE (type) == POINTER_TYPE) type = TREE_TYPE (type); @@ -971,34 +1036,15 @@ build_class_ref (tree type) && TREE_CODE (type) == RECORD_TYPE) return build_indirect_class_ref (type); + if (type == output_class && flag_indirect_classes) + return build_classdollar_field (type); + if (TREE_CODE (type) == RECORD_TYPE) - { - if (TYPE_SIZE (type) == error_mark_node) - return null_pointer_node; - decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)), - "", '/', '/', ".class"); - decl = IDENTIFIER_GLOBAL_VALUE (decl_name); - if (decl == NULL_TREE) - { - decl = build_decl (VAR_DECL, decl_name, class_type_node); - TREE_STATIC (decl) = 1; - TREE_PUBLIC (decl) = 1; - DECL_IGNORED_P (decl) = 1; - DECL_ARTIFICIAL (decl) = 1; - if (is_compiled == 1) - DECL_EXTERNAL (decl) = 1; - MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl); - DECL_CLASS_FIELD_P (decl) = 1; - DECL_CONTEXT (decl) = type; - - /* ??? We want to preserve the DECL_CONTEXT we set just above, - that that means not calling pushdecl_top_level. */ - IDENTIFIER_GLOBAL_VALUE (decl_name) = decl; - } - } + return build_static_class_ref (type); else { const char *name; + tree decl_name; char buffer[25]; if (flag_emit_class_files) { @@ -1296,16 +1342,22 @@ make_field_value (tree fdecl) PUSH_FIELD_VALUE (finit, "accflags", build_int_cst (NULL_TREE, flags)); PUSH_FIELD_VALUE (finit, "bsize", TYPE_SIZE_UNIT (TREE_TYPE (fdecl))); - PUSH_FIELD_VALUE - (finit, "info", - build_constructor_from_list (field_info_union_node, - build_tree_list - ((FIELD_STATIC (fdecl) - ? TREE_CHAIN (TYPE_FIELDS (field_info_union_node)) - : TYPE_FIELDS (field_info_union_node)), - (FIELD_STATIC (fdecl) - ? build_address_of (fdecl) - : byte_position (fdecl))))); + { + tree field_address = integer_zero_node; + if (! flag_indirect_classes && FIELD_STATIC (fdecl)) + field_address = build_address_of (fdecl); + + PUSH_FIELD_VALUE + (finit, "info", + build_constructor_from_list (field_info_union_node, + build_tree_list + ((FIELD_STATIC (fdecl) + ? TREE_CHAIN (TYPE_FIELDS (field_info_union_node)) + : TYPE_FIELDS (field_info_union_node)), + (FIELD_STATIC (fdecl) + ? field_address + : byte_position (fdecl))))); + } FINISH_RECORD_CONSTRUCTOR (finit); return finit; @@ -1599,7 +1651,7 @@ make_class_data (tree type) tree dtable_start_offset = build_int_cst (NULL_TREE, 2 * POINTER_SIZE / BITS_PER_UNIT); - this_class_addr = build_class_ref (type); + this_class_addr = build_static_class_ref (type); decl = TREE_OPERAND (this_class_addr, 0); if (supers_all_compiled (type) && ! CLASS_INTERFACE (type_decl) @@ -1613,7 +1665,8 @@ make_class_data (tree type) 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 (! flag_indirect_classes) + rest_of_decl_compilation (dtable_decl, 1, 0); if (type == class_type_node) class_dtable_decl = dtable_decl; } @@ -1958,8 +2011,21 @@ make_class_data (tree type) if (flag_hash_synchronization && POINTER_SIZE < 64) DECL_ALIGN (decl) = 64; + if (flag_indirect_classes) + { + TREE_READONLY (decl) = 1; + TREE_CONSTANT (DECL_INITIAL (decl)) = 1; + } + rest_of_decl_compilation (decl, 1, 0); + { + tree classdollar_field = build_classdollar_field (type); + if (!flag_indirect_classes) + DECL_INITIAL (classdollar_field) = build_static_class_ref (type); + rest_of_decl_compilation (classdollar_field, 1, 0); + } + TYPE_OTABLE_DECL (type) = NULL_TREE; TYPE_ATABLE_DECL (type) = NULL_TREE; TYPE_CTABLE_DECL (type) = NULL_TREE; @@ -2465,10 +2531,65 @@ register_class (void) if (!registered_class) registered_class = VEC_alloc (tree, gc, 8); - node = TREE_OPERAND (build_class_ref (current_class), 0); + if (flag_indirect_classes) + node = current_class; + else + node = TREE_OPERAND (build_class_ref (current_class), 0); VEC_safe_push (tree, gc, registered_class, node); } +/* Emit a function that calls _Jv_NewClassFromInitializer for every + class. */ + +static void +emit_indirect_register_classes (tree *list_p) +{ + tree klass, t, register_class_fn; + int i; + + tree init = NULL_TREE; + int size = VEC_length (tree, registered_class) * 2 + 1; + tree class_array_type + = build_prim_array_type (ptr_type_node, size); + tree cdecl = build_decl (VAR_DECL, get_identifier ("_Jv_CLS"), + class_array_type); + tree reg_class_list; + for (i = 0; VEC_iterate (tree, registered_class, i, klass); ++i) + { + init = tree_cons (NULL_TREE, + fold_convert (ptr_type_node, + build_static_class_ref (klass)), init); + init = tree_cons + (NULL_TREE, + fold_convert (ptr_type_node, + build_address_of (build_classdollar_field (klass))), + init); + } + init = tree_cons (NULL_TREE, integer_zero_node, init); + DECL_INITIAL (cdecl) = build_constructor_from_list (class_array_type, + nreverse (init)); + TREE_CONSTANT (DECL_INITIAL (cdecl)) = 1; + TREE_STATIC (cdecl) = 1; + DECL_ARTIFICIAL (cdecl) = 1; + DECL_IGNORED_P (cdecl) = 1; + TREE_READONLY (cdecl) = 1; + TREE_CONSTANT (cdecl) = 1; + rest_of_decl_compilation (cdecl, 1, 0); + reg_class_list = fold_convert (ptr_type_node, build_address_of (cdecl)); + + t = build_function_type_list (void_type_node, + build_pointer_type (ptr_type_node), NULL); + t = build_decl (FUNCTION_DECL, + get_identifier ("_Jv_RegisterNewClasses"), t); + TREE_PUBLIC (t) = 1; + DECL_EXTERNAL (t) = 1; + register_class_fn = t; + t = tree_cons (NULL, reg_class_list, NULL); + t = build_function_call_expr (register_class_fn, t); + append_to_statement_list (t, list_p); +} + + /* Emit something to register classes at start-up time. The preferred mechanism is through the .jcr section, which contain @@ -2485,6 +2606,12 @@ emit_register_classes (tree *list_p) if (registered_class == NULL) return; + if (flag_indirect_classes) + { + emit_indirect_register_classes (list_p); + return; + } + /* TARGET_USE_JCR_SECTION defaults to 1 if SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, else 0. Some targets meet those conditions but lack suitable crtbegin/end objects or linker support. These |