1/* imalloc.h -- internal malloc definitions shared by source files. */
2
3/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
4
5   This file is part of GNU Bash, the Bourne Again SHell.
6
7   Bash is free software; you can redistribute it and/or modify it under
8   the terms of the GNU General Public License as published by the Free
9   Software Foundation; either version 2, or (at your option) any later
10   version.
11
12   Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13   WARRANTY; without even the implied warranty of MERCHANTABILITY or
14   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15   for more details.
16
17   You should have received a copy of the GNU General Public License along
18   with Bash; see the file COPYING.  If not, write to the Free Software
19   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
20
21/* Must be included *after* config.h */
22
23#ifndef _IMALLOC_H
24#define _IMALLOC_H
25
26#ifdef MALLOC_DEBUG
27#define MALLOC_STATS
28#define MALLOC_TRACE
29#define MALLOC_REGISTER
30#define MALLOC_WATCH
31#endif
32
33#define MALLOC_WRAPFUNCS
34
35/* Generic pointer type. */
36#ifndef PTR_T
37#  if defined (__STDC__)
38#    define PTR_T void *
39#  else
40#    define PTR_T char *
41#  endif
42#endif
43
44#if !defined (NULL)
45#  define NULL 0
46#endif
47
48#if !defined (__STRING)
49#  if defined (HAVE_STRINGIZE)
50#    define __STRING(x) #x
51#  else
52#    define __STRING(x) "x"
53#  endif /* !HAVE_STRINGIZE */
54#endif /* !__STRING */
55
56#if __GNUC__ > 1
57#  define FASTCOPY(s, d, n)  __builtin_memcpy (d, s, n)
58#else /* !__GNUC__ */
59#  if !defined (HAVE_BCOPY)
60#    if !defined (HAVE_MEMMOVE)
61#      define FASTCOPY(s, d, n)  memcpy (d, s, n)
62#    else
63#      define FASTCOPY(s, d, n)  memmove (d, s, n)
64#    endif /* !HAVE_MEMMOVE */
65#  else /* HAVE_BCOPY */
66#    define FASTCOPY(s, d, n)  bcopy (s, d, n)
67#  endif /* HAVE_BCOPY */
68#endif /* !__GNUC__ */
69
70#if !defined (__P)
71#  if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) || defined (PROTOTYPES)
72#    define __P(protos) protos
73#  else
74#    define __P(protos) ()
75#  endif
76#endif
77
78/* Use Duff's device for good zeroing/copying performance.  DO NOT call the
79   Duff's device macros with NBYTES == 0. */
80
81#define MALLOC_BZERO(charp, nbytes)					\
82do {									\
83  if ((nbytes) <= 32) {							\
84    size_t * mzp = (size_t *)(charp);					\
85    unsigned long mctmp = (nbytes)/sizeof(size_t);			\
86    long mcn;								\
87    if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp &= 7; }	\
88    switch (mctmp) {							\
89      case 0: for(;;) { *mzp++ = 0;					\
90      case 7:	   *mzp++ = 0;						\
91      case 6:	   *mzp++ = 0;						\
92      case 5:	   *mzp++ = 0;						\
93      case 4:	   *mzp++ = 0;						\
94      case 3:	   *mzp++ = 0;						\
95      case 2:	   *mzp++ = 0;						\
96      case 1:	   *mzp++ = 0; if(mcn <= 0) break; mcn--; }		\
97    }									\
98  else									\
99    memset ((charp), 0, (nbytes));					\
100} while(0)
101
102#define MALLOC_ZERO(charp, nbytes) \
103do { 								\
104  size_t mzsz = (nbytes);					\
105  if (mzsz <= 9 * sizeof(mzsz) {				\
106    size_t *mz = (size_t *)(charp);				\
107    if(mzsz >= 5*sizeof(mzsz)) {	*mz++ = 0;		\
108					*mz++ = 0;		\
109      if(mzsz >= 7*sizeof(mzsz)) {	*mz++ = 0;		\
110					*mz++ = 0;		\
111	if(mzsz >= 9*sizeof(mzsz)) {	*mz++ = 0;		\
112					*mz++ = 0; }}}		\
113					*mz++ = 0;		\
114					*mz++ = 0;		\
115					*mz = 0;		\
116  } else							\
117    memset ((charp), 0, mzsz);					\
118} while (0)
119
120#define MALLOC_MEMSET(charp, xch, nbytes)				\
121do {									\
122  if ((nbytes) <= 32) {							\
123    register char * mzp = (charp);					\
124    unsigned long mctmp = (nbytes);					\
125    register long mcn;							\
126    if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp &= 7; }	\
127    switch (mctmp) {							\
128      case 0: for(;;) { *mzp++ = xch;					\
129      case 7:	   *mzp++ = xch;					\
130      case 6:	   *mzp++ = xch;					\
131      case 5:	   *mzp++ = xch;					\
132      case 4:	   *mzp++ = xch;					\
133      case 3:	   *mzp++ = xch;					\
134      case 2:	   *mzp++ = xch;					\
135      case 1:	   *mzp++ = xch; if(mcn <= 0) break; mcn--; }		\
136    }									\
137  } else								\
138    memset ((charp), (xch), (nbytes));					\
139} while(0)
140
141#define MALLOC_MEMCPY(dest,src,nbytes)					\
142do {									\
143  if ((nbytes) <= 32) {							\
144    size_t* mcsrc = (size_t*) src;					\
145    size_t* mcdst = (size_t*) dest;					\
146    unsigned long mctmp = (nbytes)/sizeof(size_t);			\
147    long mcn;								\
148    if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp &= 7; }	\
149    switch (mctmp) {							\
150      case 0: for(;;) { *mcdst++ = *mcsrc++;				\
151      case 7:	   *mcdst++ = *mcsrc++;					\
152      case 6:	   *mcdst++ = *mcsrc++;					\
153      case 5:	   *mcdst++ = *mcsrc++;					\
154      case 4:	   *mcdst++ = *mcsrc++;					\
155      case 3:	   *mcdst++ = *mcsrc++;					\
156      case 2:	   *mcdst++ = *mcsrc++;					\
157      case 1:	   *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; }	\
158  } else								\
159    memcpy ((dest), (src), (nbytes))					\
160} while(0)
161
162#if defined (SHELL)
163#  include "bashintl.h"
164#else
165#  define _(x)	x
166#endif
167
168#endif /* _IMALLOC_H */
169