summaryrefslogtreecommitdiff
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
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
-rw-r--r--libjava/ChangeLog34
-rw-r--r--libjava/boehm.cc183
-rw-r--r--libjava/defineclass.cc35
-rw-r--r--libjava/include/execution.h8
-rw-r--r--libjava/include/jvm.h11
-rw-r--r--libjava/interpret.cc25
-rw-r--r--libjava/link.cc122
7 files changed, 157 insertions, 261 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 2372781607d..c04f560913b 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,5 +1,39 @@
2006-02-08 Tom Tromey <tromey@redhat.com>
+ 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.
+
+2006-02-08 Tom Tromey <tromey@redhat.com>
+
PR java/22578:
* gcj/javaprims.h: Updated.
* sources.am, Makefile.in: Rebuilt.
diff --git a/libjava/boehm.cc b/libjava/boehm.cc
index 06b8f9889e8..fc75bdb7005 100644
--- a/libjava/boehm.cc
+++ b/libjava/boehm.cc
@@ -1,6 +1,6 @@
// boehm.cc - interface between libjava and Boehm GC.
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation
This file is part of libgcj.
@@ -85,6 +85,9 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void *env)
jclass klass = dt->clas;
GC_PTR p;
+ p = (GC_PTR) dt;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, obj);
+
# ifndef JV_HASH_SYNCHRONIZATION
// Every object has a sync_info pointer.
p = (GC_PTR) obj->sync_info;
@@ -114,25 +117,10 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void *env)
MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
p = (GC_PTR) c->superclass;
MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- for (int i = 0; i < c->constants.size; ++i)
- {
- /* FIXME: We could make this more precise by using the tags -KKT */
- p = (GC_PTR) c->constants.data[i].p;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- }
-
-#ifdef INTERPRETER
- if (_Jv_IsInterpretedClass (c))
- {
- p = (GC_PTR) c->constants.tags;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- p = (GC_PTR) c->constants.data;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- }
-#endif
- // The vtable might be allocated even for compiled code.
- p = (GC_PTR) c->vtable;
+ p = (GC_PTR) c->constants.tags;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
+ p = (GC_PTR) c->constants.data;
MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
// If the class is an array, then the methods field holds a
@@ -141,101 +129,24 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void *env)
p = (GC_PTR) c->methods;
MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- // The vtable might have been set, but the rest of the class
- // could still be uninitialized. If this is the case, then
- // c.isArray will SEGV. We check for this, and if it is the
- // case we just return.
- if (__builtin_expect (c->name == NULL, false))
- return mark_stack_ptr;
-
- if (! c->isArray() && ! c->isPrimitive())
- {
- // Scan each method in the cases where `methods' really
- // points to a methods structure.
- for (int i = 0; i < c->method_count; ++i)
- {
- p = (GC_PTR) c->methods[i].name;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- p = (GC_PTR) c->methods[i].signature;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
-
- // Note that we don't have to mark each individual throw
- // separately, as these are stored in the constant pool.
- p = (GC_PTR) c->methods[i].throws;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- }
- }
-
- // Mark all the fields.
p = (GC_PTR) c->fields;
MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- for (int i = 0; i < c->field_count; ++i)
- {
- _Jv_Field* field = &c->fields[i];
-
- p = (GC_PTR) field->name;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- p = (GC_PTR) field->type;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
-
- // For the interpreter, we also need to mark the memory
- // containing static members
- if ((field->flags & java::lang::reflect::Modifier::STATIC))
- {
- p = (GC_PTR) field->u.addr;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
-
- // also, if the static member is a reference,
- // mark also the value pointed to. We check for isResolved
- // since marking can happen before memory is allocated for
- // static members.
- // Note that field->u.addr may be null if the class c is
- // JV_STATE_LOADED but not JV_STATE_PREPARED (initialized).
- // Note also that field->type could be NULL in some
- // situations, for instance if the class has state
- // JV_STATE_ERROR.
- if (field->type && JvFieldIsRef (field)
- && p && field->isResolved())
- {
- jobject val = *(jobject*) p;
- p = (GC_PTR) val;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- }
- }
- }
+ // The vtable might be allocated even for compiled code.
p = (GC_PTR) c->vtable;
MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
+
p = (GC_PTR) c->interfaces;
MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- for (int i = 0; i < c->interface_count; ++i)
- {
- p = (GC_PTR) c->interfaces[i];
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- }
p = (GC_PTR) c->loader;
MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
// The dispatch tables can be allocated at runtime.
p = (GC_PTR) c->ancestors;
MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- if (c->idt)
- {
- p = (GC_PTR) c->idt;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
- if (c->isInterface())
- {
- p = (GC_PTR) c->idt->iface.ioffsets;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c->idt);
- }
- else if (! c->isPrimitive())
- {
- // This field is only valid for ordinary classes.
- p = (GC_PTR) c->idt->cls.itable;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c->idt);
- }
- }
+ p = (GC_PTR) c->idt;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
p = (GC_PTR) c->arrayclass;
MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
@@ -245,73 +156,6 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void *env)
MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
p = (GC_PTR) c->aux_info;
MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
-
-#ifdef INTERPRETER
- if (_Jv_IsInterpretedClass (c) && c->aux_info)
- {
- _Jv_InterpClass* ic = (_Jv_InterpClass*) c->aux_info;
-
- p = (GC_PTR) ic->interpreted_methods;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic);
-
- p = (GC_PTR) ic->source_file_name;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic);
-
- for (int i = 0; i < c->method_count; i++)
- {
- // The interpreter installs a heap-allocated trampoline
- // here, so we'll mark it.
- p = (GC_PTR) c->methods[i].ncode;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
-
- using namespace java::lang::reflect;
-
- // Mark the direct-threaded code. Note a subtlety here:
- // when we add Miranda methods to a class, we don't
- // resize its interpreted_methods array. If we try to
- // reference one of these methods, we may crash.
- // However, we know these are all abstract, and we know
- // that abstract methods have nothing useful in this
- // array. So, we skip all abstract methods to avoid the
- // problem. FIXME: this is pretty obscure, it may be
- // better to add a methods to the execution engine and
- // resize the array.
- if ((c->methods[i].accflags & Modifier::ABSTRACT) != 0)
- continue;
-
- p = (GC_PTR) ic->interpreted_methods[i];
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic);
-
- if ((c->methods[i].accflags & Modifier::NATIVE) != 0)
- {
- _Jv_JNIMethod *jm
- = (_Jv_JNIMethod *) ic->interpreted_methods[i];
- if (jm)
- {
- p = (GC_PTR) jm->jni_arg_types;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, p);
- }
- }
- else
- {
- _Jv_InterpMethod *im
- = (_Jv_InterpMethod *) ic->interpreted_methods[i];
- if (im)
- {
- p = (GC_PTR) im->line_table;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic);
- p = (GC_PTR) im->prepared;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic);
- }
- }
- }
-
- p = (GC_PTR) ic->field_initializers;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic);
-
- }
-#endif
-
}
else
{
@@ -367,6 +211,9 @@ _Jv_MarkArray (void *addr, void *msp, void *msl, void *env)
jclass klass = dt->clas;
GC_PTR p;
+ p = (GC_PTR) dt;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, array);
+
# ifndef JV_HASH_SYNCHRONIZATION
// Every object has a sync_info pointer.
p = (GC_PTR) array->sync_info;
@@ -515,7 +362,7 @@ _Jv_AllocArray (jsize size, jclass klass)
void *
_Jv_AllocRawObj (jsize size)
{
- return (void *) GC_MALLOC (size);
+ return (void *) GC_MALLOC (size ? size : 1);
}
static void
diff --git a/libjava/defineclass.cc b/libjava/defineclass.cc
index 89e0636f4aa..c15cc2265d6 100644
--- a/libjava/defineclass.cc
+++ b/libjava/defineclass.cc
@@ -1,6 +1,6 @@
// defineclass.cc - defining a class from .class format.
-/* 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.
@@ -350,7 +350,7 @@ _Jv_ClassReader::parse ()
// Allocate our aux_info here, after the name is set, to fulfill our
// contract with the collector interface.
- def->aux_info = (void *) _Jv_AllocBytes (sizeof (_Jv_InterpClass));
+ def->aux_info = (void *) _Jv_AllocRawObj (sizeof (_Jv_InterpClass));
def_interp = (_Jv_InterpClass *) def->aux_info;
int interfaces_count = read2u ();
@@ -387,8 +387,7 @@ _Jv_ClassReader::parse ()
void _Jv_ClassReader::read_constpool ()
{
tags = (unsigned char*) _Jv_AllocBytes (pool_count);
- offsets = (unsigned int *) _Jv_AllocBytes (sizeof (int)
- * pool_count) ;
+ offsets = (unsigned int *) _Jv_AllocBytes (sizeof (int) * pool_count) ;
/** first, we scan the constant pool, collecting tags and offsets */
tags[0] = JV_CONSTANT_Undefined;
@@ -656,8 +655,8 @@ void _Jv_ClassReader::read_one_code_attribute (int method_index)
int table_len = read2u ();
_Jv_LineTableEntry* table
- = (_Jv_LineTableEntry *) JvAllocBytes (table_len
- * sizeof (_Jv_LineTableEntry));
+ = (_Jv_LineTableEntry *) _Jv_AllocBytes (table_len
+ * sizeof (_Jv_LineTableEntry));
for (int i = 0; i < table_len; i++)
{
table[i].bytecode_pc = read2u ();
@@ -702,11 +701,10 @@ void _Jv_ClassReader::handleConstantPool ()
{
/** now, we actually define the class' constant pool */
- // the pool is scanned explicitly by the collector
jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
_Jv_word *pool_data
- = (_Jv_word*) _Jv_AllocBytes (pool_count * sizeof (_Jv_word));
-
+ = (_Jv_word*) _Jv_AllocRawObj (pool_count * sizeof (_Jv_word));
+
def->constants.tags = pool_tags;
def->constants.data = pool_data;
def->constants.size = pool_count;
@@ -1046,7 +1044,7 @@ _Jv_ClassReader::checkExtends (jclass sub, jclass super)
void _Jv_ClassReader::handleInterfacesBegin (int count)
{
- def->interfaces = (jclass*) _Jv_AllocBytes (count*sizeof (jclass));
+ def->interfaces = (jclass*) _Jv_AllocRawObj (count*sizeof (jclass));
def->interface_count = count;
}
@@ -1112,11 +1110,10 @@ _Jv_ClassReader::checkImplements (jclass sub, jclass super)
void _Jv_ClassReader::handleFieldsBegin (int count)
{
- def->fields = (_Jv_Field*)
- _Jv_AllocBytes (count * sizeof (_Jv_Field));
+ def->fields = (_Jv_Field*) _Jv_AllocRawObj (count * sizeof (_Jv_Field));
def->field_count = count;
- def_interp->field_initializers = (_Jv_ushort*)
- _Jv_AllocBytes (count * sizeof (_Jv_ushort));
+ def_interp->field_initializers
+ = (_Jv_ushort*) _Jv_AllocRawObj (count * sizeof (_Jv_ushort));
for (int i = 0; i < count; i++)
def_interp->field_initializers[i] = (_Jv_ushort) 0;
}
@@ -1256,11 +1253,11 @@ void _Jv_ClassReader::handleFieldsEnd ()
void
_Jv_ClassReader::handleMethodsBegin (int count)
{
- def->methods = (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method) * count);
+ def->methods = (_Jv_Method *) _Jv_AllocRawObj (sizeof (_Jv_Method) * count);
def_interp->interpreted_methods
- = (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
- * count);
+ = (_Jv_MethodBase **) _Jv_AllocRawObj (sizeof (_Jv_MethodBase *)
+ * count);
for (int i = 0; i < count; i++)
{
@@ -1331,7 +1328,7 @@ void _Jv_ClassReader::handleCodeAttribute
{
int size = _Jv_InterpMethod::size (exc_table_length, code_length);
_Jv_InterpMethod *method =
- (_Jv_InterpMethod*) (_Jv_AllocBytes (size));
+ (_Jv_InterpMethod*) (_Jv_AllocRawObj (size));
method->max_stack = max_stack;
method->max_locals = max_locals;
@@ -1390,7 +1387,7 @@ void _Jv_ClassReader::handleMethodsEnd ()
else
{
_Jv_JNIMethod *m = (_Jv_JNIMethod *)
- _Jv_AllocBytes (sizeof (_Jv_JNIMethod));
+ _Jv_AllocRawObj (sizeof (_Jv_JNIMethod));
m->defining_class = def;
m->self = method;
m->function = NULL;
diff --git a/libjava/include/execution.h b/libjava/include/execution.h
index b8f47468fc7..88189f6449e 100644
--- a/libjava/include/execution.h
+++ b/libjava/include/execution.h
@@ -1,6 +1,6 @@
// execution.h - Execution engines. -*- c++ -*-
-/* Copyright (C) 2004 Free Software Foundation
+/* Copyright (C) 2004, 2006 Free Software Foundation
This file is part of libgcj.
@@ -23,7 +23,7 @@ struct _Jv_ExecutionEngine
// interpreter does it.
bool (*need_resolve_string_fields) ();
void (*verify) (jclass);
- void (*allocate_static_fields) (jclass, int);
+ void (*allocate_static_fields) (jclass, int, int);
void (*create_ncode) (jclass);
_Jv_ResolvedMethod *(*resolve_method) (_Jv_Method *, jclass,
jboolean, jint);
@@ -55,7 +55,7 @@ struct _Jv_CompiledEngine : public _Jv_ExecutionEngine
return NULL;
}
- static void do_allocate_static_fields (jclass, int)
+ static void do_allocate_static_fields (jclass, int, int)
{
// Compiled classes don't need this.
}
@@ -99,7 +99,7 @@ class _Jv_InterpreterEngine : public _Jv_ExecutionEngine
public:
static void do_verify (jclass);
- static void do_allocate_static_fields (jclass, int);
+ static void do_allocate_static_fields (jclass, int, int);
static void do_create_ncode (jclass);
static _Jv_ResolvedMethod *do_resolve_method (_Jv_Method *, jclass,
jboolean, jint);
diff --git a/libjava/include/jvm.h b/libjava/include/jvm.h
index b0b33058307..e5187f4d3f0 100644
--- a/libjava/include/jvm.h
+++ b/libjava/include/jvm.h
@@ -1,6 +1,6 @@
// jvm.h - Header file for private implementation information. -*- c++ -*-
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
This file is part of libgcj.
@@ -72,6 +72,7 @@ struct _Jv_VTable
{
return (2 * sizeof (void *)) + (index * vtable_elt_size ());
}
+
static _Jv_VTable *new_vtable (int count);
};
@@ -374,16 +375,12 @@ void _Jv_RunMain (jclass klass, const char *name, int argc, const char **argv,
void _Jv_RunMain (struct _Jv_VMInitArgs *vm_args, jclass klass,
const char *name, int argc, const char **argv, bool is_jar);
-// Delayed until after _Jv_AllocBytes is declared.
-//
-// Note that we allocate this as unscanned memory -- the vtables
-// are handled specially by the GC.
-
+// Delayed until after _Jv_AllocRawObj is declared.
inline _Jv_VTable *
_Jv_VTable::new_vtable (int count)
{
size_t size = sizeof(_Jv_VTable) + (count - 1) * vtable_elt_size ();
- return (_Jv_VTable *) _Jv_AllocBytes (size);
+ return (_Jv_VTable *) _Jv_AllocRawObj (size);
}
// Determine if METH gets an entry in a VTable.
diff --git a/libjava/interpret.cc b/libjava/interpret.cc
index 87d357c94c2..f95671d267b 100644
--- a/libjava/interpret.cc
+++ b/libjava/interpret.cc
@@ -3877,25 +3877,30 @@ _Jv_InterpreterEngine::do_create_ncode (jclass klass)
void
_Jv_InterpreterEngine::do_allocate_static_fields (jclass klass,
- int static_size)
+ int pointer_size,
+ int other_size)
{
_Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
- char *static_data = (char *) _Jv_AllocBytes (static_size);
+ // Splitting the allocations here lets us scan reference fields and
+ // avoid scanning non-reference fields.
+ char *reference_fields = (char *) _Jv_AllocRawObj (pointer_size);
+ char *non_reference_fields = (char *) _Jv_AllocBytes (other_size);
for (int i = 0; i < klass->field_count; i++)
{
_Jv_Field *field = &klass->fields[i];
- if ((field->flags & java::lang::reflect::Modifier::STATIC) != 0)
+ if ((field->flags & java::lang::reflect::Modifier::STATIC) == 0)
+ continue;
+
+ char *base = field->isRef() ? reference_fields : non_reference_fields;
+ field->u.addr = base + field->u.boffset;
+
+ if (iclass->field_initializers[i] != 0)
{
- field->u.addr = static_data + field->u.boffset;
-
- if (iclass->field_initializers[i] != 0)
- {
- _Jv_Linker::resolve_field (field, klass->loader);
- _Jv_InitField (0, klass, i);
- }
+ _Jv_Linker::resolve_field (field, klass->loader);
+ _Jv_InitField (0, klass, i);
}
}
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);