Commit e8b22dd1 by Andrew Haley Committed by Andrew Haley

java-except.h (struct eh_range): Add `expanded' field.

2000-01-25  Andrew Haley  <aph@cygnus.com>

        * java-except.h (struct eh_range): Add `expanded' field.
        (maybe_start_try): Add end_pc arg.
        (maybe_end_try): Ditto.
	* java-tree.h (force_poplevels): new function.
        * expr.c (expand_byte_code): Don't call maybe_start_try or
        maybe_end_try.
        * except.c (add_handler): Reset expanded.
        (expand_start_java_handler): Set expanded.
        (check_start_handlers): Don't expand a start handler that's
        already been expanded.
        (maybe_start_try): Add end_pc arg.  Only expand a handler which
        ends after end_pc.
	(expand_end_java_handler): call force_poplevels.
	(force_poplevels): new function.
        * decl.c (binding_level): Add start_pc of binding level.
        (maybe_pushlevels): Call maybe_start_try when pushing binding
        levels.
        (maybe_poplevels): Call maybe_end_try when popping binding levels.
        (LARGEST_PC): Define.
        (clear_binding_level): Use LARGEST_PC.

	* java-tree.h (DEBUG_JAVA_BINDING_LEVELS): new define.
	* decl.c (DEBUG_JAVA_BINDING_LEVELS): new define.
	(binding_depth, is_class_level, current_pc): new variables.
        (struct binding_level): ditto.
	(indent): new function.
	(push_jvm_slot): add debugging info.
	(maybe_pushlevels): ditto.
	(maybe_poplevels): ditto.
	(pushlevel): ditto.
	(poplevel): ditto.
	(start_java_method): ditto.
	(give_name_to_locals): comment only.
	* except.c (binding_depth, is_class_level, current_pc):
	new variables.
	(expand_start_java_handler): add debugging info.
	(expand_end_java_handler): ditto.

