Esempio n. 1
0
EXTERN void val_gc(value v, finalizer f ) {
	if( !val_is_abstract(v) )
		failure("val_gc");
	if( f )
		GC_REGISTER_FINALIZER_NO_ORDER(v,(GC_finalization_proc)__on_finalize,f,0,0);
	else
		GC_REGISTER_FINALIZER_NO_ORDER(v,NULL,NULL,0,0);
}
Esempio n. 2
0
void rvmRegisterReference(Env* env, Object* reference, Object* referent) {
    if (referent) {
        // Add 'reference' to the references list for 'referent' in the referents hashtable
        rvmLockMutex(&referentsLock);

        ReferenceList* l = rvmAllocateMemory(env, sizeof(ReferenceList));
        if (!l) goto done; // OOM thrown
        l->reference = reference;

        void* key = (void*) GC_HIDE_POINTER(referent); // Hide the pointer from the GC so that it doesn't prevent the referent from being GCed.
        ReferentEntry* referentEntry;
        HASH_FIND_PTR(referents, &key, referentEntry);
        if (!referentEntry) {
            // referent is not in the hashtable. Add it.
            referentEntry = rvmAllocateMemory(env, sizeof(ReferentEntry));
            if (!referentEntry) goto done; // OOM thrown
            referentEntry->key = key;
            HASH_ADD_PTR(referents, key, referentEntry);
        }

        // Add the reference to the referent's list of references
        LL_PREPEND(referentEntry->references, l);

        // Register the referent for finalization
        GC_REGISTER_FINALIZER_NO_ORDER(referent, _finalizeObject, NULL, NULL, NULL);

done:
        rvmUnlockMutex(&referentsLock);
    }
}
Esempio n. 3
0
void
scm_i_set_finalizer (void *obj, scm_t_finalizer_proc proc, void *data)
{
  GC_finalization_proc prev;
  void *prev_data;
  GC_REGISTER_FINALIZER_NO_ORDER (obj, proc, data, &prev, &prev_data);
}
Esempio n. 4
0
static void finalizeObject(Env* env, Object* obj) {
//    TRACEF("finalizeObject: %p (%s)\n", obj, obj->clazz->name);

    rvmLockMutex(&referentsLock);
    void* key = (void*) GC_HIDE_POINTER(obj);
    ReferentEntry* referentEntry;
    HASH_FIND_PTR(referents, &key, referentEntry);

    assert(referentEntry != NULL);

    if (referentEntry->references == NULL) {
        // The object is not referenced by any type of reference and can never be resurrected.
        HASH_DEL(referents, referentEntry);
        rvmUnlockMutex(&referentsLock);
        return;
    }

    Object* softReferences = NULL;
    Object* weakReferences = NULL;
    Object* finalizerReferences = NULL;
    Object* phantomReferences = NULL;
    Object* clearedReferences = NULL;

    ReferenceList* refNode;
    while (referentEntry->references != NULL) {
        refNode = referentEntry->references;
        LL_DELETE(referentEntry->references, refNode);
        Object** list = NULL;
        Object* reference = refNode->reference;
        if (rvmIsSubClass(java_lang_ref_SoftReference, reference->clazz)) {
            list = &softReferences;
        } else if (rvmIsSubClass(java_lang_ref_WeakReference, reference->clazz)) {
            list = &weakReferences;
        } else if (rvmIsSubClass(java_lang_ref_FinalizerReference, reference->clazz)) {
            list = &finalizerReferences;
        } else if (rvmIsSubClass(java_lang_ref_PhantomReference, reference->clazz)) {
            list = &phantomReferences;
        }
        enqueuePendingReference(env, reference, list);
    }
    assert(referentEntry->references == NULL);

    clearAndEnqueueReferences(env, &softReferences, &clearedReferences);
    clearAndEnqueueReferences(env, &weakReferences, &clearedReferences);
    enqueueFinalizerReferences(env, &finalizerReferences, &clearedReferences);
    clearAndEnqueueReferences(env, &phantomReferences, &clearedReferences);

    // Reregister for finalization. If no new references have been added to the list of references for the referent the
    // next time it gets finalized we know it will never be resurrected.
    GC_REGISTER_FINALIZER_NO_ORDER(obj, _finalizeObject, NULL, NULL, NULL);

    rvmUnlockMutex(&referentsLock);

    if (clearedReferences != NULL) {
        rvmCallVoidClassMethod(env, java_lang_ref_ReferenceQueue, java_lang_ref_ReferenceQueue_add, clearedReferences);
        assert(rvmExceptionOccurred(env) == NULL);
    }
}
Esempio n. 5
0
File: util.c Progetto: leia/dfsch
pthread_cond_t* dfsch_create_finalized_cvar(){
  pthread_cond_t* cvar = GC_MALLOC_ATOMIC(sizeof(pthread_cond_t));
#ifdef DFSCH_THREADS_FINALIZE
  GC_REGISTER_FINALIZER_NO_ORDER(cvar, (GC_finalization_proc)cvar_finalizer,
                                 NULL, NULL, NULL);
#endif
  pthread_cond_init(cvar, NULL);
  return cvar;
}
Esempio n. 6
0
File: util.c Progetto: leia/dfsch
pthread_mutex_t* dfsch_create_finalized_mutex(){
  pthread_mutex_t* mutex = GC_MALLOC_ATOMIC(sizeof(pthread_mutex_t));
#ifdef DFSCH_THREADS_FINALIZE
  GC_REGISTER_FINALIZER_NO_ORDER(mutex, (GC_finalization_proc)mutex_finalizer,
                                 NULL, NULL, NULL);
#endif
  pthread_mutex_init(mutex, NULL);
  return mutex;
}
Esempio n. 7
0
void
mono_gc_register_for_finalization (MonoObject *obj, void *user_data)
{
	guint offset = 0;

#ifndef GC_DEBUG
	/* This assertion is not valid when GC_DEBUG is defined */
	g_assert (GC_base (obj) == (char*)obj - offset);
#endif

	GC_REGISTER_FINALIZER_NO_ORDER ((char*)obj - offset, user_data, GUINT_TO_POINTER (offset), NULL, NULL);
}
Esempio n. 8
0
void
scm_i_add_resuscitator (void *obj, scm_t_finalizer_proc proc, void *data)
{
  struct scm_t_chained_finalizer *chained_data;
  chained_data = scm_gc_malloc (sizeof (*chained_data), "chained finalizer");
  chained_data->resuscitating_p = 1;
  chained_data->proc = proc;
  chained_data->data = data;
  GC_REGISTER_FINALIZER_NO_ORDER (obj, chained_finalizer, chained_data,
                                  &chained_data->prev,
                                  &chained_data->prev_data);
}
Esempio n. 9
0
void registerCleanupHandler(Env* env, Object* object, CleanupHandler handler) {
    rvmLockMutex(&referentsLock);
    CleanupHandlerList* l = rvmAllocateMemory(env, sizeof(CleanupHandlerList));
    if (!l) goto done; // OOM thrown
    l->handler = handler;
    ReferentEntry* referentEntry = getReferentEntryForObject(env, object);
    if (!referentEntry) goto done;
    // Add the handler to the object's list of cleanup handlers
    LL_PREPEND(referentEntry->cleanupHandlers, l);
    // Register the referent for finalization
    GC_REGISTER_FINALIZER_NO_ORDER(object, _finalizeObject, NULL, NULL, NULL);

done:
    rvmUnlockMutex(&referentsLock);
}
Esempio n. 10
0
/*
 * Some of our objects may point to a different address than the address returned by GC_malloc()
 * (because of the GetHashCode hack), but we need to pass the real address to register_finalizer.
 * This also means that in the callback we need to adjust the pointer to get back the real
 * MonoObject*.
 * We also need to be consistent in the use of the GC_debug* variants of malloc and register_finalizer, 
 * since that, too, can cause the underlying pointer to be offset.
 */
