132
|
1 /**
|
|
2 * The memory module provides an interface to the garbage collector and to
|
|
3 * any other OS or API-level memory management facilities.
|
|
4 *
|
|
5 * Copyright: Copyright (C) 2005-2006 Sean Kelly. All rights reserved.
|
|
6 * License: BSD style: $(LICENSE)
|
|
7 * Authors: Sean Kelly
|
|
8 */
|
|
9 module tango.core.Memory;
|
|
10
|
|
11
|
|
12 private
|
|
13 {
|
|
14 extern (C) void gc_init();
|
|
15 extern (C) void gc_term();
|
|
16
|
|
17 extern (C) void gc_enable();
|
|
18 extern (C) void gc_disable();
|
|
19 extern (C) void gc_collect();
|
|
20
|
|
21 extern (C) uint gc_getAttr( void* p );
|
|
22 extern (C) uint gc_setAttr( void* p, uint a );
|
|
23 extern (C) uint gc_clrAttr( void* p, uint a );
|
|
24
|
|
25 extern (C) void* gc_malloc( size_t sz, uint ba = 0 );
|
|
26 extern (C) void* gc_calloc( size_t sz, uint ba = 0 );
|
|
27 extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0 );
|
|
28 extern (C) size_t gc_extend( void* p, size_t mx, size_t sz );
|
|
29 extern (C) void gc_free( void* p );
|
|
30
|
|
31 extern (C) void* gc_addrOf( void* p );
|
|
32 extern (C) size_t gc_sizeOf( void* p );
|
|
33
|
|
34 struct BlkInfo_
|
|
35 {
|
|
36 void* base;
|
|
37 size_t size;
|
|
38 uint attr;
|
|
39 }
|
|
40
|
|
41 extern (C) BlkInfo_ gc_query( void* p );
|
|
42
|
|
43 extern (C) void gc_addRoot( void* p );
|
|
44 extern (C) void gc_addRange( void* p, size_t sz );
|
|
45
|
|
46 extern (C) void gc_removeRoot( void* p );
|
|
47 extern (C) void gc_removeRange( void* p );
|
|
48
|
|
49 alias bool function( Object obj ) collectHandlerType;
|
|
50 }
|
|
51
|
|
52
|
|
53 /**
|
|
54 * This struct encapsulates all garbage collection functionality for the D
|
|
55 * programming language.
|
|
56 */
|
|
57 struct GC
|
|
58 {
|
|
59 /**
|
|
60 * Enables the garbage collector if collections have previously been
|
|
61 * suspended by a call to disable. This function is reentrant, and
|
|
62 * must be called once for every call to disable before the garbage
|
|
63 * collector is enabled.
|
|
64 */
|
|
65 static void enable()
|
|
66 {
|
|
67 gc_enable();
|
|
68 }
|
|
69
|
|
70
|
|
71 /**
|
|
72 * Disables the garbage collector. This function is reentrant, but
|
|
73 * enable must be called once for each call to disable.
|
|
74 */
|
|
75 static void disable()
|
|
76 {
|
|
77 gc_disable();
|
|
78 }
|
|
79
|
|
80
|
|
81 /**
|
|
82 * Begins a full collection. While the meaning of this may change based
|
|
83 * on the garbage collector implementation, typical behavior is to scan
|
|
84 * all stack segments for roots, mark accessible memory blocks as alive,
|
|
85 * and then to reclaim free space. This action may need to suspend all
|
|
86 * running threads for at least part of the collection process.
|
|
87 */
|
|
88 static void collect()
|
|
89 {
|
|
90 gc_collect();
|
|
91 }
|
|
92
|
|
93
|
|
94 /**
|
|
95 * Elements for a bit field representing memory block attributes. These
|
|
96 * are manipulated via the getAttr, setAttr, clrAttr functions.
|
|
97 */
|
|
98 enum BlkAttr : uint
|
|
99 {
|
|
100 FINALIZE = 0b0000_0001, /// Finalize the data in this block on collect.
|
|
101 NO_SCAN = 0b0000_0010, /// Do not scan through this block on collect.
|
|
102 NO_MOVE = 0b0000_0100 /// Do not move this memory block on collect.
|
|
103 }
|
|
104
|
|
105
|
|
106 /**
|
|
107 * Contains aggregate information about a block of managed memory. The
|
|
108 * purpose of this struct is to support a more efficient query style in
|
|
109 * instances where detailed information is needed.
|
|
110 *
|
|
111 * base = A pointer to the base of the block in question.
|
|
112 * size = The size of the block, calculated from base.
|
|
113 * attr = Attribute bits set on the memory block.
|
|
114 */
|
|
115 alias BlkInfo_ BlkInfo;
|
|
116
|
|
117
|
|
118 /**
|
|
119 * Returns a bit field representing all block attributes set for the memory
|
|
120 * referenced by p. If p references memory not originally allocated by this
|
|
121 * garbage collector, points to the interior of a memory block, or if p is
|
|
122 * null, zero will be returned.
|
|
123 *
|
|
124 * Params:
|
|
125 * p = A pointer to the root of a valid memory block or to null.
|
|
126 *
|
|
127 * Returns:
|
|
128 * A bit field containing any bits set for the memory block referenced by
|
|
129 * p or zero on error.
|
|
130 */
|
|
131 static uint getAttr( void* p )
|
|
132 {
|
|
133 return gc_getAttr( p );
|
|
134 }
|
|
135
|
|
136
|
|
137 /**
|
|
138 * Sets the specified bits for the memory references by p. If p references
|
|
139 * memory not originally allocated by this garbage collector, points to the
|
|
140 * interior of a memory block, or if p is null, no action will be performed.
|
|
141 *
|
|
142 * Params:
|
|
143 * p = A pointer to the root of a valid memory block or to null.
|
|
144 * a = A bit field containing any bits to set for this memory block.
|
|
145 *
|
|
146 * The result of a call to getAttr after the specified bits have been
|
|
147 * set.
|
|
148 */
|
|
149 static uint setAttr( void* p, uint a )
|
|
150 {
|
|
151 return gc_setAttr( p, a );
|
|
152 }
|
|
153
|
|
154
|
|
155 /**
|
|
156 * Clears the specified bits for the memory references by p. If p
|
|
157 * references memory not originally allocated by this garbage collector,
|
|
158 * points to the interior of a memory block, or if p is null, no action
|
|
159 * will be performed.
|
|
160 *
|
|
161 * Params:
|
|
162 * p = A pointer to the root of a valid memory block or to null.
|
|
163 * a = A bit field containing any bits to clear for this memory block.
|
|
164 *
|
|
165 * Returns:
|
|
166 * The result of a call to getAttr after the specified bits have been
|
|
167 * cleared.
|
|
168 */
|
|
169 static uint clrAttr( void* p, uint a )
|
|
170 {
|
|
171 return gc_clrAttr( p, a );
|
|
172 }
|
|
173
|
|
174
|
|
175 /**
|
|
176 * Requests an aligned block of managed memory from the garbage collector.
|
|
177 * This memory may be deleted at will with a call to free, or it may be
|
|
178 * discarded and cleaned up automatically during a collection run. If
|
|
179 * allocation fails, this function will call onOutOfMemory which is
|
|
180 * expected to throw an OutOfMemoryException.
|
|
181 *
|
|
182 * Params:
|
|
183 * sz = The desired allocation size in bytes.
|
|
184 * ba = A bitmask of the attributes to set on this block.
|
|
185 *
|
|
186 * Returns:
|
|
187 * A reference to the allocated memory or null if insufficient memory
|
|
188 * is available.
|
|
189 *
|
|
190 * Throws:
|
|
191 * OutOfMemoryException on allocation failure.
|
|
192 */
|
|
193 static void* malloc( size_t sz, uint ba = 0 )
|
|
194 {
|
|
195 return gc_malloc( sz, ba );
|
|
196 }
|
|
197
|
|
198
|
|
199 /**
|
|
200 * Requests an aligned block of managed memory from the garbage collector,
|
|
201 * which is initialized with all bits set to zero. This memory may be
|
|
202 * deleted at will with a call to free, or it may be discarded and cleaned
|
|
203 * up automatically during a collection run. If allocation fails, this
|
|
204 * function will call onOutOfMemory which is expected to throw an
|
|
205 * OutOfMemoryException.
|
|
206 *
|
|
207 * Params:
|
|
208 * sz = The desired allocation size in bytes.
|
|
209 * ba = A bitmask of the attributes to set on this block.
|
|
210 *
|
|
211 * Returns:
|
|
212 * A reference to the allocated memory or null if insufficient memory
|
|
213 * is available.
|
|
214 *
|
|
215 * Throws:
|
|
216 * OutOfMemoryException on allocation failure.
|
|
217 */
|
|
218 static void* calloc( size_t sz, uint ba = 0 )
|
|
219 {
|
|
220 return gc_calloc( sz, ba );
|
|
221 }
|
|
222
|
|
223
|
|
224 /**
|
|
225 * If sz is zero, the memory referenced by p will be deallocated as if
|
|
226 * by a call to free. A new memory block of size sz will then be
|
|
227 * allocated as if by a call to malloc, or the implementation may instead
|
|
228 * resize the memory block in place. The contents of the new memory block
|
|
229 * will be the same as the contents of the old memory block, up to the
|
|
230 * lesser of the new and old sizes. Note that existing memory will only
|
|
231 * be freed by realloc if sz is equal to zero. The garbage collector is
|
|
232 * otherwise expected to later reclaim the memory block if it is unused.
|
|
233 * If allocation fails, this function will call onOutOfMemory which is
|
|
234 * expected to throw an OutOfMemoryException. If p references memory not
|
|
235 * originally allocated by this garbage collector, or if it points to the
|
|
236 * interior of a memory block, no action will be taken. If ba is zero
|
|
237 * (the default) and p references the head of a valid, known memory block
|
|
238 * then any bits set on the current block will be set on the new block if a
|
|
239 * reallocation is required. If ba is not zero and p references the head
|
|
240 * of a valid, known memory block then the bits in ba will replace those on
|
|
241 * the current memory block and will also be set on the new block if a
|
|
242 * reallocation is required.
|
|
243 *
|
|
244 * Params:
|
|
245 * p = A pointer to the root of a valid memory block or to null.
|
|
246 * sz = The desired allocation size in bytes.
|
|
247 * ba = A bitmask of the attributes to set on this block.
|
|
248 *
|
|
249 * Returns:
|
|
250 * A reference to the allocated memory on success or null if sz is
|
|
251 * zero. On failure, the original value of p is returned.
|
|
252 *
|
|
253 * Throws:
|
|
254 * OutOfMemoryException on allocation failure.
|
|
255 */
|
|
256 static void* realloc( void* p, size_t sz, uint ba = 0 )
|
|
257 {
|
|
258 return gc_realloc( p, sz, ba );
|
|
259 }
|
|
260
|
|
261
|
|
262 /**
|
|
263 * Requests that the managed memory block referenced by p be extended in
|
|
264 * place by at least mx bytes, with a desired extension of sz bytes. If an
|
|
265 * extension of the required size is not possible, if p references memory
|
|
266 * not originally allocated by this garbage collector, or if p points to
|
|
267 * the interior of a memory block, no action will be taken.
|
|
268 *
|
|
269 * Params:
|
|
270 * mx = The minimum extension size in bytes.
|
|
271 * sz = The desired extension size in bytes.
|
|
272 *
|
|
273 * Returns:
|
|
274 * The size in bytes of the extended memory block referenced by p or zero
|
|
275 * if no extension occurred.
|
|
276 */
|
|
277 static size_t extend( void* p, size_t mx, size_t sz )
|
|
278 {
|
|
279 return gc_extend( p, mx, sz );
|
|
280 }
|
|
281
|
|
282
|
|
283 /**
|
|
284 * Deallocates the memory referenced by p. If p is null, no action
|
|
285 * occurs. If p references memory not originally allocated by this
|
|
286 * garbage collector, or if it points to the interior of a memory block,
|
|
287 * no action will be taken. The block will not be finalized regardless
|
|
288 * of whether the FINALIZE attribute is set. If finalization is desired,
|
|
289 * use delete instead.
|
|
290 *
|
|
291 * Params:
|
|
292 * p = A pointer to the root of a valid memory block or to null.
|
|
293 */
|
|
294 static void free( void* p )
|
|
295 {
|
|
296 gc_free( p );
|
|
297 }
|
|
298
|
|
299
|
|
300 /**
|
|
301 * Returns the base address of the memory block containing p. This value
|
|
302 * is useful to determine whether p is an interior pointer, and the result
|
|
303 * may be passed to routines such as sizeOf which may otherwise fail. If p
|
|
304 * references memory not originally allocated by this garbage collector, if
|
|
305 * p is null, or if the garbage collector does not support this operation,
|
|
306 * null will be returned.
|
|
307 *
|
|
308 * Params:
|
|
309 * p = A pointer to the root or the interior of a valid memory block or to
|
|
310 * null.
|
|
311 *
|
|
312 * Returns:
|
|
313 * The base address of the memory block referenced by p or null on error.
|
|
314 */
|
|
315 static void* addrOf( void* p )
|
|
316 {
|
|
317 return gc_addrOf( p );
|
|
318 }
|
|
319
|
|
320
|
|
321 /**
|
|
322 * Returns the true size of the memory block referenced by p. This value
|
|
323 * represents the maximum number of bytes for which a call to realloc may
|
|
324 * resize the existing block in place. If p references memory not
|
|
325 * originally allocated by this garbage collector, points to the interior
|
|
326 * of a memory block, or if p is null, zero will be returned.
|
|
327 *
|
|
328 * Params:
|
|
329 * p = A pointer to the root of a valid memory block or to null.
|
|
330 *
|
|
331 * Returns:
|
|
332 * The size in bytes of the memory block referenced by p or zero on error.
|
|
333 */
|
|
334 static size_t sizeOf( void* p )
|
|
335 {
|
|
336 return gc_sizeOf( p );
|
|
337 }
|
|
338
|
|
339
|
|
340 /**
|
|
341 * Returns aggregate information about the memory block containing p. If p
|
|
342 * references memory not originally allocated by this garbage collector, if
|
|
343 * p is null, or if the garbage collector does not support this operation,
|
|
344 * BlkInfo.init will be returned. Typically, support for this operation
|
|
345 * is dependent on support for addrOf.
|
|
346 *
|
|
347 * Params:
|
|
348 * p = A pointer to the root or the interior of a valid memory block or to
|
|
349 * null.
|
|
350 *
|
|
351 * Returns:
|
|
352 * Information regarding the memory block referenced by p or BlkInfo.init
|
|
353 * on error.
|
|
354 */
|
|
355 static BlkInfo query( void* p )
|
|
356 {
|
|
357 return gc_query( p );
|
|
358 }
|
|
359
|
|
360
|
|
361 /**
|
|
362 * Adds the memory address referenced by p to an internal list of roots to
|
|
363 * be scanned during a collection. If p is null, no operation is
|
|
364 * performed.
|
|
365 *
|
|
366 * Params:
|
|
367 * p = A pointer to a valid memory address or to null.
|
|
368 */
|
|
369 static void addRoot( void* p )
|
|
370 {
|
|
371 gc_addRoot( p );
|
|
372 }
|
|
373
|
|
374
|
|
375 /**
|
|
376 * Adds the memory block referenced by p and of size sz to an internal list
|
|
377 * of ranges to be scanned during a collection. If p is null, no operation
|
|
378 * is performed.
|
|
379 *
|
|
380 * Params:
|
|
381 * p = A pointer to a valid memory address or to null.
|
|
382 * sz = The size in bytes of the block to add. If sz is zero then the
|
|
383 * no operation will occur. If p is null then sz must be zero.
|
|
384 */
|
|
385 static void addRange( void* p, size_t sz )
|
|
386 {
|
|
387 gc_addRange( p, sz );
|
|
388 }
|
|
389
|
|
390
|
|
391 /**
|
|
392 * Removes the memory block referenced by p from an internal list of roots
|
|
393 * to be scanned during a collection. If p is null or does not represent
|
|
394 * a value previously passed to add(void*) then no operation is performed.
|
|
395 *
|
|
396 * p = A pointer to a valid memory address or to null.
|
|
397 */
|
|
398 static void removeRoot( void* p )
|
|
399 {
|
|
400 gc_removeRoot( p );
|
|
401 }
|
|
402
|
|
403
|
|
404 /**
|
|
405 * Removes the memory block referenced by p from an internal list of ranges
|
|
406 * to be scanned during a collection. If p is null or does not represent
|
|
407 * a value previously passed to add(void*, size_t) then no operation is
|
|
408 * performed.
|
|
409 *
|
|
410 * Params:
|
|
411 * p = A pointer to a valid memory address or to null.
|
|
412 */
|
|
413 static void removeRange( void* p )
|
|
414 {
|
|
415 gc_removeRange( p );
|
|
416 }
|
|
417
|
|
418
|
|
419 /**
|
|
420 * Overrides the default collect hander with a user-supplied version.
|
|
421 *
|
|
422 * Params:
|
|
423 * h = The new collect handler. Set to null to use the default handler.
|
|
424 */
|
|
425 static void collectHandler( collectHandlerType h )
|
|
426 {
|
|
427 sm_collectHandler = h;
|
|
428 }
|
|
429
|
|
430
|
|
431 private:
|
|
432 static collectHandlerType sm_collectHandler = null;
|
|
433 }
|
|
434
|
|
435
|
|
436 ////////////////////////////////////////////////////////////////////////////////
|
|
437 // Overridable Callbacks
|
|
438 ////////////////////////////////////////////////////////////////////////////////
|
|
439
|
|
440
|
|
441 /**
|
|
442 * This function will be called when resource objects (ie. objects with a dtor)
|
|
443 * are finalized by the garbage collector. The user-supplied collect handler
|
|
444 * will be called if one has been supplied, otherwise no action will be taken.
|
|
445 *
|
|
446 * Params:
|
|
447 * obj = The object being collected.
|
|
448 *
|
|
449 * Returns:
|
|
450 * true if the runtime should call this object's dtor and false if not.
|
|
451 * Default behavior is to return true.
|
|
452 */
|
|
453 extern (C) bool onCollectResource( Object obj )
|
|
454 {
|
|
455 if( GC.sm_collectHandler is null )
|
|
456 return true;
|
|
457 return GC.sm_collectHandler( obj );
|
|
458 }
|