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

📄 machine.c

📁 java virtual machince kaffe
💻 C
📖 第 1 页 / 共 3 页
字号:
/* machine.c * Translate the Kaffe instruction set to the native one. * * Copyright (c) 1996-1999 *	Transvirtual Technologies, Inc.  All rights reserved. * * Copyright (c) 2003, 2004 *	Kaffe.org contributors. See ChangeLog for details. All rights reserved. *   * Cross-language profiling changes contributed by * the Flux Research Group, Department of Computer Science, * University of Utah, http://www.cs.utah.edu/flux/ * * See the file "license.terms" for information on usage and redistribution * of this file. */#define SCHK(s)#define	SUSE(s)#include "config.h"#include "config-std.h"#include "config-mem.h"#include "gtypes.h"#include "md.h"#include "classMethod.h"#include "bytecode.h"#include "slots.h"#include "registers.h"#include "seq.h"#include "gc.h"#include "machine.h"#include "basecode.h"#include "icode.h"#include "labels.h"#include "constpool.h"#include "codeproto.h"#include "checks.h"#include "access.h"#include "object.h"#include "constants.h"#include "baseClasses.h"#include "code.h"#include "access.h"#include "lookup.h"#include "exception.h"#include "errors.h"#include "locks.h"#include "code-analyse.h"#include "external.h"#include "soft.h"#include "thread.h"#include "itypes.h"#include "support.h"#include "xprofiler.h"#if defined(KAFFE_FEEDBACK)#include "feedback.h"#endif#include "debugFile.h"#include "fileSections.h"#include "mangle.h"#include "jvmpi_kaffe.h"#include "kaffe_jni.h"#include "native-wrapper.h"#include "stats.h"const char* engine_name = "Just-in-time v3";/** * top of the operand stack. localsz <= stackno < localsz+stacksz */int stackno;int maxStack;int maxLocal;int maxTemp;int maxArgs;int maxPush;int isStatic;codeinfo* codeInfo;/** * index of first unused element of tempinfo (next available temp slot) */int tmpslot;int argcount = 0;		/* Function call argument count */uint32 pc;uint32 npc;/* Various exception related things */jitflags willcatch;/* jit3 specific prototypes from icode.c */void explicit_check_null (int x, SlotInfo* obj, int y);void check_null (int x, SlotInfo* obj, int y);void check_div (int x, SlotInfo* obj, int y);void check_div_long (int x, SlotInfo* obj, int y);void softcall_fakecall (label* from,label* to, void* func);/* Unit in which code block is increased when overrun */#define	ALLOCCODEBLOCKSZ	8192/* Codeblock redzone - allows for safe overrun when generating instructions */#define	CODEBLOCKREDZONE	256static unsigned int codeblock_size;static int code_generated;static int bytecode_processed;static int codeperbytecode;iStaticLock	translatorlock;struct {	int time;} jitStats;static jboolean generateInsnSequence(errorInfo*);/** * Look for exception handlers that enclose the given PC in the given method. * If a match is found, it will set the appropriate willcatch flags. * * @param meth The method that may contain an exception handler. * @param pc The location within the method to look for a handler. */static void checkCaughtExceptions(Method* meth, uint32 _pc);void initFakeCalls(void);static void makeFakeCalls(void);static void relinkFakeCalls(void);/* Desktop edition */#include "debug.h"Method *globalMethod;#if defined(KAFFE_PROFILER)int profFlag;static void printProfilerStats(void);#endifJTHREAD_JMPBUF JIT3_jumpExitWithOOM;void KaffeJIT3_exitWithOOM(){  JTHREAD_LONGJMP(JIT3_jumpExitWithOOM, 1);}jboolean KaffeJIT3_setupExitWithOOM(struct _errorInfo* einfo){  if (!JTHREAD_SETJMP(JIT3_jumpExitWithOOM))    return false;  postOutOfMemory(einfo);  return true;}/* * Init instruction generation. */jbooleaninitInsnSequence(int localsz, int stacksz, errorInfo* einfo){	/* Clear various counters */	tmpslot = 0;	maxTemp = 0;	maxPush = 0;	stackno = localsz + stacksz;	npc = 0;	initSeq();	initRegisters();	initSlots(stackno);	/* Before generating code, try to guess how much space we'll need. */	codeblock_size = ALLOCCODEBLOCKSZ;	codeblock = gc_malloc(codeblock_size + CODEBLOCKREDZONE,			      KGC_ALLOC_JIT_CODEBLOCK);	if (codeblock == 0) {		postOutOfMemory(einfo);		return (false);	}	CODEPC = 0;		return (true);}/* * Translate a method into native code. * * Registers are allocated per basic block, using an LRU algorithm. * Contents of registers are spilled at the end of basic block, * depending on the edges in the CFG leaving the basic block: * * - If there is an edge from the basic block to an exception handler, *   local variables are spilled on the stack * * - If there is only one non-exception edge, and the target basic *   block is following the current block immediately, no spills are done * * - Otherwise, the local variables and the operand stack are spilled *   onto the stack */jbooleantranslate(Method* xmeth, errorInfo* einfo){#if defined(KAFFE_VMDEBUG)	int i;#endif /* defined(KAFFE_VMDEBUG) */	jint low;	jint high;	jvalue tmpl;	int idx;	SlotInfo* tmp;	SlotInfo* tmp2;	SlotInfo* mtable;	bytecode* base;	uint32 len;	callInfo cinfo;	fieldInfo finfo;	Hjava_lang_Class* crinfo;	codeinfo* mycodeInfo;	nativeCodeInfo ncode;	int64 tms = 0;	int64 tme;	static bool reinvoke = false;	jboolean success = true;	lockClass(xmeth->class);	if (METHOD_TRANSLATED(xmeth)) {		goto done3;	}	/* If this code block is native, then just set it up and return */	if (methodIsNative(xmeth)) {		void *func = native(xmeth, einfo);		if (func != NULL) {			engine_create_wrapper(xmeth, func);			KAFFEJIT_TO_NATIVE(xmeth);		} else {			success = false;		}		goto done3;	}	/* Scan the code and determine the basic blocks */	success = analyzeMethod(xmeth, &mycodeInfo, einfo);	if (success == false) {		/* It may happen that we already have translated it		 * by implicit recursion in the verifier.		 */		if (METHOD_TRANSLATED(xmeth))		  success = true;		goto done3;	}#if defined(KAFFE_FEEDBACK)	if( kaffe_feedback_file )		lockMutex(kaffe_feedback_file);#endif	/* Only one in the translator at once. Must check the translation	 * hasn't been done by someone else once we get it.	 */	enterTranslator();	startTiming(&fulljit, "JIT translation");	if (Kaffe_JavaVMArgs.enableVerboseJIT) {		tms = currentTime();	}DBG(MOREJIT,    dprintf("callinfo = %p\n", &cinfo);    );#if defined(KAFFE_PROFILER)	if (profFlag) {		static int init = 0;		if (!init) {			atexit(printProfilerStats);			init = 1;		}		profiler_get_clicks(xmeth->jitClicks);		xmeth->callsCount = 0;		xmeth->totalClicks = 0;		xmeth->totalChildrenClicks = 0;	}#endif	globalMethod = xmeth;	codeInfo = mycodeInfo;	/* Handle null calls specially */	if (METHOD_BYTECODE_LEN(xmeth) == 1 && METHOD_BYTECODE_CODE(xmeth)[0] == RETURN) {		SET_METHOD_NATIVECODE(xmeth, (nativecode*)soft_null_call);		goto done;	}	assert(reinvoke == false);	reinvoke = true;	maxLocal = xmeth->localsz;	maxStack = xmeth->stacksz;        maxArgs = sizeofSigMethod(xmeth, false);	if (maxArgs == -1) {		goto done;	}	if (xmeth->accflags & ACC_STATIC) {		isStatic = 1;	}	else {		isStatic = 0;		maxArgs += 1;	}	if (KaffeJIT3_setupExitWithOOM(einfo))	  {	    success = false;	    goto oom_error;	  }DBG(MOREJIT,	dprintf("Method: %s.%s%s\n", CLASS_CNAME(xmeth->class), xmeth->name->data, METHOD_SIGD(xmeth));	for (i = 0; i < maxLocal; i++) {		dprintf(" L%d: %2d", i, codeInfo->localuse[i].use);	}	dprintf("\n"););	base = (bytecode*)METHOD_BYTECODE_CODE(xmeth);	len = METHOD_BYTECODE_LEN(xmeth);	/*	 * Initialise the translator.	 */	initFakeCalls();	/* Do any machine dependent JIT initialization */#if defined(INIT_JIT_MD)	INIT_JIT_MD(xmeth);#endif	success = initInsnSequence(xmeth->localsz, xmeth->stacksz, einfo);	if (success == false) {		goto done;	}	/***************************************/	/* Next reduce bytecode to native code */	/***************************************/	pc = 0;	start_function();	check_stack_limit();	if (Kaffe_JavaVMArgs.enableVerboseCall != 0) {		softcall_trace(xmeth);	}	monitor_enter();	if (IS_STARTOFBASICBLOCK(0)) {		end_basic_block();		success = generateInsnSequence(einfo);		if (success == false) {			goto done;		}		start_basic_block();	}	for (; pc < len; pc = npc) {		assert(stackno <= maxStack+maxLocal);		assert(stackno >= 0);		npc = pc + insnLen[base[pc]];                /* Skip over the generation of any unreachable basic blocks */                if (IS_UNREACHABLE(pc)) {                        while (npc < len && !IS_STARTOFBASICBLOCK(npc) && !IS_STARTOFEXCEPTION(npc)) {                                npc = npc + insnLen[base[npc]];                        }DBG(JIT,                dprintf("unreachable basic block pc [%d:%d]\n", pc, npc - 1);   );                        if (IS_STARTOFBASICBLOCK(npc)) {                                end_basic_block();                                start_basic_block();                                stackno = STACKPOINTER(npc);                        }                        continue;                }		/* Determine various exception conditions */		checkCaughtExceptions(xmeth, pc);		start_instruction();		/* Note start of exception handling blocks */		if (IS_STARTOFEXCEPTION(pc)) {			stackno = xmeth->localsz + xmeth->stacksz - 1;			start_exception_block();		}		switch (base[pc]) {		default:			printf("Unknown bytecode %d\n", base[pc]);			leaveTranslator();#if defined(KAFFE_FEEDBACK)			if( kaffe_feedback_file )				unlockMutex(kaffe_feedback_file);#endif			unlockClass(xmeth->class);			postException(einfo, JAVA_LANG(VerifyError));                        success = false;			break;#include "kaffe.def"		}		/* Note maximum number of temp slots used and reset it */		if (tmpslot > maxTemp) {			maxTemp = tmpslot;		}		tmpslot = 0;SCHK(		sanityCheck();					)		if (IS_STARTOFBASICBLOCK(npc)) {			end_basic_block();			success = generateInsnSequence(einfo);			if (success == false) {				goto done;			}			start_basic_block();			stackno = STACKPOINTER(npc);SCHK(			sanityCheck();				)		}	}	end_function();	makeFakeCalls();	assert(maxTemp < MAXTEMPS);	if( finishInsnSequence(NULL, &ncode, einfo) )	{		installMethodCode(NULL, xmeth, &ncode);	}	else	{		success = false;	}	goto done;oom_error:;	KaffeJIT3_cleanupInsnSequence();	done:;	KaffeJIT3_resetLabels();	KaffeJIT3_resetConstants();	tidyAnalyzeMethod(&codeInfo);	reinvoke = false;#if defined(KAFFE_PROFILER)	if (profFlag) {		profiler_click_t end;		profiler_get_clicks(end);		xmeth->jitClicks = end - xmeth->jitClicks;	}#endif	globalMethod = NULL;DBG(MOREJIT,    dprintf("Translating %s.%s%s (%s) %p\n",	    xmeth->class->name->data,	    xmeth->name->data,	    METHOD_SIGD(xmeth),	    isStatic ? "static" : "normal", METHOD_NATIVECODE(xmeth));    );		if (Kaffe_JavaVMArgs.enableVerboseJIT) {		tme = currentTime();		jitStats.time += (int)(tme - tms);		printf("<JIT: %s.%s%s time %dms (%dms) @ %p (%p)>\n",		       CLASS_CNAME(xmeth->class),		       xmeth->name->data, METHOD_SIGD(xmeth),		       (int)(tme - tms), jitStats.time,		       METHOD_NATIVECODE(xmeth), xmeth);	}	stopTiming(&fulljit);

⌨️ 快捷键说明

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