Patch: FYI: Fix PR 21703

Tom Tromey tromey@redhat.com
Sun May 22 01:43:00 GMT 2005


I'm checking this in on the 4.0 branch.  I will check it in on the
trunk once it emerges from its slushy state.

We can get into an infinite loop in String.intern(), in the case where
the intern hash table has valid entries and DELETED_STRING entries,
but no NULL entries.  The fix is to notice when we've looped back to
the beginning.  Due to the rehash behavior, in this case we know there
will be a DELETED_STRING entry.

This same bug occurs in the hash table used in natReference.cc.  (We
really should have a template in a header file for this...)

The only other place where I could remember that we used this same
approach was IdentityHashMap; I looked there and it does not have this
bug.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	PR libgcj/21703:
	* java/lang/ref/natReference.cc (find_slot): Handle case where
	table has no NULL entries.
	* java/lang/natString.cc (_Jv_StringFindSlot): Handle case where
	table has no NULL entries.

Index: java/lang/natString.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natString.cc,v
retrieving revision 1.37
diff -u -r1.37 natString.cc
--- java/lang/natString.cc 22 Apr 2005 19:02:41 -0000 1.37
+++ java/lang/natString.cc 22 May 2005 00:45:47 -0000
@@ -1,6 +1,6 @@
 // natString.cc - Implementation of java.lang.String native methods.
 
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004  Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -64,7 +64,7 @@
   int index = start_index;
   /* step must be non-zero, and relatively prime with strhash_size. */
   jint step = (hash ^ (hash >> 16)) | 1;
-  for (;;)
+  do
     {
       jstring* ptr = &strhash[index];
       jstring value = (jstring) UNMASK_PTR (*ptr);
@@ -81,8 +81,12 @@
 	       && memcmp(JvGetStringChars(value), data, 2*len) == 0)
 	return (ptr);
       index = (index + step) & (strhash_size - 1);
-      JvAssert (index != start_index);
     }
+  while (index != start_index);
+  // Note that we can have INDEX == START_INDEX if the table has no
+  // NULL entries but does have DELETED_STRING entries.
+  JvAssert (deleted_index >= 0);
+  return &strhash[deleted_index];
 }
 
 /* Calculate a hash code for the string starting at PTR at given LENGTH.
Index: java/lang/ref/natReference.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/ref/natReference.cc,v
retrieving revision 1.6
diff -u -r1.6 natReference.cc
--- java/lang/ref/natReference.cc 29 Sep 2003 21:13:55 -0000 1.6
+++ java/lang/ref/natReference.cc 22 May 2005 00:45:47 -0000
@@ -1,6 +1,6 @@
 // natReference.cc - Native code for References
 
-/* Copyright (C) 2001, 2002, 2003  Free Software Foundation
+/* Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -78,7 +78,7 @@
   int start_index = hcode & (hash_size - 1);
   int index = start_index;
   int deleted_index = -1;
-  for (;;)
+  do
     {
       object_list *ptr = &hash[index];
       if (ptr->reference == key)
@@ -96,8 +96,12 @@
 	  JvAssert (ptr->reference == DELETED_REFERENCE);
 	}
       index = (index + step) & (hash_size - 1);
-      JvAssert (index != start_index);
     }
+  while (index != start_index);
+  // Note that we can have INDEX == START_INDEX if the table has no
+  // NULL entries but does have DELETED entries.
+  JvAssert (deleted_index >= 0);
+  return &hash[deleted_index];
 }
 
 static void



More information about the Java-patches mailing list