This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: java.util.Hashtable enumerator vs specjvm javac
- To: java-patches at gcc dot gnu dot org
- Subject: Patch: java.util.Hashtable enumerator vs specjvm javac
- From: Bryce McKinlay <bryce at waitaki dot otago dot ac dot nz>
- Date: Fri, 14 Sep 2001 12:10:31 +1200
This patch changes our Hashtable enumerator implementation to work more
like Sun's, so that the specjvm javac benchmark will run correctly. In
the event that a new element is added to a table while an enumeration is
in progress, we previously could possibly throw an exception on
nextElement() even if hasMoreElements(), called before the table was
changed, returned true. nextElement() will now always return something
if the last hasMoreElements() was true. I dont think the old behaviour
was outside spec, since table modification during enumeration is unsafe
and has undefined behaviour, but the old javac used in the benchmark
apparantly expected it.
The "bug" was originally reported (and initial patch proposed) by Gansha Wu.
I've checked this in.
regards
Bryce.
2001-09-06 Bryce McKinlay <bryce@waitaki.otago.ac.nz>
* java/util/Hashtable.java (Enumerator): Ensure that if
hasMoreElements() returns true, nextElement() will always return
something even if the table has been modified.
Index: Hashtable.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/util/Hashtable.java,v
retrieving revision 1.12
diff -u -r1.12 Hashtable.java
--- Hashtable.java 2001/03/24 08:05:29 1.12
+++ Hashtable.java 2001/09/06 08:32:35
@@ -833,44 +833,57 @@
static final int VALUES = 1;
int type;
- // The total number of elements returned by nextElement(). Used to
- // determine if there are more elements remaining.
- int count;
// current index in the physical hash table.
int idx;
- // the last Entry returned.
+ // the last Entry returned by nextEntry().
Entry last;
+ // Entry which will be returned by the next nextElement() call.
+ Entry next;
Enumerator(int type)
{
this.type = type;
- this.count = 0;
this.idx = buckets.length;
}
+
+ private Entry nextEntry()
+ {
+ Entry e = null;
+ if (last != null)
+ e = last.next;
+
+ while (e == null && idx > 0)
+ {
+ e = buckets[--idx];
+ }
+ last = e;
+ return e;
+ }
+
public boolean hasMoreElements()
{
- return count < Hashtable.this.size;
+ if (next != null)
+ return true;
+ next = nextEntry();
+ return (next != null);
}
public Object nextElement()
{
- if (count >= size)
- throw new NoSuchElementException();
- count++;
Entry e = null;
- if (last != null)
- e = last.next;
-
- while (e == null)
+ if (next != null)
{
- e = buckets[--idx];
+ e = next;
+ next = null;
}
-
- last = e;
+ else
+ e = nextEntry();
+ if (e == null)
+ throw new NoSuchElementException("Hashtable Enumerator");
if (type == VALUES)
return e.value;
return e.key;
}
- }
+ }
}