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 + -
显示快捷键?