classmethod.c

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

C
2,711
字号
		clazz = findClass(centry, &info);		if (clazz == NULL) {			goto bad;		}		/* we won't ever want to lose these classes */		refAdded = gc_add_ref(clazz);		if (!refAdded) {			goto bad;		}		(*class) = centry->data.cl = clazz;	}	unlockStaticMutex(&centry->slock);	if (!(*class))		(*class) = centry->data.cl;	if (processClass(centry->data.cl, CSTATE_LINKED, &info) == true) {		assert(centry->state == NMS_DONE);		return;	}bad:	dprintf("Couldn't find or load essential class `%s' %s %s\n",			name, info.classname, (char*)info.mess);	KAFFEVM_ABORT();}/* * Look a class up by name. */Hjava_lang_Class*lookupClass(const char* name, Hjava_lang_ClassLoader* loader, errorInfo *einfo){	Hjava_lang_Class* class;	Utf8Const *utf8;	utf8 = utf8ConstFromString(name);	if (!utf8) {		postOutOfMemory(einfo);		return NULL;	}	class = loadClass(utf8, loader, einfo);	utf8ConstRelease(utf8);	if (class != NULL) {		if (processClass(class, CSTATE_COMPLETE, einfo) == true) {			return (class);		}	}	return (NULL);}/* * Return FIELD_TYPE(FLD), but if !FIELD_RESOLVED, resolve the field first. */Hjava_lang_Class*resolveFieldType(Field *fld, Hjava_lang_Class* this, errorInfo *einfo){	Hjava_lang_Class* clas;	const char* name;	/* Avoid locking if we can */	if (FIELD_RESOLVED(fld)) {		return (FIELD_TYPE(fld));	}	/* We must lock the class while we retrieve the field name and	 * while we resolve it - or we may release the utf8's field type twice	 */	lockClass(this);	if (FIELD_RESOLVED(fld)) {		unlockClass(this);		return (FIELD_TYPE(fld));	}	name = fld->signature->data;	if( (clas = getClassFromSignature(name, this->loader, einfo)) )	{		FIELD_TYPE(fld) = clas;		fld->accflags &= ~FIELD_UNRESOLVED_FLAG;	}	unlockClass(this);#if defined(KAFFE_XDEBUGGING)	if( machine_debug_file )	{		addDebugInfo(machine_debug_file,			     DIA_Class, this,			     DIA_DONE);	}#endif		return (clas);}staticboolresolveObjectFields(Hjava_lang_Class* class, errorInfo *einfo){	int fsize;	int align;	Field* fld;	int nbits, nifields;	int offset;	int maxalign;	int oldoffset;	int *map;	jboolean is_reference;	/* Find start of new fields in this object.  If start is zero, we must	 * allow for the object headers.	 */	offset = CLASS_FSIZE(class);	oldoffset = offset;	/* remember initial offset */	if (offset == 0) {		offset = sizeof(Hjava_lang_Object);	}	/* Find the largest alignment in this class */	maxalign = 1;	fld = CLASS_IFIELDS(class);	nifields = CLASS_NIFIELDS(class);	for (; --nifields >= 0; fld++) {		fsize = FIELD_SIZE(fld);		/* Work out alignment for this size entity */		fsize = ALIGNMENT_OF_SIZE(fsize);		/* If field is bigger than biggest alignment, change		 * biggest alignment		 */		if (fsize > maxalign) {			maxalign = fsize;		}	}	/* Now work out where to put each field */	fld = CLASS_IFIELDS(class);	nifields = CLASS_NIFIELDS(class);	for (; --nifields >= 0; fld++) {		fsize = FIELD_SIZE(fld);		/* Align field */		align = ALIGNMENT_OF_SIZE(fsize);		offset = ((offset + align - 1) / align) * align;		FIELD_BOFFSET(fld) = offset;		offset += fsize;	}	CLASS_FSIZE(class) = offset;	/* recall old offset */	offset = oldoffset;	/* Check whether the class is java.lang.ref.Reference */	is_reference =	   (strcmp(CLASS_CNAME(class), "java/lang/ref/Reference") == 0);	/* Now that we know how big that object is going to be, create	 * a bitmap to help the gc scan the object.  The first part is	 * inherited from the superclass.	 */	map = BITMAP_NEW(CLASS_FSIZE(class)/ALIGNMENTOF_VOIDP, KGC_ALLOC_CLASSMISC);	if (map == 0) {		postOutOfMemory(einfo);		return (false);	}	if (offset > 0) {		nbits = offset/ALIGNMENTOF_VOIDP;		BITMAP_COPY(map, class->gc_layout, nbits);	} else {		/* The walkObject routine marks the class object explicitly.		 * We assume that the header does not contain anything ELSE		 * that must be marked.		 */		offset = sizeof(Hjava_lang_Object);		nbits = offset/ALIGNMENTOF_VOIDP;	}	class->gc_layout = map;	nbits = offset/ALIGNMENTOF_VOIDP;DBG(GCPRECISE,	dprintf("GCLayout for %s:\n", CLASS_CNAME(class));    );	/* Now work out the gc layout */	fld = CLASS_IFIELDS(class);	nifields = CLASS_NIFIELDS(class);	for (; --nifields >= 0; fld++) {		fsize = FIELD_SIZE(fld);		/* Align field */		align = ALIGNMENT_OF_SIZE(fsize);		offset += (align - (offset % align)) % align;		nbits = offset/ALIGNMENTOF_VOIDP;		/* paranoia */		assert(FIELD_BOFFSET(fld) == offset);		/* Set bit if this field is a reference type, except if		 * it's a kaffe.util.Ptr (PTRCLASS).  */		if (!FIELD_RESOLVED(fld)) {			Utf8Const *sig = fld->signature;			if ((sig->data[0] == 'L' || sig->data[0] == '[') &&			    strcmp(sig->data, PTRCLASSSIG) &&			    (!is_reference || strcmp(FIELD_NAME(fld), "referent") != 0)) {				BITMAP_SET(map, nbits);			}		} else {			if (FIELD_ISREF(fld) ) {				BITMAP_SET(map, nbits);			}		}DBG(GCPRECISE,		dprintf(" offset=%3d nbits=%2d ", offset, nbits);		BITMAP_DUMP(map, nbits+1)		dprintf(" fsize=%3d (%s)\n", fsize, fld->name->data);    );		offset += fsize;	}	return (true);}/* * Allocate the space for the static class data. */staticboolallocStaticFields(Hjava_lang_Class* class, errorInfo *einfo){	int fsize;	int align;	uint8* mem;	int offset;	int n;	Field* fld;	/* No static fields */	if (CLASS_NSFIELDS(class) == 0) {		return (true);	}	/* Calculate size and position of static data */	offset = 0;	n = CLASS_NSFIELDS(class);	fld = CLASS_SFIELDS(class);	for (; --n >= 0; fld++) {		fsize = FIELD_SIZE(fld);		/* Align field offset */		align = ALIGNMENT_OF_SIZE(fsize);		offset = ((offset + align - 1) / align) * align;		FIELD_SIZE(fld) = offset;		offset += fsize;	}	assert(offset > 0);	/* Allocate memory required */	mem = gc_malloc((unsigned int)offset, KGC_ALLOC_STATICDATA);	if (mem == NULL) {		postOutOfMemory(einfo);		return (false);	}	CLASS_STATICDATA(class) = mem;	/* Rewalk the fields, pointing them at the relevant memory and/or	 * setting any constant values.	 */	fld = CLASS_SFIELDS(class);	n = CLASS_NSFIELDS(class);	for (; --n >= 0; fld++) {		offset = FIELD_SIZE(fld);		FIELD_SIZE(fld) = FIELD_CONSTIDX(fld);	/* Keep idx in size */#if defined(HAVE_GCJ_SUPPORT)		/* Check whether gcj code refers to this field.  If so,		 * we'll have storage for this field in a fixup module.		 * gcjGetFieldAddr retrieves the address for the storage		 *		 * NB: Don't confuse this with the case where class is a gcj		 * class.  In that case, this function is not even invoked!		 */		FIELD_ADDRESS(fld) =			gcjGetFieldAddr(CLASS_CNAME(class), fld->name->data);		/* not a field for which gcj provides storage */		if (FIELD_ADDRESS(fld) == 0) {			FIELD_ADDRESS(fld) = mem + offset;		}#else		FIELD_ADDRESS(fld) = mem + offset;#endif	}	return (true);}staticboolresolveStaticFields(Hjava_lang_Class* class, errorInfo *einfo){	uint8* mem;	constants* pool;	Utf8Const* utf8;	Field* fld;	unsigned int idx;	int n;	/* No locking here, assume class is already locked. */	pool = CLASS_CONSTANTS(class);	fld = CLASS_SFIELDS(class);	n = CLASS_NSFIELDS(class);	for (; --n >= 0; fld++) {		if ((fld->accflags & FIELD_CONSTANT_VALUE) != 0) {			mem = FIELD_ADDRESS(fld);			idx = FIELD_SIZE(fld);			switch (CONST_TAG(idx, pool)) {			case CONSTANT_Integer:				if (FIELD_TYPE(fld) == booleanClass ||				    FIELD_TYPE(fld) == byteClass) {					*(jbyte*)mem = CLASS_CONST_INT(class, idx);					FIELD_SIZE(fld) = TYPE_PRIM_SIZE(byteClass);				}				else if (FIELD_TYPE(fld) == charClass ||					 FIELD_TYPE(fld) == shortClass) {					*(jshort*)mem = CLASS_CONST_INT(class, idx);					FIELD_SIZE(fld) = TYPE_PRIM_SIZE(shortClass);				}				else {					*(jint*)mem = CLASS_CONST_INT(class, idx);					FIELD_SIZE(fld) = TYPE_PRIM_SIZE(intClass);				}				break;			case CONSTANT_Float:				*(jint*)mem = CLASS_CONST_INT(class, idx);				FIELD_SIZE(fld) = TYPE_PRIM_SIZE(floatClass);				break;			case CONSTANT_Long:			case CONSTANT_Double:				*(jlong*)mem = CLASS_CONST_LONG(class, idx);				FIELD_SIZE(fld) = TYPE_PRIM_SIZE(longClass);				break;			case CONSTANT_String:				{					Hjava_lang_String *st;					utf8 = WORD2UTF(pool->data[idx]);					st = utf8Const2Java(utf8);					utf8ConstRelease(utf8);					if (!st) {						postOutOfMemory(einfo);						return false;					}					pool->data[idx] = (ConstSlot)st;					pool->tags[idx] = CONSTANT_ResolvedString;				}				/* ... fall through ... */			case CONSTANT_ResolvedString:				*(jref*)mem = (jref)CLASS_CONST_DATA(class, idx);				FIELD_SIZE(fld) = PTR_TYPE_SIZE;				break;			default:				break;			}		}	}	return true;}/* * Check whether there exists a method with the same name and signature * ``meth'' in class ``clazz'' or any of its superclasses. * If so, return set the ``meth'''s index to its index and return true. * Otherwise return false. */boolgetInheritedMethodIndex(Hjava_lang_Class *super, Method *meth){	/* Search superclasses for equivalent method name.	 * If found extract its index nr.	 */	for (; super != NULL;  super = super->superclass) {		int j = CLASS_NMETHODS(super);		Method* mt = Kaffe_get_class_methods(super);		for (; --j >= 0;  ++mt) {			/* skip methods that are private or static */			if ((mt->accflags & (ACC_PRIVATE|ACC_STATIC)) != 0)				continue;			/* skip inaccessible methods */			if (!checkAccess (meth->class, super, mt->accflags))				continue;			if (utf8ConstEqual (mt->name, meth->name) &&			    utf8ConstEqual (METHOD_SIG(mt), METHOD_SIG(meth)))			{				meth->idx = mt->idx;				return (true);			}		}	}	return (false);}/** * Get start of native code of a method * * @param method a method * @return pointer to start of code */jitCodeHeader*getMethodCodeStart(Method * method) {  return method->c.ncode.ncode_start;}/** * Set start of native code of a method * * @param method a method * @param start pointer to start of code */voidsetMethodCodeStart(Method * method, jitCodeHeader* start){  method->c.ncode.ncode_start = start;}staticboolbuildDispatchTable(Hjava_lang_Class* class, errorInfo *einfo){	Method* meth;	void** mtab;	int i;	Hjava_lang_Class *cc;	if (class->superclass != NULL) {		class->msize = getSuperclass(class)->msize;	}	else {		class->msize = 0;	}	meth = Kaffe_get_class_methods(class);	i = CLASS_NMETHODS(class);	for (; --i >= 0; meth++) {		Hjava_lang_Class* super = class->superclass;		/* Do not assign dtable indices for static, private		 * and constructor methods.	         */		if (METHOD_IS_STATIC(meth) || METHOD_IS_PRIVATE(meth)		    || utf8ConstEqual(meth->name, constructor_name))		{			meth->idx = -1;			continue;		}		/* Search superclasses for equivalent method name.		 * If found extract its index nr.		 */		if (getInheritedMethodIndex(super, meth) == false) {			/* No match found so allocate a new index number ---			 * except if the method or class is final in which			 * case it doesn't need one.			 */			if (METHOD_IS_FINAL(meth) || CLASS_IS_FINAL(class)) {				meth->idx = -1;			} else {				meth->idx = class->msize++;			}		}	}	class->vtable = (dispatchTable*)gc_malloc(sizeof(dispatchTable) +		class->msize * sizeof(void*), KGC_ALLOC_DISPATCHTABLE);	if (class->vtable == 0) {		postOutOfMemory(einfo);		return (false);	}	class->vtable->class = class;	mtab = class->vtable->method;	/* now build a trampoline for each and every method */	meth = Kaffe_get_class_methods(class);	i = CLASS_NMETHODS(class);	for (; --i >= 0; meth++) {		void **where;		/*		 * Build trampoline and set the method's native code to		 * point to this trampoline.		 */		where = (void**)PMETHOD_NATIVECODE(meth);		if (engine_buildTrampoline(meth, where, einfo) == 0) {			return (false);		}	}	/* trampolines are also needed for all virtual inherited	 * methods so they can be patched up independently	 */	for (cc = class->superclass; cc != 0; cc = cc->superclass) {		meth = Kaffe_get_class_methods(cc);		i = CLASS_NMETHODS(cc);		for (; --i >= 0; meth++) {			void **where;			/* skip static and overridden methods */			if (meth->idx < 0 || mtab[meth->idx] != 0) {				continue;			}			/* else it's an inherited method.  Build a trampoline,			 * but do not update METHOD_NATIVECODE.			 */			where = &mtab[meth->idx];			if (engine_buildTrampoline(meth, where, einfo) == 0) {				return (false);			}		}	}	return (true);}/* * Build the table used by this class for dispatching the interfaces * it implements. */staticboolbuildInterfaceDispatchTable(Hjava_lang_Class* class, errorInfo *einfo){	int i, j;	/* Construct two tables:	 * This first table maps interfaces to indices in itable.

⌨️ 快捷键说明

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