/* Author: Kresten Krab Thorup <krab@gnu.org> */
#include <config.h>
+#include <platform.h>
#include <java-interp.h>
#include <java/lang/AbstractMethodError.h>
#include <java/lang/NoClassDefFoundError.h>
#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/VMClassLoader.h>
#include <java/lang/reflect/Modifier.h>
using namespace gcj;
if (! _Jv_equalUtf8Consts (field->name, field_name))
continue;
- // now, check field access.
-
- if ( (cls == klass)
- || ((field->flags & Modifier::PUBLIC) != 0)
- || (((field->flags & Modifier::PROTECTED) != 0)
- && cls->isAssignableFrom (klass))
- || (((field->flags & Modifier::PRIVATE) == 0)
- && _Jv_ClassNameSamePackage (cls->name,
- klass->name)))
+ if (_Jv_CheckAccess (klass, cls, field->flags))
{
/* resove the field using the class' own loader
if necessary */
method_signature)))
continue;
- if (cls == klass
- || ((method->accflags & Modifier::PUBLIC) != 0)
- || (((method->accflags & Modifier::PROTECTED) != 0)
- && cls->isAssignableFrom (klass))
- || (((method->accflags & Modifier::PRIVATE) == 0)
- && _Jv_ClassNameSamePackage (cls->name,
- klass->name)))
- {
- return method;
- }
+ if (_Jv_CheckAccess (klass, cls, method->accflags))
+ return method;
else
- {
- throw new java::lang::IllegalAccessError;
- }
+ throw new java::lang::IllegalAccessError;
}
return 0;
}
// resolved.
if (klass->superclass)
- java::lang::ClassLoader::resolveClass0 (klass->superclass);
+ java::lang::VMClassLoader::resolveClass (klass->superclass);
_Jv_InterpClass *clz = (_Jv_InterpClass*)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++)
{
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
+ // Set the instance size for the class. Note that first we round it
+ // 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
_Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
_Jv_VerifyMethod (im);
clz->methods[i].ncode = im->ncode ();
+
+ // Resolve ctable entries pointing to this method. See
+ // _Jv_Defer_Resolution.
+ void **code = (void **)imeth->deferred;
+ while (code)
+ {
+ void **target = (void **)*code;
+ *code = clz->methods[i].ncode;
+ code = target;
+ }
}
}
}
}
+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);
}
memcpy (&jni_arg_types[offset], &closure->arg_types[0],
arg_count * sizeof (ffi_type *));
- if (ffi_prep_cif (&jni_cif, FFI_DEFAULT_ABI,
+ if (ffi_prep_cif (&jni_cif, _Jv_platform_ffi_abi,
extra_args + arg_count, rtype,
jni_arg_types) != FFI_OK)
throw_internal_error ("ffi_prep_cif failed for JNI function");