verify.cc (state::seen_subrs): New field.

* 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
This commit is contained in:
Tom Tromey 2003-02-13 23:48:39 +00:00 committed by Tom Tromey
parent 114775850c
commit 6f2ffb37af
2 changed files with 69 additions and 5 deletions

View 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

View 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.