| 1 | /* |
| 2 | * Copyright (c) 1999-2005 Hewlett-Packard Development Company, L.P. |
| 3 | * |
| 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED |
| 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. |
| 6 | * |
| 7 | * Permission is hereby granted to use or copy this program |
| 8 | * for any purpose, provided the above notices are retained on all copies. |
| 9 | * Permission to modify the code and to distribute modified code is granted, |
| 10 | * provided the above notices are retained, and a notice that the code was |
| 11 | * modified is included with the above copyright notice. |
| 12 | */ |
| 13 | |
| 14 | #ifndef GC_TINY_FL_H |
| 15 | #define GC_TINY_FL_H |
| 16 | |
| 17 | /* |
| 18 | * Constants and data structures for "tiny" free lists. |
| 19 | * These are used for thread-local allocation and inlined allocators. |
| 20 | * Each global free list also essentially starts with one of these. |
| 21 | * However, global free lists are known to the collector. |
| 22 | * "Tiny" free lists are basically private to the client. |
| 23 | * Their contents are viewed as "in use" and marked accordingly by the |
| 24 | * core of the collector. Note that inlined code might know about the |
| 25 | * layout of these and the constants involved. Thus any change here |
| 26 | * may invalidate clients, and such changes should be avoided. |
| 27 | * Hence we keep this as simple as possible. |
| 28 | */ |
| 29 | |
| 30 | /* |
| 31 | * We always set `GC_GRANULE_BYTES` to twice the length of a pointer. |
| 32 | * This means that all allocation requests are rounded up to the next |
| 33 | * multiple of 16 on 64-bit architectures or 8 on 32-bit architectures. |
| 34 | * This appears to be a reasonable compromise between fragmentation |
| 35 | * overhead and space usage for mark bits (usually mark bytes). |
| 36 | * On many 64-bit architectures some memory references require 16-byte |
| 37 | * alignment, making this necessary anyway. For a few 32-bit |
| 38 | * architectures (e.g. i686), we may also need 16-byte alignment for |
| 39 | * certain memory references. But currently that does not seem to be |
| 40 | * the default for all conventional `malloc` implementations, so we |
| 41 | * ignore that problem. |
| 42 | * It would always be safe, and often useful, to be able to allocate |
| 43 | * very small objects with smaller alignment. But that would cost us |
| 44 | * mark bit space, so we no longer do so. |
| 45 | * `GC_GRANULE_BYTES` should not be overridden in any instances of the |
| 46 | * collector library that may be shared between applications, since it |
| 47 | * affects the ABI (application binary interface) to the library. |
| 48 | */ |
| 49 | #if defined(CPPCHECK) && GC_GRANULE_BYTES == 1 |
| 50 | # undef GC_GRANULE_BYTES |
| 51 | #endif |
| 52 | #ifdef GC_GRANULE_BYTES |
| 53 | # define GC_GRANULE_PTRS (GC_GRANULE_BYTES / GC_SIZEOF_PTR) |
| 54 | #else |
| 55 | # define GC_GRANULE_PTRS 2 /*< in pointers */ |
| 56 | # define GC_GRANULE_BYTES (GC_GRANULE_PTRS * GC_SIZEOF_PTR) |
| 57 | #endif /* !GC_GRANULE_BYTES */ |
| 58 | |
| 59 | /** Convert size in pointers to that in granules. */ |
| 60 | #define GC_PTRS_TO_GRANULES(n) ((n) / GC_GRANULE_PTRS) |
| 61 | |
| 62 | /** |
| 63 | * Convert size in pointers to that in granules, but rounding up the |
| 64 | * result. |
| 65 | */ |
| 66 | #define GC_PTRS_TO_WHOLE_GRANULES(n) \ |
| 67 | GC_PTRS_TO_GRANULES((n) + GC_GRANULE_PTRS - 1) |
| 68 | |
| 69 | /* |
| 70 | * A "tiny" free-list header contains `GC_TINY_FREELISTS` pointers to |
| 71 | * singly-linked lists of objects of different sizes, the `i`-th one |
| 72 | * containing objects of `i` granules in size. Note that there is |
| 73 | * a list of size zero objects. |
| 74 | */ |
| 75 | #ifndef GC_TINY_FREELISTS |
| 76 | # if GC_GRANULE_BYTES >= 16 |
| 77 | # define GC_TINY_FREELISTS 25 |
| 78 | # else |
| 79 | # define GC_TINY_FREELISTS 33 /*< up to and including 256 bytes */ |
| 80 | # endif |
| 81 | #endif /* !GC_TINY_FREELISTS */ |
| 82 | |
| 83 | /* |
| 84 | * The `i`-th free list corresponds to size `i * GC_GRANULE_BYTES`. |
| 85 | * Internally to the collector, the index `i` can be computed with |
| 86 | * `ALLOC_REQUEST_GRANS()`. The latter also depends on the values |
| 87 | * returned by `GC_get_dont_add_byte_at_end()` and |
| 88 | * `GC_get_all_interior_pointers()`. |
| 89 | */ |
| 90 | |
| 91 | /** |
| 92 | * Convert a free-list index to the actual size of objects on that list, |
| 93 | * including extra space we added. Not an inverse of the above. |
| 94 | */ |
| 95 | #define GC_RAW_BYTES_FROM_INDEX(i) (GC_GRANULE_BYTES * (i)) |
| 96 | |
| 97 | /* Deprecated. Use `GC_GRANULE_PTRS` instead. */ |
| 98 | #undef GC_GRANULE_WORDS |
| 99 | #define GC_GRANULE_WORDS GC_GRANULE_PTRS |
| 100 | |
| 101 | /* Deprecated. Use `GC_PTRS_TO_GRANULES()` instead. */ |
| 102 | #define GC_WORDS_TO_GRANULES(n) GC_PTRS_TO_GRANULES(n) |
| 103 | |
| 104 | /* Deprecated. */ |
| 105 | #define GC_WORDS_TO_WHOLE_GRANULES(n) GC_PTRS_TO_WHOLE_GRANULES(n) |
| 106 | |
| 107 | #endif /* GC_TINY_FL_H */ |
| 108 | |