home *** CD-ROM | disk | FTP | other *** search
- /* AE program profiling system.
- Startup and termination code and routines to manipulate AE buffer.
- Copyright (C) 1989, 1990 by James R. Larus (larus@cs.wisc.edu)
-
- This file must be compiled by GCC!
-
- AE and AEC are free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 1, or (at your option) any
- later version.
-
- AE and AEC are distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNU CC; see the file COPYING. If not, write to James R.
- Larus, Computer Sciences Department, University of Wisconsin--Madison,
- 1210 West Dayton Street, Madison, WI 53706, USA or to the Free
- Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* $Header: /var/home/larus/AE/AE/RCS/ae-buffer.c,v 2.0 90/02/09 17:18:53 larus Exp Locker: larus $ */
-
-
- #include <sys/file.h>
- #include <sys/time.h>
- #include <sys/resource.h>
- #include "ae.h"
- #include "ae-machine.h"
-
-
- /* Save pointer to beginning of AE buffer. */
-
- char *ae_buffer_base;
-
-
- /* Register or variable pointing to next free byte in AE buffer. */
-
- #ifdef AE_BUFFER_REG
- register char *ae_bp asm (AE_BUFFER_REG);
- #elif AE_BUFFER_VAR
- char *ae_bp;
- #endif
-
-
- /* Register or variable pointing to end of AE buffer. */
-
- #ifdef AE_BUFFER_BOUND_REG
- register char *ae_bound asm(AE_BUFFER_BOUND_REG);
- #elif AE_BUFFER_BOUND_VAR
- char *ae_bound;
- #endif
-
-
- /* File descriptor for writing AE buffer. */
-
- int ae_fd;
-
-
- /* Stack pointer upon entry to AE_INITIALIZE. */
-
- static char *old_sp;
-
-
-
- /* Initialize by allocating AE buffer on the stack and opening the
- output file. Invoked by AE_START (which is written in assembly
- language). Return the new stack pointer. */
-
- char *
- ae_initialize (argc, argv) /* Define main's parameters for compiler */
- int argc;
- char *argv[];
- {
- register char *sp asm (SP_REG);
- struct rlimit rl;
-
- /* Raise stacksize limit. */
- getrlimit (RLIMIT_STACK, &rl);
- rl.rlim_cur = rl.rlim_max;
- setrlimit (RLIMIT_STACK, &rl);
-
- ae_fd = open ("ae.out", O_WRONLY | O_CREAT | O_TRUNC, 0644);
-
- /* Make space on stack for AE buffer */
- #ifdef AE_BUFFER_STACK_OFFSET
- ae_buffer_base =
- (char *) (STACK_TOP - (AE_BUFFER_SIZE + AE_BUFFER_STACK_OFFSET));
- #else
- ae_buffer_base = (char *) (sp - AE_BUFFER_SIZE);
- #endif
-
- ae_bp = ae_buffer_base;
- #if (defined (AE_BUFFER_BOUND_REG) || defined(AE_BUFFER_BOUND_VAR))
- ae_bound = ae_bp + AE_BUFFER_SIZE - CHUNK_SIZE;
- #endif
-
- old_sp = sp;
- *ae_bp = 0; /* Force OS to extend stack */
- return (sp = (ae_buffer_base - AE_START_FRAME_SIZE));
- }
-
-
- /* Flush AE buffer by writing its contents to a file and reset the
- buffer pointer. This routine probably must be written in assembly
- language since it cannot affect ANY register visible to its caller
- (not just the callee-saved registers) since it is called at arbitrary
- points in a function. */
-
- #ifdef USE_C_FLUSH_BUFFER
- void
- ae_flush_buffer ()
- {
- char *x[32]; /* Space to store registers */
-
- x[0] = ae_bp; /* Example */
- write (ae_fd, ae_buffer_base, (int) ae_bp - (int) ae_buffer_base);
- ae_bp = ae_buffer_base;
- #ifdef (defined (AE_BUFFER_BOUND_REG) || defined (AE_BUFFER_BOUND_VAR))
- ae_bound = ae_bp + AE_BUFFER_SIZE - 4;
- #endif
- }
- #endif
-
-
- /* Clean up at program termination by flushing the remaining events. */
-
- void
- ae_terminate ()
- {
- register char *sp asm (SP_REG);
-
- ae_flush_buffer ();
- close (ae_fd);
- /* Restore the stack pointer. */
- sp = old_sp;
- }
-
-
- /* Redefine the EXIT routine to call AE_TERMINATE. */
-
- exit (code)
- int code;
- {
- ae_terminate ();
- _cleanup ();
- _exit (code);
- }
-