]> gcc.gnu.org Git - gcc.git/commitdiff
PR libgcj/26063, PR libgcj/17978, PR libgcj/10598:
authorTom Tromey <tromey@redhat.com>
Wed, 8 Feb 2006 20:07:29 +0000 (20:07 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Wed, 8 Feb 2006 20:07:29 +0000 (20:07 +0000)
* 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

libjava/ChangeLog
libjava/boehm.cc
libjava/defineclass.cc
libjava/include/execution.h
libjava/include/jvm.h
libjava/interpret.cc
libjava/link.cc

index 2372781607dd8ed71f333b130b1eafc5801ba07b..c04f560913b25c3ec794ce2ffc5a476e08708f39 100644 (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:
index 06b8f9889e86ed5c6690c39a96d1509db0fc9724..fc75bdb70055f76ea031a6acc94f8d1eaf329f2d 100644 (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
index 89e0636f4aa71d88607ff44e078b0723dce11e39..c15cc2265d60e98c7975b54a6baadb4e4af07651 100644 (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;
index b8f47468fc75d872b4f172721d7508994a757e93..88189f6449ec263646df103ff12e9477e03ab308 100644 (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);
index b0b330583074373604864f4e3ccd3303a450ccdd..e5187f4d3f07d49199e9d5993a3ad742e910d654 100644 (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.
index 87d357c94c2c7583b17000421f57cafb515da5ec..f95671d267bb9da3ac3eafd3ee0420da3ace1b27 100644 (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);
        }
     }
 
index 0f9f7c1ca32bdb318d8bac5e7d9a4d3650b7bb46..26bf8984e24fcf9cecf48c7732a94c6e18c10176 100644 (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
-
-  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);
 
This page took 0.108719 seconds and 5 git commands to generate.