gcfuncs.c

来自「基于LWVCL开发的库」· C语言 代码 · 共 754 行 · 第 1/2 页

C
754
字号
         * 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);                for (n = 0; n < CLASS_NFIELDS(class); n++) {			/* don't mark field types that are primitive classes */                        if (FIELD_RESOLVED(fld)				&& !CLASS_IS_PRIMITIVE(fld->type))			{				if (!CLASS_GCJ(fld->type)) {					KGC_markObject(collector, gc_info, fld->type);				}                        } /* else it's an Utf8Const that is not subject to gc */                        fld++;                }                /* walk static fields that contain references */                fld = CLASS_SFIELDS(class);                for (n = 0; n < CLASS_NSFIELDS(class); n++) {		    	/* Note that we must resolve field types eagerly			 * in processClass for gcj code cause it may never			 * call anything like getField to get the field			 * type resolved.  This can happen for such types as [C			 */                        if (FIELD_RESOLVED(fld) && FIELD_ISREF(fld)) {				void **faddr = (void**)FIELD_ADDRESS(fld);#if defined (HAVE_GCJ_SUPPORT)/* 1. GCJ work-around, see * http://sourceware.cygnus.com/ml/java-discuss/1999-q4/msg00379.html */				if (FIELD_TYPE(fld) == getStringClass()) {					KGC_markAddress(collector, gc_info, *faddr);				} else {					KGC_markObject(collector, gc_info, *faddr);				}#else				KGC_markObject(collector, gc_info, *faddr);#endif                        }                        fld++;                }        }        /* The interface table for array classes points to static memory,         * so we must not mark it.  */        if (!CLASS_IS_ARRAY(class)) {                /* mark interfaces referenced by this class */                for (n = 0; n < class->total_interface_len; n++) {                        KGC_markObject(collector, gc_info, class->interfaces[n]);                }        } else {                /* array classes should keep their element type alive */		Hjava_lang_Class *etype = Kaffe_get_array_element_type(class);		if (etype && !CLASS_IS_PRIMITIVE(etype)) {			KGC_markObject(collector, gc_info, etype);		}        }	/* Now we walk the interface table pointer. */	if (class->itable2dtable != NULL)	  {	    KGC_markObject(collector, gc_info, class->itable2dtable);	    /* We want the number of interfaces registered in the table. As	     * this number is not recorded in the table we recompute it	     * quickly using if2itable. (See classMethod.c/buildInterfaceDispatchTable).	     */	    for (idx = 1, n = 0; n < class->total_interface_len; n++)	      {		void *iface = class->itable2dtable[idx];				KGC_markObject(collector, gc_info, iface);		idx += class->interfaces[n]->msize+1;	      }	  }        /* CLASS_METHODS only points to the method array for non-array and         * non-primitive classes */        if (!CLASS_IS_PRIMITIVE(class) && !CLASS_IS_ARRAY(class) && Kaffe_get_class_methods(class) != 0) {                walkMethods(collector, gc_info, Kaffe_get_class_methods(class), CLASS_NMETHODS(class));        }        KGC_markObject(collector, gc_info, class->loader);	KGC_markObject(collector, gc_info, class->signers);	KGC_markObject(collector, gc_info, class->protectionDomain);	KGC_markObject(collector, gc_info, class->constructor);}/***************************************************************************** * various walk functions functions *//* * Walk an array object objects. */staticvoidwalkRefArray(Collector* collector, void *gc_info, void* base, uint32 size UNUSED){        Hjava_lang_Object* arr;        int i;	iLock *lk;        Hjava_lang_Object** ptr;        arr = (Hjava_lang_Object*)base;        if (arr->vtable == 0) {                 /* see walkObject */                return;        }	lk = GET_HEAVYLOCK(arr->lock);   	if (lk != NULL && KGC_getObjectIndex(collector, lk) == KGC_ALLOC_LOCK)	  KGC_markObject(collector, gc_info, lk);DBG(GCPRECISE,        dprintf("walkRefArray `%s' (num=%d)\n", CLASS_CNAME(arr->vtable->class), ARRAY_SIZE(arr));   );	ptr = OBJARRAY_DATA(arr);        /* mark class only if not a system class (which would be anchored         * anyway.)  */        if (arr->vtable->class->loader != 0) {                KGC_markObject(collector, gc_info, arr->vtable->class);        }        for (i = ARRAY_SIZE(arr); i > 0; i--) {                Hjava_lang_Object* el = *ptr++;		/*		 * NB: This would break if some objects (i.e. class objects)		 * are not gc-allocated.		 */		KGC_markObject(collector, gc_info, el);        }}/* * Walk an object. */staticvoidwalkObject(Collector* collector, void *gc_info, void* base, uint32 size){        Hjava_lang_Object *obj = (Hjava_lang_Object*)base;        Hjava_lang_Class *clazz;        int *layout;        int8* mem;        unsigned int i;	int l, nbits;	iLock *lk;        /*         * Note that there is a window after the object is allocated but         * before dtable is set.  In this case, we don't have to walk anything.         */        if (obj->vtable == 0)                return;        /* retrieve the layout of this object from its class */        clazz = obj->vtable->class;        /* class without a loader, i.e., system classes are anchored so don't         * bother marking them.         */        if (clazz->loader != 0) {                KGC_markObject(collector, gc_info, clazz);        }	lk = GET_HEAVYLOCK(obj->lock);	if (lk != NULL && KGC_getObjectIndex(collector, lk) == KGC_ALLOC_LOCK)	  KGC_markObject(collector, gc_info, lk);        layout = clazz->gc_layout;        nbits = CLASS_FSIZE(clazz)/ALIGNMENTOF_VOIDP;DBG(GCPRECISE,        dprintf("walkObject `%s' ", CLASS_CNAME(clazz));        BITMAP_DUMP(layout, nbits)        dprintf(" (nbits=%d) %p-%p\n", nbits, base, ((char *)base) + size);    );        assert(CLASS_FSIZE(clazz) > 0);        assert(size > 0);        mem = (int8 *)base;        /* optimize this! */        while (nbits > 0) {                /* get next integer from bitmap */                l = *layout++;                i = 0;                while (i < BITMAP_BPI) {                        /* skip the rest if no refs left */                        if (l == 0) {                                mem += (BITMAP_BPI - i) * ALIGNMENTOF_VOIDP;                                break;                        }                        if (l < 0) {                                /* we know this pointer points to gc'ed memory                                 * there is no need to check - go ahead and                                 * mark it.  Note that p may or may not point                                 * to a "real" Java object.                                 */				void *p = *(void **)mem;				KGC_markObject(collector, gc_info, p);                        }                        i++;                        l <<= 1;                        mem += ALIGNMENTOF_VOIDP;                }                nbits -= BITMAP_BPI;        }}/* * Walk a loader object. */staticvoidwalkLoader(Collector* collector, void *gc_info, void* base, uint32 size){        walkObject(collector, gc_info, base, size);        walkClassEntries(collector, gc_info, (Hjava_lang_ClassLoader*)base);}static void/* ARGSUSED */finalizeObject(Collector* collector UNUSED, void* ob){        Hjava_lang_Object* obj = (Hjava_lang_Object*)ob;	if (!obj->vtable) {		/* Suppose we catch ThreadDeath inside newObject() */		return;	}	assert(obj->finalizer_call != NULL);	((KaffeVM_Finalizer)obj->finalizer_call)(obj);}/* * Print a description of an object at a given address. * Single-threaded. */const char*describeObject(const void* mem){	static char buf[256];		/* BIG XXX */	const Hjava_lang_Class* clazz;	const Hjava_lang_String* str;	const Hjava_lang_Object* obj;	char* c;	jchar* jc;	int l;	int idx = KGC_getObjectIndex(main_collector, mem);	switch (idx) {	case KGC_ALLOC_JAVASTRING:		str = (const Hjava_lang_String*)mem;		strcpy(buf, "java.lang.String `");		c = buf + strlen(buf);		jc = unhand(str)->value ? STRING_DATA(str) : NULL;		l = STRING_SIZE(str);		while (jc && l-- > 0 && c < buf + sizeof(buf) - 2) {			*c++ = (char)*jc++;		}		*c++ = '\'';		*c = 0;		break;	case KGC_ALLOC_CLASSOBJECT:		clazz = (const Hjava_lang_Class*)mem;		sprintf(buf, "java.lang.Class `%s'", clazz->name ?			CLASS_CNAME(clazz) : "name unknown");		break;	case KGC_ALLOC_JAVALOADER:	case KGC_ALLOC_NORMALOBJECT:	case KGC_ALLOC_FINALIZEOBJECT:	case KGC_ALLOC_REFARRAY:	case KGC_ALLOC_PRIMARRAY:		obj = (const Hjava_lang_Object*)mem;		if (obj->vtable != 0) {			clazz = obj->vtable->class;			sprintf(buf, "%s", CLASS_CNAME(clazz));		} else {			sprintf(buf, "newly born %s",				KGC_getObjectDescription(main_collector, mem));		}		break;	/* add more? */	default:		return KGC_getObjectDescription(main_collector, mem);	}	return (buf);}Collector*initCollector(void){	Collector *gc = createGC();	DBG(INIT, dprintf("initCollector()\n"); );	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_JAVASTRING,	    stringWalk, stringDestroy, NULL, "j.l.String");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_NOWALK,	    NULL, KGC_OBJECT_NORMAL, NULL, "other-nowalk");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_NORMALOBJECT,	    walkObject, KGC_OBJECT_NORMAL, NULL, "obj-no-final");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_PRIMARRAY,	    NULL, finalizeObject, NULL, "prim-arrays");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_REFARRAY,	    walkRefArray, finalizeObject, NULL, "ref-arrays");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_CLASSOBJECT,	    walkClass, finalizeObject, destroyClass, "j.l.Class");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_FINALIZEOBJECT,	    walkObject, finalizeObject, NULL, "obj-final");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_JAVALOADER,	    walkLoader, finalizeObject, destroyClassLoader,	    "j.l.ClassLoader");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_THREADCTX, 	    NULL, KGC_OBJECT_NORMAL, NULL, "thread-ctxts");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_INTERFACE,  	    NULL, KGC_OBJECT_NORMAL, NULL, "interfaces");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_INTERFACE_TABLE,            NULL, KGC_OBJECT_NORMAL, NULL, "interface table");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_TRAMPOLINE,	    NULL, KGC_OBJECT_NORMAL, NULL, "trampoline");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_JITCODE,	    NULL, KGC_OBJECT_NORMAL, NULL, "jit-code");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_BYTECODE,	    NULL, KGC_OBJECT_NORMAL, NULL, "java-bytecode");	KGC_registerGcTypeByIndex(gc, KGC_ALLOC_LOCK,	    NULL, KGC_OBJECT_NORMAL, KaffeLock_destroyLock, "locks");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_STATIC_THREADDATA, "thread-data");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_EXCEPTIONTABLE, "exc-table");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_STATICDATA, "static-data");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_CONSTANT, "constants");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_FIXED, "other-fixed");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_DISPATCHTABLE, "dtable");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_METHOD, "methods");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_FIELD, "fields");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_UTF8CONST, "utf8consts");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_REF, "gc-refs");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JITTEMP, "jit-temp-data");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JAR, "jar");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_CODEANALYSE, "code-analyse");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_CLASSPOOL, "class-pool");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_LINENRTABLE, "linenr-table");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_LOCALVARTABLE, "lvar-table");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_DECLAREDEXC, "declared-exc");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_CLASSMISC, "class-misc");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_VERIFIER, "verifier");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_NATIVELIB, "native-lib");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_SEQ, "jit-seq");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_CONST, "jit-const");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_ARGS, "jit-args");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_FAKE_CALL, "jit-fake-call");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_SLOTS, "jit-slots");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_CODEBLOCK, "jit-codeblock");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_LABELS, "jit-labels");	KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_VMWEAKREF, "vm-weak-ref");	DBG(INIT, dprintf("initCollector() done\n"); );	return (gc);}

⌨️ 快捷键说明

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