X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=libjava%2Fjava%2Flang%2Fref%2FnatReference.cc;fp=libjava%2Fjava%2Flang%2Fref%2FnatReference.cc;h=0000000000000000000000000000000000000000;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=5743349caafc5b754ccd0f32eacfc48fa7c0301d;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/libjava/java/lang/ref/natReference.cc b/libjava/java/lang/ref/natReference.cc deleted file mode 100644 index 5743349c..00000000 --- a/libjava/java/lang/ref/natReference.cc +++ /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 - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -static void finalize_reference (jobject ref); -static void finalize_referred_to_object (jobject obj); - - - -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 (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 (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 (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 (&referent); - _Jv_GCRegisterDisappearingLink (objp); - add_to_hash (this); - } -}