4.4BSD/usr/src/contrib/mprof/mpstruct.c

/*	mpstruct.c 2.2 9/14/90 11:54:22	*/
/*	Copyright (c) 1987, Benjamin G. Zorn */

#include	<stdio.h>
#include	"mprof.h"

extern	mpcell	hmem[];
extern	bool	mprofing;

mpcell	hmem[MP_HASH_SIZE];

int	mprof_fmemC;
int	mprof_dmemC;
int	mprof_lmemC;


mpcell
mp_cons(a, d)
int	a;
mpcell	d;
{
    mpcell result = (mpcell) malloc(MPCELL_SIZE);
    
    mprof_lmemC++;
    mp_car(result) = a;
    mp_cdr(result) = d;
    return result;
}

mpsym
mp_new_fn(addr)
unsigned	addr;
{
    mpsym	newfn = (mpsym) malloc(MPSYM_SIZE);

    mprof_fmemC++;
    fn_lcount(newfn) = mp_new_data();
    fn_addr(newfn) = addr;
    fn_parents(newfn) = (mpcell) MP_NIL;
    fn_name(newfn) = NULL;
    return newfn;
}

mpdata
mp_new_data()
{
    mpdata 	result = (mpdata) malloc(MPDATA_SIZE);
    
    mprof_dmemC++;

    dt_b_small(result) = 0;
    dt_b_med(result) = 0;
    dt_b_large(result) = 0;
    dt_b_xlarge(result) = 0;
    dt_n_small(result) = 0;
    dt_n_med(result) = 0;
    dt_n_large(result) = 0;
    dt_n_xlarge(result) = 0;
    dt_d_small(result) = 0;
    dt_d_med(result) = 0;
    dt_d_large(result) = 0;
    dt_d_xlarge(result) = 0;
    return result;
}

mpdata
mp_add_data(ddest, dsrc)
mpdata	ddest, dsrc;
{
    dt_b_small(ddest) += dt_b_small(dsrc);
    dt_b_med(ddest) += dt_b_med(dsrc);
    dt_b_large(ddest) += dt_b_large(dsrc);
    dt_b_xlarge(ddest) += dt_b_xlarge(dsrc);
    dt_n_small(ddest) += dt_n_small(dsrc);
    dt_n_med(ddest) += dt_n_med(dsrc);
    dt_n_large(ddest) += dt_n_large(dsrc);
    dt_n_xlarge(ddest) += dt_n_xlarge(dsrc);
    dt_d_small(ddest) += dt_d_small(dsrc);
    dt_d_med(ddest) += dt_d_med(dsrc);
    dt_d_large(ddest) += dt_d_large(dsrc);
    dt_d_xlarge(ddest) += dt_d_xlarge(dsrc);
    return ddest;
}

int
mp_sum_data(d)
mpdata	d;
{
    return (dt_b_small(d) + dt_b_med(d) + dt_b_large(d) + dt_b_xlarge(d));
}

int
mp_sum_calls(d)
mpdata	d;
{
    return (dt_n_small(d) + dt_n_med(d) + dt_n_large(d) + dt_n_xlarge(d));
}

int
mp_sum_kept(d)
mpdata	d;
{
    return (dt_d_small(d) + dt_d_med(d) + dt_d_large(d) + dt_d_xlarge(d));
}

mpcell
mp_has_parent(c, p)
mpsym	c, p;
{
    mpcell	plist = fn_parents(c);
    unsigned	pname;
    mpcell	pair;
    mpsym	f;

    pname = fn_addr(p);
    while (!mp_null(plist)) {
	pair = (mpcell) mp_car(plist);
	f = (mpsym) mp_car(pair);
	if (fn_addr(f) == pname)
	  return pair;
	plist = (mpcell) mp_cdr(plist);
    }
    return (mpcell) MP_NIL;
}

int
mp_hash(pc)
unsigned	pc;
{
    int		hash = (pc >> 24 | (pc & 0xff00)) ^
      		       (((pc & 0xff) << 8) | (pc & 0xff0000) >> 16);
    return (hash % MP_HASH_SIZE);
}

void
mp_puthash(pc, f)
unsigned	pc;
mpsym		f;
{
    int		hash = mp_hash(pc);

    hmem[hash] = mp_cons((int) f, hmem[hash]);
}

mpsym
mp_lookup(pc)
unsigned	pc;
{
    int		hash = mp_hash(pc);
    mpcell	c = hmem[hash];
    mpsym	s;
    
    while (!mp_null(c)) {
	s = (mpsym) mp_car(c);
	if (pc == fn_addr(s))
	  return s;
	c = (mpcell) mp_cdr(c);
    }
    return (mpsym) MP_NIL;
}
	

bool	mp_pprint = FALSE;

