OSDN Git Service

PR testsuite/46230
[pf3gnuchains/gcc-fork.git] / libjava / boehm.cc
index 9ee633b..855d23c 100644 (file)
@@ -1,6 +1,6 @@
 // boehm.cc - interface between libjava and Boehm GC.
 
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation
 
    This file is part of libgcj.
@@ -36,7 +36,6 @@ details.  */
 #undef _GNU_SOURCE
 #define _GNU_SOURCE
 #include <dlfcn.h>
-#include <link.h>
 #endif
 
 extern "C"
@@ -168,6 +167,14 @@ _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);
+
+      p = (GC_PTR) c->reflection_data;
+      MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
+
+      // The class chain must be marked for runtime-allocated Classes
+      // loaded by the bootstrap ClassLoader.
+      p = (GC_PTR) c->next_or_version;
+      MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
     }
   else
     {
@@ -373,6 +380,31 @@ _Jv_AllocRawObj (jsize size)
   return (void *) GC_MALLOC (size ? size : 1);
 }
 
+#ifdef INTERPRETER
+typedef _Jv_ClosureList *closure_list_pointer;
+
+/* Release closures in a _Jv_ClosureList.  */
+static void
+finalize_closure_list (GC_PTR obj, GC_PTR)
+{
+  _Jv_ClosureList **clpp = (_Jv_ClosureList **)obj;
+  _Jv_ClosureList::releaseClosures (clpp);
+}
+
+/* Allocate a double-indirect pointer to a _Jv_ClosureList that will
+   get garbage-collected after this double-indirect pointer becomes
+   unreachable by any other objects, including finalizable ones.  */
+_Jv_ClosureList **
+_Jv_ClosureListFinalizer ()
+{
+  _Jv_ClosureList **clpp;
+  clpp = (_Jv_ClosureList **)_Jv_AllocBytes (sizeof (*clpp));
+  GC_REGISTER_FINALIZER_UNREACHABLE (clpp, finalize_closure_list,
+                                    NULL, NULL, NULL);
+  return clpp;
+}
+#endif // INTERPRETER
+
 static void
 call_finalizer (GC_PTR obj, GC_PTR client_data)
 {
@@ -433,6 +465,12 @@ _Jv_GCSetMaximumHeapSize (size_t size)
   GC_set_max_heap_size ((GC_word) size);
 }
 
+int
+_Jv_SetGCFreeSpaceDivisor (int div)
+{
+  return (int)GC_set_free_space_divisor ((GC_word)div);
+}
+
 void
 _Jv_DisableGC (void)
 {
@@ -487,7 +525,7 @@ _Jv_InitGC (void)
   // Ignore pointers that do not point to the start of an object.
   GC_all_interior_pointers = 0;
 
-#ifdef HAVE_DLFCN_H
+#if defined (HAVE_DLFCN_H) && defined (HAVE_DLADDR)
   // Tell the collector to ask us before scanning DSOs.
   GC_register_has_static_roots_callback (_Jv_GC_has_static_roots);
 #endif
@@ -582,7 +620,7 @@ _Jv_GCCanReclaimSoftReference (jobject)
 
 \f
 
-#ifdef HAVE_DLFCN_H
+#if defined (HAVE_DLFCN_H) && defined (HAVE_DLADDR)
 
 // We keep a store of the filenames of DSOs that need to be
 // conservatively scanned by the garbage collector.  During collection
@@ -662,10 +700,10 @@ _Jv_GC_has_static_roots (const char *filename, void *, size_t)
 void
 _Jv_RegisterLibForGc (const void *p __attribute__ ((__unused__)))
 {
-#ifdef HAVE_DLFCN_H
+#if defined (HAVE_DLFCN_H) && defined (HAVE_DLADDR)
   Dl_info info;
-  
-  if (dladdr (p, &info) != 0)
+
+  if (dladdr (const_cast<void *>(p), &info) != 0)
     {
       filename_node **node = find_file (info.dli_fname);
       if (! *node)
@@ -674,3 +712,50 @@ _Jv_RegisterLibForGc (const void *p __attribute__ ((__unused__)))
 #endif
 }
 
+void
+_Jv_SuspendThread (_Jv_Thread_t *thread)
+{
+#if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
+     && !defined(GC_WIN32_THREADS) && !defined(GC_DARWIN_THREADS)
+  GC_suspend_thread (_Jv_GetPlatformThreadID (thread));
+#endif
+}
+
+void
+_Jv_ResumeThread (_Jv_Thread_t *thread)
+{
+#if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
+     && !defined(GC_WIN32_THREADS) && !defined(GC_DARWIN_THREADS)
+  GC_resume_thread (_Jv_GetPlatformThreadID (thread));
+#endif
+}
+
+int
+_Jv_IsThreadSuspended (_Jv_Thread_t *thread)
+{
+#if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
+     && !defined(GC_WIN32_THREADS) && !defined(GC_DARWIN_THREADS)
+  return GC_is_thread_suspended (_Jv_GetPlatformThreadID (thread));
+#else
+  return 0;
+#endif
+}
+
+void
+_Jv_GCAttachThread ()
+{
+  // The registration interface is only defined on posixy systems and
+  // only actually works if pthread_getattr_np is defined.
+  // FIXME: until gc7 it is simpler to disable this on solaris.
+#if defined(HAVE_PTHREAD_GETATTR_NP) && !defined(GC_SOLARIS_THREADS)
+  GC_register_my_thread ();
+#endif
+}
+
+void
+_Jv_GCDetachThread ()
+{
+#if defined(HAVE_PTHREAD_GETATTR_NP) && !defined(GC_SOLARIS_THREADS)
+  GC_unregister_my_thread ();
+#endif
+}