From ba60e4754adc4181784207396de5abbd349d894f Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Tue, 29 Jun 2004 16:18:46 +0000 Subject: [PATCH] except.c (expand_start_java_handler): Push a new binding level. 2004-06-29 Andrew Haley * except.c (expand_start_java_handler): Push a new binding level. Don't build a TRY_CATCH_EXPR now, we'll do it later. Call register_exception_range() to register where we'll do it. (expand_end_java_handler): Remove old bogus code. Replace with new logic that simply builds TRY_CATCH_EXPRs and inserts them at the top of the expression we're curently building. (maybe_end_try): Delete. * decl.c (binding_level.exception_range): New field. (clear_binding_level): Add field exception_range. Reformat. (poplevel): Call expand_end_java_handler(). (poplevel): Call java_add_stmt only if functionbody is false. (maybe_poplevels): Don't call maybe_end_try() from here. (end_java_method): Clear no longer used trees in function decl. (register_exception_range): New function. * java-tree.h (register_exception_range, struct eh_range): Declare. From-SVN: r83857 --- gcc/java/ChangeLog | 18 +++++++++ gcc/java/decl.c | 84 ++++++++++++++++++++++++++++++------------ gcc/java/except.c | 83 ++++++----------------------------------- gcc/java/java-except.h | 1 + gcc/java/java-tree.h | 4 ++ 5 files changed, 94 insertions(+), 96 deletions(-) diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index f6ad5ef0e17..51a2b359bce 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,21 @@ +2004-06-29 Andrew Haley + + * except.c (expand_start_java_handler): Push a new binding level. + Don't build a TRY_CATCH_EXPR now, we'll do it later. Call + register_exception_range() to register where we'll do it. + (expand_end_java_handler): Remove old bogus code. Replace with + new logic that simply builds TRY_CATCH_EXPRs and inserts them at + the top of the expression we're curently building. + (maybe_end_try): Delete. + * decl.c (binding_level.exception_range): New field. + (clear_binding_level): Add field exception_range. Reformat. + (poplevel): Call expand_end_java_handler(). + (poplevel): Call java_add_stmt only if functionbody is false. + (maybe_poplevels): Don't call maybe_end_try() from here. + (end_java_method): Clear no longer used trees in function decl. + (register_exception_range): New function. + * java-tree.h (register_exception_range, struct eh_range): Declare. + 2004-06-28 Bryce McKinlay * jcf-write.c (get_classfile_modifiers): Formatting fixes. diff --git a/gcc/java/decl.c b/gcc/java/decl.c index 682c8b3e3fd..508727a888a 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -314,6 +314,9 @@ struct binding_level GTY(()) /* The statements in this binding level. */ tree stmts; + /* An exception range associated with this binding level. */ + struct eh_range * GTY((skip (""))) exception_range; + /* Binding depth at which this level began. Used only for debugging. */ unsigned binding_depth; }; @@ -341,8 +344,18 @@ static GTY(()) struct binding_level *global_binding_level; /* Binding level structures are initialized by copying this one. */ static const struct binding_level clear_binding_level - = {NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, - NULL_BINDING_LEVEL, LARGEST_PC, 0, NULL_TREE, 0}; += { + NULL_TREE, /* names */ + NULL_TREE, /* shadowed */ + NULL_TREE, /* blocks */ + NULL_TREE, /* this_lock */ + NULL_BINDING_LEVEL, /* level_chain */ + LARGEST_PC, /* end_pc */ + 0, /* start_pc */ + NULL, /* stmts */ + NULL, /* exception_range */ + 0, /* binding_depth */ + }; #if 0 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function @@ -1316,6 +1329,9 @@ poplevel (int keep, int reverse, int functionbody) TREE_TYPE (block) = void_type_node; } + if (current_binding_level->exception_range) + expand_end_java_handler (current_binding_level->exception_range); + if (block != 0) { /* If any statements have been generated at this level, create a @@ -1341,7 +1357,6 @@ poplevel (int keep, int reverse, int functionbody) bind = build (BIND_EXPR, TREE_TYPE (block), BLOCK_VARS (block), BLOCK_EXPR_BODY (block), block); - BIND_EXPR_BODY (bind) = current_binding_level->stmts; if (BIND_EXPR_BODY (bind) @@ -1448,24 +1463,27 @@ poplevel (int keep, int reverse, int functionbody) DECL_INITIAL (current_function_decl) = block; DECL_SAVED_TREE (current_function_decl) = bind; } - else if (block) + else { - if (!block_previously_created) - current_binding_level->blocks - = chainon (current_binding_level->blocks, block); + if (block) + { + if (!block_previously_created) + current_binding_level->blocks + = chainon (current_binding_level->blocks, block); + } + /* If we did not make a block for the level just exited, + any blocks made for inner levels + (since they cannot be recorded as subblocks in that level) + must be carried forward so they will later become subblocks + of something else. */ + else if (subblocks) + current_binding_level->blocks + = chainon (current_binding_level->blocks, subblocks); + + if (bind) + java_add_stmt (bind); } - /* If we did not make a block for the level just exited, - any blocks made for inner levels - (since they cannot be recorded as subblocks in that level) - must be carried forward so they will later become subblocks - of something else. */ - else if (subblocks) - current_binding_level->blocks - = chainon (current_binding_level->blocks, subblocks); - - if (bind) - java_add_stmt (bind); - + if (block) TREE_USED (block) = 1; return block; @@ -1521,11 +1539,7 @@ maybe_poplevels (int pc) #endif while (current_binding_level->end_pc <= pc) - { - maybe_end_try (current_binding_level->start_pc, pc); - poplevel (1, 0, 0); - } - maybe_end_try (0, pc); + poplevel (1, 0, 0); } /* Terminate any binding which began during the range beginning at @@ -1781,6 +1795,14 @@ end_java_method (void) flag_unit_at_a_time = 0; finish_method (fndecl); + if (! flag_unit_at_a_time) + { + /* Nulling these fields when we no longer need them saves + memory. */ + DECL_SAVED_TREE (fndecl) = NULL; + DECL_STRUCT_FUNCTION (fndecl) = NULL; + DECL_INITIAL (fndecl) = NULL_TREE; + } current_function_decl = NULL_TREE; } @@ -1929,5 +1951,19 @@ get_stmts (void) return ¤t_binding_level->stmts; } +/* Register an exception range as belonging to the current binding + level. There may only be one: if there are more, we'll create more + binding levels. However, each range can have multiple handlers, + and these are expanded when we call expand_end_java_handler(). */ + +void +register_exception_range (struct eh_range *range, int pc, int end_pc) +{ + if (current_binding_level->exception_range) + abort (); + current_binding_level->exception_range = range; + current_binding_level->end_pc = end_pc; + current_binding_level->start_pc = pc; +} #include "gt-java-decl.h" diff --git a/gcc/java/except.c b/gcc/java/except.c index b77842e8a66..91f741f63d0 100644 --- a/gcc/java/except.c +++ b/gcc/java/except.c @@ -40,7 +40,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "toplev.h" static void expand_start_java_handler (struct eh_range *); -static void expand_end_java_handler (struct eh_range *); static struct eh_range *find_handler_in_range (int, struct eh_range *, struct eh_range *); static void link_handler (struct eh_range *, struct eh_range *); @@ -305,13 +304,8 @@ expand_start_java_handler (struct eh_range *range) fprintf (stderr, "expand start handler pc %d --> %d\n", current_pc, range->end_pc); #endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */ - { - tree new = build (TRY_CATCH_EXPR, void_type_node, NULL, NULL); - TREE_SIDE_EFFECTS (new) = 1; - java_add_stmt (build_java_empty_stmt ()); - range->stmt = java_add_stmt (new); - } - + pushlevel (0); + register_exception_range (range, range->start_pc, range->end_pc); range->expanded = 1; } @@ -428,13 +422,11 @@ build_exception_object_ref (tree type) /* If there are any handlers for this range, isssue end of range, and then all handler blocks */ -static void +void expand_end_java_handler (struct eh_range *range) { tree handler = range->handlers; - tree compound = NULL; - force_poplevels (range->start_pc); for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler)) { /* For bytecode we treat exceptions a little unusually. A @@ -444,55 +436,18 @@ expand_end_java_handler (struct eh_range *range) extra (and difficult) work to get this to look like a gcc-style finally clause. */ tree type = TREE_PURPOSE (handler); - if (type == NULL) type = throwable_type_node; - type = prepare_eh_table_type (type); - if (compound) - { - /* If we already have a COMPOUND there is more than one - catch handler for this try block. Wrap the - TRY_CATCH_EXPR in operand 1 of COMPOUND with another - TRY_CATCH_EXPR. */ - tree inner_try_expr = TREE_OPERAND (compound, 1); - tree catch_expr - = build (CATCH_EXPR, void_type_node, type, - build (GOTO_EXPR, void_type_node, TREE_VALUE (handler))); - tree try_expr - = build (TRY_CATCH_EXPR, void_type_node, - inner_try_expr, catch_expr); - TREE_OPERAND (compound, 1) = try_expr; - } - else - { - tree *stmts = get_stmts (); - tree outer; - tree try_expr; - compound = range->stmt; - outer = TREE_OPERAND (compound, 0); - try_expr = TREE_OPERAND (compound, 1); - /* On the left of COMPOUND is the expresion to be evaluated - before the try handler is entered; on the right is a - TRY_FINALLY_EXPR with no operands as yet. In the current - statement list is an expression that we're going to move - inside the try handler. We'll create a new COMPOUND_EXPR - with the outer context on the left and the TRY_FINALLY_EXPR - on the right, then nullify both operands of COMPOUND, which - becomes the final expression in OUTER. This new compound - expression replaces the current statement list. */ - TREE_OPERAND (try_expr, 0) = *stmts; - TREE_OPERAND (try_expr, 1) - = build (CATCH_EXPR, void_type_node, type, - build (GOTO_EXPR, void_type_node, TREE_VALUE (handler))); - TREE_SIDE_EFFECTS (try_expr) = 1; - TREE_OPERAND (compound, 0) = build_java_empty_stmt (); - TREE_OPERAND (compound, 1) = build_java_empty_stmt (); - compound - = build (COMPOUND_EXPR, TREE_TYPE (try_expr), outer, try_expr); - *stmts = compound; - } + { + tree catch_expr + = build (CATCH_EXPR, void_type_node, type, + build (GOTO_EXPR, void_type_node, TREE_VALUE (handler))); + tree try_catch_expr = build (TRY_CATCH_EXPR, void_type_node, + *get_stmts (), catch_expr); + *get_stmts () = try_catch_expr; + } } #if defined(DEBUG_JAVA_BINDING_LEVELS) indent (); @@ -536,19 +491,3 @@ maybe_start_try (int start_pc, int end_pc) check_start_handlers (range, start_pc); } -/* Emit any end-of-try-range ending at end_pc and starting before - start_pc. */ - -void -maybe_end_try (int start_pc, int end_pc) -{ - if (! doing_eh (1)) - return; - - while (current_range != NULL_EH_RANGE && current_range->end_pc <= end_pc - && current_range->start_pc >= start_pc) - { - expand_end_java_handler (current_range); - current_range = current_range->outer; - } -} diff --git a/gcc/java/java-except.h b/gcc/java/java-except.h index 0646d61b591..960a9155023 100644 --- a/gcc/java/java-except.h +++ b/gcc/java/java-except.h @@ -68,3 +68,4 @@ extern void maybe_end_try (int, int); extern void add_handler (int, int, tree, tree); extern void handle_nested_ranges (void); extern void expand_resume_after_catch (void); +extern void expand_end_java_handler (struct eh_range *); diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 64c07784d23..1089e595083 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -1117,6 +1117,9 @@ struct lang_type GTY(()) #define SEARCH_SUPER 2 #define SEARCH_VISIBLE 4 +/* Defined in java-except.h */ +struct eh_range; + extern void java_parse_file (int); extern bool java_mark_addressable (tree); extern tree java_type_for_mode (enum machine_mode, int); @@ -1345,6 +1348,7 @@ extern tree add_stmt_to_compound (tree, tree, tree); extern tree java_add_stmt (tree); extern tree java_add_local_var (tree decl); extern tree *get_stmts (void); +extern void register_exception_range(struct eh_range *, int, int); extern void finish_method (tree); extern void java_expand_body (tree); -- 2.30.2