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:
parent
b5642e2029
commit
8b1753e3ec
7 changed files with 155 additions and 259 deletions
|
@ -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:
|
||||
|
|
183
libjava/boehm.cc
183
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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
118
libjava/link.cc
118
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
|
||||
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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue