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

📄 machine.c

📁 java virtual machince kaffe
💻 C
📖 第 1 页 / 共 2 页
字号:
	KaffeJIT_linkLabels(codeInfo, (uintp)jch->code_start);	/* Note info on the compiled code for later installation */	code->mem = methblock;	code->memlen = exc_len + constlen + CODEPC;	code->code = jch->code_start;	code->codelen = CODEPC;		return (true);}static intgetInsnPC(int pc, codeinfo* codeInfo, nativeCodeInfo* code) {	int maxPC = codeInfo->codelen;	while (pc < maxPC) {		if (IS_STARTOFINSTRUCTION(pc)) {			int insn = INSNPC(pc);			if (insn!=-1) {				return insn;			}		}		pc++;	}	return code->codelen;} /* * Install the compiled code in the method. */voidinstallMethodCode(codeinfo* codeInfo, Method* meth, nativeCodeInfo* code){	unsigned int i;	jexceptionEntry* e;	jitCodeHeader *jch;	void *tramp;	/* Work out new estimate of code per bytecode */	code_generated += code->memlen;	bytecode_processed += meth->c.bcode.codelen;	codeperbytecode = code_generated / bytecode_processed;	tramp = METHOD_NATIVECODE(meth);	/* install the jitted code */	SET_METHOD_JITCODE(meth, code->code);	setMethodCodeStart(meth, code->mem);	meth->c.ncode.ncode_end = (nativecode *)code->code + code->codelen;	jch = (jitCodeHeader *)code->mem;	jch->method = meth;		/* Flush code out of cache */	FLUSH_DCACHE(METHOD_NATIVECODE(meth), meth->c.ncode.ncode_end);#if defined(MD_REGISTER_JIT_EXCEPTION_INFO)	MD_REGISTER_JIT_EXCEPTION_INFO (getMethodCodeStart(meth),					METHOD_NATIVECODE(meth),					meth->c.ncode.ncode_end);#endif	/* Translate exception table and make it available */	if (meth->exception_table != 0) {		for (i = 0; i < meth->exception_table->length; i++) {			/* Note that we cannot assume that the bytecode			 * instructions that are at the start/end/handler			 * pc index have a corresponding native pc.			 * They only have one if they already emitted			 * native instructions during translation.			 * Jikes, for instance, likes to put a `nop' at			 * the end_pc index of an exception handler range.			 *			 * If this happens, we simply find the next bytecode			 * instruction that has a native pc and use it instead.			 */			e = &meth->exception_table->entry[i];			e->start_pc = getInsnPC(e->start_pc, codeInfo, code) + (uintp)code->code;			e->end_pc = getInsnPC(e->end_pc, codeInfo, code) + (uintp)code->code;			e->handler_pc = getInsnPC(e->handler_pc, codeInfo, code) + (uintp)code->code;			assert(e->start_pc <= e->end_pc);		}	}	/* Translate line numbers table */	if (meth->lines != 0) {		for (i = 0; i < meth->lines->length; i++) {			meth->lines->entry[i].start_pc = getInsnPC(meth->lines->entry[i].start_pc, codeInfo, code) + (uintp)code->code;		}	}}/* * Init instruction generation. */boolinitInsnSequence(Method* meth, int codesize, int localsz, int stacksz,		 struct _errorInfo *einfo){	/* Clear various counters */	tmpslot = 0;	maxTemp = 0;	maxPush = 0;  	stackno = localsz + stacksz;	maxTemp = MAXTEMPS - 1; /* XXX */ 	npc = 0;	initSeq();	initRegisters();	initSlots(stackno);	KaffeJIT_resetLabels();	KaffeJIT_resetConstants();	localinfo = &slotinfo[0];	tempinfo = &localinfo[stackno];	/* Before generating code, try to guess how much space we'll need. */	codeblock_size = codesize;	if (codeblock_size < ALLOCCODEBLOCKSZ) {		codeblock_size = ALLOCCODEBLOCKSZ;	}	codeblock = KMALLOC(codeblock_size + CODEBLOCKREDZONE);	if (!codeblock) {		postOutOfMemory(einfo);		return false;	}	addToCounter(&jitcodeblock, "jitmem-codeblock", 1,		     (jlong) GCSIZEOF(codeblock));	CODEPC = 0;	/* 	 * add the method we're translating as the first entry to the constant pool,	 * so that we can look it up pretty easily when creating stack traces.	 */	KaffeJIT_newConstant(CPref, meth);	return true;}/* */void KaffeJIT_cleanupInsnSequence(){  initSeq();}/* * Generate instructions from current set of sequences. */staticvoidgenerateInsnSequence(codeinfo* codeInfo){	sequence* t;	for (t = firstSeq; t != currSeq; t = t->next) {		/* If we overrun the codeblock, reallocate and continue.  */		if (CODEPC >= codeblock_size) {			codeblock_size += ALLOCCODEBLOCKSZ;			addToCounter(&jitcodeblock, "jitmem-codeblock", 0,				    -(jlong)GCSIZEOF(codeblock));			codeblock = KREALLOC(codeblock, codeblock_size + CODEBLOCKREDZONE);			addToCounter(&jitcodeblock, "jitmem-codeblock", 0,				     (jlong)GCSIZEOF(codeblock));		}		/* Generate sequences */		(*(void (*)(sequence*, codeinfo*))(t->func))(t, codeInfo);	}	/* Reset */	initSeq();}/* * Start a new instruction. */voidstartInsn(sequence* s, codeinfo* codeInfo){	SET_INSNPC(const_int(2), CODEPC);}/* * Mark slot not to be written back. */voidnowritebackSlot(sequence* s){	seq_slot(s, 0)->modified |= rnowriteback;}/* * Start a new basic block. */voidstartBlock(sequence* s){	startSubBlock(s);}/* * Start a new basic sub-block. */voidstartSubBlock(sequence* s UNUSED){	int i;	/* Invalidate all slots - don't use clobberRegister which will	 * flush them - we do not want to do that even if they are dirty.	 */	for (i = maxslot - 1; i >= 0; i--) {		if (slotinfo[i].regno != NOREG) {			register_invalidate(slotinfo[i].regno);			slot_invalidate(&slotinfo[i]);		}	}}/* * Fixup after a function call. */voidfixupFunctionCall(sequence* s UNUSED){	int i;	/* Invalidate all slots - don't use clobberRegister which will	 * flush them - we do not want to do that even if they are dirty.	 */	for (i = maxslot - 1; i >= 0; i--) {		if (slotinfo[i].regno != NOREG && (KaffeVM_jitGetRegInfo()[slotinfo[i].regno].flags & Rnosaveoncall) == 0) {			register_invalidate(slotinfo[i].regno);			slot_invalidate(&slotinfo[i]);		}	}}/* * End a basic block. */voidendBlock(sequence* s){	endSubBlock(s);}/* * End a basic sub-block. */voidendSubBlock(sequence* s){	int stkno;	int tmpslot;	int i;	/* Spill locals */	for (i = 0; i < maxLocal; i++) {		if ((localinfo[i].modified & rwrite) != 0 && localinfo[i].regno != NOREG) {			if ((localinfo[i].modified & rnowriteback) == 0) {				spill(&localinfo[i]);				localinfo[i].modified = 0;			}			else {				localinfo[i].modified &= ~rnowriteback;			}		}	}	/* Spill stack */	stkno = const_int(1);	for (i = stkno; i < maxStack+maxLocal; i++) {		if ((localinfo[i].modified & rwrite) != 0 && localinfo[i].regno != NOREG) {			if ((localinfo[i].modified & rnowriteback) == 0) {				spill(&localinfo[i]);				localinfo[i].modified = 0;			}			else {				localinfo[i].modified &= ~rnowriteback;			}		}	}	/* Spill temps currently in use */	tmpslot = const_int(2);	for (i = 0; i < tmpslot; i++) {		if ((tempinfo[i].modified & rwrite) != 0 && tempinfo[i].regno != NOREG) {			if ((tempinfo[i].modified & rnowriteback) == 0) {				spill(&tempinfo[i]);				tempinfo[i].modified = 0;			}			else {				tempinfo[i].modified &= ~rnowriteback;			}		}	}}/* * Prepare register state for function call. */voidprepareFunctionCall(sequence* s){	int stkno;	int tmpslot;	int i;	/* Spill locals */	for (i = 0; i < maxLocal; i++) {		if ((localinfo[i].modified & rwrite) != 0 && localinfo[i].regno != NOREG && (KaffeVM_jitGetRegInfo()[localinfo[i].regno].flags & Rnosaveoncall) == 0) {			spill(&localinfo[i]);			localinfo[i].modified = 0;		}	}	/* Spill stack */	stkno = const_int(1);	for (i = stkno; i < maxStack+maxLocal; i++) {		if ((localinfo[i].modified & rwrite) != 0 && localinfo[i].regno != NOREG && (KaffeVM_jitGetRegInfo()[localinfo[i].regno].flags & Rnosaveoncall) == 0) {			spill(&localinfo[i]);			localinfo[i].modified = 0;		}	}	/* Spill temps currently in use */	tmpslot = const_int(2);	for (i = 0; i < tmpslot; i++) {		if ((tempinfo[i].modified & rwrite) != 0 && tempinfo[i].regno != NOREG && (KaffeVM_jitGetRegInfo()[tempinfo[i].regno].flags & Rnosaveoncall) == 0) {			spill(&tempinfo[i]);			tempinfo[i].modified = 0;		}	}}/* * Sync register state back to memory (but don't clean anything). */voidsyncRegisters(sequence* s){	int stkno;	int tmpslot;	int i;	int old_ro;	old_ro = KaffeVM_jitGetEnableReadonce();	KaffeVM_jitSetEnableReadonce(0);	/* Spill locals */	for (i = 0; i < maxLocal; i++) {		if ((localinfo[i].modified & rwrite) != 0 && localinfo[i].regno != NOREG && (KaffeVM_jitGetRegInfo()[localinfo[i].regno].flags & Rnosaveoncall) == 0) {			spill(&localinfo[i]);		}	}	/* Spill stack */	stkno = const_int(1);	for (i = stkno; i < maxLocal+maxStack; i++) {		if ((localinfo[i].modified & rwrite) != 0 && localinfo[i].regno != NOREG && (KaffeVM_jitGetRegInfo()[localinfo[i].regno].flags & Rnosaveoncall) == 0) {			spill(&localinfo[i]);		}	}	/* Spill temps currently in use */	tmpslot = const_int(2);	for (i = 0; i < tmpslot; i++) {		if ((tempinfo[i].modified & rwrite) != 0 && tempinfo[i].regno != NOREG && (KaffeVM_jitGetRegInfo()[tempinfo[i].regno].flags & Rnosaveoncall) == 0) {			spill(&tempinfo[i]);		}	}	KaffeVM_jitSetEnableReadonce(old_ro);}/* * Cancel any pending nowriteback flags. */voidcancelNoWriteback(void){	int i;	for (i = stackno; i < maxLocal+maxStack; i++) {		localinfo[i].modified &= ~rnowriteback;	}}/* * check what synchronous exceptions are caught for a given instruction */staticvoid checkCaughtExceptions(Method* meth, unsigned int pc){	unsigned int i;	willcatch.BADARRAYINDEX = false;	willcatch.NULLPOINTER = false;	if (meth->exception_table == 0) 		return;	/* Determine various exception conditions */	for (i = 0; i < meth->exception_table->length; i++) {		Hjava_lang_Class* etype;		/* include only if exception handler range matches pc */		if (meth->exception_table->entry[i].start_pc > pc ||		    meth->exception_table->entry[i].end_pc <= pc)			continue;		etype = meth->exception_table->entry[i].catch_type;		if (etype == 0) {			willCatch(BADARRAYINDEX);			willCatch(NULLPOINTER);		}		else {			if (instanceof(javaLangArrayIndexOutOfBoundsException, etype)) {				willCatch(BADARRAYINDEX);			}			if (instanceof(javaLangNullPointerException, etype)) {				willCatch(NULLPOINTER);			}		}	}}/* * return what engine we're using */const char* getEngine(void){	return "kaffe.jit";}void initEngine(void){  initStaticLock(&translatorlock);}#if defined(KAFFE_PROFILER)static jlong click_multiplier;static profiler_click_t click_divisor;static FILE *prof_output;static intprofilerClassStat(Hjava_lang_Class *clazz, void *param UNUSED){	Method *meth;	int mindex;	for (mindex = CLASS_NMETHODS(clazz), meth = Kaffe_get_class_methods(clazz);	     mindex-- > 0; meth++) {		if (meth->callsCount == 0)			continue;		fprintf(prof_output,			"%10d %10.6g %10.6g %10.6g %10.6g %s.%s%s\n",			meth->callsCount,			(click_multiplier * ((double)meth->totalClicks)) / click_divisor,			(click_multiplier * ((double)(meth->totalClicks						      - meth->totalChildrenClicks)))			/ click_divisor,			(click_multiplier * ((double)meth->totalChildrenClicks)) / click_divisor,			(click_multiplier * ((double)meth->jitClicks)) / click_divisor,			meth->class->name->data,			meth->name->data,			METHOD_SIGD(meth)		       );	}	return 0;}static voidprintProfilerStats(void){	profiler_click_t start, end;	jlong m_start, m_end;	/* If the profFlag == 0, don't bother printing anything */	if (profFlag == 0)		return; 	/* open file */ 	prof_output = fopen("prof.out", "w");	if (prof_output == NULL) {		return;	}	/* Need to figure out what profiler_click  _really_ is.	 * Use currentTime() to guest how long is a second.  Call it before	 * to don't count dynamic linker resolve time.  */	m_start = currentTime();	profiler_get_clicks(start);	sleep (1);	m_end = currentTime();	profiler_get_clicks(end);	click_multiplier = m_end - m_start;	click_divisor = end - start;	fprintf(prof_output,		"# clockTick: %lld per 1/%lld seconds aka %lld per milliseconds\n",		click_divisor,		click_multiplier,		click_divisor / click_multiplier); 	fprintf(prof_output, "%10s %10s %10s %10s %10s %s\n", 		"#    count", "total", "self", "children", "jit", 		"method-name");	/* Traverse through class hash table */	walkClassPool(profilerClassStat, NULL);	fclose(prof_output);}#endif

⌨️ 快捷键说明

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