source: proiecte/swift/trunk/lib/hoard-371/src/heaplayers/wrapper.cpp @ 176

Last change on this file since 176 was 176, checked in by (none), 14 years ago
  • imported repo from "guagal"
File size: 7.4 KB
Line 
1/* -*- C++ -*- */
2
3/*
4
5  Heap Layers: An Extensible Memory Allocation Infrastructure
6 
7  Copyright (C) 2000-2007 by Emery Berger
8  http://www.cs.umass.edu/~emery
9  emery@cs.umass.edu
10 
11  This program is free software; you can redistribute it and/or modify
12  it under the terms of the GNU General Public License as published by
13  the Free Software Foundation; either version 2 of the License, or
14  (at your option) any later version.
15 
16  This program is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, write to the Free Software
23  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
25*/
26
27/*
28 * @file   wrapper.cpp
29 * @brief  Replaces malloc with appropriate calls to TheCustomHeapType.
30 * @author Emery Berger <http://www.cs.umass.edu/~emery>
31 */
32
33#include <string.h> // for memcpy
34
35#if defined(__APPLE__)
36#include <malloc/malloc.h>
37#elif defined(__FreeBSD__)
38#include <stdlib.h>
39#else
40#include <malloc.h> // for memalign
41#endif
42
43#ifdef _WIN32
44#define WIN32_LEAN_AND_MEAN
45#include <windows.h>
46// Disable warnings about long (> 255 chars) identifiers.
47#pragma warning(disable:4786)
48// Set inlining to the maximum possible depth.
49#pragma inline_depth(255)
50#pragma warning(disable: 4074)  // initializers put in compiler reserved area
51#pragma init_seg(compiler)
52
53#pragma comment(linker, "/merge:.CRT=.data")
54
55#pragma comment(linker, "/disallowlib:libc.lib")
56#pragma comment(linker, "/disallowlib:libcd.lib")
57#pragma comment(linker, "/disallowlib:libcmt.lib")
58#pragma comment(linker, "/disallowlib:libcmtd.lib")
59#pragma comment(linker, "/disallowlib:msvcrtd.lib")
60
61#else
62#include <errno.h>
63#endif
64
65#if !defined(CUSTOM_PREFIX)
66#define CUSTOM_PREFIX(n) n
67#endif
68
69#define CUSTOM_MALLOC(x)     CUSTOM_PREFIX(malloc)(x)
70#define CUSTOM_FREE(x)       CUSTOM_PREFIX(free)(x)
71#define CUSTOM_REALLOC(x,y)  CUSTOM_PREFIX(realloc)(x,y)
72#define CUSTOM_CALLOC(x,y)   CUSTOM_PREFIX(calloc)(x,y)
73#define CUSTOM_MEMALIGN(x,y) CUSTOM_PREFIX(memalign)(x,y)
74#define CUSTOM_GETSIZE(x)    CUSTOM_PREFIX(malloc_usable_size)(x)
75#define CUSTOM_MALLOPT(x,y)  CUSTOM_PREFIX(mallopt)(x,y)
76#define CUSTOM_VALLOC(x)     CUSTOM_PREFIX(valloc)(x)
77#define CUSTOM_PVALLOC(x)    CUSTOM_PREFIX(pvalloc)(x)
78
79#if defined(_WIN32)
80#define MYCDECL __cdecl
81#if !defined(NO_INLINE)
82#define NO_INLINE __declspec(noinline)
83#endif
84#pragma inline_depth(255)
85
86#if !defined(NDEBUG)
87#define __forceinline inline
88#endif
89
90#else
91#define MYCDECL
92#endif
93
94/***** generic malloc functions *****/
95
96extern "C" void * MYCDECL CUSTOM_MALLOC (size_t sz)
97{
98  TheCustomHeapType * theCustomHeap = getCustomHeap();
99  void * ptr = theCustomHeap->malloc (sz);
100  return ptr;
101}
102
103extern "C" void * MYCDECL CUSTOM_CALLOC (size_t nelem, size_t elsize)
104{
105  size_t n = nelem * elsize;
106  void * ptr = CUSTOM_MALLOC (n);
107  // Zero out the malloc'd block.
108  if (ptr != NULL) {
109    memset (ptr, 0, n);
110  }
111  return ptr;
112}
113
114
115#if !defined(_WIN32)
116extern "C" void * MYCDECL CUSTOM_MEMALIGN (size_t alignment, size_t size);
117
118extern "C" int posix_memalign (void **memptr, size_t alignment, size_t size)
119{
120  // Check for non power-of-two alignment.
121  if ((alignment == 0) ||
122      (alignment & (alignment - 1)))
123    {
124      return EINVAL;
125    }
126  void * ptr = CUSTOM_MEMALIGN (alignment, size);
127  if (!ptr) {
128    return ENOMEM;
129  } else {
130    *memptr = ptr;
131    return 0;
132  }
133}
134#endif
135
136
137extern "C" void * MYCDECL CUSTOM_MEMALIGN (size_t alignment, size_t size)
138{
139  // NOTE: This function is deprecated.
140  if (alignment == sizeof(double)) {
141    return CUSTOM_MALLOC (size);
142  } else {
143    void * ptr = CUSTOM_MALLOC (size + 2 * alignment);
144    void * alignedPtr = (void *) (((size_t) ptr + alignment - 1) & ~(alignment - 1));
145    return alignedPtr;
146  }
147}
148
149extern "C" size_t MYCDECL CUSTOM_GETSIZE (void * ptr)
150{
151  TheCustomHeapType * theCustomHeap = getCustomHeap();
152  if (ptr == NULL) {
153    return 0;
154  }
155  return theCustomHeap->getSize(ptr);
156}
157
158extern "C" void MYCDECL CUSTOM_FREE (void * ptr)
159{
160  TheCustomHeapType * theCustomHeap = getCustomHeap();
161  theCustomHeap->free (ptr);
162}
163
164extern "C" void * MYCDECL CUSTOM_REALLOC (void * ptr, size_t sz)
165{
166  if (ptr == NULL) {
167    ptr = CUSTOM_MALLOC (sz);
168    return ptr;
169  }
170  if (sz == 0) {
171    CUSTOM_FREE (ptr);
172    return NULL;
173  }
174
175  size_t objSize = CUSTOM_GETSIZE (ptr);
176
177  void * buf = CUSTOM_MALLOC ((size_t) (sz));
178
179  if (buf != NULL) {
180    if (objSize == CUSTOM_GETSIZE(buf)) {
181      // The objects are the same actual size.
182      // Free the new object and return the original.
183      CUSTOM_FREE (buf);
184      return ptr;
185    }
186    // Copy the contents of the original object
187    // up to the size of the new block.
188    size_t minSize = (objSize < sz) ? objSize : sz;
189    memcpy (buf, ptr, minSize);
190  }
191
192  // Free the old block.
193  CUSTOM_FREE (ptr);
194
195  // Return a pointer to the new one.
196  return buf;
197}
198
199#if defined(linux)
200extern "C" char * MYCDECL CUSTOM_PREFIX(strndup) (const char * s, size_t sz)
201{
202  char * newString = NULL;
203  if (s != NULL) {
204    size_t cappedLength = strnlen (s, sz);
205    if ((newString = (char *) CUSTOM_MALLOC(cappedLength + 1))) {
206      strncpy(newString, s, cappedLength);
207      newString[cappedLength] = '\0';
208    }
209  }
210  return newString;
211}
212#endif
213
214extern "C" char * MYCDECL CUSTOM_PREFIX(strdup) (const char * s)
215{
216  char * newString = NULL;
217  if (s != NULL) {
218    if ((newString = (char *) CUSTOM_MALLOC(strlen(s) + 1))) {
219      strcpy(newString, s);
220    }
221  }
222  return newString;
223}
224
225#if !defined(_WIN32)
226#include <dlfcn.h>
227#include <limits.h>
228
229#if !defined(RTLD_NEXT)
230#define RTLD_NEXT ((void *) -1)
231#endif
232
233
234typedef char * getcwdFunction (char *, size_t);
235
236extern "C"  char * MYCDECL CUSTOM_PREFIX(getcwd) (char * buf, size_t size)
237{
238  static getcwdFunction * real_getcwd
239    = (getcwdFunction *) dlsym (RTLD_NEXT, "getcwd");
240 
241  if (!buf) {
242    if (size == 0) {
243      size = PATH_MAX;
244    }
245    buf = (char *) CUSTOM_PREFIX(malloc)(size);
246  }
247  return (real_getcwd)(buf, size);
248}
249
250#endif
251
252
253void * operator new (size_t sz)
254{
255  void * ptr = CUSTOM_MALLOC (sz);
256  if (ptr == NULL) {
257    throw std::bad_alloc();
258  } else {
259    return ptr;
260  }
261}
262
263void operator delete (void * ptr)
264{
265  CUSTOM_FREE (ptr);
266}
267
268#if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x420
269void * operator new (size_t sz, const std::nothrow_t&) throw() {
270  return CUSTOM_MALLOC(sz);
271} 
272
273void * operator new[] (size_t size) 
274{
275  void * ptr = CUSTOM_MALLOC(size);
276  if (ptr == NULL) {
277    throw std::bad_alloc();
278  } else {
279    return ptr;
280  }
281}
282
283void * operator new[] (size_t sz, const std::nothrow_t&) throw() {
284  return CUSTOM_MALLOC (sz);
285} 
286
287void operator delete[] (void * ptr)
288{
289  CUSTOM_FREE (ptr);
290}
291
292#endif
293
294
295/***** replacement functions for GNU libc extensions to malloc *****/
296
297// A stub function to ensure that we capture mallopt.
298// It does nothing and always returns a failure value (0).
299extern "C" int MYCDECL CUSTOM_MALLOPT (int number, int value)
300{
301  number = number;
302  value = value;
303  // Always fail.
304  return 0;
305}
306
307// NOTE: for convenience, we assume page size = 8192.
308
309extern "C" void * MYCDECL CUSTOM_VALLOC (size_t sz)
310{
311  return CUSTOM_MEMALIGN (8192, sz);
312}
313
314
315extern "C" void * MYCDECL CUSTOM_PVALLOC (size_t sz)
316{
317  // Rounds up to the next pagesize and then calls valloc. Hoard
318  // doesn't support aligned memory requests.
319  return CUSTOM_VALLOC ((sz + 8191) & ~8191);
320}
Note: See TracBrowser for help on using the repository browser.