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

📄 machine.c

📁 java virtual machince kaffe
💻 C
📖 第 1 页 / 共 3 页
字号:
	leaveTranslator();#if defined(KAFFE_FEEDBACK)	if( kaffe_feedback_file )		unlockMutex(kaffe_feedback_file);#endifdone3:;	unlockClass(xmeth->class);#if defined(ENABLE_JVMPI)	if (success && JVMPI_EVENT_ISENABLED(JVMPI_EVENT_COMPILED_METHOD_LOAD) )	  {	    JVMPI_Event ev;	    jvmpiFillMethodLoad(&ev, xmeth);	    jvmpiPostEvent(&ev);	  }#endif	return (success);}voidKaffeJIT3_cleanupInsnSequence(){  sequence *s;  for (s = firstSeq; s != currSeq; s = s->next)    {      if (s->func != doSpill)	continue;            /* According to doSpill */      gc_free(s->u[1].smask);    }   initSeq();}/* * Generate the code. */jbooleanfinishInsnSequence(void* dummy UNUSED, nativeCodeInfo* code, errorInfo* einfo){	uint32 constlen;	jitCodeHeader *jch;	nativecode* methblock;	jboolean success;	uintp const_align = sizeof(union _constpoolval) - 1;	/* Emit pending instructions */	success = generateInsnSequence(einfo);	if (success == false) {		return (false);	}	relinkFakeCalls();	/* Okay, put this into malloc'ed memory. We allocate some more	 * memory for alignment purpose. */	constlen = KaffeJIT3_getNumberOfConstants() * sizeof(union _constpoolval); 	methblock = gc_malloc(sizeof(jitCodeHeader) +			      constlen + const_align +			      CODEPC,			      KGC_ALLOC_JITCODE);	if (methblock == 0) {		postOutOfMemory(einfo);		return (false);	}	jch = (jitCodeHeader *)methblock;	jch->pool = (void *)(jch + 1);	jch->pool = (void *) ( ((unsigned long)(jch->pool) + const_align) & ~const_align);	jch->code_start = ((nativecode *)jch->pool) + constlen;	jch->code_len = CODEPC;	memcpy(jch->code_start, codeblock, jch->code_len);	gc_free(codeblock);	/* Establish any code constants */	KaffeJIT3_establishConstants(jch->pool);	/* Link it */	KaffeJIT3_linkLabels((uintp)jch->code_start);	/* Note info on the compiled code for later installation */	code->mem = methblock;	code->memlen = constlen + CODEPC;	code->code = jch->code_start;	code->codelen = CODEPC;	return (true);}/* * Get the instruction offset corresponding to the given PC. * If the PC doesn't point at the start of a valid instruction, * look forward until we find one. If we reach the end of the * method, we return code->codelen */staticintgetInsnPC(int _pc, codeinfo* _codeInfo, nativeCodeInfo *code){	int maxPc = _codeInfo->codelen;	while (_pc < maxPc) {		if (IS_STARTOFINSTRUCTION(_pc)) {			int res = INSNPC(_pc);			if (res != -1) {				return (res);			}		}		_pc ++;	}	return code->codelen;}/* * Install the compiled code in the method. * Returns true if successful */voidinstallMethodCode(void* ignore UNUSED, Method* meth, nativeCodeInfo* code){	uint32 i;	jexceptionEntry* e;	jitCodeHeader *jch;	void *tramp;#if defined(KAFFE_XPROFILER) || defined(KAFFE_XDEBUGGING)	struct mangled_method *mm = 0;#endif#if defined(KAFFE_FEEDBACK)	char *sym = 0;#endif	/* Work out new estimate of code per bytecode */	code_generated += code->memlen;	bytecode_processed += METHOD_BYTECODE_LEN(meth);	/* When using GCJ, the only use for the translator may be to output	 * JNI wrappers which have zero bytecode ;-); hence the test	 */	if (bytecode_processed > 0) {		codeperbytecode = code_generated / bytecode_processed;	}	//KGC_WRITE(meth, code->mem);	jch = (jitCodeHeader *)code->mem;	jch->method = meth;	tramp = METHOD_NATIVECODE(meth);	SET_METHOD_JITCODE(meth, code->code);	setMethodCodeStart(meth, code->mem);	meth->c.ncode.ncode_end = (void*)((uintp)code->code + code->codelen);	#if defined(KAFFE_FEEDBACK)	if( kaffe_feedback_file && !meth->class->loader )	{		sym = gc_malloc(strlen(CLASS_CNAME(meth->class)) +				1 + /* '/' */				strlen(meth->name->data) +				strlen(METHOD_SIGD(meth)) +				1,				KGC_ALLOC_JITTEMP);		assert(sym != NULL);		sprintf(sym,			"%s/%s%s",			CLASS_CNAME(meth->class),			meth->name->data,			METHOD_SIGD(meth));		feedbackJITMethod(sym, code->code, code->codelen, true);		gc_free(sym);	}#endif#if defined(KAFFE_XPROFILER) || defined(KAFFE_XDEBUGGING)	if( (#if defined(KAFFE_XPROFILER)	     xProfFlag ||#else	     0 ||#endif#if defined(KAFFE_XDEBUGGING)	     machine_debug_file#else	    0#endif	     ) &&	    (mm = createMangledMethod()) )	{		mangleMethod(mm, meth);	}#endif#if defined(KAFFE_XPROFILER)	profileFunction(mm, code->code, code->codelen);#endif	/* Flush code out of cache */#if defined(FLUSH_DCACHE)	FLUSH_DCACHE(code->code, (void*)((uintp)code->code + code->codelen));#endif	/* Translate exception table and make it available */	if (meth->exception_table != 0) {		for (i = 0; i < meth->exception_table->length; i++) {			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) {#if defined(KAFFE_XDEBUGGING)		struct debug_file *df = machine_debug_file;		/* Mark the start of this source file */		char *sourcefile = meth->class->sourcefile;		if (! sourcefile)			sourcefile = "Unknown source file";		addDebugInfo(df,			     DIA_IncludeFile,			     meth->class->name->data,			     meth->class->packageLength,			     sourcefile,			     code->code,			     DIA_Function,			     meth, mm, meth->lines->entry[0].line_nr,			     code->code, code->codelen,			     DIA_DONE);#endif		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;#if defined(KAFFE_XDEBUGGING)			/* Add line debugging */			addDebugInfo(df,				     DIA_SourceLine,				     meth->lines->entry[i].line_nr,				     meth->lines->entry[i].start_pc -				     (uintp)code->code,				     DIA_DONE);#endif		}		if( meth->lvars != NULL ) {			localVariableEntry *lve;						for (i = 0; i < meth->lvars->length; i++) {				lve = &meth->lvars->entry[i];				lve->start_pc =					(uintp)code->code +					getInsnPC(lve->start_pc,						  codeInfo,						  code);#if defined(KAFFE_XDEBUGGING) && defined(SLOT2LOCALOFFSET)				if( df != NULL ) {					struct Hjava_lang_Class *cl;					const char *vname, *vsig;					errorInfo einfo;					vname = CONST_UTF2CHAR(						lve->name_index,						CLASS_CONSTANTS(meth->class));					vsig = CONST_UTF2CHAR(						lve->descriptor_index,						CLASS_CONSTANTS(meth->class));					cl = getClassFromSignature(						vsig,						meth->class->loader,						&einfo);					if( cl == NULL )					{						discardErrorInfo(&einfo);					}					/* Add line debugging */					addDebugInfo(df,						     lve->index < maxArgs ?						     DIA_Parameter :						     DIA_LocalVariable,						     vname,						     cl,						     local(lve->index)->slot->offset,						     DIA_DONE);				}#endif			}		}#if defined(KAFFE_XDEBUGGING)		/*		 * Mark the end of the function.  This needs to be here so that		 * gdb doesn't get confused about the range of the function		 * since that will be determined by the next debugging		 * information that is added.		 */		addDebugInfo(df,			     DIA_EndFunction, code->code + code->codelen,			     DIA_DONE);#endif	}	else	{#if defined(KAFFE_XDEBUGGING)		/*		 * No line debugging, but we'd like a symbol to show up anyways		 */                char *sourcefile = meth->class->sourcefile;                if (! sourcefile)                        sourcefile = "Unknown source file";		addDebugInfo(			machine_debug_file,			DIA_IncludeFile,			meth->class->name->data,			meth->class->packageLength,			sourcefile,			code->code,						DIA_Function, meth, mm, 0, code->code, code->codelen,			DIA_EndFunction, code->code + code->codelen,			DIA_DONE);#endif	}#if defined(KAFFE_XPROFILER) || defined(KAFFE_XDEBUGGING)	deleteMangledMethod(mm);#endif		/* record framesize for gcj unwinding information */#if defined(LABEL_Lframe)	LABEL_Lframe(&meth->framesize, /* unused */ 0, /* unused */ 0);#endif}/* * Generate instructions from current set of sequences. */staticjbooleangenerateInsnSequence(errorInfo* einfo){	sequence* t;	int i;	int m;	for (t = firstSeq; t != currSeq; t = t->next) {		/* If we overrun the codeblock, reallocate and continue.  */		if (CODEPC >= codeblock_size) {			nativecode *new_codeblock;						codeblock_size += ALLOCCODEBLOCKSZ;			new_codeblock = gc_realloc(codeblock,						   codeblock_size +						   CODEBLOCKREDZONE,						   KGC_ALLOC_JIT_CODEBLOCK);			if (new_codeblock == NULL) {				gc_free(codeblock);				codeblock = NULL;				postOutOfMemory(einfo);				return (false);			} else {				codeblock = new_codeblock;			}		}SCHK(		sanityCheck();					);		/* Generate sequences */		assert(t->func != 0);		if (t->refed != 0) {			(*(t->func))(t);		}		else {			/* printf("discard instruction\n"); */		}		/* Handle dead slots */		m = t->lastuse;		if (m != 0) {			for (i = 0; m != 0; m = m >> 1, i++) {				if ((m & 1) != 0) {					assert(!isGlobal(t->u[i].slot));					slot_kill_readonce(t->u[i].slot);					slot_invalidate(t->u[i].slot);				}			}		}	}	/* Reset */	initSeq();	return (true);}/* * check what synchronous exceptions are caught for a given instruction */staticvoid checkCaughtExceptions(Method* meth, uint32 _pc){	unsigned int i;	willcatch.ANY = false;	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;		willCatch(ANY);		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);			}		}	}}/* * Start a new instruction. */voidstartInsn(sequence* s){	SET_INSNPC(const_int(2), CODEPC);}voiddoSpill(sequence* s){	SlotData** mem;	SlotData* sd;	int type;	int old_ro;SCHK(	sanityCheck();						)	type = s->u[2].value.i;	old_ro = enable_readonce;	if (type == SR_SYNC) {		enable_readonce = 0;	}	/* Spill the registers */	for (mem = s->u[1].smask; *mem != 0; mem++) {		sd = *mem;		/* Determine if we need to spill this slot at all */		if ((sd->modified & rwrite) != 0 && sd->regno != NOREG) {			switch (type) {			case SR_BASIC:			case SR_SUBBASIC:				/* We only spill if it's not global */				if (!isGlobal(sd)) {					spillAndUpdate(sd, true);				}				break;			case SR_SYNC:				spillAndUpdate(sd, false);				break;			case SR_FUNCTION:				if (calleeSave(sd->regno) == 0 || s->jflags.ANY != 0) {					spillAndUpdate(sd, true);				}				break;			default:				KAFFEVM_ABORT();			}		}

⌨️ 快捷键说明

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