static void
object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*))
{
#if HAVE_BOEHM_GC
	guint offset = 0;
	MonoDomain *domain;

	if (obj == NULL)
		mono_raise_exception (mono_get_exception_argument_null ("obj"));
	
	domain = obj->vtable->domain;

#ifndef GC_DEBUG
	/* This assertion is not valid when GC_DEBUG is defined */
	g_assert (GC_base (obj) == (char*)obj - offset);
#endif

	if (mono_domain_is_unloading (domain) && (callback != NULL))
		/*
		 * Can't register finalizers in a dying appdomain, since they
		 * could be invoked after the appdomain has been unloaded.
		 */
		return;

	mono_domain_finalizers_lock (domain);

	if (callback)
		g_hash_table_insert (domain->finalizable_objects_hash, obj, obj);
	else
		g_hash_table_remove (domain->finalizable_objects_hash, obj);

	mono_domain_finalizers_unlock (domain);

	GC_REGISTER_FINALIZER_NO_ORDER ((char*)obj - offset, callback, GUINT_TO_POINTER (offset), NULL, NULL);
#elif defined(HAVE_SGEN_GC)
	if (obj == NULL)
		mono_raise_exception (mono_get_exception_argument_null ("obj"));

	/*
	 * If we register finalizers for domains that are unloading we might
	 * end up running them while or after the domain is being cleared, so
	 * the objects will not be valid anymore.
	 */
	if (!mono_domain_is_unloading (obj->vtable->domain))
		mono_gc_register_for_finalization (obj, callback);
#endif
}
Esempio n. 11
0
void rvmRegisterReference(Env* env, Object* reference, Object* referent) {
    if (referent) {
        // Add 'reference' to the references list for 'referent' in the referents hashtable
        rvmLockMutex(&referentsLock);

        ReferenceList* l = rvmAllocateMemory(env, sizeof(ReferenceList));
        if (!l) goto done; // OOM thrown
        l->reference = reference;
        ReferentEntry* referentEntry = getReferentEntryForObject(env, referent);
        if (!referentEntry) goto done;
        // Add the reference to the referent's list of references
        LL_PREPEND(referentEntry->references, l);
        // Register the referent for finalization
        GC_REGISTER_FINALIZER_NO_ORDER(referent, _finalizeObject, NULL, NULL, NULL);

done:
        rvmUnlockMutex(&referentsLock);
    }
}
Esempio n. 12
0
void Scm_UnregisterFinalizer(ScmObj z)
{
    GC_finalization_proc ofn; void *ocd;
    GC_REGISTER_FINALIZER_NO_ORDER(z, (GC_finalization_proc)NULL, NULL,
                                   &ofn, &ocd);
}
Esempio n. 13
0
/*=============================================================
 * Finalization.  Scheme finalizers are added as NO_ORDER.
 */
void Scm_RegisterFinalizer(ScmObj z, ScmFinalizerProc finalizer, void *data)
{
    GC_finalization_proc ofn; void *ocd;
    GC_REGISTER_FINALIZER_NO_ORDER(z, (GC_finalization_proc)finalizer,
                                   data, &ofn, &ocd);
}
Esempio n. 14
0
void ILGCRegisterFinalizer(void *block, ILGCFinalizer func, void *data)
{
	/* We use the Java-style finalization algorithm, which
	   ignores cycles in the object structure */
	GC_REGISTER_FINALIZER_NO_ORDER(block, func, data, 0, 0);	
}
Esempio n. 15
0
void smem_set_filnalizer(SExp s, void (*func)(SExp)) {
#ifndef DONT_USE_GC
	void* ptr = S2PTR(s);
	GC_REGISTER_FINALIZER_NO_ORDER(ptr, (GC_finalization_proc)func, ptr, NULL, NULL);
#endif
}