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.

From-SVN: r110763
This commit is contained in:
Tom Tromey 2006-02-08 20:07:29 +00:00 committed by Tom Tromey
parent b5642e2029
commit 8b1753e3ec
7 changed files with 155 additions and 259 deletions

View File

@ -1,3 +1,37 @@
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:

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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
method_closure *closure
= (method_closure *) _Jv_AllocBytes(sizeof (method_closure));
ffi_closure *closure = (ffi_closure *) _Jv_Malloc( sizeof( ffi_closure ));
ffi_cif *cif = (ffi_cif *) _Jv_Malloc( sizeof( ffi_cif ));
closure->arg_types[0] = &ffi_type_void;
// 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
// 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);