Patch: array alignment
Tom Tromey
tromey@cygnus.com
Wed Nov 24 16:13:00 GMT 1999
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
More information about the Java-patches
mailing list