verify.cc (state::seen_subrs): New field.
authorTom Tromey <tromey@redhat.com>
Thu, 13 Feb 2003 23:48:39 +0000 (23:48 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Thu, 13 Feb 2003 23:48:39 +0000 (23:48 +0000)
* verify.cc (state::seen_subrs): New field.
(state::state): Initialize it.
(state::clean_subrs): New method.
(state::~state): Call it.
(state::copy): Copy subroutine list.
(state::add_subr): New method.
(state::merge): Only register a change if the current subroutine
hasn't yet been noted.

From-SVN: r62878

libjava/ChangeLog
libjava/verify.cc

index cb8ea70e4529b6aadf6378fe4265c9286b1410a9..e53a2e7ff122b816566675f301ab2111090a626e 100644 (file)
@@ -1,3 +1,14 @@
+2003-02-13  Tom Tromey  <tromey@redhat.com>
+
+       * verify.cc (state::seen_subrs): New field.
+       (state::state): Initialize it.
+       (state::clean_subrs): New method.
+       (state::~state): Call it.
+       (state::copy): Copy subroutine list.
+       (state::add_subr): New method.
+       (state::merge): Only register a change if the current subroutine
+       hasn't yet been noted.
+
 2003-02-13  Mark Wielaard  <mark@klomp.org>
 
        * java/io/InputStreamReader.java (getEncoding): Return null when
index 238a3e926f1e833eca06ffa085857fbd647193d3..a7b0ee2eb8b2442058fa376d259e008736e06591 100644 (file)
@@ -1,6 +1,6 @@
 // defineclass.cc - defining a class from .class format.
 
-/* Copyright (C) 2001, 2002  Free Software Foundation
+/* Copyright (C) 2001, 2002, 2003  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -821,6 +821,12 @@ private:
     // assigns to locals[0] (overwriting `this') and then returns
     // without really initializing.
     type this_type;
+    // This is a list of all subroutines that have been seen at this
+    // point.  Ordinarily this is NULL; it is only allocated and used
+    // in relatively weird situations involving non-ret exit from a
+    // subroutine.  We have to keep track of this in this way to avoid
+    // endless recursion in these cases.
+    subr_info *seen_subrs;
 
     // INVALID marks a state which is not on the linked list of states
     // requiring reverification.
@@ -839,6 +845,7 @@ private:
       stack = NULL;
       locals = NULL;
       local_changed = NULL;
+      seen_subrs = NULL;
     }
 
     state (int max_stack, int max_locals)
@@ -851,6 +858,7 @@ private:
        stack[i] = unsuitable_type;
       locals = new type[max_locals];
       local_changed = (bool *) _Jv_Malloc (sizeof (bool) * max_locals);
+      seen_subrs = NULL;
       for (int i = 0; i < max_locals; ++i)
        {
          locals[i] = unsuitable_type;
@@ -866,6 +874,7 @@ private:
       stack = new type[max_stack];
       locals = new type[max_locals];
       local_changed = (bool *) _Jv_Malloc (sizeof (bool) * max_locals);
+      seen_subrs = NULL;
       copy (orig, max_stack, max_locals, ret_semantics);
       next = INVALID;
     }
@@ -878,6 +887,7 @@ private:
        delete[] locals;
       if (local_changed)
        _Jv_Free (local_changed);
+      clean_subrs ();
     }
 
     void *operator new[] (size_t bytes)
@@ -900,6 +910,17 @@ private:
       _Jv_Free (mem);
     }
 
+    void clean_subrs ()
+    {
+      subr_info *info = seen_subrs;
+      while (info != NULL)
+       {
+         subr_info *next = info->next;
+         _Jv_Free (info);
+         info = next;
+       }
+    }
+
     void copy (const state *copy, int max_stack, int max_locals,
               bool ret_semantics = false)
     {
@@ -919,6 +940,16 @@ private:
            locals[i] = copy->locals[i];
          local_changed[i] = copy->local_changed[i];
        }
+
+      clean_subrs ();
+      if (copy->seen_subrs)
+       {
+         for (subr_info *info = seen_subrs; info != NULL; info = info->next)
+           add_subr (info->pc);
+       }
+      else
+       seen_subrs = NULL;
+
       this_type = copy->this_type;
       // Don't modify `next'.
     }
@@ -945,6 +976,15 @@ private:
        local_changed[i] = false;
     }
 
+    // Indicate that we've been in this this subroutine.
+    void add_subr (int pc)
+    {
+      subr_info *n = (subr_info *) _Jv_Malloc (sizeof (subr_info));
+      n->pc = pc;
+      n->next = seen_subrs;
+      seen_subrs = n;
+    }
+
     // Merge STATE_OLD into this state.  Destructively modifies this
     // state.  Returns true if the new state was in fact changed.
     // Will throw an exception if the states are not mergeable.
@@ -972,10 +1012,23 @@ private:
        }
       else
        {
-         // If the subroutines differ, indicate that the state
-         // changed.  This is needed to detect when subroutines have
-         // merged.
-         changed = true;
+         // If the subroutines differ, and we haven't seen this
+         // subroutine before, indicate that the state changed.  This
+         // is needed to detect when subroutines have merged.
+         bool found = false;
+         for (subr_info *info = seen_subrs; info != NULL; info = info->next)
+           {
+             if (info->pc == state_old->subroutine)
+               {
+                 found = true;
+                 break;
+               }
+           }
+         if (! found)
+           {
+             add_subr (state_old->subroutine);
+             changed = true;
+           }
        }
 
       // Merge stacks.  Special handling for NO_STACK case.