OSDN Git Service

* except.h (struct eh_queue): Add `next' pointer.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 12 Dec 1999 18:32:36 +0000 (18:32 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 12 Dec 1999 18:32:36 +0000 (18:32 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30874 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/except.c
gcc/except.h
gcc/stmt.c

index 82e9630..315e748 100644 (file)
@@ -1,3 +1,27 @@
+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>
 
        * gthr-single.h (__gthread_active_p): Add prototype arguments.
index 5c85ba8..4b25b10 100644 (file)
@@ -1533,7 +1533,7 @@ expand_eh_region_end (handler)
   /* create region entry in final exception table */
   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 (is_eh_region ())
@@ -1551,7 +1551,7 @@ expand_eh_region_end (handler)
 
   /* Go through the goto handlers in the queue, emitting their
      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 
        && node->entry->outer_context == entry->rethrow_label)
       emit_cleanup_handler (node->entry);
@@ -1596,7 +1596,7 @@ expand_fixup_region_end (cleanup)
   for (node = ehstack.top; node && node->entry->finalization != cleanup; )
     node = node->chain;
   if (node == 0)
-    for (node = ehqueue.head; node && node->entry->finalization != cleanup; )
+    for (node = ehqueue->head; node && node->entry->finalization != cleanup; )
       node = node->chain;
   if (node == 0)
     abort ();
@@ -1678,9 +1678,9 @@ expand_leftover_cleanups ()
 {
   struct eh_entry *entry;
 
-  for (entry = dequeue_eh_entry (&ehqueue); 
+  for (entry = dequeue_eh_entry (ehqueue); 
        entry;
-       entry = dequeue_eh_entry (&ehqueue))
+       entry = dequeue_eh_entry (ehqueue))
     {
       /* A leftover try block.  Shouldn't be one here.  */
       if (entry->finalization == integer_zero_node)
@@ -1787,6 +1787,29 @@ end_catch_handler ()
   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.  */
 
 static void
@@ -1795,13 +1818,11 @@ emit_cleanup_handler (entry)
 {
   rtx prev;
   rtx handler_insns;
-  struct eh_queue q;
 
   /* Since the cleanup could itself contain try-catch blocks, we
      squirrel away the current queue and replace it when we are done
      with this function.  */
-  q = ehqueue;
-  ehqueue.head = ehqueue.tail = NULL;
+  push_ehqueue ();
 
   /* Put these handler instructions in a sequence.  */
   do_pending_stack_adjust ();
@@ -1844,8 +1865,7 @@ emit_cleanup_handler (entry)
   end_sequence ();
 
   /* Now we've left the handler.  */
-  expand_leftover_cleanups ();
-  ehqueue = q;
+  pop_ehqueue ();
 }
 
 /* Generate RTL for the start of a group of catch clauses. 
@@ -1889,9 +1909,9 @@ expand_start_all_catch ()
   /* 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
      still be gotos pending.  */
-  for (entry = dequeue_eh_entry (&ehqueue); 
+  for (entry = dequeue_eh_entry (ehqueue); 
        entry->finalization != integer_zero_node;
-       entry = dequeue_eh_entry (&ehqueue))
+       entry = dequeue_eh_entry (ehqueue))
     free (entry);
 
   /* At this point, all the cleanups are done, and the ehqueue now has
@@ -2477,8 +2497,11 @@ static void
 mark_eh_queue (q)
      struct eh_queue *q;
 {
-  if (q)
-    mark_eh_node (q->head);
+  while (q)
+    {
+      mark_eh_node (q->head);
+      q = q->next;
+    }
 }
 
 /* Mark NODE for GC.  A label_node contains a union containing either
@@ -2506,7 +2529,7 @@ mark_eh_status (eh)
 
   mark_eh_stack (&eh->x_ehstack);
   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);
 
   lang_mark_false_label_stack (eh->x_false_label_stack);
@@ -2577,6 +2600,7 @@ init_eh_for_function ()
 {
   current_function->eh
     = (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_stack_adjust = NULL_RTX;
   eh_return_handler = NULL_RTX;
@@ -2586,6 +2610,7 @@ void
 free_eh_status (f)
      struct function *f;
 {
+  free (f->eh->x_ehqueue);
   free (f->eh);
   f->eh = NULL;
 }
index 6f15ff0..befbccc 100644 (file)
@@ -93,6 +93,7 @@ struct eh_stack {
 struct eh_queue {
   struct eh_node *head;
   struct eh_node *tail;
+  struct eh_queue *next;
 };
 
 /* Used to save exception handling status for each function.  */
@@ -115,7 +116,7 @@ struct eh_status
      As we exit a region, we enqueue a new entry. The entries are then
      dequeued during expand_leftover_cleanups and
      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.
      They are currently emitted by the frontend code.  */
   rtx x_catch_clauses;
@@ -443,6 +444,12 @@ extern rtx get_dynamic_cleanup_chain               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.  */
 
 extern int exceptions_via_longjmp;
index 6137d66..8256646 100644 (file)
@@ -4270,7 +4270,11 @@ expand_cleanups (list, dont_do, in_fixup, reachable)
                if (protect)
                  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);
+               pop_ehqueue ();
                if (protect)
                  expand_fixup_region_end (TREE_VALUE (tail));
                free_temp_slots ();