From-SVN: r31861
parent 665792eb
2000-01-25 Andrew Haley <aph@cygnus.com>
* java-except.h (struct eh_range): Add `expanded' field.
(maybe_start_try): Add end_pc arg.
(maybe_end_try): Ditto.
* java-tree.h (force_poplevels): new function.
* expr.c (expand_byte_code): Don't call maybe_start_try or
maybe_end_try.
* except.c (add_handler): Reset expanded.
(expand_start_java_handler): Set expanded.
(check_start_handlers): Don't expand a start handler that's
already been expanded.
(maybe_start_try): Add end_pc arg. Only expand a handler which
ends after end_pc.
(expand_end_java_handler): call force_poplevels.
(force_poplevels): new function.
* decl.c (binding_level): Add start_pc of binding level.
(maybe_pushlevels): Call maybe_start_try when pushing binding
levels.
(maybe_poplevels): Call maybe_end_try when popping binding levels.
(LARGEST_PC): Define.
(clear_binding_level): Use LARGEST_PC.
* java-tree.h (DEBUG_JAVA_BINDING_LEVELS): new define.
* decl.c (DEBUG_JAVA_BINDING_LEVELS): new define.
(binding_depth, is_class_level, current_pc): new variables.
(struct binding_level): ditto.
(indent): new function.
(push_jvm_slot): add debugging info.
(maybe_pushlevels): ditto.
(maybe_poplevels): ditto.
(pushlevel): ditto.
(poplevel): ditto.
(start_java_method): ditto.
(give_name_to_locals): comment only.
* except.c (binding_depth, is_class_level, current_pc):
new variables.
(expand_start_java_handler): add debugging info.
(expand_end_java_handler): ditto.
2000-02-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 2000-02-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gjavah.c (overloaded_jni_method_exists_p): Add prototype. * gjavah.c (overloaded_jni_method_exists_p): Add prototype.
......
...@@ -29,12 +29,19 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ ...@@ -29,12 +29,19 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
#include "tree.h" #include "tree.h"
#include "toplev.h"
#include "flags.h"
#include "java-tree.h" #include "java-tree.h"
#include "jcf.h" #include "jcf.h"
#include "toplev.h" #include "toplev.h"
#include "function.h" #include "function.h"
#include "except.h" #include "except.h"
#include "defaults.h" #include "defaults.h"
#include "java-except.h"
#if defined (DEBUG_JAVA_BINDING_LEVELS)
extern void indent PROTO((void));
#endif
static tree push_jvm_slot PARAMS ((int, tree)); static tree push_jvm_slot PARAMS ((int, tree));
static tree lookup_name_current_level PARAMS ((tree)); static tree lookup_name_current_level PARAMS ((tree));
...@@ -63,6 +70,21 @@ tree pending_local_decls = NULL_TREE; ...@@ -63,6 +70,21 @@ tree pending_local_decls = NULL_TREE;
/* Push a local variable or stack slot into the decl_map, /* Push a local variable or stack slot into the decl_map,
and assign it an rtl. */ and assign it an rtl. */
#if defined(DEBUG_JAVA_BINDING_LEVELS)
int binding_depth = 0;
int is_class_level = 0;
int current_pc;
void
indent ()
{
register unsigned i;
for (i = 0; i < binding_depth*2; i++)
putc (' ', stderr);
}
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
static tree static tree
push_jvm_slot (index, decl) push_jvm_slot (index, decl)
int index; int index;
...@@ -199,6 +221,12 @@ struct binding_level ...@@ -199,6 +221,12 @@ struct binding_level
/* The bytecode PC that marks the end of this level. */ /* The bytecode PC that marks the end of this level. */
int end_pc; int end_pc;
int start_pc;
#if defined(DEBUG_JAVA_BINDING_LEVELS)
/* Binding depth at which this level began. */
unsigned binding_depth;
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
}; };
#define NULL_BINDING_LEVEL (struct binding_level *) NULL #define NULL_BINDING_LEVEL (struct binding_level *) NULL
...@@ -217,11 +245,15 @@ static struct binding_level *free_binding_level; ...@@ -217,11 +245,15 @@ static struct binding_level *free_binding_level;
static struct binding_level *global_binding_level; static struct binding_level *global_binding_level;
/* A PC value bigger than any PC value we may ever may encounter. */
#define LARGEST_PC (( (unsigned int)1 << (HOST_BITS_PER_INT - 1)) - 1)
/* Binding level structures are initialized by copying this one. */ /* Binding level structures are initialized by copying this one. */
static struct binding_level clear_binding_level static struct binding_level clear_binding_level
= {NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, = {NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE,
NULL_BINDING_LEVEL, 0, 0, 0, 0, 1000000000}; NULL_BINDING_LEVEL, 0, 0, 0, 0, LARGEST_PC, 0, 0};
#if 0 #if 0
/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
...@@ -1123,6 +1155,14 @@ pushlevel (unused) ...@@ -1123,6 +1155,14 @@ pushlevel (unused)
keep_next_level_flag = 0; keep_next_level_flag = 0;
newlevel->keep_if_subblocks = keep_next_if_subblocks; newlevel->keep_if_subblocks = keep_next_if_subblocks;
keep_next_if_subblocks = 0; keep_next_if_subblocks = 0;
#if defined(DEBUG_JAVA_BINDING_LEVELS)
newlevel->binding_depth = binding_depth;
indent ();
fprintf (stderr, "push %s level 0x%08x pc %d\n",
(is_class_level) ? "class" : "block", newlevel, current_pc);
is_class_level = 0;
binding_depth++;
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
} }
/* Exit a binding level. /* Exit a binding level.
...@@ -1155,6 +1195,26 @@ poplevel (keep, reverse, functionbody) ...@@ -1155,6 +1195,26 @@ poplevel (keep, reverse, functionbody)
tree decl; tree decl;
int block_previously_created; int block_previously_created;
#if defined(DEBUG_JAVA_BINDING_LEVELS)
binding_depth--;
indent ();
if (current_binding_level->end_pc != LARGEST_PC)
fprintf (stderr, "pop %s level 0x%08x pc %d (end pc %d)\n",
(is_class_level) ? "class" : "block", current_binding_level, current_pc,
current_binding_level->end_pc);
else
fprintf (stderr, "pop %s level 0x%08x pc %d\n",
(is_class_level) ? "class" : "block", current_binding_level, current_pc);
#if 0
if (is_class_level != (current_binding_level == class_binding_level))
{
indent ();
fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n");
}
is_class_level = 0;
#endif
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
keep |= current_binding_level->keep; keep |= current_binding_level->keep;
/* Get the decls in the order they were written. /* Get the decls in the order they were written.
...@@ -1334,6 +1394,10 @@ void ...@@ -1334,6 +1394,10 @@ void
maybe_pushlevels (pc) maybe_pushlevels (pc)
int pc; int pc;
{ {
#if defined(DEBUG_JAVA_BINDING_LEVELS)
current_pc = pc;
#endif
while (pending_local_decls != NULL_TREE && while (pending_local_decls != NULL_TREE &&
DECL_LOCAL_START_PC (pending_local_decls) <= pc) DECL_LOCAL_START_PC (pending_local_decls) <= pc)
{ {
...@@ -1352,24 +1416,57 @@ maybe_pushlevels (pc) ...@@ -1352,24 +1416,57 @@ maybe_pushlevels (pc)
if (end_pc > current_binding_level->end_pc) if (end_pc > current_binding_level->end_pc)
end_pc = current_binding_level->end_pc; end_pc = current_binding_level->end_pc;
maybe_start_try (pc, end_pc);
pushlevel (1); pushlevel (1);
expand_start_bindings (0); expand_start_bindings (0);
current_binding_level->end_pc = end_pc;
current_binding_level->end_pc = end_pc;
current_binding_level->start_pc = pc;
current_binding_level->names = decl; current_binding_level->names = decl;
for ( ; decl != NULL_TREE; decl = TREE_CHAIN (decl)) for ( ; decl != NULL_TREE; decl = TREE_CHAIN (decl))
{ {
push_jvm_slot (DECL_LOCAL_SLOT_NUMBER (decl), decl); push_jvm_slot (DECL_LOCAL_SLOT_NUMBER (decl), decl);
} }
} }
maybe_start_try (pc, 0);
} }
void void
maybe_poplevels (pc) maybe_poplevels (pc)
int pc; int pc;
{ {
#if defined(DEBUG_JAVA_BINDING_LEVELS)
current_pc = pc;
#endif
while (current_binding_level->end_pc <= pc) while (current_binding_level->end_pc <= pc)
{ {
tree decls = getdecls ();
expand_end_bindings (getdecls (), 1, 0);
maybe_end_try (current_binding_level->start_pc, pc);
poplevel (1, 0, 0);
}
maybe_end_try (0, pc);
}
/* Terminate any binding which began during the range beginning at
start_pc. This tidies up improperly nested local variable ranges
and exception handlers; a variable declared within an exception
range is forcibly terminated when that exception ends. */
void
force_poplevels (start_pc)
int start_pc;
{
while (current_binding_level->start_pc > start_pc)
{
tree decls = getdecls ();
if (pedantic && current_binding_level->start_pc > start_pc)
warning_with_decl (current_function_decl,
"In %s: overlapped variable and exception ranges at %d",
current_binding_level->start_pc);
expand_end_bindings (getdecls (), 1, 0); expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0); poplevel (1, 0, 0);
} }
...@@ -1468,6 +1565,14 @@ give_name_to_locals (jcf) ...@@ -1468,6 +1565,14 @@ give_name_to_locals (jcf)
= (struct lang_decl *) permalloc (sizeof (struct lang_decl_var)); = (struct lang_decl *) permalloc (sizeof (struct lang_decl_var));
DECL_LOCAL_SLOT_NUMBER (decl) = slot; DECL_LOCAL_SLOT_NUMBER (decl) = slot;
DECL_LOCAL_START_PC (decl) = start_pc; DECL_LOCAL_START_PC (decl) = start_pc;
#if 0
/* FIXME: The range used internally for exceptions and local
variable ranges, is a half-open interval:
start_pc <= pc < end_pc. However, the range used in the
Java VM spec is inclusive at both ends:
start_pc <= pc <= end_pc. */
end_pc++;
#endif
DECL_LOCAL_END_PC (decl) = end_pc; DECL_LOCAL_END_PC (decl) = end_pc;
/* Now insert the new decl in the proper place in /* Now insert the new decl in the proper place in
...@@ -1612,6 +1717,10 @@ start_java_method (fndecl) ...@@ -1612,6 +1717,10 @@ start_java_method (fndecl)
decl_map = make_tree_vec (i); decl_map = make_tree_vec (i);
type_map = (tree *) oballoc (i * sizeof (tree)); type_map = (tree *) oballoc (i * sizeof (tree));
#if defined(DEBUG_JAVA_BINDING_LEVELS)
fprintf (stderr, "%s:\n", (*decl_printable_name) (fndecl, 2));
current_pc = 0;
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
pushlevel (1); /* Push parameters. */ pushlevel (1); /* Push parameters. */
ptr = &DECL_ARGUMENTS (fndecl); ptr = &DECL_ARGUMENTS (fndecl);
......
...@@ -42,7 +42,6 @@ static void expand_end_java_handler PARAMS ((struct eh_range *)); ...@@ -42,7 +42,6 @@ static void expand_end_java_handler PARAMS ((struct eh_range *));
static struct eh_range *find_handler_in_range PARAMS ((int, struct eh_range *, static struct eh_range *find_handler_in_range PARAMS ((int, struct eh_range *,
struct eh_range *)); struct eh_range *));
static void link_handler PARAMS ((struct eh_range *, struct eh_range *)); static void link_handler PARAMS ((struct eh_range *, struct eh_range *));
static void check_start_handlers PARAMS ((struct eh_range *, int));
extern struct obstack permanent_obstack; extern struct obstack permanent_obstack;
...@@ -62,6 +61,14 @@ static struct eh_range *cache_next_child; ...@@ -62,6 +61,14 @@ static struct eh_range *cache_next_child;
struct eh_range whole_range; struct eh_range whole_range;
#if defined(DEBUG_JAVA_BINDING_LEVELS)
int binding_depth;
int is_class_level;
int current_pc;
extern void indent ();
#endif
/* Search for the most specific eh_range containing PC. /* Search for the most specific eh_range containing PC.
Assume PC is within RANGE. Assume PC is within RANGE.
CHILD is a list of children of RANGE such that any CHILD is a list of children of RANGE such that any
...@@ -278,6 +285,7 @@ add_handler (start_pc, end_pc, handler, type) ...@@ -278,6 +285,7 @@ add_handler (start_pc, end_pc, handler, type)
h->outer = NULL; h->outer = NULL;
h->handlers = build_tree_list (type, handler); h->handlers = build_tree_list (type, handler);
h->next_sibling = NULL; h->next_sibling = NULL;
h->expanded = 0;
if (prev == NULL) if (prev == NULL)
whole_range.first_child = h; whole_range.first_child = h;
...@@ -289,8 +297,14 @@ add_handler (start_pc, end_pc, handler, type) ...@@ -289,8 +297,14 @@ add_handler (start_pc, end_pc, handler, type)
/* if there are any handlers for this range, issue start of region */ /* if there are any handlers for this range, issue start of region */
static void static void
expand_start_java_handler (range) expand_start_java_handler (range)
struct eh_range *range ATTRIBUTE_UNUSED; struct eh_range *range;
{ {
#if defined(DEBUG_JAVA_BINDING_LEVELS)
indent ();
fprintf (stderr, "expand start handler pc %d --> %d\n",
current_pc, range->end_pc);
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
range->expanded = 1;
push_obstacks (&permanent_obstack, &permanent_obstack); push_obstacks (&permanent_obstack, &permanent_obstack);
expand_eh_region_start (); expand_eh_region_start ();
pop_obstacks (); pop_obstacks ();
...@@ -329,6 +343,7 @@ expand_end_java_handler (range) ...@@ -329,6 +343,7 @@ expand_end_java_handler (range)
struct eh_range *range; struct eh_range *range;
{ {
tree handler = range->handlers; tree handler = range->handlers;
force_poplevels (range->start_pc);
push_obstacks (&permanent_obstack, &permanent_obstack); push_obstacks (&permanent_obstack, &permanent_obstack);
expand_start_all_catch (); expand_start_all_catch ();
pop_obstacks (); pop_obstacks ();
...@@ -341,6 +356,11 @@ expand_end_java_handler (range) ...@@ -341,6 +356,11 @@ expand_end_java_handler (range)
end_catch_handler (); end_catch_handler ();
} }
expand_end_all_catch (); expand_end_all_catch ();
#if defined(DEBUG_JAVA_BINDING_LEVELS)
indent ();
fprintf (stderr, "expand end handler pc %d <-- %d\n",
current_pc, range->start_pc);
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
} }
/* Recursive helper routine for maybe_start_handlers. */ /* Recursive helper routine for maybe_start_handlers. */
...@@ -353,35 +373,48 @@ check_start_handlers (range, pc) ...@@ -353,35 +373,48 @@ check_start_handlers (range, pc)
if (range != NULL_EH_RANGE && range->start_pc == pc) if (range != NULL_EH_RANGE && range->start_pc == pc)
{ {
check_start_handlers (range->outer, pc); check_start_handlers (range->outer, pc);
if (!range->expanded)
expand_start_java_handler (range); expand_start_java_handler (range);
} }
} }
struct eh_range *current_range;
/* Emit any start-of-try-range start at PC. */ static struct eh_range *current_range;
/* Emit any start-of-try-range starting at start_pc and ending after
end_pc. */
void void
maybe_start_try (pc) maybe_start_try (start_pc, end_pc)
int pc; int start_pc;
int end_pc;
{ {
struct eh_range *range;
if (! doing_eh (1)) if (! doing_eh (1))
return; return;
current_range = find_handler (pc); range = find_handler (start_pc);
check_start_handlers (current_range, pc); while (range != NULL_EH_RANGE && range->start_pc == start_pc
&& range->end_pc < end_pc)
range = range->outer;
current_range = range;
check_start_handlers (range, start_pc, end_pc);
} }
/* Emit any end-of-try-range end at PC. */ /* Emit any end-of-try-range ending at end_pc and starting before
start_pc. */
void void
maybe_end_try (pc) maybe_end_try (start_pc, end_pc)
int pc; int start_pc;
int end_pc;
{ {
if (! doing_eh (1)) if (! doing_eh (1))
return; return;
while (current_range != NULL_EH_RANGE && current_range->end_pc <= pc) while (current_range != NULL_EH_RANGE && current_range->end_pc <= end_pc
&& current_range->start_pc >= start_pc)
{ {
expand_end_java_handler (current_range); expand_end_java_handler (current_range);
current_range = current_range->outer; current_range = current_range->outer;
......
...@@ -2289,13 +2289,9 @@ expand_byte_code (jcf, method) ...@@ -2289,13 +2289,9 @@ expand_byte_code (jcf, method)
} }
} }
} }
maybe_start_try (PC);
maybe_pushlevels (PC); maybe_pushlevels (PC);
PC = process_jvm_instruction (PC, byte_ops, length); PC = process_jvm_instruction (PC, byte_ops, length);
maybe_poplevels (PC); maybe_poplevels (PC);
maybe_end_try (PC);
} /* for */ } /* for */
if (dead_code_index != -1) if (dead_code_index != -1)
......
...@@ -47,6 +47,9 @@ struct eh_range ...@@ -47,6 +47,9 @@ struct eh_range
/* The next child of outer, in address order. */ /* The next child of outer, in address order. */
struct eh_range *next_sibling; struct eh_range *next_sibling;
/* True if this range has already been expanded. */
int expanded;
}; };
/* A dummy range that represents the entire method. */ /* A dummy range that represents the entire method. */
...@@ -60,9 +63,9 @@ extern void method_init_exceptions PARAMS ((void)); ...@@ -60,9 +63,9 @@ extern void method_init_exceptions PARAMS ((void));
extern void emit_handlers PARAMS ((void)); extern void emit_handlers PARAMS ((void));
extern void maybe_start_try PARAMS ((int)); extern void maybe_start_try PARAMS ((int, int));
extern void maybe_end_try PARAMS ((int)); extern void maybe_end_try PARAMS ((int, int));
extern void add_handler PARAMS ((int, int, tree, tree)); extern void add_handler PARAMS ((int, int, tree, tree));
......
...@@ -592,6 +592,7 @@ extern int class_depth PARAMS ((tree)); ...@@ -592,6 +592,7 @@ extern int class_depth PARAMS ((tree));
extern int verify_jvm_instructions PARAMS ((struct JCF *, const unsigned char *, long)); extern int verify_jvm_instructions PARAMS ((struct JCF *, const unsigned char *, long));
extern void maybe_pushlevels PARAMS ((int)); extern void maybe_pushlevels PARAMS ((int));
extern void maybe_poplevels PARAMS ((int)); extern void maybe_poplevels PARAMS ((int));
extern void force_poplevels PARAMS ((int));
extern int process_jvm_instruction PARAMS ((int, const unsigned char *, long)); extern int process_jvm_instruction PARAMS ((int, const unsigned char *, long));
extern void set_local_type PARAMS ((int, tree)); extern void set_local_type PARAMS ((int, tree));
extern int merge_type_state PARAMS ((tree)); extern int merge_type_state PARAMS ((tree));
...@@ -944,3 +945,5 @@ extern int java_error_count; \ ...@@ -944,3 +945,5 @@ extern int java_error_count; \
if (java_error_count > save_error_count) \ if (java_error_count > save_error_count) \
return; \ return; \
} }
#undef DEBUG_JAVA_BINDING_LEVELS
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment