9 // Allocating temporary data of arbitrary size.
10 // We prefer to allocate it on the stack instead of via malloc(), because
11 // that's fully inlinable and causes less cache misses. But the global stack
12 // size of applications is limited (typically 8 MB on Unix, 1 MB on Windows),
13 // and we don't want users of CLN to need to change these limits. Therefore
14 // we use stack allocation only for amounts < 64KB, and malloc() for larger
19 // ... = cl_alloca(...);
21 // ... = cl_small_alloca(...);
23 // ... = cl_alloca(...);
26 // CL_ALLOCA_STACK declares that use of cl_alloca() and cl_small_alloca() is
27 // possible. Then cl_alloca() and cl_small_alloca() can be used an arbitrary
28 // number of times to get room.
29 // The allocated room's extent ends at the end of the { ... } block.
30 // In every C function CL_ALLOCA_STACK should only called once.
31 // Because of a gcc bug, functions using these macros shouldn't be declared
33 // cl_alloca(size) fetches a block of size bytes.
34 // cl_small_alloca(size) fetches a block of size bytes, with size < 65536.
35 // CL_SMALL_ALLOCA_STACK is similar to CL_ALLOCA_STACK, but allows only
36 // the use of cl_small_alloca(), not cl_alloca().
38 // CL_ALLOCA_STACK creates a variable containing a linked list of pointers
39 // to be freed when the block is exited.
41 struct cl_alloca_header {
42 cl_alloca_header* next;
43 long usable_memory[1]; // "long" guarantees alignment
46 extern cl_alloca_header* cl_alloc_alloca_header (size_t size);
47 extern void cl_free_alloca_header (cl_alloca_header* pointer);
49 class cl_alloca_stack {
50 cl_alloca_header* pointer;
52 cl_alloca_stack () { pointer = NULL; }
53 ~cl_alloca_stack () { if (pointer) cl_free_alloca_header(pointer); }
54 void* push (cl_alloca_header* p) { p->next = pointer; pointer = p; return &p->usable_memory; }
57 #define CL_ALLOCA_STACK \
58 cl_alloca_stack _alloca_stack
60 #define CL_ALLOCA_MAX 65536
62 #if defined(__GNUC__) && !defined(__riscos) && !defined(__convex__)
63 #define cl_alloca(size) ((size) >= CL_ALLOCA_MAX ? _alloca_stack.push(cl_alloc_alloca_header(size)) : __builtin_alloca(size))
64 #define cl_small_alloca(size) __builtin_alloca(size)
65 #define CL_SMALL_ALLOCA_STACK
66 #elif !defined(NO_ALLOCA) && !defined(__sparc__) && !defined(__sparc64__)
67 #define cl_alloca(size) ((size) >= CL_ALLOCA_MAX ? _alloca_stack.push(cl_alloc_alloca_header(size)) : alloca(size))
68 #define cl_small_alloca(size) alloca(size)
69 #define CL_SMALL_ALLOCA_STACK
71 #define cl_alloca(size) _alloca_stack.push(cl_alloc_alloca_header(size))
72 #define cl_small_alloca(size) _alloca_stack.push(cl_alloc_alloca_header(size))
73 #define CL_SMALL_ALLOCA_STACK CL_ALLOCA_STACK
76 // cl_alloc_array(type,size)
77 // cl_small_alloc_array(type,size)
78 // allocate an array with dynamic extent.
79 #define cl_alloc_array(arrayeltype,arraysize) \
80 (arrayeltype*)cl_alloca((arraysize)*sizeof(arrayeltype))
81 #define cl_small_alloc_array(arrayeltype,arraysize) \
82 (arrayeltype*)cl_small_alloca((arraysize)*sizeof(arrayeltype))
84 #endif /* _CL_ALLOCA_H */