diff options
author | Alexandre Petit-Bianco <apbianco@redhat.com> | 2001-08-08 21:19:12 -0700 |
---|---|---|
committer | Alexandre Petit-Bianco <apbianco@gcc.gnu.org> | 2001-08-08 21:19:12 -0700 |
commit | 4009bb7d50ece62b164d3717d218ed16b51bddf4 (patch) | |
tree | 1c89de048bc9427066e52a374b05b125c6ec6ba2 /gcc/java/expr.c | |
parent | 6351543d13052c85f87b6e1e8af0273279a5c771 (diff) | |
download | gcc-4009bb7d50ece62b164d3717d218ed16b51bddf4.zip gcc-4009bb7d50ece62b164d3717d218ed16b51bddf4.tar.gz gcc-4009bb7d50ece62b164d3717d218ed16b51bddf4.tar.bz2 |
check-init.c (flags.h): Include
2001-08-08 Alexandre Petit-Bianco <apbianco@redhat.com>
* check-init.c (flags.h): Include
(check_init): Don't report uninitialized static class
initialization flags, don't free bit index when doing static class
initialization optimization.
(check_for_initialization): Return type changed to `unsigned int.'
(attach_initialized_static_class): New function.
* class.c (add_method_1): Create the initialized static class
table if necessary.
(finish_class): Always emit deferred inline methods.
* decl.c (emit_init_test_initialization): Moved to expr.c
(complete_start_java_method): Don't traverse
DECL_FUNCTION_INIT_TEST_TABLE.
(lang_mark_tree): Mark hash tables in function decls.
* expr.c (emit_init_test_initialization): Moved from decl.c.
(build_class_init): Create LAG_DECL_SPECIFIC for the static class
initialization flag, set DECL_CONTEXT and
LOCAL_CLASS_INITIALIZATION_FLAG.
(java_lang_expand_expr): Emit initialization code for static class
initialized flags when entering block, if necessary.
* gcj.texi (-fno-optimize-static-class-initialization): Documented.
* java-tree.h (flag_optimize_sci): New global variable declaration.
(DECL_FUNCTION_INITIALIZED_CLASS_TABLE): New macro.
(DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND): Likewise.
(LOCAL_FINAL_P): Fixed typo in comment.
(FINAL_VARIABLE_P): Likewise.
(LOCAL_CLASS_INITIALIZATIO_FLAG): New macro.
(LOCAL_CLASS_INITIALIZATIO_FLAG_P): Likewise.
(struct lang_decl): New fields `ict', `smic' and `cif.'
(check_for_initialization): New returned value for global.
(attach_initialized_static_class): New global function.
(STATIC_CLASS_INIT_OPT_P): New macro.
* lang-options.h (-fno-optimize-static-class-initialization): New flag.
* lang.c (java_decode_option): Handle
`-fno-optimize-static-class-initialization'
* parse.y (start_complete_expand_method): New function.
(java_expand_method_bodies): Likewise.
(attach_init_test_initialization_flags): Likewise.
(adjust_init_test_initialization): Likewise.
(emit_test_initialization): Likewise.
(java_complete_expand_methods): Nullify abstract and native method
bodies.
(java_complete_expand_method): New locals `fbody', `block_body'
and `exception_copy.' Reorganized: directly return on empty method
bodies, call `start_complete_expand_method', remember definitely
initialized static class in function, don't expand method bodies.
(java_expand_classes): Call `java_expand_method_bodies' before
`finish_class' when compiling to native.
(resolve_expression_name): Use `orig' after building outer class
field access.
(patch_invoke): Remember static method invokations.
(http://gcc.gnu.org/ml/gcc-patches/2001-08/msg00454.html)
From-SVN: r44733
Diffstat (limited to 'gcc/java/expr.c')
-rw-r--r-- | gcc/java/expr.c | 69 |
1 files changed, 65 insertions, 4 deletions
diff --git a/gcc/java/expr.c b/gcc/java/expr.c index c9b4a3c..f7056fe 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -82,6 +82,8 @@ static tree build_java_check_indexed_type PARAMS ((tree, tree)); static tree java_array_data_offset PARAMS ((tree)); static tree case_identity PARAMS ((tree, tree)); static unsigned char peek_opcode_at_pc PARAMS ((struct JCF *, int, int)); +static bool emit_init_test_initialization PARAMS ((struct hash_entry *, + PTR ptr)); static tree operand_type[59]; extern struct obstack permanent_obstack; @@ -1710,10 +1712,20 @@ build_class_init (clas, expr) TRUE, NULL); if (ite->init_test_decl == 0) - ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE, - boolean_type_node); - /* Tell the check-init code to ignore this decl. */ - DECL_BIT_INDEX(ite->init_test_decl) = -1; + { + /* Build a declaration and mark it as a flag used to track + static class initializations. */ + ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE, + boolean_type_node); + MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (ite->init_test_decl); + LOCAL_CLASS_INITIALIZATION_FLAG (ite->init_test_decl) = 1; + DECL_CONTEXT (ite->init_test_decl) = current_function_decl; + + /* Tell the check-init code to ignore this decl when not + optimizing class initialization. */ + if (!STATIC_CLASS_INIT_OPT_P ()) + DECL_BIT_INDEX(ite->init_test_decl) = -1; + } init = build (CALL_EXPR, void_type_node, build_address_of (soft_initclass_node), @@ -2459,16 +2471,31 @@ java_lang_expand_expr (exp, target, tmode, modifier) { tree local; tree body = BLOCK_EXPR_BODY (exp); + /* Set to 1 or more when we found a static class + initialization flag. */ + int found_class_initialization_flag = 0; + pushlevel (2); /* 2 and above */ expand_start_bindings (0); local = BLOCK_EXPR_DECLS (exp); while (local) { tree next = TREE_CHAIN (local); + found_class_initialization_flag += + LOCAL_CLASS_INITIALIZATION_FLAG_P (local); layout_decl (local, 0); expand_decl (pushdecl (local)); local = next; } + + /* Emit initialization code for test flags if we saw one. */ + if (! always_initialize_class_p + && current_function_decl + && found_class_initialization_flag) + hash_traverse + (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), + emit_init_test_initialization, NULL); + /* Avoid deep recursion for long block. */ while (TREE_CODE (body) == COMPOUND_EXPR) { @@ -3335,3 +3362,37 @@ force_evaluation_order (node) } return node; } + +/* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE of a + method in order to emit initialization code for each test flag. */ + +static bool +emit_init_test_initialization (entry, key) + struct hash_entry *entry; + hash_table_key key ATTRIBUTE_UNUSED; +{ + struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry; + tree klass = build_class_ref ((tree) entry->key); + tree rhs; + + /* If the DECL_INITIAL of the test flag is set to true, it + means that the class is already initialized the time it + is in use. */ + if (DECL_INITIAL (ite->init_test_decl) == boolean_true_node) + rhs = boolean_true_node; + /* Otherwise, we initialize the class init check variable by looking + at the `state' field of the class to see if it is already + initialized. This makes things a bit faster if the class is + already initialized, which should be the common case. */ + else + rhs = build (GE_EXPR, boolean_type_node, + build (COMPONENT_REF, byte_type_node, + build1 (INDIRECT_REF, class_type_node, klass), + lookup_field (&class_type_node, + get_identifier ("state"))), + build_int_2 (JV_STATE_DONE, 0)); + + expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node, + ite->init_test_decl, rhs)); + return true; +} |