home *** CD-ROM | disk | FTP | other *** search
/ Programming Win32 Under the API / ProgrammingWin32UnderTheApiPatVillani.iso / src / mingw-runtime-19991107 / mingw / profile / mcount.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-04  |  5.5 KB  |  181 lines

  1. /*-
  2.  * Copyright (c) 1983, 1992, 1993
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #if !defined(lint) && !defined(_KERNEL) && defined(LIBC_SCCS)
  35. static char rcsid[] = "$OpenBSD: mcount.c,v 1.6 1997/07/23 21:11:27 kstailey Exp $";
  36. #endif
  37.  
  38. /*
  39.  * This file is taken from Cygwin distribution. Please keep it in sync.
  40.  * The differences should be within __MINGW32__ guard.
  41.  */
  42.  
  43. #ifndef __MINGW32__
  44. #include <sys/param.h>
  45. #endif
  46. #include <sys/types.h>
  47. #include <gmon.h>
  48.  
  49. /*
  50.  * mcount is called on entry to each function compiled with the profiling
  51.  * switch set.  _mcount(), which is declared in a machine-dependent way
  52.  * with _MCOUNT_DECL, does the actual work and is either inlined into a
  53.  * C routine or called by an assembly stub.  In any case, this magic is
  54.  * taken care of by the MCOUNT definition in <machine/profile.h>.
  55.  *
  56.  * _mcount updates data structures that represent traversals of the
  57.  * program's call graph edges.  frompc and selfpc are the return
  58.  * address and function address that represents the given call graph edge.
  59.  *
  60.  * Note: the original BSD code used the same variable (frompcindex) for
  61.  * both frompcindex and frompc.  Any reasonable, modern compiler will
  62.  * perform this optimization.
  63.  */
  64. //_MCOUNT_DECL __P((u_long frompc, u_long selfpc));
  65. _MCOUNT_DECL(frompc, selfpc)    /* _mcount; may be static, inline, etc */
  66.     register u_long frompc, selfpc;
  67. {
  68.     register u_short *frompcindex;
  69.     register struct tostruct *top, *prevtop;
  70.     register struct gmonparam *p;
  71.     register long toindex;
  72.  
  73.     p = &_gmonparam;
  74.     /*
  75.      * check that we are profiling
  76.      * and that we aren't recursively invoked.
  77.      */
  78.     if (p->state != GMON_PROF_ON)
  79.         return;
  80.     p->state = GMON_PROF_BUSY;
  81.     /*
  82.      * check that frompcindex is a reasonable pc value.
  83.      * for example:    signal catchers get called from the stack,
  84.      *        not from text space.  too bad.
  85.      */
  86.     frompc -= p->lowpc;
  87.     if (frompc > p->textsize)
  88.         goto done;
  89.  
  90. #if (HASHFRACTION & (HASHFRACTION - 1)) == 0
  91.     if (p->hashfraction == HASHFRACTION)
  92.         frompcindex =
  93.             &p->froms[frompc / (HASHFRACTION * sizeof(*p->froms))];
  94.     else
  95. #endif
  96.         frompcindex =
  97.             &p->froms[frompc / (p->hashfraction * sizeof(*p->froms))];
  98.     toindex = *frompcindex;
  99.     if (toindex == 0) {
  100.         /*
  101.          *    first time traversing this arc
  102.          */
  103.         toindex = ++p->tos[0].link;
  104.         if (toindex >= p->tolimit)
  105.             /* halt further profiling */
  106.             goto overflow;
  107.  
  108.         *frompcindex = toindex;
  109.         top = &p->tos[toindex];
  110.         top->selfpc = selfpc;
  111.         top->count = 1;
  112.         top->link = 0;
  113.         goto done;
  114.     }
  115.     top = &p->tos[toindex];
  116.     if (top->selfpc == selfpc) {
  117.         /*
  118.          * arc at front of chain; usual case.
  119.          */
  120.         top->count++;
  121.         goto done;
  122.     }
  123.     /*
  124.      * have to go looking down chain for it.
  125.      * top points to what we are looking at,
  126.      * prevtop points to previous top.
  127.      * we know it is not at the head of the chain.
  128.      */
  129.     for (; /* goto done */; ) {
  130.         if (top->link == 0) {
  131.             /*
  132.              * top is end of the chain and none of the chain
  133.              * had top->selfpc == selfpc.
  134.              * so we allocate a new tostruct
  135.              * and link it to the head of the chain.
  136.              */
  137.             toindex = ++p->tos[0].link;
  138.             if (toindex >= p->tolimit)
  139.                 goto overflow;
  140.  
  141.             top = &p->tos[toindex];
  142.             top->selfpc = selfpc;
  143.             top->count = 1;
  144.             top->link = *frompcindex;
  145.             *frompcindex = toindex;
  146.             goto done;
  147.         }
  148.         /*
  149.          * otherwise, check the next arc on the chain.
  150.          */
  151.         prevtop = top;
  152.         top = &p->tos[top->link];
  153.         if (top->selfpc == selfpc) {
  154.             /*
  155.              * there it is.
  156.              * increment its count
  157.              * move it to the head of the chain.
  158.              */
  159.             top->count++;
  160.             toindex = prevtop->link;
  161.             prevtop->link = top->link;
  162.             top->link = *frompcindex;
  163.             *frompcindex = toindex;
  164.             goto done;
  165.         }
  166.     }
  167. done:
  168.     p->state = GMON_PROF_ON;
  169.     return;
  170. overflow:
  171.     p->state = GMON_PROF_ERROR;
  172.     return;
  173. }
  174.  
  175. /*
  176.  * Actual definition of mcount function.  Defined in <machine/profile.h>,
  177.  * which is included by <sys/gmon.h>
  178.  */
  179. MCOUNT
  180.  
  181.