This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: gcj/ggc fix
- From: Tom Tromey <tromey at redhat dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Cc: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 20 Jan 2003 23:16:06 -0700
- Subject: Patch: gcj/ggc fix
- Reply-to: tromey at redhat dot com
This patch fixes a GC failure in gcj.
We're allocating uninitialized memory in set_constant_entry. If the
right calls are made in the right sequence, we can end up with a
situation where the GC sees uninitialized tags values. The symptom is
a compiler crash.
The appended patch fixes this by ensuring that the new memory is
always cleared before use. This probably isn't the most efficient
approach, but it is easy to understand.
Tested on x86 Red Hat Linux 7.3.
I don't have a simple test case.
Ok for trunk?
(3.3 is different and I don't think this is a problem there.)
Tom
2003-01-20 Tom Tromey <tromey@redhat.com>
* constants.c (set_constant_entry): Allocated cleared memory.
Index: constants.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/constants.c,v
retrieving revision 1.29
diff -u -r1.29 constants.c
--- constants.c 18 Jan 2003 22:15:50 -0000 1.29
+++ constants.c 21 Jan 2003 06:09:06 -0000
@@ -46,12 +46,14 @@
if (cpool->data == NULL)
{
cpool->capacity = 100;
- cpool->tags = ggc_alloc (sizeof(uint8) * cpool->capacity);
- cpool->data = ggc_alloc (sizeof(union cpool_entry) * cpool->capacity);
+ cpool->tags = ggc_alloc_cleared (sizeof(uint8) * cpool->capacity);
+ cpool->data = ggc_alloc_cleared (sizeof(union cpool_entry)
+ * cpool->capacity);
cpool->count = 1;
}
if (index >= cpool->capacity)
{
+ int old_cap = cpool->capacity;
cpool->capacity *= 2;
if (index >= cpool->capacity)
cpool->capacity = index + 10;
@@ -59,6 +61,11 @@
sizeof(uint8) * cpool->capacity);
cpool->data = ggc_realloc (cpool->data,
sizeof(union cpool_entry) * cpool->capacity);
+
+ /* Make sure GC never sees uninitialized tag values. */
+ memset (cpool->tags + old_cap, 0, cpool->capacity - old_cap);
+ memset (cpool->data + old_cap, 0,
+ (cpool->capacity - old_cap) * sizeof (union cpool_entry));
}
if (index >= cpool->count)
cpool->count = index + 1;