source: proiecte/swift/trunk/lib/hoard-371/src/heaplayers/mmapheap.h @ 176

Last change on this file since 176 was 176, checked in by (none), 14 years ago
  • imported repo from "guagal"
File size: 5.1 KB
Line 
1/* -*- C++ -*- */
2
3/*
4
5  Heap Layers: An Extensible Memory Allocation Infrastructure
6 
7  Copyright (C) 2000-2004 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#ifndef _MMAPHEAP_H_
28#define _MMAPHEAP_H_
29
30#if defined(_WIN32)
31#include <windows.h>
32#else
33// UNIX
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <fcntl.h>
37#include <unistd.h>
38#include <sys/mman.h>
39#include <map>
40#endif
41
42#include "sassert.h"
43#include "myhashmap.h"
44#include "stlallocator.h"
45#include "freelistheap.h"
46#include "zoneheap.h"
47#include "lockedheap.h"
48#include "spinlock.h"
49#include "hldefines.h"
50
51#if HL_EXECUTABLE_HEAP
52#define HL_MMAP_PROTECTION_MASK (PROT_READ | PROT_WRITE | PROT_EXEC)
53#else
54#define HL_MMAP_PROTECTION_MASK (PROT_READ | PROT_WRITE)
55#endif
56
57#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
58#define MAP_ANONYMOUS MAP_ANON
59#endif
60
61
62#include <new>
63
64/**
65 * @class MmapHeap
66 * @brief A "source heap" that manages memory via calls to the VM interface.
67 * @author Emery Berger
68 */
69
70namespace HL {
71
72  class PrivateMmapHeap {
73  public:
74
75    /// All memory from here is zeroed.
76    enum { ZeroMemory = 1 };
77
78#if defined(_WIN32)
79
80    // Microsoft Windows aligns all memory to a 64K boundary.
81    enum { Alignment = 64 * 1024 };
82
83    inline void * malloc (size_t sz) {
84      //    printf ("mmapheap: Size request = %d\n", sz);
85#if HL_EXECUTABLE_HEAP
86      char * ptr = (char *) VirtualAlloc (NULL, sz, MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
87#else
88      char * ptr = (char *) VirtualAlloc (NULL, sz, MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE);
89#endif
90      return (void *) ptr;
91    }
92 
93    inline void free (void * ptr, size_t) {
94      VirtualFree (ptr, 0, MEM_RELEASE);
95    }
96
97    inline void free (void * ptr) {
98      VirtualFree (ptr, 0, MEM_RELEASE);
99    }
100 
101    inline static size_t getSize (void * ptr) {
102      MEMORY_BASIC_INFORMATION mbi;
103      VirtualQuery (ptr, &mbi, sizeof(mbi));
104      return (size_t) mbi.RegionSize;
105    }
106
107#else
108
109    virtual ~PrivateMmapHeap (void) {}
110
111#if defined(__SVR4)
112
113    // Solaris aligns all memory to a 64K boundary.
114    enum { Alignment = 64 * 1024 };
115#else
116    // Linux and most other operating systems align memory to a 4K boundary.
117    enum { Alignment = 4 * 1024 };
118#endif
119
120    inline void * malloc (size_t sz) {
121#if defined(MAP_ALIGN) && defined(MAP_ANON)
122      // Request memory aligned to the Alignment value above.
123      void * ptr = mmap ((char *) Alignment, sz, HL_MMAP_PROTECTION_MASK, MAP_PRIVATE | MAP_ALIGN | MAP_ANON, -1, 0);
124#elif !defined(MAP_ANONYMOUS)
125      static int fd = ::open ("/dev/zero", O_RDWR);
126      void * ptr = mmap (NULL, sz, HL_MMAP_PROTECTION_MASK, MAP_PRIVATE, fd, 0);
127#else
128      void * ptr = mmap (NULL, sz, HL_MMAP_PROTECTION_MASK, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
129#endif
130      if (ptr == MAP_FAILED) {
131        ptr = NULL;
132      }
133      return ptr;
134    }
135   
136#if 1
137    inline void free (void * ptr) {
138      abort();
139      munmap (reinterpret_cast<char *>(ptr), getSize(ptr));
140    }
141
142    inline size_t getSize (void * ptr) {
143      ptr = ptr;
144      abort();
145      return Alignment; // Obviously broken. Such is life.
146    }
147#endif
148
149    void free (void * ptr, size_t sz)
150    {
151      if ((long) sz < 0) {
152        abort();
153      }
154
155      munmap (reinterpret_cast<char *>(ptr), sz);
156    }
157
158#endif
159
160  };
161
162
163  class MmapHeap : public PrivateMmapHeap {
164#if !defined(_WIN32)
165
166  private:
167
168    class MyHeap : public LockedHeap<SpinLockType, FreelistHeap<ZoneHeap<PrivateMmapHeap, 16384 - 16> > > {}; // FIX ME: 16 = size of ZoneHeap header.
169
170    typedef MyHashMap<void *, size_t, MyHeap> mapType;
171
172  protected:
173    mapType MyMap;
174
175    SpinLockType MyMapLock;
176
177  public:
178    inline void * malloc (size_t sz) {
179      void * ptr = PrivateMmapHeap::malloc (sz);
180      MyMapLock.lock();
181      MyMap.set (ptr, sz);
182      MyMapLock.unlock();
183      assert (reinterpret_cast<size_t>(ptr) % Alignment == 0);
184      return const_cast<void *>(ptr);
185    }
186
187    inline size_t getSize (void * ptr) {
188      MyMapLock.lock();
189      size_t sz = MyMap.get (ptr);
190      MyMapLock.unlock();
191      return sz;
192    }
193
194    // WORKAROUND: apparent gcc bug.
195    void free (void * ptr, size_t sz) {
196      PrivateMmapHeap::free (ptr, sz);
197    }
198
199    inline void free (void * ptr) {
200      assert (reinterpret_cast<size_t>(ptr) % Alignment == 0);
201      MyMapLock.lock();
202      size_t sz = MyMap.get (ptr);
203      PrivateMmapHeap::free (ptr, sz);
204      MyMap.erase (ptr);
205      MyMapLock.unlock();
206    }
207#endif
208  };
209
210}
211
212#endif
Note: See TracBrowser for help on using the repository browser.