#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
/* define DBG_SUB to cause a warning on each subroutine entry. */
/*#define DBG_SUB 1 */
/* define DBG_TIMER to cause a warning when the timer is turned on and off. */
/*#define DBG_TIMER 1 */
#ifdef DEBUGGING
#else
#define ASSERT(x)
#endif
static CV *
{
} else {
} else {
croak("DProf: don't know what subroutine to profile");
}
}
return cv;
}
#ifdef DBG_SUB
void
warn("XS DBsub(%s::%s)\n",
} else {
}
}
#else
# define DBG_SUB_NOTIFY(A) /* nothing */
#endif
#ifdef DBG_TIMER
# define DBG_TIMER_NOTIFY(A) warn(A)
#else
# define DBG_TIMER_NOTIFY(A) /* nothing */
#endif
/* HZ == clock ticks per second */
#ifdef VMS
# include <starlet.h> /* prototype for sys$gettim() */
#else
# ifndef HZ
# ifdef CLK_TCK
# else
# define HZ 60
# endif
# endif
# ifdef OS2 /* times() has significant overhead */
# define INCL_DOSPROFILE
# define INCL_DOSERRORS
# include <os2.h>
# define DPROF_HZ g_dprof_ticks
# else
# endif
#endif
/* Everything is built on times(2). See its manpage for a description
* of the timings.
*/
union prof_any {
char *name;
};
typedef struct {
char* out_file_name; /* output file (defaults to tmon.out) */
int SAVE_STACK; /* How much data to buffer until end of run */
int prof_pid; /* pid of profiled process */
struct tms prof_start;
int profstack_max;
int profstack_ix;
#ifdef OS2
long long start_cnt;
#endif
#ifdef PERL_IMPLICIT_CONTEXT
# define register
pTHX;
# undef register
#endif
} prof_state_t;
#ifdef PERL_IMPLICIT_CONTEXT
#endif
#ifdef OS2
#endif
{
#ifdef OS2
if (!g_frequ) {
else
croak("DosTmrQueryTime: %s",
}
t->tms_stime = 0;
#else /* !OS2 */
# ifdef VMS
/* Get wall time and convert to 10 ms intervals to
* produce the return value dprof expects */
# include <ints.h>
vmstime /= 100000;
# else
/* (Older hw or ccs don't have an atomic 64-bit type, so we
* juggle 32-bit ints (and a float) to produce a time_t result
* with minimal loss of information.) */
# endif
/* Fill in the struct tms using the CRTL routine . . .*/
# else /* !VMS && !OS2 */
return times(t);
# endif
#endif
}
static void
{
if (ptype == OP_LEAVESUB) {
}
else if(ptype == OP_ENTERSUB) {
}
}
}
else {
}
}
static void
{
}
static void
{
}
static void
{
long base = 0;
}
}
else {
}
}
/* The (IV) casts are one possibility:
* the Painfully Correct Way would be to
* have Clock_t_f. */
}
}
static void
{
}
static void
{
struct tms t;
if (g_SAVE_STACK) {
}
}
if (g_SAVE_STACK) {
}
else { /* Write it to disk now so's not to eat up core */
if (g_prof_pid == (int)getpid()) {
}
}
g_otms_stime = t.tms_stime;
g_otms_utime = t.tms_utime;
}
{
: "(null)");
return;
if (g_SAVE_STACK) { /* Store it for later recording -JH */
}
else { /* Write it to disk now so's not to eat up core */
/* Only record the parent's info */
if (g_prof_pid == (int)getpid()) {
}
else
PL_perldb = 0; /* Do not debug the kid. */
}
}
else {
}
}
g_total++;
if (g_SAVE_STACK) { /* Store it for later recording -JH */
/* Only record the parent's info */
if (g_SAVE_STACK < g_profstack_ix) {
if (g_prof_pid == (int)getpid())
else
PL_perldb = 0; /* Do not debug the kid. */
g_profstack_ix = 0;
}
}
else { /* Write it to disk now so's not to eat up core */
/* Only record the parent's info */
if (g_prof_pid == (int)getpid()) {
}
else
PL_perldb = 0; /* Do not debug the kid. */
}
}
#ifdef PL_NEEDED
# define defstash PL_defstash
#endif
/* Counts overhead of prof_mark and extra XS call. */
static void
{
int i, j, k = 0;
g_SAVE_STACK = 1000000;
while (k < 2) {
i = 0;
/* Disable debugging of perl_call_sv on second pass: */
while (++i <= 100) {
j = 0;
g_profstack_ix = 0; /* Do not let the stack grow */
while (++j <= 100) {
/* prof_mark(aTHX_ OP_ENTERSUB); */
PL_stack_sp--;
/* prof_mark(aTHX_ OP_LEAVESUB); */
}
}
if (k == 0) { /* Put time with debugging */
}
else { /* Subtract time without debug */
}
k++;
}
}
static void
{
clock_t r, u, s;
/* g_fp is opened in the BOOT section */
/* The (IV) casts are one possibility:
* the Painfully Correct Way would be to
* have Clock_t_f. */
/* Pad with whitespace. */
/* This should be enough even for very large numbers. */
}
static void
{
/* g_fp is opened in the BOOT section */
/* Now that we know the runtimes, fill them in at the recorded
location -JH */
if (g_SAVE_STACK) {
}
/* Write into reserved 240 bytes: */
/* The (IV) casts are one possibility:
* the Painfully Correct Way would be to
* have Clock_t_f. */
}
#define NONESUCH()
static void
{
if (need_depth != g_depth) {
if (need_depth > g_depth) {
warn("garbled call depth when profiling");
}
else {
/* warn("Check_depth: got %d, expected %d\n", g_depth, need_depth); */
while (marks--) {
}
}
}
}
#define for_real
#ifdef for_real
{
#ifdef PERL_IMPLICIT_CONTEXT
/* profile only the interpreter that loaded us */
}
else
#endif
{
g_depth++;
/* Make sure we are on the same context and scope as before the call
* to the sub. If the called sub was exited via a goto, next or
* last then this will try to croak(), however perl may still crash
* with a segfault. */
croak("panic: Devel::DProf inconsistent subroutine return");
g_depth--;
}
return;
}
{
#ifdef PERL_IMPLICIT_CONTEXT
#endif
{
return;
}
}
#endif /* for_real */
#ifdef testing
void
sub(...)
{
/* SP -= items; added by xsubpp */
/* PUTBACK; added by xsubpp */
}
#endif /* testing */
void
END()
{
if (PL_DBsub) {
/* maybe the process forked--we want only
* the parent's profile.
*/
if (
#ifdef PERL_IMPLICIT_CONTEXT
#endif
g_prof_pid == (int)getpid())
{
DBG_TIMER_NOTIFY("Profiler timer is off.\n");
}
}
}
void
NONESUCH()
BOOT:
{
g_TIMES_LOCATION = 42;
g_profstack_max = 128;
#ifdef PERL_IMPLICIT_CONTEXT
#endif
/* Before we go anywhere make sure we were invoked
* properly, else we'll dump core.
*/
if (!PL_DBsub)
croak("DProf: run perl with -d to use DProf.\n");
/* When we hook up the XS DB::sub we'll be redefining
* the DB::sub from the PM file. Turn off warnings
* while we do this.
*/
{
PL_dowarn = 0;
}
{
if (buffer) {
}
if (buffer) {
}
else {
g_dprof_ticks = HZ;
}
}
croak("DProf: unable to write '%s', errno = %d\n",
g_prof_pid = (int)getpid();
DBG_TIMER_NOTIFY("Profiler timer is on.\n");
}