This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch: FYI: another alignment fix


I'm checking this in on the trunk.
It doesn't need to go in 3.3 because in 3.3 there is no supported way
for compiled code to observe interpreted classes.

First, we were computing alignment of fields incorrectly.  It turns
out that the alignment of a type can differ from the alignment of a
field of that type.  In particular, on x86 alignof(double) is 8, but a
double as a field has alignment 4.

Second, we need to round up the size of the new class according to its
alignment.  A previous patch had us use alignof(Object), but that is
wrong is one of our ancestors has stricter alignment.  So now we
search the class hierarchy to find the alignment we require.  This
particular rule will change whenever we switch to new-ABI-compatible
structure layout.

This code gets the correct answer for a few test cases I tried on x86
and PPC.

Tom

Index: libjava/ChangeLog
from  Tom Tromey  <tromey at redhat dot com>

	* resolve.cc (_Jv_PrepareClass): Round size up to alignment
	required by this object.  Search superclasses to find required
	alignment.
	(get_alignment_from_class): Use alignment of type as it appears
	in a struct.
	(ALIGNOF): New macro.
	(struct aligner): New helper structure.

Index: libjava/resolve.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/resolve.cc,v
retrieving revision 1.39
diff -u -r1.39 resolve.cc
--- libjava/resolve.cc 15 Apr 2003 02:17:12 -0000 1.39
+++ libjava/resolve.cc 23 Apr 2003 19:02:25 -0000
@@ -459,16 +459,36 @@
 
   /************ PART ONE: OBJECT LAYOUT ***************/
 
+  // Compute the alignment for this type by searching through the
+  // superclasses and finding the maximum required alignment.  We
+  // could consider caching this in the Class.
+  int max_align = __alignof__ (java::lang::Object);
+  jclass super = clz->superclass;
+  while (super != NULL)
+    {
+      int num = JvNumInstanceFields (super);
+      _Jv_Field *field = JvGetFirstInstanceField (super);
+      while (num > 0)
+	{
+	  int field_align = get_alignment_from_class (field->type);
+	  if (field_align > max_align)
+	    max_align = field_align;
+	  ++field;
+	  --num;
+	}
+      super = super->superclass;
+    }
+
   int instance_size;
-  int static_size;
+  int static_size = 0;
 
   // Although java.lang.Object is never interpreted, an interface can
-  // have a null superclass.
+  // have a null superclass.  Note that we have to lay out an
+  // interface because it might have static fields.
   if (clz->superclass)
     instance_size = clz->superclass->size();
   else
     instance_size = java::lang::Object::class$.size();
-  static_size   = 0;
 
   for (int i = 0; i < clz->field_count; i++)
     {
@@ -510,13 +530,15 @@
 	  instance_size      = ROUND (instance_size, field_align);
 	  field->u.boffset   = instance_size;
 	  instance_size     += field_size;
+	  if (field_align > max_align)
+	    max_align = field_align;
 	}
     }
 
   // Set the instance size for the class.  Note that first we round it
-  // to the alignment required for Object; this keeps us in sync with
-  // our current ABI.
-  instance_size = ROUND (instance_size, __alignof__ (java::lang::Object));
+  // to the alignment required for this object; this keeps us in sync
+  // with our current ABI.
+  instance_size = ROUND (instance_size, max_align);
   clz->size_in_bytes = instance_size;
 
   // allocate static memory
@@ -709,27 +731,39 @@
     }
 }
 
+template<typename T>
+struct aligner
+{
+  T field;
+};
+
+#define ALIGNOF(TYPE) (__alignof__ (((aligner<TYPE> *) 0)->field))
+
+// This returns the alignment of a type as it would appear in a
+// structure.  This can be different from the alignment of the type
+// itself.  For instance on x86 double is 8-aligned but struct{double}
+// is 4-aligned.
 static int
 get_alignment_from_class (jclass klass)
 {
   if (klass == JvPrimClass (byte))
-    return  __alignof__ (jbyte);
+    return ALIGNOF (jbyte);
   else if (klass == JvPrimClass (short))
-    return  __alignof__ (jshort);
+    return ALIGNOF (jshort);
   else if (klass == JvPrimClass (int)) 
-    return  __alignof__ (jint);
+    return ALIGNOF (jint);
   else if (klass == JvPrimClass (long))
-    return  __alignof__ (jlong);
+    return ALIGNOF (jlong);
   else if (klass == JvPrimClass (boolean))
-    return  __alignof__ (jboolean);
+    return ALIGNOF (jboolean);
   else if (klass == JvPrimClass (char))
-    return  __alignof__ (jchar);
+    return ALIGNOF (jchar);
   else if (klass == JvPrimClass (float))
-    return  __alignof__ (jfloat);
+    return ALIGNOF (jfloat);
   else if (klass == JvPrimClass (double))
-    return  __alignof__ (jdouble);
+    return ALIGNOF (jdouble);
   else
-    return __alignof__ (jobject);
+    return ALIGNOF (jobject);
 }
 
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]