This is not a bug in classpath's Hashtable implementation. The behaviour
here is undefined, and it is very dangerous to add elements to a
Hashtable while an enumeration is in progress. For example if a rehash
occurs, the table will be reordered and elements which have already been
enumerated could be returned again.
However, I can see the value in adjusting our implementation if it means
that we can run this common benchmark. As I understand it, 213_javac is
expecting that if a call to hasMoreElements() returns true, then the
next nextElement() will return an object even if the structure of the
table has changed between these calls. This patch changes our
implementation to make that guarantee. Its a different behaviour, but no
more correct than before. Patrick, can you try this in your tree against
the 213_javac. If it solves the problem you are seeing, I'll check it in.
regards
Bryce.
Cierniak, Michal wrote:
>Patrick,
>Gansha has submitted all the necessary fixes to Classpath. I don't remember
>if the email you mentioned is sufficient by itself, but certainly the
>combined fixes submitted by Gansha to the mailing list should fix all the
>SPEC JVM98 213_javac problems -- we can run 213_javac without any problems.
>
>Those fixes have not been checked into the Classpath CVS tree yet.
>
>Michal
>
>
>>-----Original Message-----
>>From: Patrick Doyle [mailto:[EMAIL PROTECTED]]
>>Sent: Tuesday, August 28, 2001 9:44 AM
>>To: [EMAIL PROTECTED]
>>Subject: Hashtable enumeration
>>
>>
>>
>>I have run into a problem with Hashtable enumeration, when
>>running javac.
>>When an element is added to the Hashtable in a certain way, the
>>enumeration fails with a NoSuchElementException, while it
>>succeeds under
>>the Sun libraries. This is an issue which has arisen before,
>>apparently:
>>
>> http://www.mail-archive.com/[email protected]/msg03259.html
>>
>>Has this been resolved? Is the latest CVS version of Hashtable fixed?
>>
>>--
>>Patrick Doyle
>>[EMAIL PROTECTED]
>>
2001-09-06 Bryce McKinlay <[EMAIL PROTECTED]>
* 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;
}
- }
+ }
}