xprofiler.c

来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· C语言 代码 · 共 713 行 · 第 1/2 页

C
713
字号
			walkMemorySamples(kaffe_memory_samples,					  low,					  high -					  (extraProfileCount * HISTFRACTION),					  &pgf,					  profilerSampleWalker);			if( pgf.pgf_file )			{				/* Dump out the call graph data */				writeCallGraph(kaffe_call_graph, pgf.pgf_file);				deleteGmonFile(pgf.pgf_file);			}			else			{				resetMemorySamples(kaffe_memory_samples);			}		}		else		{			fprintf(stderr,				"XProf Notice: Cannot create gmon file %s\n",				filename);			KFREE(filename);			resetMemorySamples(kaffe_memory_samples);		}	}	else	{		fprintf(stderr,			"XProf Notice: Not enough memory to write "			"profiling data\n");		resetMemorySamples(kaffe_memory_samples);	}	resetCallGraph(kaffe_call_graph);	xProfilingOn();	jthread_unsuspendall();}int profileGmonFile(char *name){	/* Just set the file for now, we'll make it at exit */	kaffe_gmon_filename = name;	return( true );}int profileSymbolFile(char *name){	kaffe_syms_filename = name;	return( true );}#if defined(KAFFE_XPROFILER)struct sigaction oldSigAction;static void profileTimerHandler(SIGNAL_ARGS(sig, sc)){	SIGNAL_CONTEXT_POINTER(scp) = GET_SIGNAL_CONTEXT_POINTER(sc);	char *addr = (char *)SIGNAL_PC(scp);	if( kaffe_memory_samples && xProfRecord )	{		if( profiler_sample_override_pc )		{			profiler_sample_overrides++;			/* Use the override address */			addr = profiler_sample_override_pc;			/* Null it out to stop false positives */			profiler_sample_override_pc = 0;		}		memoryHit(kaffe_memory_samples, addr);	}}int enableProfileTimer(void){	struct sigaction sa;	int retval = false;	/* Setup our signal handler */	sa.sa_handler = (SIG_T)profileTimerHandler;	sigfillset(&sa.sa_mask);	sa.sa_flags = 0;#if 0	if( sigaction(SIGALRM, &sa, &oldSigAction) >= 0 )	{		struct itimerval new_value;				/* Setup a 10ms timer */		new_value.it_interval.tv_sec = 0;		new_value.it_interval.tv_usec = 10000;		new_value.it_value.tv_sec = 0;		new_value.it_value.tv_usec = 10000;		if( setitimer(ITIMER_REAL, &new_value, 0) >= 0 )		{			retval = true;		}	}#endif	retval = 1;	return( retval );}void disableProfileTimer(void){	struct itimerval disable_value;	timerclear(&disable_value.it_interval);	timerclear(&disable_value.it_value);	setitimer(ITIMER_REAL, &disable_value, 0);}#elseint enableProfileTimer(void){	return( 1 );}void disableProfileTimer(void){}#endif/* The rest of these are just wrappers for other code */int profileFunction(struct mangled_method *mm, char *code, int codelen){	int retval = false;	if( xProfFlag && kaffe_memory_samples )	{		/*		 * Add the function name to the symbol file and observe the		 * memory		 */		xProfilingOff();		if( observeMemory(kaffe_memory_samples, code, codelen) &&		    addDebugInfo(profiler_debug_file,				 DIA_FunctionSymbol, mm, code, codelen,				 DIA_DONE) )		{			retval = true;		}		xProfilingOn();	}	else	{		retval = true;	}	return( retval );}int profileMemory(char *code, int codelen){	int retval = false;		if( xProfFlag )	{		xProfilingOff();		if( observeMemory(kaffe_memory_samples, code, codelen) )		{			retval = true;		}		xProfilingOn();	}	else	{		retval = true;	}	return( retval );}int profileSymbol(struct mangled_method *mm, char *addr, int size){	int retval = false;		if( xProfFlag )	{		if( addDebugInfo(profiler_debug_file,				 DIA_FunctionSymbol, mm, addr, size,				 DIA_DONE) )		{			retval = true;		}	}	else	{		retval = true;	}	return( retval );}void profileArcHit(char *frompc, char *selfpc){	char *old_override = profiler_sample_override_pc;		/*	 * profiler_sample_override_pc is a nasty hack to keep the	 * accounting function from being counted as a hit when it	 * should really be the caller.	 */	profiler_sample_override_pc = selfpc;	if( kaffe_call_graph && xProfRecord )	{		arcHit(kaffe_call_graph, frompc, selfpc);	}	profiler_sample_override_pc = old_override;}#if defined(KAFFE_XPROFILER) && defined(KAFFE_CPROFILER) && defined(_KAFFE_OVERRIDE_MCOUNT_DEF)_KAFFE_OVERRIDE_MCOUNT_DEF{	char *old_override = profiler_sample_override_pc;		/*	 * profiler_sample_override_pc is a nasty hack to keep the	 * accounting function from being counted as a hit when it	 * should really be the caller.	 */	profiler_sample_override_pc = (char *)selfpc;	if( kaffe_call_graph )	{		register struct gmonparam *gp = getGmonParam();				if( !xProfRecord || (gp && (gp->state != GMON_PROF_ON)) )			goto fini;		arcHit(kaffe_call_graph, (char *)frompc, (char *)selfpc);	}	else	{		register u_short *frompcindex;		register struct tostruct *top, *prevtop;		register struct gmonparam *p;		register long toindex;		p = getGmonParam();		/*		 * check that we are profiling		 * and that we aren't recursively invoked.		 */		if( !p || (p->state != GMON_PROF_ON) )			goto fini;		p->state = GMON_PROF_BUSY;				/*		 * check that frompcindex is a reasonable pc value.		 * for example:	signal catchers get called from the stack,		 *		not from text space.  too bad.		 */		frompc -= p->lowpc;		if (frompc > p->textsize)			goto done;				frompcindex = &p->froms[frompc /				       (p->hashfraction * sizeof(*p->froms))];		toindex = *frompcindex;		if (toindex == 0) {			/*			 *	first time traversing this arc			 */			toindex = ++p->tos[0].link;			if (toindex >= p->tolimit)				/* halt further profiling */				goto overflow;						*frompcindex = toindex;			top = &p->tos[toindex];			top->selfpc = selfpc;			top->count = 1;			top->link = 0;			goto done;		}		top = &p->tos[toindex];		if (top->selfpc == selfpc) {			/*			 * arc at front of chain; usual case.			 */			top->count++;			goto done;		}		/*		 * have to go looking down chain for it.		 * top points to what we are looking at,		 * prevtop points to previous top.		 * we know it is not at the head of the chain.		 */		for (; /* goto done */; ) {			if (top->link == 0) {				/*				 * top is end of the chain and none of the				 * chain had top->selfpc == selfpc.  so we				 * allocate a new tostruct and link it to the				 * head of the chain.				 */				toindex = ++p->tos[0].link;				if (toindex >= p->tolimit)					goto overflow;								top = &p->tos[toindex];				top->selfpc = selfpc;				top->count = 1;				top->link = *frompcindex;				*frompcindex = toindex;				goto done;			}			/*			 * otherwise, check the next arc on the chain.			 */			prevtop = top;			top = &p->tos[top->link];			if (top->selfpc == selfpc) {				/*				 * there it is.				 * increment its count				 * move it to the head of the chain.				 */				top->count++;				toindex = prevtop->link;				prevtop->link = top->link;				top->link = *frompcindex;				*frompcindex = toindex;				goto done;			}					}	done:		p->state = GMON_PROF_ON;		goto fini;	overflow:		p->state = GMON_PROF_ERROR;		goto fini;	} fini:	profiler_sample_override_pc = old_override;}_KAFFE_OVERRIDE_MCOUNT#endifvoid profileHit(char *addr){	if( kaffe_memory_samples && xProfRecord )	{		if( profiler_sample_override_pc )		{			profiler_sample_overrides++;			/* Use the override address */			addr = profiler_sample_override_pc;			/* Null it out to stop false positives */			profiler_sample_override_pc = 0;		}		memoryHit(kaffe_memory_samples, addr);	}}#endif /* KAFFE_XPROFILER */

⌨️ 快捷键说明

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