Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

root/tags/releases/0.99.9/tango/core/Memory.d

Revision 5298, 16.8 kB (checked in by kris, 2 years ago)

tentative support for weak-references, courtesy of wm4

  • Property svn:eol-style set to native
Line 
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     extern (C) void gc_minimize();
21
22     extern (C) uint gc_getAttr( void* p );
23     extern (C) uint gc_setAttr( void* p, uint a );
24     extern (C) uint gc_clrAttr( void* p, uint a );
25
26     extern (C) void*  gc_malloc( size_t sz, uint ba = 0 );
27     extern (C) void*  gc_calloc( size_t sz, uint ba = 0 );
28     extern (C) void*  gc_realloc( void* p, size_t sz, uint ba = 0 );
29     extern (C) size_t gc_extend( void* p, size_t mx, size_t sz );
30     extern (C) size_t gc_reserve( size_t sz );
31     extern (C) void   gc_free( void* p );
32
33     extern (C) void*   gc_addrOf( void* p );
34     extern (C) size_t  gc_sizeOf( void* p );
35
36     struct BlkInfo_
37     {
38         void*  base;
39         size_t size;
40         uint   attr;
41     }
42
43     extern (C) BlkInfo_ gc_query( void* p );
44
45     extern (C) void gc_addRoot( void* p );
46     extern (C) void gc_addRange( void* p, size_t sz );
47
48     extern (C) void gc_removeRoot( void* p );
49     extern (C) void gc_removeRange( void* p );
50
51     extern(C) Object gc_weakpointerGet (void* wp);
52     extern(C) void*  gc_weakpointerCreate (Object r);
53     extern(C) void   gc_weakpointerDestroy (void* wp);
54 }
55
56
57 /**
58  * This struct encapsulates all garbage collection functionality for the D
59  * programming language.
60  */
61 struct GC
62 {
63     /**
64      * Enables the garbage collector if collections have previously been
65      * suspended by a call to disable.  This function is reentrant, and
66      * must be called once for every call to disable before the garbage
67      * collector is enabled.
68      */
69     static void enable()
70     {
71         gc_enable();
72     }
73
74
75     /**
76      * Disables the garbage collector.  This function is reentrant, but
77      * enable must be called once for each call to disable.
78      */
79     static void disable()
80     {
81         gc_disable();
82     }
83
84
85     /**
86      * Begins a full collection.  While the meaning of this may change based
87      * on the garbage collector implementation, typical behavior is to scan
88      * all stack segments for roots, mark accessible memory blocks as alive,
89      * and then to reclaim free space.  This action may need to suspend all
90      * running threads for at least part of the collection process.
91      */
92     static void collect()
93     {
94         gc_collect();
95     }
96
97     /**
98      * Indicates that the managed memory space be minimized by returning free
99      * physical memory to the operating system.  The amount of free memory
100      * returned depends on the allocator design and on program behavior.
101      */
102     static void minimize()
103     {
104         gc_minimize();
105     }
106
107
108     /**
109      * Elements for a bit field representing memory block attributes.  These
110      * are manipulated via the getAttr, setAttr, clrAttr functions.
111      */
112     enum BlkAttr : uint
113     {
114         FINALIZE = 0b0000_0001, /// Finalize the data in this block on collect.
115         NO_SCAN  = 0b0000_0010, /// Do not scan through this block on collect.
116         NO_MOVE  = 0b0000_0100  /// Do not move this memory block on collect.
117     }
118
119
120     /**
121      * Contains aggregate information about a block of managed memory.  The
122      * purpose of this struct is to support a more efficient query style in
123      * instances where detailed information is needed.
124      *
125      * base = A pointer to the base of the block in question.
126      * size = The size of the block, calculated from base.
127      * attr = Attribute bits set on the memory block.
128      */
129     alias BlkInfo_ BlkInfo;
130
131
132     /**
133      * Returns a bit field representing all block attributes set for the memory
134      * referenced by p.  If p references memory not originally allocated by this
135      * garbage collector, points to the interior of a memory block, or if p is
136      * null, zero will be returned.
137      *
138      * Params:
139      *  p = A pointer to the root of a valid memory block or to null.
140      *
141      * Returns:
142      *  A bit field containing any bits set for the memory block referenced by
143      *  p or zero on error.
144      */
145     static uint getAttr( void* p )
146     {
147         return gc_getAttr( p );
148     }
149
150
151     /**
152      * Sets the specified bits for the memory references by p.  If p references
153      * memory not originally allocated by this garbage collector, points to the
154      * interior of a memory block, or if p is null, no action will be performed.
155      *
156      * Params:
157      *  p = A pointer to the root of a valid memory block or to null.
158      *  a = A bit field containing any bits to set for this memory block.
159      *
160      *  The result of a call to getAttr after the specified bits have been
161      *  set.
162      */
163     static uint setAttr( void* p, uint a )
164     {
165         return gc_setAttr( p, a );
166     }
167
168
169     /**
170      * Clears the specified bits for the memory references by p.  If p
171      * references memory not originally allocated by this garbage collector,
172      * points to the interior of a memory block, or if p is null, no action
173      * will be performed.
174      *
175      * Params:
176      *  p = A pointer to the root of a valid memory block or to null.
177      *  a = A bit field containing any bits to clear for this memory block.
178      *
179      * Returns:
180      *  The result of a call to getAttr after the specified bits have been
181      *  cleared.
182      */
183     static uint clrAttr( void* p, uint a )
184     {
185         return gc_clrAttr( p, a );
186     }
187
188
189     /**
190      * Requests an aligned block of managed memory from the garbage collector.
191      * This memory may be deleted at will with a call to free, or it may be
192      * discarded and cleaned up automatically during a collection run.  If
193      * allocation fails, this function will call onOutOfMemory which is
194      * expected to throw an OutOfMemoryException.
195      *
196      * Params:
197      *  sz = The desired allocation size in bytes.
198      *  ba = A bitmask of the attributes to set on this block.
199      *
200      * Returns:
201      *  A reference to the allocated memory or null if insufficient memory
202      *  is available.
203      *
204      * Throws:
205      *  OutOfMemoryException on allocation failure.
206      */
207     static void* malloc( size_t sz, uint ba = 0 )
208     {
209         return gc_malloc( sz, ba );
210     }
211
212
213     /**
214      * Requests an aligned block of managed memory from the garbage collector,
215      * which is initialized with all bits set to zero.  This memory may be
216      * deleted at will with a call to free, or it may be discarded and cleaned
217      * up automatically during a collection run.  If allocation fails, this
218      * function will call onOutOfMemory which is expected to throw an
219      * OutOfMemoryException.
220      *
221      * Params:
222      *  sz = The desired allocation size in bytes.
223      *  ba = A bitmask of the attributes to set on this block.
224      *
225      * Returns:
226      *  A reference to the allocated memory or null if insufficient memory
227      *  is available.
228      *
229      * Throws:
230      *  OutOfMemoryException on allocation failure.
231      */
232     static void* calloc( size_t sz, uint ba = 0 )
233     {
234         return gc_calloc( sz, ba );
235     }
236
237
238     /**
239      * If sz is zero, the memory referenced by p will be deallocated as if
240      * by a call to free.  A new memory block of size sz will then be
241      * allocated as if by a call to malloc, or the implementation may instead
242      * resize the memory block in place.  The contents of the new memory block
243      * will be the same as the contents of the old memory block, up to the
244      * lesser of the new and old sizes.  Note that existing memory will only
245      * be freed by realloc if sz is equal to zero.  The garbage collector is
246      * otherwise expected to later reclaim the memory block if it is unused.
247      * If allocation fails, this function will call onOutOfMemory which is
248      * expected to throw an OutOfMemoryException.  If p references memory not
249      * originally allocated by this garbage collector, or if it points to the
250      * interior of a memory block, no action will be taken.  If ba is zero
251      * (the default) and p references the head of a valid, known memory block
252      * then any bits set on the current block will be set on the new block if a
253      * reallocation is required.  If ba is not zero and p references the head
254      * of a valid, known memory block then the bits in ba will replace those on
255      * the current memory block and will also be set on the new block if a
256      * reallocation is required.
257      *
258      * Params:
259      *  p  = A pointer to the root of a valid memory block or to null.
260      *  sz = The desired allocation size in bytes.
261      *  ba = A bitmask of the attributes to set on this block.
262      *
263      * Returns:
264      *  A reference to the allocated memory on success or null if sz is
265      *  zero.  On failure, the original value of p is returned.
266      *
267      * Throws:
268      *  OutOfMemoryException on allocation failure.
269      */
270     static void* realloc( void* p, size_t sz, uint ba = 0 )
271     {
272         return gc_realloc( p, sz, ba );
273     }
274
275
276     /**
277      * Requests that the managed memory block referenced by p be extended in
278      * place by at least mx bytes, with a desired extension of sz bytes.  If an
279      * extension of the required size is not possible, if p references memory
280      * not originally allocated by this garbage collector, or if p points to
281      * the interior of a memory block, no action will be taken.
282      *
283      * Params:
284      *  mx = The minimum extension size in bytes.
285      *  sz = The  desired extension size in bytes.
286      *
287      * Returns:
288      *  The size in bytes of the extended memory block referenced by p or zero
289      *  if no extension occurred.
290      */
291     static size_t extend( void* p, size_t mx, size_t sz )
292     {
293         return gc_extend( p, mx, sz );
294     }
295
296
297     /**
298      * Requests that at least sz bytes of memory be obtained from the operating
299      * system and marked as free.
300      *
301      * Params:
302      *  sz = The desired size in bytes.
303      *
304      * Returns:
305      *  The actual number of bytes reserved or zero on error.
306      */
307     static size_t reserve( size_t sz )
308     {
309         return gc_reserve( sz );
310     }
311
312
313     /**
314      * Deallocates the memory referenced by p.  If p is null, no action
315      * occurs.  If p references memory not originally allocated by this
316      * garbage collector, or if it points to the interior of a memory block,
317      * no action will be taken.  The block will not be finalized regardless
318      * of whether the FINALIZE attribute is set.  If finalization is desired,
319      * use delete instead.
320      *
321      * Params:
322      *  p = A pointer to the root of a valid memory block or to null.
323      */
324     static void free( void* p )
325     {
326         gc_free( p );
327     }
328
329
330     /**
331      * Returns the base address of the memory block containing p.  This value
332      * is useful to determine whether p is an interior pointer, and the result
333      * may be passed to routines such as sizeOf which may otherwise fail.  If p
334      * references memory not originally allocated by this garbage collector, if
335      * p is null, or if the garbage collector does not support this operation,
336      * null will be returned.
337      *
338      * Params:
339      *  p = A pointer to the root or the interior of a valid memory block or to
340      *      null.
341      *
342      * Returns:
343      *  The base address of the memory block referenced by p or null on error.
344      */
345     static void* addrOf( void* p )
346     {
347         return gc_addrOf( p );
348     }
349
350
351     /**
352      * Returns the true size of the memory block referenced by p.  This value
353      * represents the maximum number of bytes for which a call to realloc may
354      * resize the existing block in place.  If p references memory not
355      * originally allocated by this garbage collector, points to the interior
356      * of a memory block, or if p is null, zero will be returned.
357      *
358      * Params:
359      *  p = A pointer to the root of a valid memory block or to null.
360      *
361      * Returns:
362      *  The size in bytes of the memory block referenced by p or zero on error.
363      */
364     static size_t sizeOf( void* p )
365     {
366         return gc_sizeOf( p );
367     }
368
369
370     /**
371      * Returns aggregate information about the memory block containing p.  If p
372      * references memory not originally allocated by this garbage collector, if
373      * p is null, or if the garbage collector does not support this operation,
374      * BlkInfo.init will be returned.  Typically, support for this operation
375      * is dependent on support for addrOf.
376      *
377      * Params:
378      *  p = A pointer to the root or the interior of a valid memory block or to
379      *      null.
380      *
381      * Returns:
382      *  Information regarding the memory block referenced by p or BlkInfo.init
383      *  on error.
384      */
385     static BlkInfo query( void* p )
386     {
387         return gc_query( p );
388     }
389
390
391     /**
392      * Adds the memory address referenced by p to an internal list of roots to
393      * be scanned during a collection.  If p is null, no operation is
394      * performed.
395      *
396      * Params:
397      *  p = A pointer to a valid memory address or to null.
398      */
399     static void addRoot( void* p )
400     {
401         gc_addRoot( p );
402     }
403
404
405     /**
406      * Adds the memory block referenced by p and of size sz to an internal list
407      * of ranges to be scanned during a collection.  If p is null, no operation
408      * is performed.
409      *
410      * Params:
411      *  p  = A pointer to a valid memory address or to null.
412      *  sz = The size in bytes of the block to add.  If sz is zero then the
413      *       no operation will occur.  If p is null then sz must be zero.
414      */
415     static void addRange( void* p, size_t sz )
416     {
417         gc_addRange( p, sz );
418     }
419
420
421     /**
422      * Removes the memory block referenced by p from an internal list of roots
423      * to be scanned during a collection.  If p is null or does not represent
424      * a value previously passed to add(void*) then no operation is performed.
425      *
426      *  p  = A pointer to a valid memory address or to null.
427      */
428     static void removeRoot( void* p )
429     {
430         gc_removeRoot( p );
431     }
432
433
434     /**
435      * Removes the memory block referenced by p from an internal list of ranges
436      * to be scanned during a collection.  If p is null or does not represent
437      * a value previously passed to add(void*, size_t) then no operation is
438      * performed.
439      *
440      * Params:
441      *  p  = A pointer to a valid memory address or to null.
442      */
443     static void removeRange( void* p )
444     {
445         gc_removeRange( p );
446     }
447    
448
449     /**
450      * Create a weak pointer to the given object.
451      * Returns a pointer to an opaque struct allocated in C memory.
452      */
453     static void* weakPointerCreate( Object o )
454     {
455         return gc_weakpointerCreate (o);
456     }
457
458
459     /**
460      * Destroy a weak pointer returned by weakpointerCreate().
461      * If null is passed, nothing happens.
462      */
463     static void weakPointerDestroy( void* p )
464     {
465         return gc_weakpointerDestroy (p);
466     }
467
468
469     /**
470      * Query a weak pointer and return either the object passed to
471      * weakpointerCreate, or null if it was free'd in the meantime.
472      * If null is passed, null is returned.
473      */
474     static Object weakPointerGet( void* p )
475     {
476         return gc_weakpointerGet (p);
477     }
478
479
480     /**
481     * returns the amount to allocate to keep some extra space
482     * for large allocations the extra allocated space decreases, but is still enough
483     * so that the number of reallocations when linearly growing stays logaritmic
484     * Params:
485     * newlength = the number of elements to allocate
486     * elSize = size of one element
487     */
488     static size_t growLength (size_t newlength, size_t elSize=1)
489     {   
490         return growLength (newlength, elSize, 100, 0, 1);
491     }
492    
493
494     /**
495     * returns the amount to allocate to keep some extra space
496     * for large allocations the extra allocated space decreases, but is still enough
497     * so that the number of reallocations when linearly growing stays logaritmic
498     * Params:
499     * newlength = the number of elements to allocate
500     * elSize = size of one element
501     * a = maximum extra space in percent (the allocated space gets rounded up, so might be larger)
502     * b = flatness factor, how fast the extra space decreases with array size (the larger the more constant)
503     * minBits = minimum number of bits of newlength
504     */
505     static size_t growLength (size_t newlength, size_t elSize, size_t a, size_t b=0, size_t minBits=1)
506     {
507         static size_t log2(size_t c)
508         {
509             // could use the bsr bit op
510             size_t i=1;
511             while(c >>= 1)
512                   ++i;
513             return i;
514         }
515
516         size_t newext = 0;
517         size_t newcap = newlength*elSize;
518         long mult = 100 + a*(minBits+b) / (log2(newlength)+b);
519         newext = elSize*cast(size_t)(((newcap * mult)+99) / 100);
520         newcap = newext > newcap ? newext : newcap; // just to handle overflows
521         return newcap;
522     }
523 }
Note: See TracBrowser for help on using the browser.