void
mp_print_fn(mprof_file, f)
int	mprof_file;
mpsym	f;
{
    mpcell	plist;

    plist = fn_parents(f);
    if (fn_name(f) != NULL)
      mp_pprint = TRUE;

    /* print name, lcount, and parents
     */

    if (mp_pprint) {
	write(mprof_file, "(\"", 2);
	write(mprof_file, fn_name(f), strlen(fn_name(f)));
	write(mprof_file, "\" ", 2);
	mp_print_data(mprof_file, fn_lcount(f));
	write(mprof_file, " ", 1);
	mp_print_parents(mprof_file, plist);
	write(mprof_file, ")\n", 2);
    } else {
	mp_print_addr(mprof_file, f);
	mp_print_data(mprof_file, fn_lcount(f));
	mp_print_parents(mprof_file, plist);
    }
}

void
mp_print_addr(mprof_file, f)
int	mprof_file;
mpsym	f;
{
    char	digits[14];

    sprintf(digits, "%d\n", fn_addr(f));
    write(mprof_file, digits, strlen(digits));
}

char *
mp_sprint_data(d)
mpdata	d;
{
    char	digits[255];
    char	*result;

    sprintf(digits, "(%d %d %d %d %d %d %d %d %d %d %d %d)",
	    dt_b_small(d),
	    dt_b_med(d),
	    dt_b_large(d),
	    dt_b_xlarge(d),
	    dt_n_small(d),
	    dt_n_med(d),
	    dt_n_large(d),
	    dt_n_xlarge(d),
	    dt_d_small(d),
	    dt_d_med(d),
	    dt_d_large(d),
	    dt_d_xlarge(d));
    result = malloc(strlen(digits) + 1);
    strcpy(result, digits);
    return result;
}

void
mp_print_data(mprof_file, d)
int	mprof_file;
mpdata	d;
{
    char	digits[255];

    if (mp_pprint) {
	sprintf(digits, "(%d %d %d %d %d %d %d %d %d %d %d %d)",
		dt_b_small(d),
		dt_b_med(d),
		dt_b_large(d),
		dt_b_xlarge(d),
		dt_n_small(d),
		dt_n_med(d),
		dt_n_large(d),
		dt_n_xlarge(d),
		dt_d_small(d),
		dt_d_med(d),
		dt_d_large(d),
		dt_d_xlarge(d));
    } else {
	sprintf(digits, "%d %d %d %d %d %d %d %d %d %d %d %d\n",
		dt_b_small(d),
		dt_b_med(d),
		dt_b_large(d),
		dt_b_xlarge(d),
		dt_n_small(d),
		dt_n_med(d),
		dt_n_large(d),
		dt_n_xlarge(d),
		dt_d_small(d),
		dt_d_med(d),
		dt_d_large(d),
		dt_d_xlarge(d));
    }
    write(mprof_file, digits, strlen(digits));
}

void
mp_print_parents(mprof_file, l)
int	mprof_file;
mpcell	l;
{
    mpcell	rest = l;
    mpcell	p;

    if (mp_pprint) {
	write(mprof_file, "(", 1);
	while (!mp_null(rest)) {
	    p = (mpcell) mp_car(rest);
	    write(mprof_file, "(\"", 2);
	    write(mprof_file,
		  fn_name((mpsym) mp_car(p)),
		  strlen(fn_name((mpsym) mp_car(p))));
	    write(mprof_file, "\" ", 2);
	    mp_print_data(mprof_file, (mpdata) mp_cdr(p));
	    write(mprof_file, ")", 1);
	    rest = mp_cdr(rest);
	    if (!mp_null(rest)) {
		write(mprof_file, " ", 1);
	    }
	}
	write(mprof_file, ")", 1);
    } else {
	while (!mp_null(rest)) {
	    p = (mpcell) mp_car(rest);
	    mp_print_addr(mprof_file, (mpsym) mp_car(p));
	    mp_print_data(mprof_file, (mpdata) mp_cdr(p));
	    rest = (mpcell) mp_cdr(rest);
	}
	write(mprof_file, "-1\n", 3);
    }
}


void
mprof_print(mprof_file)
int	mprof_file;
{
    mpsym	s;
    int		i;
    mpcell	chain;

    for (i = 0; i < MP_HASH_SIZE; i++) {
	chain = hmem[i];
	while (!mp_null(chain)) {
	    s = (mpsym) mp_car(chain);
	    mp_print_fn(mprof_file, s);
	    chain = (mpcell) mp_cdr(chain);
	}
    }
}


mpsym
pc_lookup(pc)
unsigned	pc;
{
    mpsym	s;
    
    s = mp_lookup(pc);
    if (!mp_null(s)) {
	return s;
    } else {
	/*
	 *  create a new function
	 */
	s = mp_new_fn(pc);
	mp_puthash(pc, s);
	return s;
    }
}

void
mpstruct_init()
{
    int		i;
    
    for (i = 0; i < MP_HASH_SIZE; i++) {
	hmem[i] = (mpcell) MP_NIL;
    }
    mprof_lmemC = 0;
    mprof_fmemC = 0;
    mprof_dmemC = 0;
}