This is fat_string.c in view mode; [Download] [Up]
/*
(c) Copyright W. Schelter 1988, All rights reserved.
*/
#include "include.h"
#include "page.h"
#define FAT_STRING
enum type what_to_collect;
/* start fasdump stuff */
#include "fasdump.c"
object sSAprofile_arrayA;
#ifdef NO_PROFILE
profil()
{;}
#endif
DEFUNO("PROFILE",object,fSprofile,SI
,2,2,NONE,OO,OO,OO,OO,siLprofile,
"Sets up profiling with START-ADDRESS and SCALE where scale is \
between 0 and 256")(start_address,scale)
object start_address,scale;
{ /* 2 args */
object ar=sSAprofile_arrayA->s.s_dbind;
if (type_of(ar)!=t_string)
FEerror("si:*Profile-array* not a string",0);
if( type_of(start_address)!=t_fixnum || type_of(scale)!=t_fixnum)
FEerror("Needs start address and scale as args",0);
profil((char *) (ar->ust.ust_self), (ar->ust.ust_dim),
fix(start_address),fix(scale) << 8);
RETURN1(start_address);
}
DEFUNO("FUNCTION-START",object,fSfunction_start,SI
,1,1,NONE,OO,OO,OO,OO,siLfunction_start,"")(funobj)
object funobj;
{/* 1 args */
if(type_of(funobj)!=t_cfun) FEerror("not compiled function",0);
funobj=make_fixnum((int) (funobj->cf.cf_self));
RETURN1(funobj);
}
/* begin fasl stuff*/
#include "ext_sym.h"
#ifdef AIX3
#include <sys/ldr.h>
char *data_load_addr =0;
#endif
read_special_symbols(symfile)
char *symfile;
{FILE *symin;
char *symbols;
int i,jj;
struct lsymbol_table tab;
#ifdef AIX3
{char buf[500];
struct ld_info * ld;
loadquery(L_GETINFO,buf,sizeof(buf));
ld = (struct ld_info *)buf;
data_load_addr = ld->ldinfo_dataorg ;}
#endif
if (!(symin=fopen(symfile,"r")))
{perror(symfile);exit(1);};
if(!fread((char *)&tab,sizeof(tab),1,symin))
FEerror("No header",0);
symbols=malloc(tab.tot_leng);
c_table.alloc_length=( (PTABLE_EXTRA+ tab.n_symbols));
(c_table.ptable) = (TABL *) malloc(sizeof(struct node) * c_table.alloc_length);
if (!(c_table.ptable)) {perror("could not allocate"); exit(1);};
i=0; c_table.length=tab.n_symbols;
while(i < tab.n_symbols)
{ fread((char *)&jj,sizeof(int),1,symin);
#ifdef FIX_ADDRESS
FIX_ADDRESS(jj);
#endif
(SYM_ADDRESS(c_table,i))=jj;
SYM_STRING(c_table,i)=symbols;
while( *(symbols++) = getc(symin))
{;}
/* dprintf( name %s , SYM_STRING(c_table,i));
dprintf( addr %d , jj);
*/
i++;
}
/*
for(i=0;i< 5;i++)
{printf("Symbol: %d %s %d \n",i,SYM_STRINGN(c_table,i),
SYM_ADDRESS(*ptable,i));}
*/
if (symin) fclose(symin);
}
node_compare(node1,node2)
char *node1, *node2;
{ return(strcmp( ((struct node *)node1)->string,
((struct node *)node2)->string));}
DEFUNO("READ-EXTERNALS",object,fSread_externals,SI
,1,1,NONE,OO,OO,OO,OO,siLread_externals,"")(x0)
object x0;
{/* 1 args */
{object x=x0;
unsigned int n;
char *str;
n=x->st.st_fillp;
check_type_string(&x);
str=malloc(n+1);
str[n]=NULL;
(void) strncpy(str,x->st.st_self,n);
read_special_symbols(str);
/* we sort them since these are used by the sfasl loader too */
qsort((char*)(c_table.ptable),(int)(c_table.length),sizeof(struct node),node_compare);
free(str);}
RETURN1(x0);
}
#define CFUN_LIM 10000
int maxpage;
object sScdefn;
#define CF_FLAG (1 << 31)
cfuns_to_combined_table(n) /* non zero n will ensure new table length */
unsigned int n;
{int ii=0;
STATIC int i, j;
STATIC object x;
STATIC char *p,*cf_addr;
STATIC struct typemanager *tm;
if (! (n || combined_table.ptable)) n=CFUN_LIM;
if (n && combined_table.alloc_length < n)
{
(combined_table.ptable)=NULL;
(combined_table.ptable)= (TABL *)malloc(n* sizeof(struct node));
if(!combined_table.ptable)
FEerror("unable to allocate",0);
combined_table.alloc_length=n;}
for (i = 0; i < maxpage; i++) {
if ((enum type)type_map[i]!=tm_table[(short)t_cfun].tm_type &&
(enum type)type_map[i]!=tm_table[(short)t_gfun].tm_type &&
(enum type)type_map[i]!=tm_table[(short)t_sfun].tm_type &&
(enum type)type_map[i]!=tm_table[(short)t_vfun].tm_type
)
continue;
tm = tm_of((enum type)type_map[i]);
p = pagetochar(i);
for (j = tm->tm_nppage; j > 0; --j, p += tm->tm_size) {
x = (object)p;
if (type_of(x)!=t_cfun &&
type_of(x)!=t_sfun &&
type_of(x)!=t_vfun &&
type_of(x)!=t_gfun
) continue;
if ((x->d.m == FREE) || x->cf.cf_self == NULL)
continue;
/* the cdefn things are the proclaimed call types. */
cf_addr=(char * ) ((unsigned int)(x->cf.cf_self));
SYM_ADDRESS(combined_table,ii)=(unsigned int)cf_addr;
SYM_STRING(combined_table,ii)= (char *)(CF_FLAG | (unsigned int)x) ;
/* (x->cf.cf_name ? x->cf.cf_name->s.st_self : NULL) ; */
combined_table.length = ++ii;
if (ii >= combined_table.alloc_length)
FEerror("Need a larger combined_table",0);
}
}
}
address_node_compare(node1,node2)
char *node1, *node2;
{unsigned int a1,a2;
a1=((struct node *)node1)->address;
a2=((struct node *)node2)->address;
if (a1> a2) return 1;
if (a1< a2) return -1;
return 0;
}
DEFUNO("SET-UP-COMBINED",object,fSset_up_combined,SI
,0,1,NONE,OO,OO,OO,OO,siLset_up_combined,"")(va_alist)
va_dcl
{ int nargs=VFUN_NARGS;
unsigned int n;
object siz;
va_list ap;
{ va_start(ap);
if (nargs>=1) siz=va_arg(ap,object);
else goto LDEFAULT1;
goto LEND_VARARG;
LDEFAULT1: siz = small_fixnum(0);
LEND_VARARG: va_end(ap);}
CHECK_ARG_RANGE(0,1);
n = (unsigned int) fix(siz);
cfuns_to_combined_table(n);
if (c_table.ptable)
{int j,k;
if((k=combined_table.length)+c_table.length >=
combined_table.alloc_length)
cfuns_to_combined_table(combined_table.length+c_table.length +20);
for(j = 0; j < c_table.length;)
{ SYM_ADDRESS(combined_table,k) =SYM_ADDRESS(c_table,j);
SYM_STRING(combined_table,k) =SYM_STRING(c_table,j);
k++;j++;
};
combined_table.length += c_table.length ;}
qsort((char*)combined_table.ptable,(int)combined_table.length,
sizeof(struct node),address_node_compare);
RETURN1(siz);
}
static int prof_start;
prof_ind(address,scale)
unsigned int address;
{address = address - prof_start ;
if (address > 0) return ((address * scale) >> 8) ;
return 0;
}
/* sum entries AAR up to DIM entries */
string_sum(aar,dim)
register unsigned char *aar;
unsigned int dim;
{register unsigned char *endar;
register unsigned int count = 0;
endar=aar+dim;
for ( ; aar< endar; aar++)
count += *aar;
return count;
}
DEFUNO("DISPLAY-PROFILE",object,fSdisplay_profile,SI
,2,2,NONE,OO,OO,OO,OO,siLdisplay_profile,"")(start_addr,scal)
object start_addr,scal;
{if (!combined_table.ptable)
FEerror("must symbols first",0);
/* 2 args */
{unsigned int prev,next,upto,dim,total;
int j,scale,count;
unsigned char *ar;
object obj_ar;
obj_ar=sSAprofile_arrayA->s.s_dbind;
if (type_of(obj_ar)!=t_string)
FEerror("si:*Profile-array* not a string",0);
ar=obj_ar->ust.ust_self;
scale=fix(scal);
prof_start=fix(start_addr);
vs_top=vs_base;
dim= (obj_ar->ust.ust_dim);
total=string_sum(ar,dim);
j=0;
{int i, finish = combined_table.length-1;
for(i =0,prev=SYM_ADDRESS(combined_table,i); i< finish;
prev=next)
{ ++i;
next=SYM_ADDRESS(combined_table,i);
if ( prev < prof_start) continue;
upto=prof_ind(next,scale);
if (upto >= dim) upto=dim;
{char *name; unsigned int uname;
count=0;
for( ; j<upto;j++)
count += ar[j];
if (count > 0) {
name=SYM_STRING(combined_table,i-1);
uname = (unsigned int) name;
printf("\n%6.2f%% (%5d): ",(100.0*count)/total, count);
fflush(stdout);
if (CF_FLAG & uname)
{if (~CF_FLAG & uname) prin1( ((object) (~CF_FLAG & uname))->cf.cf_name,Cnil);}
else if (name ) printf("%s",name);};
if (upto==dim) goto TOTALS ;
}}}
TOTALS:
printf("\nTotal ticks %d",total);fflush(stdout);
}
RETURN1(start_addr);
}
#ifdef SFASL
int build_symbol_table();
#endif
/* end fasl stuff*/
/* These are some low level hacks to allow determining the address
of an array body, and to allow jumping to inside the body
of the array */
DEFUNO("ARRAY-ADRESS",object,fSarray_adress,SI
,1,1,NONE,OO,OO,OO,OO,siLarray_adress,"")(array)
object array;
{/* 1 args */
array=make_fixnum((int) (&(array->st.st_self[0])));
RETURN1(array);
}
/* This is some very low level code for hacking invokation of
m68k instructions in a lisp array. The index used should be
a byte index. So invoke(ar,3) jmps to byte ar+3.
*/
#ifdef CLI
invoke(ar)
char *ar;
{asm("movel a6@(8),a0");
asm("jmp a0@");
}
/* save regs (2 3 4 5 6 7 10 11 12 13 14) and invoke restoring them */
save_regs_invoke(ar)
char *ar;
{asm("moveml #0x3f3e,sp@-");
invoke(ar);
asm("moveml a6@(-44),#0x7cfc");
}
/* DEFUNO("SAVE-REGS-INVOKE",object,fSsave_regs_invoke,SI
,2,2,NONE,OO,OO,OO,OO,siLsave_regs_invoke,"")(x0,x1)
object x0,x1;
{int x;
check_type_integer(&x1);
x=save_regs_invoke((x0->st.st_self)+fix(x1));
x0=make_fixnum(x);
RETURN1(x0);
}
*/
#endif
DEFVAR("*PROFILE-ARRAY*",sSAprofile_arrayA,SI,Cnil,"");
init_fat_string()
{
make_si_constant("*ASH->>*",(-1==(((int)-1) >> 50))? Ct :Cnil);
#ifdef SFASL
make_si_function("BUILD-SYMBOL-TABLE",build_symbol_table);
#endif
init_fasdump();
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.