gcc3.2.1源代码

源代码在线查看: natreference.cc

软件大小: 26469 K
上传用户: ccuading
关键词: gcc 源代码
下载地址: 免注册下载 普通下载 VIP

相关代码

				// 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 					{					  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);				    }				}							

相关资源