summaryrefslogtreecommitdiff
path: root/libjava/link.cc
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-08 20:07:29 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-08 20:07:29 +0000
commit862ad8b433732c1533f670040617716f641d3a55 (patch)
treedad7dc41d043dce968c02f6043b92ddb8c7cbff7 /libjava/link.cc
parent35792caf91f289bd8fa2aa9a871e5865f0ed0630 (diff)
downloadgcc-862ad8b433732c1533f670040617716f641d3a55.tar.gz
PR libgcj/26063, PR libgcj/17978, PR libgcj/10598:
* defineclass.cc (parse): Use _Jv_AllocRawObj. (read_constpool): Likewise. (read_one_code_attribute): Use internal function name. (handleConstantPool): Use _Jv_AllocRawObj. (handleInterfacesBegin): Likewise. (handleFieldsBegin): Likewise. (handleMethodsBegin): Likewise. (handleCodeAttribute): Likewise. (handleMethodsEnd): Likewise. * include/jvm.h (new_vtable): Use _Jv_AllocRawObj. * interpret.cc (do_allocate_static_fields): Use _Jv_AllocRawObj. Allocate reference fields separately. * link.cc (prepare_constant_time_tables): Use _Jv_AllocRawObj. (add_miranda_methods): Likewise. (generate_itable): Use _Jv_AllocBytes. (find_iindex): Likewise. (struct method_closure): New structure. (create_error_method): Use struct method_closure; allocate with _Jv_AllocBytes. (ensure_fields_laid_out): Separate reference fields from non-reference fields. * boehm.cc (_Jv_MarkObj): Mark vtable. Only mark direct fields of Class. (_Jv_MarkArray): Mark vtable. (_Jv_AllocRawObj): Don't allocate objects of size 0. * include/execution.h (_Jv_ExecutionEngine::allocate_static_fields): Added 'int' parameter. (struct _Jv_CompiledEngine): Updated. (class _Jv_InterpreterEngine): Updated. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@110763 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/link.cc')
-rw-r--r--libjava/link.cc122
1 files changed, 69 insertions, 53 deletions
diff --git a/libjava/link.cc b/libjava/link.cc
index 0f9f7c1ca32..26bf8984e24 100644
--- a/libjava/link.cc
+++ b/libjava/link.cc
@@ -1,6 +1,6 @@
// link.cc - Code for linking and resolving classes and pool entries.
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
This file is part of libgcj.
@@ -588,10 +588,10 @@ _Jv_Linker::prepare_constant_time_tables (jclass klass)
// a pointer to the current class, and the rest are pointers to the
// classes ancestors, ordered from the current class down by decreasing
// depth. We do not include java.lang.Object in the table of ancestors,
- // since it is redundant.
+ // since it is redundant. Note that the classes pointed to by
+ // 'ancestors' will always be reachable by other paths.
- // FIXME: _Jv_AllocBytes
- klass->ancestors = (jclass *) _Jv_Malloc (klass->depth
+ klass->ancestors = (jclass *) _Jv_AllocBytes (klass->depth
* sizeof (jclass));
klass0 = klass;
for (int index = 0; index < klass->depth; index++)
@@ -611,9 +611,8 @@ _Jv_Linker::prepare_constant_time_tables (jclass klass)
return;
}
- // FIXME: _Jv_AllocBytes
klass->idt =
- (_Jv_IDispatchTable *) _Jv_Malloc (sizeof (_Jv_IDispatchTable));
+ (_Jv_IDispatchTable *) _Jv_AllocRawObj (sizeof (_Jv_IDispatchTable));
_Jv_ifaces ifaces;
ifaces.count = 0;
@@ -624,9 +623,10 @@ _Jv_Linker::prepare_constant_time_tables (jclass klass)
if (ifaces.count > 0)
{
+ // The classes pointed to by the itable will always be reachable
+ // via other paths.
klass->idt->cls.itable =
- // FIXME: _Jv_AllocBytes
- (void **) _Jv_Malloc (itable_size * sizeof (void *));
+ (void **) _Jv_AllocBytes (itable_size * sizeof (void *));
klass->idt->cls.itable_length = itable_size;
jshort *itable_offsets =
@@ -725,14 +725,12 @@ _Jv_Linker::generate_itable (jclass klass, _Jv_ifaces *ifaces,
/* Create interface dispatch table for iface */
if (iface->idt == NULL)
{
- // FIXME: _Jv_AllocBytes
iface->idt
- = (_Jv_IDispatchTable *) _Jv_Malloc (sizeof (_Jv_IDispatchTable));
+ = (_Jv_IDispatchTable *) _Jv_AllocRawObj (sizeof (_Jv_IDispatchTable));
// The first element of ioffsets is its length (itself included).
- // FIXME: _Jv_AllocBytes
- jshort *ioffsets = (jshort *) _Jv_Malloc (INITIAL_IOFFSETS_LEN
- * sizeof (jshort));
+ jshort *ioffsets = (jshort *) _Jv_AllocBytes (INITIAL_IOFFSETS_LEN
+ * sizeof (jshort));
ioffsets[0] = INITIAL_IOFFSETS_LEN;
for (int i = 1; i < INITIAL_IOFFSETS_LEN; i++)
ioffsets[i] = -1;
@@ -934,9 +932,8 @@ _Jv_Linker::find_iindex (jclass *ifaces, jshort *offsets, jshort num)
if (i >= newlen)
newlen = i + 3;
jshort *old_ioffsets = ifaces[j]->idt->iface.ioffsets;
- // FIXME: _Jv_AllocBytes
- jshort *new_ioffsets = (jshort *) _Jv_Malloc (newlen
- * sizeof(jshort));
+ jshort *new_ioffsets = (jshort *) _Jv_AllocBytes (newlen
+ * sizeof(jshort));
memcpy (&new_ioffsets[1], &old_ioffsets[1],
(len - 1) * sizeof (jshort));
new_ioffsets[0] = newlen;
@@ -954,42 +951,47 @@ _Jv_Linker::find_iindex (jclass *ifaces, jshort *offsets, jshort num)
return i;
}
+#ifdef USE_LIBFFI
+
+// We use a structure of this type to store the closure that
+// represents a missing method.
+struct method_closure
+{
+ // This field must come first, since the address of this field will
+ // be the same as the address of the overall structure. This is due
+ // to disabling interior pointers in the GC.
+ ffi_closure closure;
+ ffi_cif cif;
+ ffi_type *arg_types[1];
+};
+
+#endif // USE_LIBFFI
void *
_Jv_Linker::create_error_method (_Jv_Utf8Const *class_name)
{
#ifdef USE_LIBFFI
- // TODO: The following structs/objects are heap allocated are
- // unreachable by the garbage collector:
- // - cif, arg_types
-
- ffi_closure *closure = (ffi_closure *) _Jv_Malloc( sizeof( ffi_closure ));
- ffi_cif *cif = (ffi_cif *) _Jv_Malloc( sizeof( ffi_cif ));
-
- // Pretends that we want to call a void (*) (void) function via
- // ffi_call.
- ffi_type **arg_types = (ffi_type **) _Jv_Malloc( sizeof( ffi_type * ));
- arg_types[0] = &ffi_type_void;
-
- // Initializes the cif and the closure. If that worked the closure is
- // returned and can be used as a function pointer in a class' atable.
- if (ffi_prep_cif (
- cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, arg_types) == FFI_OK
- && (ffi_prep_closure (
- closure, cif, _Jv_ThrowNoClassDefFoundErrorTrampoline,
- class_name) == FFI_OK))
- {
- return closure;
- }
- else
+ method_closure *closure
+ = (method_closure *) _Jv_AllocBytes(sizeof (method_closure));
+
+ closure->arg_types[0] = &ffi_type_void;
+
+ // Initializes the cif and the closure. If that worked the closure
+ // is returned and can be used as a function pointer in a class'
+ // atable.
+ if (ffi_prep_cif (&closure->cif, FFI_DEFAULT_ABI, 1, &ffi_type_void,
+ closure->arg_types) == FFI_OK
+ && ffi_prep_closure (&closure->closure, &closure->cif,
+ _Jv_ThrowNoClassDefFoundErrorTrampoline,
+ class_name) == FFI_OK)
+ return &closure->closure;
+ else
{
java::lang::StringBuffer *buffer = new java::lang::StringBuffer();
- buffer->append(
- JvNewStringLatin1("Error setting up FFI closure"
- " for static method of missing class: "));
-
+ buffer->append(JvNewStringLatin1("Error setting up FFI closure"
+ " for static method of"
+ " missing class: "));
buffer->append (_Jv_NewStringUtf8Const(class_name));
-
throw new java::lang::InternalError(buffer->toString());
}
#else
@@ -1484,7 +1486,11 @@ _Jv_Linker::ensure_fields_laid_out (jclass klass)
}
int instance_size;
- int static_size = 0;
+ // This is the size of the 'static' non-reference fields.
+ int non_reference_size = 0;
+ // This is the size of the 'static' reference fields. We count
+ // these separately to make it simpler for the GC to scan them.
+ int reference_size = 0;
// Although java.lang.Object is never interpreted, an interface can
// have a null superclass. Note that we have to lay out an
@@ -1523,11 +1529,20 @@ _Jv_Linker::ensure_fields_laid_out (jclass klass)
if (field->u.addr == NULL)
{
// This computes an offset into a region we'll allocate
- // shortly, and then add this offset to the start
+ // shortly, and then adds this offset to the start
// address.
- static_size = ROUND (static_size, field_align);
- field->u.boffset = static_size;
- static_size += field_size;
+ if (field->isRef())
+ {
+ reference_size = ROUND (reference_size, field_align);
+ field->u.boffset = reference_size;
+ reference_size += field_size;
+ }
+ else
+ {
+ non_reference_size = ROUND (non_reference_size, field_align);
+ field->u.boffset = non_reference_size;
+ non_reference_size += field_size;
+ }
}
}
else
@@ -1540,8 +1555,9 @@ _Jv_Linker::ensure_fields_laid_out (jclass klass)
}
}
- if (static_size != 0)
- klass->engine->allocate_static_fields (klass, static_size);
+ if (reference_size != 0 || non_reference_size != 0)
+ klass->engine->allocate_static_fields (klass, reference_size,
+ non_reference_size);
// 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
@@ -1696,8 +1712,8 @@ _Jv_Linker::add_miranda_methods (jclass base, jclass iface_class)
// found is really unique among all superinterfaces.
int new_count = base->method_count + 1;
_Jv_Method *new_m
- = (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method)
- * new_count);
+ = (_Jv_Method *) _Jv_AllocRawObj (sizeof (_Jv_Method)
+ * new_count);
memcpy (new_m, base->methods,
sizeof (_Jv_Method) * base->method_count);