]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - libjava/java/lang/ref/natReference.cc
Imported gcc-4.4.3
[msp430-gcc.git] / libjava / java / lang / ref / natReference.cc
diff --git a/libjava/java/lang/ref/natReference.cc b/libjava/java/lang/ref/natReference.cc
deleted file mode 100644 (file)
index 5743349..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-// natReference.cc - Native code for References
-
-/* Copyright (C) 2001  Free Software Foundation
-
-   This file is part of libgcj.
-
-This software is copyrighted work licensed under the terms of the
-Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
-details.  */
-
-// Written by Tom Tromey <tromey@redhat.com>
-
-#include <config.h>
-
-#include <gcj/cni.h>
-#include <jvm.h>
-#include <java/lang/Throwable.h>
-#include <java/lang/ref/Reference.h>
-#include <java/lang/ref/SoftReference.h>
-#include <java/lang/ref/WeakReference.h>
-#include <java/lang/ref/PhantomReference.h>
-#include <java/lang/ref/ReferenceQueue.h>
-
-static void finalize_reference (jobject ref);
-static void finalize_referred_to_object (jobject obj);
-
-\f
-
-enum weight
-{
-  SOFT = 0,
-  WEAK = 1,
-  FINALIZE = 2,
-  PHANTOM = 3,
-
-  // This is used to mark the head of a list.
-  HEAD = 4,
-
-  // This is used to mark a deleted item.
-  DELETED = 5
-};
-
-// Objects of this type are used in the hash table to keep track of
-// the mapping between a finalizable object and the various References
-// which refer to it.
-struct object_list
-{
-  // The reference object.  This is NULL for FINALIZE weight.
-  jobject reference;
-
-  // The weight of this object.
-  enum weight weight;
-
-  // Next in list.
-  object_list *next;
-};
-
-// Hash table used to hold mapping from object to References.  The
-// object_list item in the hash holds the object itself in the
-// reference field; chained to it are all the references sorted in
-// order of weight (lowest first).
-static object_list *hash = NULL;
-
-// Number of slots used in HASH.
-static int hash_count = 0;
-
-// Number of slots total in HASH.  Must be power of 2.
-static int hash_size = 0;
-
-static object_list *
-find_slot (jobject key)
-{
-  jint hcode = _Jv_HashCode (key);
-  /* step must be non-zero, and relatively prime with hash_size. */
-  jint step = (hcode ^ (hcode >> 16)) | 1;
-  int start_index = hcode & (hash_size - 1);
-  int index = start_index;
-  int deleted_index = -1;
-  for (;;)
-    {
-      object_list *ptr = &hash[index];
-      if (ptr->reference == key)
-       return ptr;
-      else if (ptr->reference == NULL)
-       {
-         if (deleted_index == -1)
-           return ptr;
-         else
-           return &hash[deleted_index];
-       }
-      else if (ptr->weight == DELETED)
-       deleted_index = index;
-      index = (index + step) & (hash_size - 1);
-      JvAssert (index != start_index);
-    }
-}
-
-static void
-rehash ()
-{
-  if (hash == NULL)
-    {
-      hash_size = 1024;
-      hash = (object_list *) _Jv_Malloc (hash_size * sizeof (object_list));
-      memset (hash, 0, hash_size * sizeof (object_list));
-    }
-  else
-    {
-      object_list *old = hash;
-      int i = hash_size;
-
-      hash_size *= 2;
-      hash = (object_list *) _Jv_Malloc (hash_size * sizeof (object_list));
-      memset (hash, 0, hash_size * sizeof (object_list));
-
-      while (--i >= 0)
-       {
-         if (old[i].reference == NULL || old[i].weight == DELETED)
-           continue;
-         object_list *newslot = find_slot (old[i].reference);
-         *newslot = old[i];
-       }
-
-      _Jv_Free (old);
-    }
-}
-
-// Remove a Reference.
-static void
-remove_from_hash (jobject obj)
-{
-  java::lang::ref::Reference *ref
-    = reinterpret_cast<java::lang::ref::Reference *> (obj);
-  object_list *head = find_slot (ref->copy);
-  object_list **link = &head->next;
-  head = head->next;
-
-  while (head && head->reference != ref)
-    {
-      link = &head->next;
-      head = head->next;
-    }
-
-  // Remove the slot.
-  if (head)
-    {
-      *link = head->next;
-      _Jv_Free (head);
-    }
-}
-
-// FIXME what happens if an object's finalizer creates a Reference to
-// the object, and the object has never before been added to the hash?
-// Madness!
-
-// Add an item to the hash table.  If the item is new, we also add a
-// finalizer item.  We keep items in the hash table until they are
-// completely collected; this lets us know when an item is new, even
-// if it has been resurrected after its finalizer has been run.
-static void
-add_to_hash (java::lang::ref::Reference *the_reference)
-{
-  JvSynchronize sync (java::lang::ref::Reference::lock);
-
-  if (3 * hash_count >= 2 * hash_size)
-    rehash ();
-
-  jobject referent = the_reference->referent;
-  object_list *item = find_slot (referent);
-  if (item->reference == NULL)
-    {
-      // New item, so make an entry for the finalizer.
-      item->reference = referent;
-      item->weight = HEAD;
-
-      item->next = (object_list *) _Jv_Malloc (sizeof (object_list));
-      item->next->reference = NULL;
-      item->next->weight = FINALIZE;
-      item->next->next = NULL;
-      ++hash_count;
-    }
-
-  object_list *n = (object_list *) _Jv_Malloc (sizeof (object_list));
-  n->reference = the_reference;
-
-  enum weight w = PHANTOM;
-  if (java::lang::ref::SoftReference::class$.isInstance (the_reference))
-    w = SOFT;
-  else if (java::lang::ref::WeakReference::class$.isInstance (the_reference))
-    w = WEAK;
-  n->weight = w;
-
-  object_list **link = &item->next;
-  object_list *iter = *link;
-  while (iter && iter->weight < n->weight)
-    {
-      link = &iter->next;
-      iter = *link;
-    }
-  n->next = (*link) ? (*link)->next : NULL;
-  *link = n;
-}
-
-// This is called when an object is ready to be finalized.  This
-// actually implements the appropriate Reference semantics.
-static void
-finalize_referred_to_object (jobject obj)
-{
-  JvSynchronize sync (java::lang::ref::Reference::lock);
-
-  object_list *list = find_slot (obj);
-  object_list *head = list->next;
-  if (head == NULL)
-    {
-      // We have a truly dead object: the object's finalizer has been
-      // run, all the object's references have been processed, and the
-      // object is unreachable.  There is, at long last, no way to
-      // resurrect it.
-      list->weight = DELETED;
-      --hash_count;
-      return;
-    }
-
-  enum weight w = head->weight;
-  if (w == FINALIZE)
-    {
-      // If we have a Reference A to a Reference B, and B is
-      // finalized, then we have to take special care to make sure
-      // that B is properly deregistered.  This is super gross.  FIXME
-      // will it fail if B's finalizer resurrects B?
-      if (java::lang::ref::Reference::class$.isInstance (obj))
-       finalize_reference (obj);
-      else
-       _Jv_FinalizeObject (obj);
-      list->next = head->next;
-      _Jv_Free (head);
-    }
-  else if (w != SOFT || _Jv_GCCanReclaimSoftReference (obj))
-    {
-      // If we just decided to reclaim a soft reference, we might as
-      // well do all the weak references at the same time.
-      if (w == SOFT)
-       w = WEAK;
-
-      while (head && head->weight <= w)
-       {
-         java::lang::ref::Reference *ref
-           = reinterpret_cast<java::lang::ref::Reference *> (head->reference);
-         // If the copy is already NULL then the user must have
-         // called Reference.clear().
-         if (ref->copy != NULL)
-           {
-             if (w == PHANTOM)
-               ref->referent = ref->copy;
-             else
-               ref->copy = NULL;
-             ref->enqueue ();
-           }
-
-         object_list *next = head->next;
-         _Jv_Free (head);
-         head = next;
-       }
-      list->next = head;
-    }
-
-  // Re-register this finalizer.  We always re-register because we
-  // can't know until the next collection cycle whether or not the
-  // object is truly unreachable.
-  _Jv_RegisterFinalizer (obj, finalize_referred_to_object);
-}
-
-// This is called when a Reference object is finalized.  If there is a
-// Reference pointing to this Reference then that case is handled by
-// finalize_referred_to_object.
-static void
-finalize_reference (jobject ref)
-{
-  JvSynchronize sync (java::lang::ref::Reference::lock);
-  remove_from_hash (ref);
-  // The user might have a subclass of Reference with a finalizer.
-  _Jv_FinalizeObject (ref);
-}
-
-void
-::java::lang::ref::Reference::create (jobject ref)
-{
-  // Nothing says you can't make a Reference with a NULL referent.
-  // But there's nothing to do in such a case.
-  referent = reinterpret_cast<gnu::gcj::RawData *> (ref);
-  copy = referent;
-  if (referent != NULL)
-    {
-      JvSynchronize sync (java::lang::ref::Reference::lock);
-      // `this' is a new Reference object.  We register a new
-      // finalizer for pointed-to object and we arrange a special
-      // finalizer for ourselves as well.
-      _Jv_RegisterFinalizer (this, finalize_reference);
-      _Jv_RegisterFinalizer (referent, finalize_referred_to_object);
-      jobject *objp = reinterpret_cast<jobject *> (&referent);
-      _Jv_GCRegisterDisappearingLink (objp);
-      add_to_hash (this);
-    }
-}