resolve.cc (_Jv_PrepareClass): Round size up to alignment required by this object.
authorTom Tromey <tromey@redhat.com>
Wed, 23 Apr 2003 19:09:56 +0000 (19:09 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Wed, 23 Apr 2003 19:09:56 +0000 (19:09 +0000)
* 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.

From-SVN: r66008

libjava/ChangeLog
libjava/resolve.cc

index 956a317a7fbc4f1181f8c06a9e4d7b327dc1471b..03e855f6aa7be449a1ef4aac638c883e1f1c3e2a 100644 (file)
@@ -1,3 +1,13 @@
+2003-04-23  Tom Tromey  <tromey@redhat.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.
+
 2003-04-20  Scott Gilbertson  <scottg@mantatest.com>
 
        * java/awt/Container.java (addImpl): Enable paint events if adding
index fbdc284945f9f03ec375d0d9f89fdde6569a5261..7cf0b0a3f8ee583cad3e300c2e5469fa241e9f90 100644 (file)
@@ -459,16 +459,36 @@ _Jv_PrepareClass(jclass klass)
 
   /************ 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 @@ _Jv_PrepareClass(jclass klass)
          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 @@ _Jv_InitField (jobject obj, jclass klass, int index)
     }
 }
 
+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);
 }