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

📄 gcj-glue.c

📁 java virtual machince kaffe
💻 C
📖 第 1 页 / 共 2 页
字号:
			} else {				kenvPostClassNotFound(name, einfo);			}		}		if (!ftype) {			return (false);		}		FIELD_TYPE(fld) = ftype;		if (CLASS_IS_PRIMITIVE(ftype)) {			assert(info->bsize == TYPE_PRIM_SIZE(ftype));		} else {			assert(info->bsize == PTR_TYPE_SIZE);		}	} else {		const char *ksig = info->type;		FIELD_TYPE(fld) = (Hjava_lang_Class*)			makePathUtf8FromClassChar(ksig);		if (ksig[0] == 'L' || ksig[0] == '[') {			assert(info->bsize == PTR_TYPE_SIZE);		} /* else unresolved primitive type */	}	FIELD_SIZE(fld) = info->bsize;	if (fld->accflags & ACC_STATIC) {		FIELD_ADDRESS(fld) = info->u.addr;	}DBG(GCJ, 	dprintf("making kaffe field #%d %s.%s @%p type=%p flags=0x%x addr=%p\n",		info->idx, CLASS_CNAME(c), fld->name->data, fld, 		fld->type, fld->accflags, FIELD_ADDRESS(fld));    )        CLASS_NFIELDS(c)++;        if (fld->accflags & ACC_STATIC) {                CLASS_NSFIELDS(c)++;        }	/* Instance fields are inserted in opposite order, so let's switch	 * them here.  This is what finishFields does.	 */	if (info->idx == 0) {		finishFields(c);	}	return (true);}const char *kenvGetClassName(struct Hjava_lang_Class *clazz){	return (CLASS_CNAME(clazz));}void* kenvMakeJavaString(const char *utf8data, int utf8length, int utf8hash){	Utf8Const *u;	Hjava_lang_String *s;	u = utf8ConstNew(utf8data, utf8length);	/* make sure kaffe and gcj computed the same hash --- unfortunately	 * gcj only stores the lower 16 bits.	 */	assert((u->hash & 0xffff) == utf8hash);	s = utf8Const2Java(u);	utf8ConstRelease(u);	/* Nail these down for now because we do not walk a gcj class's	 * constant pool from which these strings may be referenced.	 */	if (!gc_add_ref(s)) {		errorInfo info;		postOutOfMemory(&info);		throwError(&info);	}	return (s);}/* * Given a pointer to a java::lang::Class, return kaffe's surrogate class  */Hjava_lang_Class*kenvFindClassByAddress2(void *clazz, errorInfo *einfo){	Hjava_lang_Class *kclass;	/* Check if this class was preloaded.  If so, a surrogate will	 * be constructed and returned.	 */	kclass = gcjFindClassByAddress(clazz, einfo);	/* Either it wasn't preloaded or some other problem occurred	 * during processing.  XXX think about what it would to do if	 * another problem occurred.	 *	 * If it's not a precompiled class, it could be an unresolved ref.	 */	if (kclass == 0 /* XXX:  && error was class not found !? */) {		/* It could be a kaffe class, which was an unresolved symbol  		 * in the shared module, but for which there should be an entry		 * in the symbol table of the fixup module which we've loaded		 * by now.		 */		char *name;		name = gcjFindUnresolvedClassByAddress(clazz);		if (name) {			kclass = kenvFindClass(name, einfo);		} else {			kenvPostClassNotFound(name, einfo);		}	}        if (kclass && kclass->state < CSTATE_LINKED) {		if (processClass(kclass, CSTATE_LINKED, einfo) == false)  {DBG(GCJ, 		dprintf("gcjGetClass: failed to process class %s@%p\n",				kclass);     )			return (0);		}        	}DBG(GCJ,	dprintf("%s: %p -> %p %s\n", __FUNCTION__, clazz,		kclass, kclass ? CLASS_CNAME(kclass) : "<nil>");    )	return (kclass);}Hjava_lang_Class*kenvFindClassByAddress(void *gcjclazz){	Hjava_lang_Class* kclass;	errorInfo info;	kclass = kenvFindClassByAddress2(gcjclazz, &info);	if (kclass == 0) {		dprintf("GCJ: Missing needed class @%p\n", gcjclazz);		throwError(&info);	}	return (kclass);}/* * Find a method that implements an interface by its name and signature * Unfortunately, gcj doesn't use the constant-time method to lookup * interfaces yet.  I hope they'll follow suit and implement the lookup  * based on interface class and index. */#define HSIZE	1024struct mCacheEntry {	Hjava_lang_Class 	*kclass;	const char 		*mname;	const char 		*msig;	Method 			*meth;} mCache[HSIZE];#define MHASH(V)   ((((uintp)(V) >> 2) ^ ((uintp)(V) >> 9))%HSIZE)/* Try to lookup a class/methodname/methodsignature combo in the cache, * return location to where Method can be found.  If we have a cache miss, * clear that location. */static inlineMethod **tryCache(Hjava_lang_Class *kclass, const char *mname, const char *msig){	/* With this hash function, I'm getting these hit ratios:	    mpegaudio       : 181945 hits, 28 misses	    db              : 19297313 hits, 19 misses	    jack            : 14507926 hits, 40 misses	    jess            : 706127 hits, 139 misses	    compress        : 184 hits, 15 misses	 */	int h = MHASH(kclass) ^ MHASH(mname);	struct mCacheEntry *e = mCache + h;	if (e->kclass != kclass || e->mname != mname || e->msig != msig) {		e->kclass = kclass;		e->mname = mname;		e->msig = msig;		e->meth = 0;	}	return (&(e->meth));}/* #define COUNT_CACHE	1 */#if COUNT_CACHEstatic long long cachehits;static long long cachemisses;void printInterfaceCacheStats() {	dprintf("GCJ interface cache: %qd hits, %qd misses\n",		cachehits, cachemisses);}#endifvoid* kenvFindMethod(Hjava_lang_Class *kclass, 		const char *mname,	        const char *msig){	Method *meth; 	Method **mptr;	errorInfo info;	mptr = tryCache(kclass, mname, msig);	meth = *mptr;	if (meth) {#if COUNT_CACHE		cachehits++;#endif		goto found;	}#if COUNT_CACHE	cachemisses++;#endif        for (; kclass != 0; kclass = kclass->superclass) {		int n = CLASS_NMETHODS(kclass);        		for (meth = Kaffe_get_class_methods(kclass); --n >= 0; ++meth) {			/* Ouch.  GCJ keeps signatures in dotted form, we 			 * keep them in slashed form.			 */			if (!strcmp(mname, meth->name->data)			    && comparePath2ClassName(			    		PSIG_DATA(METHOD_PSIG(meth)), 					msig))			{				*mptr = meth;			    	goto found;			}		}	}	postExceptionMessage(&info, JAVA_LANG(NoSuchMethodError), "%s", mname);	throwError(&info);	return (0);found:DBG(GCJ, dprintf("%s: %s.%s is at %p\n", 		__FUNCTION__, mname, msig, METHOD_NATIVECODE(meth));    )	assert(METHOD_NATIVECODE(meth));	return (METHOD_NATIVECODE(meth));}/* * A GCJ trampoline. * Invoked only once per method so can be expensive. * Note that the msig is only a partial signature: it doesn't have the * return type in it. */void *kenvTranslateMethod(const char *classname, const char *mname, const char *msig){	Method *meth;	errorInfo info;	Hjava_lang_Class *kclass, *cc;	int msiglen = strlen(msig);	kclass = kenvFindClass((char*)classname, &info);	if (kclass == 0) {		throwError(&info);	}	/* 	 * GCJ invokes (static) native methods w/o calling Jv_InitClass	 * first.  (Jv_InitClass is the first thing a gcj static method	 * does.)  Hence, make sure the class's static initialized has	 * been invoked to ensure the static native method is even here.	 *	 * XXX need a different approach for static linking here!	 */	kenvProcessClass(kclass);	for (cc = kclass; cc; cc = cc->superclass) {		int  nm = CLASS_NMETHODS(cc);		meth = Kaffe_get_class_methods(cc);		while (nm-- > 0) {			if (!strcmp(mname, meth->name->data) &&			    !strncmp(msig, METHOD_SIGD(meth), msiglen)) 			{				goto found;			}			meth++;		}	}DBG(GCJ,	dprintf("%s: NoSuchMethod %s.%s.%s\n", __FUNCTION__, 			classname, mname, msig);    )	postExceptionMessage(&info, JAVA_LANG(NoSuchMethodError), 		"%s.%s.%s", classname, mname, msig);	throwError(&info);	return (0);found:	assert(meth);	if (!METHOD_TRANSLATED(meth)) {		if (translate(meth, &info) == false) {			throwError(&info);		}	}	return (METHOD_NATIVECODE(meth));}/* * Find a class by its GCJ address. * Exception: if we're asked to find a class with the address * "ObjectClass", return the address of ObjectClass??? * * XXX this has only to do with interface/java.lang.Object * XXX CLEAN ME UP and possibly eliminate this function. */Hjava_lang_Class* gcjGetClass(void *jclazz, errorInfo *einfo){	Hjava_lang_Class* kclass;	/* Both java.lang.Object and interfaces have their superclass field	 * set to null.  To distinguish interfaces, we set their field to	 * ObjectClass in kenvMakeClass	 */	if (jclazz == (void*)ObjectClass) {		return (ObjectClass);	}	kclass = kenvFindClassByAddress2(jclazz, einfo);	if (kclass == 0) {DBG(GCJ, 			dprintf("gcjGetClass: class not found at %p\n", jclazz); 	)		return (0);	}	return (kclass);}void* kenvMalloc(int size, struct _errorInfo *einfo){	void *p = KMALLOC(size);	if (p == 0) {		postOutOfMemory(einfo); 	}	return (p);}void kenvFree(void * ptr){	KFREE(ptr);}#endif /* HAVE_GCJ_SUPPORT */

⌨️ 快捷键说明

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