⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reference.c

📁 基于LWVCL开发的库
💻 C
字号:
/* reference.c * Maintain the table of Java references.  * Implement special finalizer for reclaiming or clearing the references. * * Copyright (c) 2005 *      The Kaffe.org's developers. See ChangeLog for details. * * See the file "license.terms" for information on usage and redistribution * of this file. */#include "debug.h"#include "gtypes.h"#include "hashtab.h"#include "baseClasses.h"#include "reference.h"#include "locks.h"#include "gc.h"#include "classMethod.h"#include "native.h"#include "thread.h"#include "utf8const.h"#include "kaffe/jmalloc.h"typedef struct _referenceLinkList {  jobject reference;  kgc_reference_type weight;  struct _referenceLinkList *next;} referenceLinkList;typedef struct _referenceLinkListHead {  jobject obj;  referenceLinkList *references;} referenceLinkListHead;static iStaticLock referencesLock;static hashtab_t referencesHashTable;static uint32 referentOffset = ~((uint32)0);static intobjectHash(const void *p){  const referenceLinkListHead *head = (const referenceLinkListHead *)p;  void *obj = head->obj;#if SIZEOF_INT == SIZEOF_VOID_P && SIZEOF_INT == 4  return (int)(obj) & ((1UL << 31) - 1);#elif SIZEOF_INT == SIZEOF_VOID_P && SIZEOF_INT == 8  return (int)(obj) & ((1ULL << 63) - 1);#elif SIZEOF_INT == 4 && SIZEOF_VOID_P == 8  return (int)( ((uintp)obj >> 32) ^ ((uintp)obj & 0xffffffff));#else#error "Don't know what to do to build a hash function for objects."#endif}static intobjectComp(const void *p1, const void *p2){  const referenceLinkListHead *head1 = (const referenceLinkListHead *)p1;  const referenceLinkListHead *head2 = (const referenceLinkListHead *)p2;  return !(head1->obj == head2->obj);}void KaffeVM_referenceInit(void){  referencesHashTable = hashInit(objectHash, objectComp, NULL, NULL);  initStaticLock(&referencesLock);}void KaffeVM_registerObjectReference(jobject reference, jobject obj, kgc_reference_type reftype){  referenceLinkList *ll;  referenceLinkListHead *head, *temp;  ll = KMALLOC(sizeof(referenceLinkList));  ll->reference = reference;  ll->weight = reftype;  head = KMALLOC(sizeof(referenceLinkListHead));  head->references = ll;  head->obj = obj;    lockStaticMutex(&referencesLock);  temp = (referenceLinkListHead *)hashAdd(referencesHashTable, head);  /* Check whether the hash entry was already filled by someone. */  if (temp != 0 && temp != head)    {      KFREE(head);      ll->next = temp->references;      temp->references = ll;    }  unlockStaticMutex(&referencesLock);  KaffeVM_setFinalizer(reference, KGC_OBJECT_REFERENCE_FINALIZER);  KaffeVM_setFinalizer(obj, KGC_REFERENCE_FINALIZER);   if (referentOffset == ~((uint32)0))    {      Utf8Const *referent_name = utf8ConstFromString("referent");      Field *referent_field;      errorInfo einfo;      referent_field = lookupClassField(javaLangRefReference, referent_name, false, &einfo);      utf8ConstRelease(referent_name);      if (referent_field == NULL)	{	  dumpErrorInfo(&einfo);	  DBG(REFERENCE,	    dprintf("Internal error: The java/lang/ref/Reference class does not have any "		    "'referent' field.\n"		    "Aborting.\n");	  );	  KAFFEVM_ABORT();	}      referentOffset = FIELD_BOFFSET(referent_field);    }  DBG(REFERENCE, dprintf("Reference %p (%s) added for object %p (%s)\n",                 reference, CLASS_CNAME(OBJECT_CLASS((Hjava_lang_Object *)reference)),                 obj, CLASS_CNAME(OBJECT_CLASS((Hjava_lang_Object *)obj))); );  KGC_addWeakRef(main_collector, obj,		 (void **)((char *)reference + referentOffset));}bool KaffeVM_isReferenced(jobject ob){  const referenceLinkListHead *ref;  referenceLinkListHead search_ref;  lockStaticMutex(&referencesLock);  search_ref.obj = ob;  ref = (referenceLinkListHead *)hashFind(referencesHashTable, &search_ref);  unlockStaticMutex(&referencesLock);  return ref != NULL;}static voiddefaultObjectFinalizer(jobject ob){     Hjava_lang_Class* objclass;  Hjava_lang_Object* obj = (Hjava_lang_Object*)ob;  Method* final;    objclass = OBJECT_CLASS(obj);  DBG(REFERENCE, dprintf("Calling default finalizer for object %p (%s)\n",                 obj, CLASS_CNAME(objclass)); );  final = objclass->finalizer;    if (!final)    {      return;    }  KaffeVM_safeCallMethodA(final, METHOD_NATIVECODE(final), obj, NULL, NULL, 0);  THREAD_DATA()->exceptObj = NULL;}static voidreferenceObjectFinalizer(jobject ob){  referenceLinkListHead *head;  referenceLinkList *ll;  referenceLinkListHead search_ref;  lockStaticMutex(&referencesLock);  search_ref.obj = ob;  head = (referenceLinkListHead *)hashFind(referencesHashTable, &search_ref);  hashRemove(referencesHashTable, head);  unlockStaticMutex(&referencesLock);    assert(head != NULL);  assert(head->obj != NULL);  ll = head->references;  while (ll != NULL)    {      referenceLinkList *temp = ll->next;      errorInfo einfo;      Hjava_lang_Class *ref_clazz = OBJECT_CLASS((Hjava_lang_Object*)ll->reference);      Method *mid = lookupClassMethod(ref_clazz, "enqueue", "()Z", false, &einfo);      if (mid != NULL && !METHOD_IS_STATIC(mid))	{	  KaffeVM_safeCallMethodA(mid, METHOD_NATIVECODE(mid), ll->reference, NULL, NULL, false);	  /* Clear any exception thrown */	  THREAD_DATA()->exceptObj = NULL;	}      else	{	  DBG(REFERENCE,	    dprintf("Internal error: a reference (%p) without the enqueue method "		    "has been registered.", ll->reference);	    dprintf("Aborting.\n");	  );	  KAFFEVM_ABORT();	}      DBG(REFERENCE, dprintf("Reference %p java-enqueued and C-dequeud\n", ll->reference); );      KFREE(ll);      ll = temp;    }  KFREE(head);  defaultObjectFinalizer(ob);}static voidreferenceFinalizer(jobject ref){  void *referent;  referenceLinkList **ll;  referenceLinkListHead *head;  referenceLinkListHead search_ref;  DBG(REFERENCE,       dprintf("referenceFinalizer: finalizing reference %p (%s)\n", ref, 	      CLASS_CNAME(OBJECT_CLASS((Hjava_lang_Object *)ref)));       );  assert(referentOffset != ~((uint32)0));  referent = *(void **)((char *)ref + referentOffset);  if (referent == NULL)    {      DBG(REFERENCE,	  dprintf("reference is NULL. The object has already been finalized\n");	  );      defaultObjectFinalizer(ref);      return;    }    lockStaticMutex(&referencesLock);  search_ref.obj = referent;  head = (referenceLinkListHead *)hashFind(referencesHashTable, &search_ref);  /* The object has already been finalized though the reference is still here. */  if (head == NULL)    {      unlockStaticMutex(&referencesLock);      DBG(REFERENCE,	  dprintf("The reference has not been found in the hash table.\n");	  );      defaultObjectFinalizer(ref);      return;    }  ll = &head->references;  while (*ll != NULL)    {      if ((*ll)->reference == ref)	{	  void *temp = *ll;	  *ll = (*ll)->next;	  KFREE(temp);	  break;	}      ll = &(*ll)->next;    }  unlockStaticMutex(&referencesLock);  KGC_rmWeakRef(main_collector, referent,		(void **)((char *)ref + referentOffset));  defaultObjectFinalizer(ref);}void KaffeVM_setFinalizer(jobject obj, kgc_finalizer_type fintype){  Hjava_lang_Object *kobj = (Hjava_lang_Object *)obj;  switch (fintype)    {    case KGC_OBJECT_REFERENCE_FINALIZER:      kobj->finalizer_call = referenceFinalizer;  DBG(REFERENCE,       dprintf("Set object reference finalizer for %p (%s).\n", kobj, 	      CLASS_CNAME(OBJECT_CLASS(kobj)));       );      break;    case KGC_DEFAULT_FINALIZER:      kobj->finalizer_call = defaultObjectFinalizer;      break;    case KGC_REFERENCE_FINALIZER:      kobj->finalizer_call = referenceObjectFinalizer;  DBG(REFERENCE,       dprintf("Set reference finalizer for %p (%s).\n", kobj, 	      CLASS_CNAME(OBJECT_CLASS(kobj)));       );      break;    default:      DBG(REFERENCE,        dprintf("Internal error: invalid finalizer type %d for object %p.\n", fintype, obj);        dprintf("Aborting.\n");      );      KAFFEVM_ABORT();    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -