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

📄 gcfuncs.c

📁 kaffe Java 解释器语言,源码,Java的子集系统,开放源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * gcFuncs.c * Methods to implement gc-related activities of objects and classes * * Copyright (c) 1996, 1997, 1998, 1999 *      Transvirtual Technologies, Inc.  All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. *//* * This file contains those functions that have to do with gc */#include "config.h"#include "debug.h"#include "config-std.h"#include "config-mem.h"#include "gtypes.h"#include "slots.h"#include "access.h"#include "object.h"#include "errors.h"#include "code.h"#include "file.h"#include "readClass.h"#include "classMethod.h"#include "baseClasses.h"#include "stringSupport.h"#include "thread.h"#include "jthread.h"#include "itypes.h"#include "bytecode.h"#include "exception.h"#include "md.h"#include "external.h"#include "lookup.h"#include "support.h"#include "gc.h"#include "locks.h"#include "md.h"#include "jni.h"#include "soft.h"#include "thread.h"#include "gcRefs.h"#include "methodCache.h"#include "jvmpi_kaffe.h"/***************************************************************************** * Class-related functions *//* * Destroy a class object. */static void/* ARGSUSED */destroyClass(Collector *collector, void* c){        int i, j;	int idx;	Hjava_lang_Class* clazz = c;	constants* pool;DBG(CLASSGC,        dprintf("destroying class %s @ %p\n",		clazz->name ? clazz->name->data : "newborn", c);   )	assert(!CLASS_IS_PRIMITIVE(clazz)); 	/* NB: Make sure that we don't unload fully loaded classes without	 * classloaders.  This is wrong and indicate of a bug.	 *	 * NB: Note that this function must destroy any partially	 * initialized class.  Class processing may fail at any	 * state, and the discarded class objects destroyed.	 */	assert(clazz->state != CSTATE_COMPLETE || clazz->loader != 0);#if defined(ENABLE_JVMPI)	if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_CLASS_UNLOAD) )	{		JVMPI_Event ev;		ev.event_type = JVMPI_EVENT_CLASS_UNLOAD;		ev.u.class_unload.class_id = c;		jvmpiPostEvent(&ev);	}#endif	if (Kaffe_JavaVMArgs[0].enableVerboseGC > 0 && clazz->name) {		dprintf("<GC: unloading class `%s'>\n",			CLASS_CNAME(clazz));	}        /* destroy all fields */        if (CLASS_FIELDS(clazz) != 0) {                Field *f = CLASS_FIELDS(clazz);                for (i = 0; i < CLASS_NFIELDS(clazz); i++) {                        utf8ConstRelease(f->name);                        /* if the field was never resolved, we must release the                         * Utf8Const to which its type field points */			utf8ConstRelease(f->signature);			f++;                }                KFREE(CLASS_FIELDS(clazz));        }        /* destroy all methods, only if this class has indeed a method table */        if (!CLASS_IS_ARRAY(clazz) && CLASS_METHODS(clazz) != 0) {                Method *m = CLASS_METHODS(clazz);                for (i = 0; i < CLASS_NMETHODS(clazz); i++) {			void *ncode = 0;			if (!CLASS_IS_INTERFACE(clazz))			{				ncode = METHOD_NATIVECODE(m);#if defined(TRANSLATOR) && (defined (MD_UNREGISTER_JIT_EXCEPTION_INFO) || defined (JIT3))				if (METHOD_JITTED(m)) {#if defined(MD_UNREGISTER_JIT_EXCEPTION_INFO)					MD_UNREGISTER_JIT_EXCEPTION_INFO (m->c.ncode.ncode_start,									  ncode,									  m->c.ncode.ncode_end);#endif#if defined(ENABLE_JVMPI)					if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_COMPILED_METHOD_UNLOAD)  )					{						JVMPI_Event ev;						ev.event_type = JVMPI_EVENT_COMPILED_METHOD_UNLOAD;						ev.u.compiled_method_unload.							method_id = m;						jvmpiPostEvent(&ev);					}#endif				}#endif			}                        utf8ConstRelease(m->name);                        utf8ConstRelease(METHOD_SIG(m));                        KFREE(METHOD_PSIG(m));                        KFREE(m->lines);			if( m->ndeclared_exceptions != -1 )				KFREE(m->declared_exceptions);                        KFREE(m->exception_table);                        KFREE(m->c.bcode.code);	 /* aka c.ncode.ncode_start */			/* Free ncode if necessary: this concerns			 * any uninvoked trampolines			 */			if (GC_getObjectIndex(collector, ncode) != -1) {				KFREE(ncode);			}			m++;                }                KFREE(CLASS_METHODS(clazz));        }        /* release remaining refs to utf8consts in constant pool */	pool = CLASS_CONSTANTS (clazz);	for (idx = 0; idx < pool->size; idx++) {		switch (pool->tags[idx]) {		case CONSTANT_String:	/* unresolved strings */		case CONSTANT_Utf8:			utf8ConstRelease(WORD2UTF(pool->data[idx]));			break;		}	}	/* free constant pool */	if (pool->data != 0) {		KFREE(pool->data);	}        /* free various other fixed things */        KFREE(CLASS_STATICDATA(clazz));	if( clazz->dtable )	{		for( i = 0; i < clazz->msize; i++ )		{			if( clazz->dtable->method[i] == 0 )				continue;			/* Free ncode if necessary: this concerns			 * any uninvoked trampolines			 */			if (GC_getObjectIndex(collector,					      clazz->dtable->method[i])			    == GC_ALLOC_DISPATCHTABLE) {				KFREE(clazz->dtable->method[i]);			}		}		KFREE(clazz->dtable);	}        KFREE(clazz->if2itable);	if( clazz->itable2dtable )	{		for (i = 0; i < clazz->total_interface_len; i++) {			Hjava_lang_Class* iface = clazz->interfaces[i];			/* only if interface has not been freed already */			if (GC_getObjectIndex(collector, iface)			    == GC_ALLOC_CLASSOBJECT)			{				iface->implementors[clazz->impl_index] = -1;			}		}		/* NB: we can't just sum up the msizes of the interfaces		 * here because they might be destroyed simultaneously		 */		j = GC_getObjectSize(collector, clazz->itable2dtable)			/ sizeof (void*);		for( i = 0; i < j; i++ )		{			if (GC_getObjectIndex(collector,					      clazz->itable2dtable[i])			    == GC_ALLOC_DISPATCHTABLE) {				GC_free(collector, clazz->itable2dtable[i]);			}		}		GC_free(collector, clazz->itable2dtable);	}	if( clazz->gc_layout &&	    (clazz->superclass->gc_layout != clazz->gc_layout) )	{		KFREE(clazz->gc_layout);	}	KFREE(clazz->sourcefile);	KFREE(clazz->implementors);	KFREE(clazz->inner_classes);        /* The interface table for array classes points to static memory */        if (!CLASS_IS_ARRAY(clazz)) {                KFREE(clazz->interfaces);        }        utf8ConstRelease(clazz->name);}/* * Walk the methods of a class. */staticvoidwalkMethods(Collector* collector, Method* m, int nm){        while (nm-- > 0) {#if defined(TRANSLATOR) && 0                /* walk the block of jitted code conservatively.                 * Is this really needed? 		 */                if (METHOD_TRANSLATED(m) && (m->accflags & ACC_NATIVE) == 0) {                        void *mem = m->c.ncode.ncode_start;                        if (mem != 0) {				GC_walkConservative(collector, mem,					GC_getObjectSize(collector, mem));                        }                }#endif                GC_markObject(collector, m->class);                /* walk exception table in order to keep resolved catch types                   alive */                if (m->exception_table != 0) {                        jexceptionEntry* eptr = &m->exception_table->entry[0];                        int i;                        for (i = 0; i < m->exception_table->length; i++) {                                Hjava_lang_Class* c = eptr[i].catch_type;                                if (c != 0 && c != UNRESOLVABLE_CATCHTYPE) {                                        GC_markObject(collector, c);                                }                        }                }                m++;        }}/* * Walk a class object. */static voidwalkClass(Collector* collector, void* base, uint32 size){        Hjava_lang_Class* class;        Field* fld;        int n;        constants* pool;        int idx;        class = (Hjava_lang_Class*)base;DBG(GCPRECISE,        dprintf("walkClass `%s' state=%d\n", CLASS_CNAME(class), class->state);    )        if (class->state >= CSTATE_PREPARED) {                GC_markObject(collector, class->superclass);        }        /* walk constant pool - only resolved classes and strings count */        pool = CLASS_CONSTANTS(class);        for (idx = 0; idx < pool->size; idx++) {                switch (pool->tags[idx]) {                case CONSTANT_ResolvedClass:			assert(!CLASS_IS_PRIMITIVE(CLASS_CLASS(idx, pool)));                        GC_markObject(collector, CLASS_CLASS(idx, pool));                        break;                case CONSTANT_ResolvedString:                        GC_markObject(collector, (void*)pool->data[idx]);                        break;                }        }        /*         * NB: We suspect that walking the class pool should suffice if         * we ensured that all classes referenced from this would show up         * as a ResolvedClass entry in the pool.  However, this is not         * currently the case: for instance, resolved field type are not         * marked as resolved in the constant pool, even though they do         * have an index there! XXX         *         * The second hypothesis is that if the class is loaded by the         * system and thus anchored, then everything that we can reach from         * here is anchored as well.  If that property holds, we should be         * able to just return if class->loader == null here.   XXX         */        /* walk fields */        if (CLASS_FIELDS(class) != 0) {                /* walk all fields to keep their types alive */                fld = CLASS_FIELDS(class);

⌨️ 快捷键说明

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