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

📄 methodcalls.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
字号:
/* * methodcalls.c * Implementation of method calls * * Copyright (c) 1996, 1997 *	Transvirtual Technologies, Inc.  All rights reserved. * * Copyright (c) 2004 *      The kaffe.org's developers. See ChangeLog for details. * * See the file "license.terms" for information on usage and redistribution  * of this file.  */#include "config.h"#if defined(HAVE_LIBFFI)#include "sysdepCallMethod-ffi.h"#else#define NEED_sysdepCallMethod 1#endif#include "machine.h"#include "methodcalls.h"#include "thread.h"#include "callKaffeException.h"#define TDBG(s)/* * Trampolines come in here - do the translation and replace the trampoline. */nativecode*soft_fixup_trampoline(FIXUP_TRAMPOLINE_DECL){	Method* meth;	void **where;	void *tramp;	errorInfo info;	/* FIXUP_TRAMPOLINE_INIT sets tramp and where */	FIXUP_TRAMPOLINE_INIT;	tramp = *where;DBG(MOREJIT,	dprintf("soft_fixup_trampoline(): meth %p, where %p, native code %p\n",		meth, where, PMETHOD_NATIVECODE(meth));    );	/* If this class needs initializing, do it now.  */	if (meth->class->state != CSTATE_COMPLETE &&		processClass(meth->class, CSTATE_COMPLETE, &info) == false) {		throwError(&info);	}	/* Generate code on demand.  */	if (!METHOD_TRANSLATED(meth)) {		if (!translate(meth, &info)) {			throwError(&info);		}	}	/*	 * Update the origin of the trampoline and free it if necessary. 	 * Another thread might have jumped through the same trampoline	 * while we were translating the method, so we have to make this	 * atomic.	 */#if defined(COMPARE_AND_EXCHANGE)	if (COMPARE_AND_EXCHANGE(where, tramp, METHOD_NATIVECODE(meth))) {		;	}#elif defined(ATOMIC_EXCHANGE)	{		void *tmp = METHOD_NATIVECODE(meth);		ATOMIC_EXCHANGE(where, tmp);	}#else#error "You have to define either COMPARE_AND_EXCHANGE or ATOMIC_EXCHANGE"#endif#if 0	if (METHOD_PRE_COMPILED(meth)) {		nativecode* ncode = METHOD_TRUE_NCODE(meth);		nativecode* ocode = METHOD_NATIVECODE(meth);		METHOD_NATIVECODE(meth) = ncode;		/* Update the dtable entries for all classes if this isn't a	   	   static method.  */		if (meth->idx >= 0 && ocode != ncode) {			meth->class->dtable->method[meth->idx] = ncode;		}		SET_METHOD_PRE_COMPILED(meth, 0);	}#endifTDBG(	dprintf("Calling %s:%s%s @ %p\n", meth->class->name->data, meth->name->data, METHOD_SIGD(meth), METHOD_NATIVECODE(meth));	)DBG(MOREJIT,	dprintf("soft_fixup_trampoline(): return %p\n",		METHOD_NATIVECODE(meth));    );	return (METHOD_NATIVECODE(meth));}/* * When do we need a trampoline? * * NB: this method is invoked for *all* methods a class defines or * inherits. */static boolmethodNeedsTrampoline(Method *meth){ 	/* A gcj class's native virtual methods always need a trampoline	 * since the gcj trampoline doesn't work for them.  By using a	 * trampoline, we can fix the vtable the first time it is invoked.	 *	 * NB: If we'll ever support CNI, revisit this.	 */	if (CLASS_GCJ((meth)->class) && (meth->accflags & ACC_NATIVE) &&		meth->idx != -1)		return (true);	/* If the method hasn't been translated, we need a trampoline	 * NB: we assume the TRANSLATED flag for abstract methods produced	 * by gcj is cleared.	 */	if (!METHOD_TRANSLATED(meth))		return (true);	/* We also need one if it's a static method and the class	 * hasn't been initialized, because such method invocation	 * would constitute a first active use, requiring the initializer	 * to be run.	 */	if ((meth->accflags & ACC_STATIC)		&& meth->class->state < CSTATE_DOING_INIT)	{		/* Exception: gcj's classes don't need trampolines for two		 * reasons: 		 *   a) call _Jv_InitClass before invoking any static method.		 *   b) they're not compiled as indirect invocations anyway		 */		if (!CLASS_GCJ(meth->class)) {			return (true);		}	}	return (false);}void *engine_buildTrampoline (Method *meth, void **where, errorInfo *einfo){	void *ret;	methodTrampoline *tramp;	if (methodNeedsTrampoline(meth)) {		/* XXX don't forget to pick those up at class gc time */		tramp = (methodTrampoline*)gc_malloc(sizeof(methodTrampoline), KGC_ALLOC_TRAMPOLINE);		if (tramp == NULL) {			postOutOfMemory(einfo);			return (NULL);		}		FILL_IN_TRAMPOLINE(tramp, meth, where);		/* a disadvantage of building trampolines individually---as		 * opposed to allocating them in a contiguous region---is that		 * we have flush the dcache individually for each trampoline		 */		FLUSH_DCACHE(tramp, tramp+1);		/* for native gcj methods, we do override their		 * anchors so we can patch them up before they're invoked.		 */		if (!(CLASS_GCJ((meth)->class)			&& (meth->accflags & ACC_NATIVE)))		{			assert(*where == NULL ||				!!!"Cannot override trampoline anchor");		}		ret = tramp;		//		gc_add_ref(tramp);	} else {		if (CLASS_GCJ((meth)->class)) {			_SET_METHOD_NATIVECODE(meth, meth->ncode);		}		assert(METHOD_NATIVECODE(meth) != NULL);		ret = METHOD_NATIVECODE(meth);	}	*where = ret;	return ret;}voidengine_callMethod (callMethodInfo *call){	/* Clear the long value to clear the all return value. */	if (call->ret != NULL)	  call->ret->j = 0;	sysdepCallMethod (call);}voidengine_dispatchException (uintp framePointer, uintp handler, 			  struct Hjava_lang_Throwable *throwable){  /* I do not like the following line. I think that the interpreter   * can be adapted so that we do not need to include that line in the JIT.   */  THREAD_DATA()->exceptObj = NULL;  CALL_KAFFE_EXCEPTION(framePointer, handler, throwable);}

⌨️ 快捷键说明

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