This is the mail archive of the
java-patches@sourceware.cygnus.com
mailing list for the Java project.
Patch: array alignment
- To: Java Patch List <java-patches at sourceware dot cygnus dot com>
- Subject: Patch: array alignment
- From: Tom Tromey <tromey at cygnus dot com>
- Date: 24 Nov 1999 17:11:58 -0700
- Reply-To: tromey at cygnus dot com
I'm committing the appended patch. It fixes code that didn't take
into account the fact that the first element of an array must have
proper alignment.
1999-11-24 Tom Tromey <tromey@cygnus.com>
* prims.cc (_Jv_NewObjectArray): Use
_Jv_GetArrayElementFromElementType.
(_Jv_NewPrimArray): Likewise.
* java/lang/natObject.cc (clone): Use
_Jv_GetArrayElementFromElementType instead of sizeof.
* java/lang/natSystem.cc (arraycopy): Use
_Jv_GetArrayElementFromElementType.
* include/jvm.h (_Jv_GetArrayElementFromElementType): New
function.
Tom
Index: prims.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/prims.cc,v
retrieving revision 1.13
diff -u -r1.13 prims.cc
--- prims.cc 1999/11/05 17:34:32 1.13
+++ prims.cc 1999/11/24 23:48:27
@@ -328,16 +328,22 @@
if (count < 0)
JvThrow (new java::lang::NegativeArraySizeException);
+ JvAssert (! elementClass->isPrimitive ());
+
+ jobjectArray obj = NULL;
+ size_t size = (size_t) _Jv_GetArrayElementFromElementType (obj,
+ elementClass);
+
// Check for overflow.
- if ((size_t) count > (SIZE_T_MAX - sizeof (__JArray)) / sizeof (jobject))
+ if ((size_t) count > (SIZE_T_MAX - size) / sizeof (jobject))
JvThrow (no_memory);
- size_t size = count * sizeof (jobject) + sizeof (__JArray);
+ size += count * sizeof (jobject);
// FIXME: second argument should be "current loader" //
jclass clas = _Jv_FindArrayClass (elementClass, 0);
- jobjectArray obj = (jobjectArray) _Jv_AllocArray (size);
+ obj = (jobjectArray) _Jv_AllocArray (size);
if (! obj)
JvThrow (no_memory);
obj->length = count;
@@ -365,12 +371,15 @@
if (count < 0)
JvThrow (new java::lang::NegativeArraySizeException ());
+ JvAssert (eltype->isPrimitive ());
+ jobject dummy = NULL;
+ size_t size = (size_t) _Jv_GetArrayElementFromElementType (dummy, eltype);
+
// Check for overflow.
- if ((size_t) count > (SIZE_T_MAX - sizeof (__JArray)) / elsize)
+ if ((size_t) count > (SIZE_T_MAX - size) / elsize)
JvThrow (no_memory);
- __JArray *arr = (__JArray*) _Jv_AllocObj (sizeof (__JArray)
- + elsize * count);
+ __JArray *arr = (__JArray*) _Jv_AllocObj (size + elsize * count);
if (! arr)
JvThrow (no_memory);
arr->length = count;
Index: include/jvm.h
===================================================================
RCS file: /cvs/java/libgcj/libjava/include/jvm.h,v
retrieving revision 1.6
diff -u -r1.6 jvm.h
--- jvm.h 1999/10/22 19:43:40 1.6
+++ jvm.h 1999/11/24 23:48:27
@@ -114,6 +114,36 @@
return (jint) obj;
}
+// Return a raw pointer to the elements of an array given the array
+// and its element type. You might think we could just pick a single
+// array type and use elements() on it, but we can't because we must
+// account for alignment of the element type.
+inline char *
+_Jv_GetArrayElementFromElementType (jobject array,
+ jclass element_type)
+{
+ char *elts;
+ if (element_type == JvPrimClass (byte))
+ elts = (char *) elements ((jbyteArray) array);
+ else if (element_type == JvPrimClass (short))
+ elts = (char *) elements ((jshortArray) array);
+ else if (element_type == JvPrimClass (int))
+ elts = (char *) elements ((jintArray) array);
+ else if (element_type == JvPrimClass (long))
+ elts = (char *) elements ((jlongArray) array);
+ else if (element_type == JvPrimClass (boolean))
+ elts = (char *) elements ((jbooleanArray) array);
+ else if (element_type == JvPrimClass (char))
+ elts = (char *) elements ((jcharArray) array);
+ else if (element_type == JvPrimClass (float))
+ elts = (char *) elements ((jfloatArray) array);
+ else if (element_type == JvPrimClass (double))
+ elts = (char *) elements ((jdoubleArray) array);
+ else
+ elts = (char *) elements ((jobjectArray) array);
+ return elts;
+}
+
extern "C" void _Jv_ThrowBadArrayIndex (jint bad_index);
extern "C" jobject _Jv_NewArray (jint type, jint size);
extern "C" jobject _Jv_NewMultiArray (jclass klass, jint dims, ...);
Index: java/lang/natObject.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/natObject.cc,v
retrieving revision 1.3
diff -u -r1.3 natObject.cc
--- natObject.cc 1999/09/10 22:03:08 1.3
+++ natObject.cc 1999/11/24 23:48:30
@@ -84,7 +84,10 @@
r = _Jv_NewObjectArray (array->length, comp, NULL);
eltsize = sizeof (jobject);
}
- size = sizeof (__JArray) + array->length * eltsize;
+ // We can't use sizeof on __JArray because we must account for
+ // alignment of the element type.
+ size = (_Jv_GetArrayElementFromElementType (array, comp) - (char *) array
+ + array->length * eltsize);
}
else
{
Index: java/lang/natSystem.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/natSystem.cc,v
retrieving revision 1.13
diff -u -r1.13 natSystem.cc
--- natSystem.cc 1999/10/15 16:53:41 1.13
+++ natSystem.cc 1999/11/24 23:48:30
@@ -124,52 +124,10 @@
const size_t size = (prim ? src_comp->size()
: sizeof elements((jobjectArray)src)[0]);
- // In an ideal world we would do this via a virtual function in
- // __JArray. However, we can't have virtual functions in
- // __JArray due to the need to copy an array's virtual table in
- // _Jv_FindArrayClass.
- // We can't just pick a single subtype of __JArray to use due to
- // alignment concerns.
- char *src_elts = NULL;
- if (! prim)
- src_elts = (char *) elements ((jobjectArray) src);
- else if (src_comp == JvPrimClass (byte))
- src_elts = (char *) elements ((jbyteArray) src);
- else if (src_comp == JvPrimClass (short))
- src_elts = (char *) elements ((jshortArray) src);
- else if (src_comp == JvPrimClass (int))
- src_elts = (char *) elements ((jintArray) src);
- else if (src_comp == JvPrimClass (long))
- src_elts = (char *) elements ((jlongArray) src);
- else if (src_comp == JvPrimClass (boolean))
- src_elts = (char *) elements ((jbooleanArray) src);
- else if (src_comp == JvPrimClass (char))
- src_elts = (char *) elements ((jcharArray) src);
- else if (src_comp == JvPrimClass (float))
- src_elts = (char *) elements ((jfloatArray) src);
- else if (src_comp == JvPrimClass (double))
- src_elts = (char *) elements ((jdoubleArray) src);
+ char *src_elts = _Jv_GetArrayElementFromElementType (src, src_comp);
src_elts += size * src_offset;
- char *dst_elts = NULL;
- if (! prim)
- dst_elts = (char *) elements ((jobjectArray) dst);
- else if (dst_comp == JvPrimClass (byte))
- dst_elts = (char *) elements ((jbyteArray) dst);
- else if (dst_comp == JvPrimClass (short))
- dst_elts = (char *) elements ((jshortArray) dst);
- else if (dst_comp == JvPrimClass (int))
- dst_elts = (char *) elements ((jintArray) dst);
- else if (dst_comp == JvPrimClass (long))
- dst_elts = (char *) elements ((jlongArray) dst);
- else if (dst_comp == JvPrimClass (boolean))
- dst_elts = (char *) elements ((jbooleanArray) dst);
- else if (dst_comp == JvPrimClass (char))
- dst_elts = (char *) elements ((jcharArray) dst);
- else if (dst_comp == JvPrimClass (float))
- dst_elts = (char *) elements ((jfloatArray) dst);
- else if (dst_comp == JvPrimClass (double))
- dst_elts = (char *) elements ((jdoubleArray) dst);
+ char *dst_elts = _Jv_GetArrayElementFromElementType (dst, dst_comp);
dst_elts += size * dst_offset;
#if HAVE_MEMMOVE