Commit f54a7f6f by Mark Mitchell Committed by Mark Mitchell

except.h (struct eh_queue): Add `next' pointer.

	* except.h (struct eh_queue): Add `next' pointer.
	(struct eh_status): Make x_ehqueue a pointer.
	(push_ehqueue):  Declare.
	(pop_ehqueue): Likewise.
	* except.c (expand_eh_region_end): Adjust now that ehqueue is a
	pointer.
	(expand_fixup_region_end): Likewise.
	(expand_leftover_cleanups): Likewise.
	(push_ehqueue): Define.
	(pop_ehqueue): Likewise.
	(emit_cleanup_handler): Use push_ehqueue and pop_ehqueue rather
	than doing it inline.
	(expand_start_all_catch):  Adjust now that ehqueue is a
	pointer.
	(mark_eh_queue): Mark all level of the queue.
	(mark_eh_status):  Adjust now that ehqueue is a
	pointer.
	(init_eh_for_function): Allocate ehqueue.
	(free_eh_status): Free it.
	* stmt.c (expand_cleanups): Save the ehqueue around the cleanup
	expansion for a fixup.

From-SVN: r30874
parent d0017c11
1999-12-12 Mark Mitchell <mark@codesourcery.com>
* except.h (struct eh_queue): Add `next' pointer.
(struct eh_status): Make x_ehqueue a pointer.
(push_ehqueue): Declare.
(pop_ehqueue): Likewise.
* except.c (expand_eh_region_end): Adjust now that ehqueue is a
pointer.
(expand_fixup_region_end): Likewise.
(expand_leftover_cleanups): Likewise.
(push_ehqueue): Define.
(pop_ehqueue): Likewise.
(emit_cleanup_handler): Use push_ehqueue and pop_ehqueue rather
than doing it inline.
(expand_start_all_catch): Adjust now that ehqueue is a
pointer.
(mark_eh_queue): Mark all level of the queue.
(mark_eh_status): Adjust now that ehqueue is a
pointer.
(init_eh_for_function): Allocate ehqueue.
(free_eh_status): Free it.
* stmt.c (expand_cleanups): Save the ehqueue around the cleanup
expansion for a fixup.
1999-12-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 1999-12-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gthr-single.h (__gthread_active_p): Add prototype arguments. * gthr-single.h (__gthread_active_p): Add prototype arguments.
......
...@@ -1533,7 +1533,7 @@ expand_eh_region_end (handler) ...@@ -1533,7 +1533,7 @@ expand_eh_region_end (handler)
/* create region entry in final exception table */ /* create region entry in final exception table */
r = new_eh_region_entry (NOTE_EH_HANDLER (note), entry->rethrow_label); r = new_eh_region_entry (NOTE_EH_HANDLER (note), entry->rethrow_label);
enqueue_eh_entry (&ehqueue, entry); enqueue_eh_entry (ehqueue, entry);
/* If we have already started ending the bindings, don't recurse. */ /* If we have already started ending the bindings, don't recurse. */
if (is_eh_region ()) if (is_eh_region ())
...@@ -1551,7 +1551,7 @@ expand_eh_region_end (handler) ...@@ -1551,7 +1551,7 @@ expand_eh_region_end (handler)
/* Go through the goto handlers in the queue, emitting their /* Go through the goto handlers in the queue, emitting their
handlers if we now have enough information to do so. */ handlers if we now have enough information to do so. */
for (node = ehqueue.head; node; node = node->chain) for (node = ehqueue->head; node; node = node->chain)
if (node->entry->goto_entry_p if (node->entry->goto_entry_p
&& node->entry->outer_context == entry->rethrow_label) && node->entry->outer_context == entry->rethrow_label)
emit_cleanup_handler (node->entry); emit_cleanup_handler (node->entry);
...@@ -1596,7 +1596,7 @@ expand_fixup_region_end (cleanup) ...@@ -1596,7 +1596,7 @@ expand_fixup_region_end (cleanup)
for (node = ehstack.top; node && node->entry->finalization != cleanup; ) for (node = ehstack.top; node && node->entry->finalization != cleanup; )
node = node->chain; node = node->chain;
if (node == 0) if (node == 0)
for (node = ehqueue.head; node && node->entry->finalization != cleanup; ) for (node = ehqueue->head; node && node->entry->finalization != cleanup; )
node = node->chain; node = node->chain;
if (node == 0) if (node == 0)
abort (); abort ();
...@@ -1678,9 +1678,9 @@ expand_leftover_cleanups () ...@@ -1678,9 +1678,9 @@ expand_leftover_cleanups ()
{ {
struct eh_entry *entry; struct eh_entry *entry;
for (entry = dequeue_eh_entry (&ehqueue); for (entry = dequeue_eh_entry (ehqueue);
entry; entry;
entry = dequeue_eh_entry (&ehqueue)) entry = dequeue_eh_entry (ehqueue))
{ {
/* A leftover try block. Shouldn't be one here. */ /* A leftover try block. Shouldn't be one here. */
if (entry->finalization == integer_zero_node) if (entry->finalization == integer_zero_node)
...@@ -1787,6 +1787,29 @@ end_catch_handler () ...@@ -1787,6 +1787,29 @@ end_catch_handler ()
catchstack.top->entry->false_label = NULL_RTX; catchstack.top->entry->false_label = NULL_RTX;
} }
/* Save away the current ehqueue. */
void
push_ehqueue ()
{
struct eh_queue *q;
q = xcalloc (1, sizeof (struct eh_queue));
q->next = ehqueue;
ehqueue = q;
}
/* Restore a previously pushed ehqueue. */
void
pop_ehqueue ()
{
struct eh_queue *q;
expand_leftover_cleanups ();
q = ehqueue->next;
free (ehqueue);
ehqueue = q;
}
/* Emit the handler specified by ENTRY. */ /* Emit the handler specified by ENTRY. */
static void static void
...@@ -1795,13 +1818,11 @@ emit_cleanup_handler (entry) ...@@ -1795,13 +1818,11 @@ emit_cleanup_handler (entry)
{ {
rtx prev; rtx prev;
rtx handler_insns; rtx handler_insns;
struct eh_queue q;
/* Since the cleanup could itself contain try-catch blocks, we /* Since the cleanup could itself contain try-catch blocks, we
squirrel away the current queue and replace it when we are done squirrel away the current queue and replace it when we are done
with this function. */ with this function. */
q = ehqueue; push_ehqueue ();
ehqueue.head = ehqueue.tail = NULL;
/* Put these handler instructions in a sequence. */ /* Put these handler instructions in a sequence. */
do_pending_stack_adjust (); do_pending_stack_adjust ();
...@@ -1844,8 +1865,7 @@ emit_cleanup_handler (entry) ...@@ -1844,8 +1865,7 @@ emit_cleanup_handler (entry)
end_sequence (); end_sequence ();
/* Now we've left the handler. */ /* Now we've left the handler. */
expand_leftover_cleanups (); pop_ehqueue ();
ehqueue = q;
} }
/* Generate RTL for the start of a group of catch clauses. /* Generate RTL for the start of a group of catch clauses.
...@@ -1889,9 +1909,9 @@ expand_start_all_catch () ...@@ -1889,9 +1909,9 @@ expand_start_all_catch ()
/* Throw away entries in the queue that we won't need anymore. We /* Throw away entries in the queue that we won't need anymore. We
need entries for regions that have ended but to which there might need entries for regions that have ended but to which there might
still be gotos pending. */ still be gotos pending. */
for (entry = dequeue_eh_entry (&ehqueue); for (entry = dequeue_eh_entry (ehqueue);
entry->finalization != integer_zero_node; entry->finalization != integer_zero_node;
entry = dequeue_eh_entry (&ehqueue)) entry = dequeue_eh_entry (ehqueue))
free (entry); free (entry);
/* At this point, all the cleanups are done, and the ehqueue now has /* At this point, all the cleanups are done, and the ehqueue now has
...@@ -2477,8 +2497,11 @@ static void ...@@ -2477,8 +2497,11 @@ static void
mark_eh_queue (q) mark_eh_queue (q)
struct eh_queue *q; struct eh_queue *q;
{ {
if (q) while (q)
mark_eh_node (q->head); {
mark_eh_node (q->head);
q = q->next;
}
} }
/* Mark NODE for GC. A label_node contains a union containing either /* Mark NODE for GC. A label_node contains a union containing either
...@@ -2506,7 +2529,7 @@ mark_eh_status (eh) ...@@ -2506,7 +2529,7 @@ mark_eh_status (eh)
mark_eh_stack (&eh->x_ehstack); mark_eh_stack (&eh->x_ehstack);
mark_eh_stack (&eh->x_catchstack); mark_eh_stack (&eh->x_catchstack);
mark_eh_queue (&eh->x_ehqueue); mark_eh_queue (eh->x_ehqueue);
ggc_mark_rtx (eh->x_catch_clauses); ggc_mark_rtx (eh->x_catch_clauses);
lang_mark_false_label_stack (eh->x_false_label_stack); lang_mark_false_label_stack (eh->x_false_label_stack);
...@@ -2577,6 +2600,7 @@ init_eh_for_function () ...@@ -2577,6 +2600,7 @@ init_eh_for_function ()
{ {
current_function->eh current_function->eh
= (struct eh_status *) xcalloc (1, sizeof (struct eh_status)); = (struct eh_status *) xcalloc (1, sizeof (struct eh_status));
ehqueue = (struct eh_queue *) xcalloc (1, sizeof (struct eh_queue));
eh_return_context = NULL_RTX; eh_return_context = NULL_RTX;
eh_return_stack_adjust = NULL_RTX; eh_return_stack_adjust = NULL_RTX;
eh_return_handler = NULL_RTX; eh_return_handler = NULL_RTX;
...@@ -2586,6 +2610,7 @@ void ...@@ -2586,6 +2610,7 @@ void
free_eh_status (f) free_eh_status (f)
struct function *f; struct function *f;
{ {
free (f->eh->x_ehqueue);
free (f->eh); free (f->eh);
f->eh = NULL; f->eh = NULL;
} }
......
...@@ -93,6 +93,7 @@ struct eh_stack { ...@@ -93,6 +93,7 @@ struct eh_stack {
struct eh_queue { struct eh_queue {
struct eh_node *head; struct eh_node *head;
struct eh_node *tail; struct eh_node *tail;
struct eh_queue *next;
}; };
/* Used to save exception handling status for each function. */ /* Used to save exception handling status for each function. */
...@@ -115,7 +116,7 @@ struct eh_status ...@@ -115,7 +116,7 @@ struct eh_status
As we exit a region, we enqueue a new entry. The entries are then As we exit a region, we enqueue a new entry. The entries are then
dequeued during expand_leftover_cleanups and dequeued during expand_leftover_cleanups and
expand_start_all_catch. */ expand_start_all_catch. */
struct eh_queue x_ehqueue; struct eh_queue *x_ehqueue;
/* Insns for all of the exception handlers for the current function. /* Insns for all of the exception handlers for the current function.
They are currently emitted by the frontend code. */ They are currently emitted by the frontend code. */
rtx x_catch_clauses; rtx x_catch_clauses;
...@@ -443,6 +444,12 @@ extern rtx get_dynamic_cleanup_chain PROTO((void)); ...@@ -443,6 +444,12 @@ extern rtx get_dynamic_cleanup_chain PROTO((void));
extern void emit_throw PROTO((void)); extern void emit_throw PROTO((void));
/* Save away the current ehqueue. */
extern void push_ehqueue PROTO((void));
/* Restore a previously pushed ehqueue. */
extern void pop_ehqueue PROTO((void));
/* One to use setjmp/longjmp method of generating code. */ /* One to use setjmp/longjmp method of generating code. */
extern int exceptions_via_longjmp; extern int exceptions_via_longjmp;
......
...@@ -4270,7 +4270,11 @@ expand_cleanups (list, dont_do, in_fixup, reachable) ...@@ -4270,7 +4270,11 @@ expand_cleanups (list, dont_do, in_fixup, reachable)
if (protect) if (protect)
expand_fixup_region_start (); expand_fixup_region_start ();
/* The cleanup might contain try-blocks, so we have to
preserve our current queue. */
push_ehqueue ();
expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0); expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
pop_ehqueue ();
if (protect) if (protect)
expand_fixup_region_end (TREE_VALUE (tail)); expand_fixup_region_end (TREE_VALUE (tail));
free_temp_slots (); free_temp_slots ();
......
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