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:
parent
114775850c
commit
6f2ffb37af
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user