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

📄 machine.c

📁 java virtual machince kaffe
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	/* If this isn't being done for a function call we can free the	 * spill mask now.  Otherwise it will be freed by the function	 * reloader.	 */	if (type != SR_FUNCTION) {		gc_free(s->u[1].smask);	}	enable_readonce = old_ro;SCHK(	sanityCheck();						)}voiddoReload(sequence* s){	SlotData* sd;	SlotData** mem;	int type;SCHK(	sanityCheck();						)	type = s->u[2].value.i;	for (mem = s->u[1].smask; *mem != 0; mem++) {		sd = *mem;		if (sd->regno != NOREG && !isGlobal(sd)) {			switch (type) {			case SR_BASIC:			case SR_SUBBASIC:				slot_invalidate(sd);				break;			case SR_FUNCTION:				if (calleeSave(sd->regno) == 0) {					slot_invalidate(sd);				}				break;			case SR_START:			case SR_EXCEPTION:				break;			default:				KAFFEVM_ABORT();			}		}	}	/* Deal with global reloading */	for (mem = s->u[1].smask; *mem != 0; mem++) {		sd = *mem;		if (isGlobal(sd)) {			switch (type) {			case SR_BASIC:			case SR_SUBBASIC:				if (!isGlobalReadonly(sd)) {					sd->modified = rwrite;				}				break;			case SR_FUNCTION:				break;			case SR_START:				if (isGlobalPreload(sd)) {					reload(sd);				}				break;			case SR_EXCEPTION:				reload(sd);				break;			default:				KAFFEVM_ABORT();			}		}	}	gc_free(s->u[1].smask);SCHK(	sanityCheck();						)}/* * Create the spill/reload mask. * This contains a list of slot/global pairs indicating which slots are * active and should be spilled or reloaded now.  The global flag indicates * that at this point the slot is global (ie. carried between basic blocks) * so should be handled with care. */SlotData**createSpillMask(void){	SlotData** mem;	SlotData* d;	int i;	int c;	/* Count the number of slots we need to remember.  Note: we	 * include the number of potentially active temps.	 */	i = maxLocal + maxStack + tmpslot;	c = 0;	for (i--; i >= 0; i--) {		d = slotinfo[i].slot;		if (d->rseq != 0 || d->wseq != 0 || isGlobal(d)) {			c++;		}	}#if defined(STACK_LIMIT)	d = stack_limit->slot;	if (d->rseq != 0 || d->wseq != 0) {		c++;	}#endif	c++; /* Add null slot on the end */	mem = gc_malloc(c * sizeof(SlotData*), KGC_ALLOC_JIT_SLOTS);	if (mem == NULL)	  KaffeJIT3_exitWithOOM();		i = maxLocal + maxStack + tmpslot;	c = 0;	for (i--; i >= 0; i--) {		d = slotinfo[i].slot;		if (d->rseq != 0 || d->wseq != 0 || isGlobal(d)) {			mem[c++] = d;		}	}#if defined(STACK_LIMIT)	d = stack_limit->slot;	if (d->rseq != 0 || d->wseq != 0) {		mem[c++] = d;	}#endif	return (mem);}/* * Alias one slot's register to reference another. */voidslotAlias(sequence* s){	int reg;	SlotData* to;	SlotData* from;	int type;SCHK(	sanityCheck();						)	to = s->u[0].slot;	type = s->u[1].value.i;	from = s->u[2].slot;	if (reginfo[from->regno].flags & Rreadonce) {		/*		 * XXX Aggressively spill the floating point register on x86.		 * Otherwise it might not get spilled out at all.		 */		spillAndUpdate(from, true);	}		/* If this slot has a register we must invalidate it before we	 * overwrite it.	 */	if (to->regno != NOREG) {		/* If it has the register already then don't do anything */		if (from->regno == to->regno) {			return;		}		assert(isGlobal(to) == 0);		slot_invalidate(to);	}	/* Get the register we're aliasing and attach the 'to' slot	 * to it.	 */	reg = slotRegister(from, type, rread, NOREG);	reginfo[reg].refs++;	to->regno = reg;	to->modified = rwrite;	/* Prepend slot onto register use lists */	to->rnext = reginfo[reg].slot;	reginfo[reg].slot = to;SCHK(	sanityCheck();						)}voidsetupArgumentRegisters(void){#if defined(NR_ARGUMENTS)	int args;	int i;	static sequence argseq[1];	args = maxArgs;	if (args > NR_ARGUMENTS) {		args = NR_ARGUMENTS;	}	for (i = 0; i < args; i++) {		writeslot(argseq, i, &localinfo[i], 1);		localinfo[i].slot->modified = rwrite;	}#if defined(STACK_LIMIT)	if (args < NR_ARGUMENTS) {		writeslot(argseq, i, stack_limit, 1);		stack_limit->slot->modified = rwrite;	}#endif#endif}/* * Build multi-dimensional array. *  This is sufficiently different from the standard *  to require our own routine. */void*jit_soft_multianewarray(Hjava_lang_Class* class, jint dims, ...){	errorInfo einfo;	int array[16];	Hjava_lang_Object* obj;	jint arg;	int i;	int* arraydims;	va_list ap;        if (dims < 16-1) {		arraydims = array;	}	else {		arraydims = checkPtr(gc_calloc(dims+1, sizeof(int), KGC_ALLOC_JITTEMP));	}	/* Extract the dimensions into an array */	va_start(ap, dims);	for (i = 0; i < dims; i++) {		arg = va_arg(ap, jint);		if (arg < 0) {			if (arraydims != array) {				gc_free (arraydims);			}                        throwException(NegativeArraySizeException);		}		arraydims[i] = arg;	}	arraydims[i] = -1;	va_end(ap);	/* Mmm, okay now build the array using the wonders of recursion */        obj = newMultiArrayChecked(class, arraydims, &einfo);	if (arraydims != array) {		gc_free(arraydims);	}	if (!obj) {		throwError(&einfo);	}	/* Return the base object */	return (obj);}/* * Include the machine specific trampoline functions. */typedef struct _fakeCall {	struct _fakeCall*	next;	struct _fakeCall*	parent;	label*			from;	label*			to;	void*			func;} fakeCall;/* XXX These are globally shared */static fakeCall* firstFake;static fakeCall** lastFake = &firstFake;static fakeCall* fakePool;static fakeCall* redundantFake;voidinitFakeCalls(void){	*lastFake = redundantFake;	redundantFake = NULL;	fakePool = firstFake;	firstFake = NULL;	lastFake = &firstFake;}#if defined(HAVE_branch_and_link)staticfakeCall *findFakeCall(void *func){	fakeCall *fc, *retval = NULL;	for( fc = firstFake; fc && !retval; fc = fc->next )	{		if( fc->func == func )			retval = fc;	}	return( retval );}#endif /* defined(HAVE_branch_and_link) *//* * Build a fake call to a function. *  A fake call has a return address which is different from where it's *  actually called from. */label*newFakeCall(void* func, uintp currpc){	fakeCall *fc;	label* from;	label* to;	/* This is used to mark where I'm calling from */	from = reference_code_label(currpc);	/* This is where I'm calling to */	to = KaffeJIT3_newLabel();	to->type = Linternal;	to->at = 0;	to->to = 0;	to->from = 0;	/* XXX This isn't safe, but noone checks the return value :( */	if( fakePool )	{		fc = fakePool;		fakePool = fakePool->next;		fc->next = NULL;	}	else	{		fc = KGC_malloc(main_collector,				sizeof(fakeCall),				KGC_ALLOC_JIT_FAKE_CALL);		if (fc == NULL)		  KaffeJIT3_exitWithOOM();	}#if defined(HAVE_branch_and_link)	fc->parent = findFakeCall(func);#endif	fc->from = from;	fc->to = to;	fc->func = func;	if( fc->parent != NULL )	{		fc->next = redundantFake;		redundantFake = fc;	}	else	{		*lastFake = fc;		lastFake = &fc->next;	}	return (to);}staticvoidmakeFakeCalls(void){	fakeCall* c;	for (c = firstFake; c; c = c->next) {		softcall_fakecall(c->from, c->to, c->func);	}}staticvoid relinkFakeCalls(void){	fakeCall *fc;		for( fc = redundantFake; fc; fc = fc->next )	{		fc->to->to = fc->parent->to->to;		fc->to->type = fc->parent->to->type;				fc->from->at = fc->parent->from->at;		fc->from->type = fc->parent->from->type;		assert(fc->to->from != 0);	}}/* * 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 + -