diff --git a/src/Makefile.in b/src/Makefile.in index d2f21c6f22cf21a6802ef6eed9c62280e553dc32..b3c26a3c34fa316381ab2234f668ba802eeb92b9 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -164,6 +164,7 @@ CORE_OBJ= \ pike_types.o \ pike_embed.o \ mapping.o \ + block_allocator.o \ pike_memory.o \ module_support.o \ pikecode.o \ @@ -1431,6 +1432,7 @@ HFILES= \ main.protos \ stralloc.protos \ mapping.protos \ + block_allocator.protos \ stuff.protos \ dynamic_buffer.protos \ svalue.protos \ diff --git a/src/backend.cmod b/src/backend.cmod index 126f3d0f74de43cb06c2a3ce1a779d2dcdc1c527..0e1a08461d69f7198ed9013d2b8b5b356fd0f7d7 100644 --- a/src/backend.cmod +++ b/src/backend.cmod @@ -37,6 +37,7 @@ #include "svalue.h" #include "gc.h" #include "module_support.h" +#include "block_allocator.h" /* * Things to do @@ -132,8 +133,8 @@ /* Declarations for the legacy backend interface stuff. */ -#include "block_alloc_h.h" -BLOCK_ALLOC (compat_cb_box, N/A); +static struct compat_cb_box * alloc_compat_cb_box(); +static void really_free_compat_cb_box(struct compat_cb_box * b); static int compat_box_dispatcher (struct fd_callback_box *box, int event); /* CALL OUT STUFF */ @@ -5116,18 +5117,29 @@ struct compat_cb_box int flags; /* fs event flags */ }; -#include "block_alloc.h" - -#undef BLOCK_ALLOC_NEXT -#define BLOCK_ALLOC_NEXT read_data - #undef DMALLOC_DESCRIBE_BLOCK #define DMALLOC_DESCRIBE_BLOCK(X) do { \ fprintf (stderr, " backend: %p, fd: %d, events: 0x%x\n", \ X->box.backend, X->box.fd, X->box.events); \ } while (0) -BLOCK_ALLOC_FILL_PAGES (compat_cb_box, 1) +static struct block_allocator compat_cb_allocator = BA_INIT_PAGES(sizeof(struct compat_cb_box), 1); + +static struct compat_cb_box * alloc_compat_cb_box() { + return ba_alloc(&compat_cb_allocator); +} + +static void really_free_compat_cb_box(struct compat_cb_box * b) { + ba_free(&compat_cb_allocator, b); +} + +void count_memory_in_compat_cb_boxs(size_t * n, size_t * s) { + ba_count_all(&compat_cb_allocator, n, s); +} + +void free_all_compat_cb_box_blocks() { + ba_destroy(&compat_cb_allocator); +} static int compat_box_dispatcher (struct fd_callback_box *box, int event) { @@ -5404,7 +5416,6 @@ static struct callback *mem_callback; void init_backend(void) { IF_PD(fprintf(stderr, "BACKEND: Init compat callback boxes...\n")); - init_compat_cb_box_blocks(); IF_PD(fprintf(stderr, "BACKEND: INIT...\n")); INIT; IF_PD(fprintf(stderr, "BACKEND: Creating default backend...\n")); diff --git a/src/backend.h b/src/backend.h index 0e442fd3ede54b4d8767712146c24f3bed2fbd8f..de8344247da8f55a014d7a9bf04d06c11edeaa1b 100644 --- a/src/backend.h +++ b/src/backend.h @@ -83,6 +83,7 @@ extern struct callback_list do_debug_callbacks; PMOD_EXPORT extern struct program *Backend_program; void count_memory_in_compat_cb_boxs(size_t *num, size_t *size); +void free_all_compat_cb_box_blocks(); PMOD_EXPORT void debug_check_fd_not_in_use (int fd); #if 1 diff --git a/src/post_modules/CritBit/bitvector.h b/src/bitvector.h similarity index 99% rename from src/post_modules/CritBit/bitvector.h rename to src/bitvector.h index 0f4bb7b24b97f79e38465385d4b75e619ceceac2..3e7de8c9f1f1a777396bd8bb223402c5a68d7c3e 100644 --- a/src/post_modules/CritBit/bitvector.h +++ b/src/bitvector.h @@ -1,7 +1,7 @@ #ifndef BITVECTOR_H #define BITVECTOR_H -#include "critbit_config.h" +#include "machine.h" #define MOD_PRIME #include "pike_int_types.h" diff --git a/src/block_alloc.h b/src/block_alloc.h index 0351753ef7af92ab720b3c7aef97358c4d2aa7f4..3317f4150e5953f8c7d607103a2779e4e4229363 100644 --- a/src/block_alloc.h +++ b/src/block_alloc.h @@ -98,6 +98,21 @@ DO_IF_DMALLOC( + sizeof(INT32))) #endif +#define WALK_NONFREE_BLOCKS(DATA, BLOCK, FCOND, CODE) do { \ + struct PIKE_CONCAT(DATA,_block) * p; \ + for(p=PIKE_CONCAT(DATA,_blocks);p;p=p->next) { \ + int n = p->used; \ + int i; \ + for (i = 0; n && i < (sizeof(p->x)/sizeof(struct DATA)); i++) { \ + BLOCK = &p->x[i]; \ + if (FCOND) { \ + do CODE while(0); \ + --n; \ + } \ + } \ + } \ +} while(0) + #define BLOCK_ALLOC(DATA,BSIZE) \ \ struct PIKE_CONCAT(DATA,_block) \ @@ -513,19 +528,16 @@ static INLINE struct DATA * \ PIKE_CONCAT3(really_low_find_,DATA,_unlocked)(void *ptr, \ PIKE_HASH_T hval) \ { \ - struct DATA *p,**pp; \ + struct DATA *p; \ p=PIKE_CONCAT(DATA,_hash_table)[hval]; \ if(!p || p->PTR_HASH_ALLOC_DATA == ptr) \ { \ return p; \ } \ - while((p=*(pp=&p->BLOCK_ALLOC_NEXT))) \ + while((p=p->BLOCK_ALLOC_NEXT)) \ { \ if(p->PTR_HASH_ALLOC_DATA==ptr) \ { \ - *pp=p->BLOCK_ALLOC_NEXT; \ - p->BLOCK_ALLOC_NEXT=PIKE_CONCAT(DATA,_hash_table)[hval]; \ - PIKE_CONCAT(DATA,_hash_table)[hval]=p; \ return p; \ } \ } \ @@ -622,18 +634,22 @@ int PIKE_CONCAT3(check_,DATA,_semaphore)(void *ptr) \ \ void PIKE_CONCAT(move_,DATA)(struct DATA *block, void *new_ptr) \ { \ + struct DATA **pp, *p; \ PIKE_HASH_T hval = \ (PIKE_HASH_T)PTR_TO_INT(block->PTR_HASH_ALLOC_DATA); \ DO_IF_RUN_UNLOCKED(mt_lock(&PIKE_CONCAT(DATA,_mutex))); \ hval %= (PIKE_HASH_T)PIKE_CONCAT(DATA,_hash_table_size); \ - if (!PIKE_CONCAT3(really_low_find_,DATA,_unlocked)( \ - block->PTR_HASH_ALLOC_DATA, hval)) \ - Pike_fatal("The block to move wasn't found.\n"); \ - DO_IF_DEBUG( \ - if (PIKE_CONCAT(DATA,_hash_table)[hval] != block) \ - Pike_fatal("Expected the block to be at the top of the hash chain.\n"); \ - ); \ - PIKE_CONCAT(DATA,_hash_table)[hval] = block->BLOCK_ALLOC_NEXT; \ + pp=PIKE_CONCAT(DATA,_hash_table) + hval; \ + while((p = *pp)) \ + { \ + if(p == block) \ + { \ + *pp = p->BLOCK_ALLOC_NEXT; \ + break; \ + } \ + pp = &p->BLOCK_ALLOC_NEXT; \ + } \ + if (!p) Pike_fatal("The block to move wasn't found.\n"); \ block->PTR_HASH_ALLOC_DATA = new_ptr; \ hval = (PIKE_HASH_T)PTR_TO_INT(new_ptr) % \ (PIKE_HASH_T)PIKE_CONCAT(DATA,_hash_table_size); \ @@ -644,7 +660,7 @@ void PIKE_CONCAT(move_,DATA)(struct DATA *block, void *new_ptr) \ \ int PIKE_CONCAT(remove_,DATA)(void *ptr) \ { \ - struct DATA *p; \ + struct DATA **pp, *p; \ PIKE_HASH_T hval = (PIKE_HASH_T)PTR_TO_INT(ptr); \ DO_IF_RUN_UNLOCKED(mt_lock(&PIKE_CONCAT(DATA,_mutex))); \ if(!PIKE_CONCAT(DATA,_hash_table)) \ @@ -653,15 +669,18 @@ int PIKE_CONCAT(remove_,DATA)(void *ptr) \ return 0; \ } \ hval %= (PIKE_HASH_T)PIKE_CONCAT(DATA,_hash_table_size); \ - if((p=PIKE_CONCAT3(really_low_find_,DATA,_unlocked)(ptr, hval))) \ + pp=PIKE_CONCAT(DATA,_hash_table) + hval; \ + while((p = *pp)) \ { \ - PIKE_CONCAT(num_,DATA)--; \ - DO_IF_DEBUG( if(PIKE_CONCAT(DATA,_hash_table)[hval]!=p) \ - Pike_fatal("GAOssdf\n"); ); \ - PIKE_CONCAT(DATA,_hash_table)[hval]=p->BLOCK_ALLOC_NEXT; \ - BA_UL(PIKE_CONCAT(really_free_,DATA))(p); \ - DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \ - return 1; \ + if(p->PTR_HASH_ALLOC_DATA==ptr) \ + { \ + *pp = p->BLOCK_ALLOC_NEXT; \ + PIKE_CONCAT(num_,DATA)--; \ + BA_UL(PIKE_CONCAT(really_free_,DATA))(p); \ + DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \ + return 1; \ + } \ + pp = &p->BLOCK_ALLOC_NEXT; \ } \ DO_IF_RUN_UNLOCKED(mt_unlock(&PIKE_CONCAT(DATA,_mutex))); \ return 0; \ diff --git a/src/block_allocator.c b/src/block_allocator.c new file mode 100644 index 0000000000000000000000000000000000000000..44e3fd90e3748126a5af83297390d01001f07ad6 --- /dev/null +++ b/src/block_allocator.c @@ -0,0 +1,200 @@ +#include "global.h" +#include "pike_error.h" +#include "pike_memory.h" + +#include "block_allocator.h" +#include "bitvector.h" + +#define BA_BLOCKN(l, p, n) ((struct ba_block_header *)(((char*)((p)+1)) + (n)*((l).block_size))) +#define BA_LASTBLOCK(l, p) ((struct ba_block_header*)((char*)((p)+1) + (l).offset)) +#define BA_CHECK_PTR(l, p, ptr) ((size_t)((char*)(ptr) - (char*)((p)+1)) <= (l).offset) + +#define BA_ONE ((struct ba_block_header *)1) + +static INLINE void ba_dec_layout(struct ba_layout * l, int i) { + l->blocks >>= i; + l->offset += l->block_size; + l->offset >>= i; + l->offset -= l->block_size; +} + +static INLINE void ba_inc_layout(struct ba_layout * l, int i) { + l->blocks <<= i; + l->offset += l->block_size; + l->offset <<= i; + l->offset -= l->block_size; +} + +static INLINE void ba_double_layout(struct ba_layout * l) { + ba_inc_layout(l, 1); +} + +static INLINE void ba_half_layout(struct ba_layout * l) { + ba_dec_layout(l, 1); +} + +static INLINE struct ba_layout ba_get_layout(const struct block_allocator * a, int i) { + struct ba_layout l = a->l; + ba_inc_layout(&l, i); + return l; +} + +struct ba_block_header { + struct ba_block_header * next; +}; + +static struct ba_page * ba_alloc_page(struct block_allocator * a, int i) { + struct ba_layout l = ba_get_layout(a, i); + size_t n = l.offset + l.block_size + sizeof(struct ba_page); + struct ba_page * p = (struct ba_page*)xalloc(n); + p->h.first = BA_BLOCKN(a->l, p, 0); + p->h.first->next = BA_ONE; + p->h.used = 0; + return p; +} + +PMOD_EXPORT void ba_init(struct block_allocator * a, unsigned INT32 block_size, unsigned INT32 blocks) { + block_size = MAXIMUM(block_size, sizeof(struct ba_block_header)); + blocks = round_up32(blocks); + a->alloc = a->last_free = 0; + a->size = 1; + a->l.block_size = block_size; + a->l.blocks = blocks; + a->l.offset = block_size * (blocks-1); + memset(a->pages, 0, sizeof(a->pages)); + a->pages[0] = ba_alloc_page(a, 0); +} + +PMOD_EXPORT void ba_destroy(struct block_allocator * a) { + int i; + for (i = 0; i < a->size; i++) { + if (a->pages[i]) { + free(a->pages[i]); + a->pages[i] = NULL; + } + } + a->size = 0; + a->alloc = 0; + a->last_free = 0; +} + +PMOD_EXPORT size_t ba_count(const struct block_allocator * a) { + size_t c = 0; + unsigned int i; + for (i = 0; i < a->size; i++) { + c += a->pages[i]->h.used; + } + + return c; +} + +PMOD_EXPORT void ba_count_all(const struct block_allocator * a, size_t * num, size_t * size) { + size_t n = (a->l.blocks << (a->size-1)) - a->l.blocks; + *num = n; + *size = a->l.block_size * n; +} + +static void ba_low_alloc(struct block_allocator * a) { + if (a->l.offset) { + unsigned int i; + + for (i = 1; i <= a->size; i++) { + struct ba_page * p = a->pages[a->size - i]; + + if (p->h.first) { + a->alloc = a->size - i; + return; + } + } + if (a->size == (sizeof(a->pages)/sizeof(a->pages[0]))) { + Pike_error("Out of memory."); + } + a->pages[a->size] = ba_alloc_page(a, a->size); + a->alloc = a->size; + a->size++; + } else { + ba_init(a, a->l.block_size, a->l.blocks); + } +} + +ATTRIBUTE((malloc)) +PMOD_EXPORT void * ba_alloc(struct block_allocator * a) { + struct ba_page * p = a->pages[a->alloc]; + struct ba_block_header * ptr; + + if (!p || !p->h.first) { + ba_low_alloc(a); + p = a->pages[a->alloc]; + } + + ptr = p->h.first; + + p->h.used++; + + if (ptr->next == BA_ONE) { + struct ba_layout l = ba_get_layout(a, a->alloc); + p->h.first = (struct ba_block_header*)((char*)ptr + a->l.block_size); + p->h.first->next = (struct ba_block_header*)(ptrdiff_t)!(p->h.first == BA_LASTBLOCK(l, p)); + } else { + p->h.first = ptr->next; + } + + return ptr; +} + +PMOD_EXPORT void ba_free(struct block_allocator * a, void * ptr) { + int i = a->last_free; + struct ba_page * p = a->pages[i]; + struct ba_layout l = ba_get_layout(a, i); + + if (BA_CHECK_PTR(l, p, ptr)) goto found; + + p = NULL; + + for (i = a->size-1, l = ba_get_layout(a, i); i >= 0; i--, ba_half_layout(&l)) { + if (BA_CHECK_PTR(l, a->pages[i], ptr)) { + a->last_free = i; + p = a->pages[i]; + break; + } + } +found: + +#ifdef PIKE_DEBUG + if (p) { +#endif + { + struct ba_block_header * b = (struct ba_block_header*)ptr; + b->next = p->h.first; + p->h.first = b; +#ifdef PIKE_DEBUG + if (!p->h.used) { + fprintf(stderr, "freeing from empty page %p\n", p); + goto ERR; + } +#endif + if (!(--p->h.used) && i+1 == a->size) { + while (i >= 0 && !(p->h.used)) { + free(p); + a->pages[i] = NULL; + + p = a->pages[--i]; + } + a->size = i+1; + a->alloc = a->last_free = MAXIMUM(0, i); + } + } +#ifdef PIKE_DEBUG + } else { + int i; +ERR: + for (i = a->size-1, l = ba_get_layout(a, i); i >= 0; ba_half_layout(&l), i--) { + p = a->pages[i]; + fprintf(stderr, "page: %p used: %u/%u last: %p p+offset: %p\n", a->pages[i], + p->h.used, l.blocks, + BA_BLOCKN(l, p, l.blocks-1), BA_LASTBLOCK(l, p)); + } + Pike_fatal("ptr %p not in any page.\n", ptr); + } +#endif +} diff --git a/src/block_allocator.h b/src/block_allocator.h new file mode 100644 index 0000000000000000000000000000000000000000..9c0d27d3b8e286d28e53ddc1f6ff3c226035f661 --- /dev/null +++ b/src/block_allocator.h @@ -0,0 +1,60 @@ +#ifndef BLOCK_ALLOCATOR_H +#define BLOCK_ALLOCATOR_H + +#include "global.h" +#include "pike_error.h" +#include "pike_memory.h" +#include "pike_int_types.h" + +struct ba_layout { + unsigned INT32 offset; + unsigned INT32 block_size; + unsigned INT32 blocks; +}; + +#define BA_LAYOUT_INIT(block_size, blocks) { 0, (block_size), (blocks) } + +struct ba_page_header { + struct ba_block_header * first; + unsigned INT32 used; +}; + +struct ba_page { + struct ba_page_header h; +}; + +struct block_allocator { + struct ba_layout l; + unsigned char size; + unsigned char last_free; + unsigned char alloc; + unsigned char __align; + /* + * This places an upper limit on the number of blocks + * and should be adjusted as needed. + * + * the formula is as follows: + * (initial_size << 24) - initial_size + * for example for short pike strings this means that at most + * 192 GB of short pike strings with shift width 0 can be allocated. + */ + struct ba_page * pages[24]; +}; + +#define BA_INIT(block_size, blocks) { \ + BA_LAYOUT_INIT(block_size, blocks), \ + 0, 0, 0, 0, \ + { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \ + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \ + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL } \ +} + +#define BA_INIT_PAGES(block_size, pages) BA_INIT(block_size, ((pages) * PIKE_MALLOC_PAGE_SIZE)/(block_size)) + +PMOD_EXPORT void ba_init(struct block_allocator * a, unsigned INT32 block_size, unsigned INT32 blocks); +ATTRIBUTE((malloc)) PMOD_EXPORT void * ba_alloc(struct block_allocator * a); +PMOD_EXPORT void ba_free(struct block_allocator * a, void * ptr); +PMOD_EXPORT void ba_destroy(struct block_allocator * a); +PMOD_EXPORT size_t ba_count(const struct block_allocator * a); +PMOD_EXPORT void ba_count_all(const struct block_allocator * a, size_t * num, size_t * size); +#endif diff --git a/src/builtin.cmod b/src/builtin.cmod index 841e63f813d521f6257dcb97eb5c786852a96d97..a159721b6b7d207d09d1a161cc967cb50ce390de 100644 --- a/src/builtin.cmod +++ b/src/builtin.cmod @@ -28,7 +28,7 @@ #include "fsort.h" #include "port.h" #include "gc.h" -#include "block_alloc.h" +#include "block_allocator.h" #include "pikecode.h" #include "opcodes.h" @@ -4142,31 +4142,36 @@ PIKEFUN array __automap__(mixed fun, mixed ... tmpargs) /* Linked list stuff. */ -#undef INIT_BLOCK -#define INIT_BLOCK(NODE) do { \ - (NODE)->next = (NODE)->prev = NULL; \ - (NODE)->refs = 1; \ - SET_SVAL((NODE)->val, T_INT, NUMBER_UNDEFINED, \ - integer, 0); \ - } while(0) - -#undef EXIT_BLOCK -#define EXIT_BLOCK(NODE) do { \ - if ((NODE)->prev) { \ - free_list_node((NODE)->prev); \ - } \ - if ((NODE)->next) { \ - free_list_node((NODE)->next); \ - } \ - free_svalue(&(NODE)->val); \ - } while(0) - -BLOCK_ALLOC_FILL_PAGES(pike_list_node, 4); +static struct block_allocator pike_list_node_allocator = BA_INIT_PAGES(sizeof(struct pike_list_node), 4); + +ATTRIBUTE((malloc)) +static struct pike_list_node * alloc_pike_list_node() { + struct pike_list_node * node = ba_alloc(&pike_list_node_allocator); + node->next = node->prev = NULL; + node->refs = 1; + SET_SVAL(node->val, T_INT, NUMBER_UNDEFINED, integer, 0); + return node; +} + +void count_memory_in_pike_list_nodes(size_t * n, size_t * s) { + ba_count_all(&pike_list_node_allocator, n, s); +} + +void free_all_pike_list_node_blocks() { + ba_destroy(&pike_list_node_allocator); +} PMOD_EXPORT void free_list_node(struct pike_list_node *node) { if (!sub_ref(node)) { - really_free_pike_list_node(node); + if (node->prev) { + free_list_node(node->prev); + } + if (node->next) { + free_list_node(node->next); + } + free_svalue(&node->val); + ba_free(&pike_list_node_allocator, node); } } @@ -5760,7 +5765,6 @@ PIKECLASS __Backtrace_Tester__ void init_builtin(void) { - init_pike_list_node_blocks(); INIT } @@ -5773,7 +5777,7 @@ void exit_builtin(void) * in this case, so that the pike_list_node's are valid at cleanup * time, thus avoiding "got invalid pointer" fatals at exit. */ - free_all_pike_list_node_blocks(); + ba_destroy(&pike_list_node_allocator); #endif #ifndef USE_SETENV if (env_allocs) free_mapping (env_allocs); diff --git a/src/builtin_functions.h b/src/builtin_functions.h index be92d4a2e04542163744ce68c4067360b7c6b6e3..c8658d253fd5c3f32c8d4be24eb29dbceab9754f 100644 --- a/src/builtin_functions.h +++ b/src/builtin_functions.h @@ -10,7 +10,6 @@ #define TYPEP(ID,NAME,TYPE) PMOD_EXPORT void ID(INT32 args); #include "callback.h" -#include "block_alloc_h.h" /* Weak flags for arrays, multisets and mappings. 1 is avoided for * compatibility reasons. */ @@ -207,7 +206,8 @@ struct pike_list_node struct pike_list_node *prev; struct svalue val; }; -BLOCK_ALLOC_FILL_PAGES(pike_list_node, 4); +void count_memory_in_pike_list_nodes(size_t * n, size_t * s); +void free_all_pike_list_node_blocks(); PMOD_EXPORT void free_list_node(struct pike_list_node *node); PMOD_EXPORT void unlink_list_node(struct pike_list_node *n); PMOD_EXPORT void prepend_list_node(struct pike_list_node *node, diff --git a/src/callback.c b/src/callback.c index 7f4f720cc5f93c17b0ece4033fdcfc6ab88601ba..de977cd69a01d11427568b110ed23e33436ea3a4 100644 --- a/src/callback.c +++ b/src/callback.c @@ -35,7 +35,14 @@ struct callback #define PRE_INIT_BLOCK(X) X->free_func=(callback_func)remove_callback; #endif #endif -BLOCK_ALLOC(callback, CALLBACK_CHUNK) + +#include "block_allocator.h" +static struct block_allocator callback_allocator + = BA_INIT(sizeof(struct callback), CALLBACK_CHUNK); + +void count_memory_in_callbacks(size_t * num, size_t * size) { + ba_count_all(&callback_allocator, num, size); +} #ifdef PIKE_DEBUG @@ -53,7 +60,7 @@ static int is_in_free_list(struct callback * c) if ((bar->x <= c) && ((c - bar->x) < CALLBACK_CHUNK)) { struct callback *foo; for (foo = bar->free_callbacks; foo; - foo = (void *)foo->BLOCK_ALLOC_NEXT) { + foo = (void *)foo->next) { if (foo == c) return 1; } return 0; @@ -191,7 +198,7 @@ PMOD_EXPORT void low_call_callback(struct callback_list *lst, void *arg) l->free_func=(callback_func)remove_callback; #endif #endif - really_free_callback(l); + ba_free(&callback_allocator, l); }else{ ptr=& l->next; } @@ -206,7 +213,7 @@ PMOD_EXPORT struct callback *debug_add_to_callback(struct callback_list *lst, callback_func free_func) { struct callback *l; - l=alloc_callback(); + l=(struct callback*)ba_alloc(&callback_allocator); l->call=call; l->arg=arg; l->free_func=free_func; @@ -246,11 +253,11 @@ void free_callback_list(struct callback_list *lst) if(l->free_func) l->free_func(l, l->arg, 0); *ptr=l->next; - really_free_callback(l); + ba_free(&callback_allocator, l); } } void cleanup_callbacks(void) { - free_all_callback_blocks(); + ba_destroy(&callback_allocator); } diff --git a/src/callback.h b/src/callback.h index a04f1b2e8a6ef9356460d0b53bd85eae61f824cd..34138348a358df199fd68177084a09b6132ad512 100644 --- a/src/callback.h +++ b/src/callback.h @@ -21,10 +21,7 @@ extern struct callback_list fork_child_callback; typedef void (*callback_func)(struct callback *, void *,void *); -#include "block_alloc_h.h" /* Prototypes begin here */ -struct callback; -BLOCK_ALLOC(callback, CALLBACK_CHUNK); PMOD_EXPORT void low_call_callback(struct callback_list *lst, void *arg); PMOD_EXPORT struct callback *debug_add_to_callback(struct callback_list *lst, callback_func call, diff --git a/src/configure.in b/src/configure.in index 24e2e689c35814984754e2176b9b7e483a1257d6..0f6c4e6aad5f35cc0dde6b6a2b62dffe8ff97560 100644 --- a/src/configure.in +++ b/src/configure.in @@ -2474,6 +2474,67 @@ if test "x$pike_cv_sys_have_crc_intrinsics" = "xyes" ; then AC_DEFINE(HAVE_CRC32_INTRINSICS,[], [True if crc32 intrinsics are available]) fi +# test for several buildins + +define(TEST_BUILTIN, [ + AC_MSG_CHECKING(for $1) + AC_TRY_RUN([ +$3 +unsigned long lint; +int main(int argc, char **argv) { + static volatile int foo = 0; + foo = (int)$1($2); + return 0; +} + ], + AC_MSG_RESULT(yes) + AC_DEFINE(translit([HAS_$1], [a-z], [A-Z]), 1, [Whether $1 is available]) + , + AC_MSG_RESULT(no) + ) +]) + +# GCC builtins +TEST_BUILTIN(__builtin_clz, 23) +TEST_BUILTIN(__builtin_clzl, 23) +TEST_BUILTIN(__builtin_clzll, 23) +TEST_BUILTIN(__builtin_ctz, 23) +TEST_BUILTIN(__builtin_ctzl, 23) +TEST_BUILTIN(__builtin_ctzll, 23) +TEST_BUILTIN(__builtin_bswap32, 23) +TEST_BUILTIN(__builtin_bswap64, 23) +TEST_BUILTIN(__builtin_expect, [argc,0]) +# ICC builtins +TEST_BUILTIN(_bswap, 23) +TEST_BUILTIN(_bswap64, 23) +TEST_BUILTIN(_bit_scan_reverse, 23) +TEST_BUILTIN(_bit_scan_forward, 23) +# Visual Studio builtins +TEST_BUILTIN(_BitScanForward, [&lint, 23], [ + #include <intrin.h> +]) +TEST_BUILTIN(_BitScanForward64, [&lint, 23], [ + #include <intrin.h> +]) +TEST_BUILTIN(_BitScanReverse, [&lint, 23], [ + #include <intrin.h> +]) +TEST_BUILTIN(_BitScanReverse64, [&lint, 23], [ + #include <intrin.h> +]) +TEST_BUILTIN(_byteswap_ulong, 23, [ + #include <stdlib.h> +]) +TEST_BUILTIN(_byteswap_uint64, 23, [ + #include <stdlib.h> +]) +# IBM C builtins +TEST_BUILTIN(__cntlz4, 23) +TEST_BUILTIN(__cntlz8, 23) +TEST_BUILTIN(__cnttz4, 23) +TEST_BUILTIN(__cnttz8, 23) + + ############################################################################# # Script to translate from POSIX paths to native paths. diff --git a/src/constants.c b/src/constants.c index a7663026176b9f0934e02ff0d3816fc4a3f22460..7d89182fc9c15647a7dd78325ecaf50d7a4f1d4c 100644 --- a/src/constants.c +++ b/src/constants.c @@ -68,11 +68,6 @@ PMOD_EXPORT void add_global_program(const char *name, struct program *p) low_add_constant(name, p?&s:NULL); } -#undef INIT_BLOCK -#define INIT_BLOCK(X) do { \ - DO_IF_DEBUG (DOUBLELINK (first_callable, X)); \ - } while (0) - #undef EXIT_BLOCK #define EXIT_BLOCK(X) do { \ DO_IF_DEBUG (DOUBLEUNLINK (first_callable, X)); \ @@ -82,7 +77,20 @@ PMOD_EXPORT void add_global_program(const char *name, struct program *p) EXIT_PIKE_MEMOBJ(X); \ }while(0) -BLOCK_ALLOC_FILL_PAGES(callable,2) +#include "block_allocator.h" +static struct block_allocator callable_allocator + = BA_INIT_PAGES(sizeof(struct callable), 2); + +void really_free_callable(struct callable * c) { + EXIT_BLOCK(c); + ba_free(&callable_allocator, c); +} +void count_memory_in_callables(size_t * num, size_t * size) { + ba_count_all(&callable_allocator, num, size); +} +void free_all_callable_blocks() { + ba_destroy(&callable_allocator); +} int global_callable_flags=0; @@ -94,7 +102,10 @@ PMOD_EXPORT struct callable *low_make_callable(c_fun fun, optimize_fun optimize, docode_fun docode) { - struct callable *f=alloc_callable(); + struct callable *f=(struct callable*)ba_alloc(&callable_allocator); +#ifdef PIKE_DEBUG + DOUBLELINK(first_callable, f); +#endif INIT_PIKE_MEMOBJ(f, T_STRUCT_CALLABLE); f->function=fun; f->name=name; @@ -213,17 +224,9 @@ PMOD_EXPORT void visit_callable (struct callable *c, int action) #ifdef PIKE_DEBUG void present_constant_profiling(void) { - struct callable_block *b; - size_t e; - for(b=callable_blocks;b;b=b->next) - { - for(e=0;e<NELEM(b->x);e++) - { - if(b->x[e].name) - { - fprintf(stderr,"%010ld @E@: %s\n",b->x[e].runs, b->x[e].name->str); - } - } + struct callable *c; + for (c = first_callable; c; c = c->next) { + fprintf(stderr,"%010ld @E@: %s\n",c->runs, c->name->str); } } #endif diff --git a/src/constants.h b/src/constants.h index 6c894b1a694371059e46199a02a9c9d3ec471d49..d9ffdcdbad41cf7c39ba8d8dc3c0f1a4bed7b63c 100644 --- a/src/constants.h +++ b/src/constants.h @@ -48,7 +48,9 @@ void low_add_efun(struct pike_string *name, struct svalue *fun); void low_add_constant(const char *name, struct svalue *fun); void add_pike_string_constant(const char *name, const char *str, int len); PMOD_EXPORT void add_global_program(const char *name, struct program *p); -BLOCK_ALLOC_FILL_PAGES(callable,2); +void really_free_callable(struct callable * c); +void count_memory_in_callables(size_t * num, size_t * size); +void free_all_callable_blocks(); PMOD_EXPORT struct callable *low_make_callable(c_fun fun, struct pike_string *name, struct pike_type *type, diff --git a/src/gc.c b/src/gc.c index d8cc7c206749d73a4def428bb36440cf2a85268d..c2d1459eee0d7010b5b049cff3402454a11b6e2a 100644 --- a/src/gc.c +++ b/src/gc.c @@ -27,6 +27,7 @@ struct callback *gc_evaluator_callback=0; #include "pike_threadlib.h" #include "gc.h" #include "main.h" +#include "block_allocator.h" #include <math.h> @@ -420,25 +421,25 @@ static unsigned rec_frames, link_frames, free_extra_frames; static unsigned max_rec_frames, max_link_frames; static unsigned tot_max_rec_frames = 0, tot_max_link_frames = 0, tot_max_free_extra_frames = 0; -#undef INIT_BLOCK -#define INIT_BLOCK(f) do { \ - if (++rec_frames > max_rec_frames) \ - max_rec_frames = rec_frames; \ - } while (0) -#undef EXIT_BLOCK -#define EXIT_BLOCK(f) do { \ - DO_IF_DEBUG ({ \ - if (f->rf_flags & GC_FRAME_FREED) \ - gc_fatal (f->data, 0, "Freeing gc_rec_frame twice.\n"); \ - f->rf_flags |= GC_FRAME_FREED; \ - f->u.link_top = (struct link_frame *) (ptrdiff_t) -1; \ - f->prev = f->next = f->cycle_id = f->cycle_piece = \ - (struct gc_rec_frame *) (ptrdiff_t) -1; \ - }); \ - rec_frames--; \ - } while (0) +struct block_allocator gc_rec_frame_allocator = + BA_INIT_PAGES(sizeof(struct gc_rec_frame), 2); -BLOCK_ALLOC_FILL_PAGES (gc_rec_frame, 2) +static void really_free_gc_rec_frame(struct gc_rec_frame * f) { +#ifdef PIKE_DEBUG + if (f->rf_flags & GC_FRAME_FREED) + gc_fatal (f->data, 0, "Freeing gc_rec_frame twice.\n"); + f->rf_flags |= GC_FRAME_FREED; + f->u.link_top = (struct link_frame *) (ptrdiff_t) -1; + f->prev = f->next = f->cycle_id = f->cycle_piece = + (struct gc_rec_frame *) (ptrdiff_t) -1; +#endif + rec_frames--; + ba_free(&gc_rec_frame_allocator, f); +} + +void count_memory_in_gc_rec_frames(size_t *num, size_t * size) { + ba_count_all(&gc_rec_frame_allocator, num, size); +} /* Link and free_extra frames are approximately the same size, so let * them share block_alloc area. */ @@ -451,18 +452,16 @@ struct ba_mixed_frame } u; }; -#undef BLOCK_ALLOC_NEXT -#define BLOCK_ALLOC_NEXT u.next -#undef INIT_BLOCK -#define INIT_BLOCK(f) -#undef EXIT_BLOCK -#define EXIT_BLOCK(f) +static struct block_allocator ba_mixed_frame_allocator + = BA_INIT_PAGES(sizeof(struct ba_mixed_frame), 2); -BLOCK_ALLOC_FILL_PAGES (ba_mixed_frame, 2) +void count_memory_in_ba_mixed_frames(size_t *num, size_t * size) { + ba_count_all(&ba_mixed_frame_allocator, num, size); +} static INLINE struct link_frame *alloc_link_frame() { - struct ba_mixed_frame *f = alloc_ba_mixed_frame(); + struct ba_mixed_frame *f = ba_alloc(&ba_mixed_frame_allocator); if (++link_frames > max_link_frames) max_link_frames = link_frames; return (struct link_frame *) f; @@ -470,7 +469,7 @@ static INLINE struct link_frame *alloc_link_frame() static INLINE struct free_extra_frame *alloc_free_extra_frame() { - struct ba_mixed_frame *f = alloc_ba_mixed_frame(); + struct ba_mixed_frame *f = ba_alloc(&ba_mixed_frame_allocator); free_extra_frames++; return (struct free_extra_frame *) f; } @@ -478,13 +477,13 @@ static INLINE struct free_extra_frame *alloc_free_extra_frame() static INLINE void really_free_link_frame (struct link_frame *f) { link_frames--; - really_free_ba_mixed_frame ((struct ba_mixed_frame *) f); + ba_free(&ba_mixed_frame_allocator, f); } static INLINE void really_free_free_extra_frame (struct free_extra_frame *f) { free_extra_frames--; - really_free_ba_mixed_frame ((struct ba_mixed_frame *) f); + ba_free(&ba_mixed_frame_allocator, f); } /* These are only collected for the sake of gc_status. */ @@ -522,6 +521,8 @@ static void gc_cycle_pop(); (X)->flags=(X)->refs=(X)->weak_refs=0; \ (X)->frame = 0; #endif +#undef EXIT_BLOCK +#define EXIT_BLOCK(f) #undef get_marker #define get_marker debug_get_marker @@ -574,7 +575,7 @@ static void describe_rec_stack (struct gc_rec_frame *p1, const char *p1_name, struct gc_rec_frame *p3, const char *p3_name) { struct gc_rec_frame *l, *cp; - size_t longest; + size_t longest = 0; if (p1) longest = strlen (p1_name); if (p2) {size_t l = strlen (p2_name); if (l > longest) longest = l;} @@ -2039,8 +2040,8 @@ void exit_gc(void) if (!gc_keep_markers) cleanup_markers(); - free_all_gc_rec_frame_blocks(); - free_all_ba_mixed_frame_blocks(); + ba_destroy(&gc_rec_frame_allocator); + ba_destroy(&ba_mixed_frame_allocator); #ifdef PIKE_DEBUG if (gc_is_watching) { @@ -2347,7 +2348,7 @@ static void check_rec_stack (struct gc_rec_frame *p1, const char *p1n, /* This debug check is disabled during the final cleanup since this * is O(n^2) on the stack size, and the stack gets a lot larger then. */ if (gc_debug && !gc_destruct_everything) { - struct gc_rec_frame *l, *last_cycle_id; + struct gc_rec_frame *l, *last_cycle_id = NULL; for (l = &sentinel_frame; l != stack_top;) { l = l->next; check_rec_stack_frame (l, p1, p1n, p2, p2n, file, line); @@ -2636,7 +2637,9 @@ PMOD_EXPORT void gc_cycle_enqueue(gc_cycle_check_cb *checkfn, void *data, int we static struct gc_rec_frame *gc_cycle_enqueue_rec (void *data) { - struct gc_rec_frame *r = alloc_gc_rec_frame(); + struct gc_rec_frame *r = + (struct gc_rec_frame*)ba_alloc(&gc_rec_frame_allocator); + if (++rec_frames > max_rec_frames) max_rec_frames = rec_frames; #ifdef PIKE_DEBUG if (Pike_in_gc != GC_PASS_CYCLE) gc_fatal(data, 0, "Use of the gc frame stack outside the cycle check pass.\n"); diff --git a/src/las.c b/src/las.c index be3d32e22f0bc30a9738faf962c2daf27dc47cbb..2d204d16d28eb10ad289f9dc2a481d9f99a36e3f 100644 --- a/src/las.c +++ b/src/las.c @@ -404,13 +404,11 @@ static int check_node_type(node *n, struct pike_type *t, const char *msg) #undef PRE_INIT_BLOCK #define PRE_INIT_BLOCK(NODE) do { \ - NODE->token = USHRT_MAX; \ + (NODE)->token = USHRT_MAX; \ } while (0) BLOCK_ALLOC_FILL_PAGES(node_s, 2) -#define NODES (sizeof (((struct node_s_block *) NULL)->x) / sizeof (struct node_s)) - #undef BLOCK_ALLOC_NEXT #define BLOCK_ALLOC_NEXT next @@ -419,32 +417,15 @@ void free_all_nodes(void) if(!Pike_compiler->previous) { node *tmp; - struct node_s_block *tmp2; - size_t e=0; #ifndef PIKE_DEBUG - if(cumulative_parse_error) - { + if(cumulative_parse_error) { +#else + size_t e=0, s=0; + count_memory_in_node_ss(&e, &s); + if(e) { #endif - - for(tmp2=node_s_blocks;tmp2;tmp2=tmp2->next) e+=tmp2->used; - if(e) - { - size_t e2=e; - struct node_s_block *nextblk; - for(tmp2=node_s_blocks;tmp2;tmp2=nextblk) - { - int n = tmp2->used; - nextblk = tmp2->next; - /* We want to be able to access the token field of all - * the blocks... - */ - PIKE_MEM_RW(tmp2->x); - for(e=0;n && e<NODES;e++) - { - if (tmp2->x[e].token != USHRT_MAX) - { - tmp=tmp2->x+e; + WALK_NONFREE_BLOCKS(node_s, tmp, tmp->token != USHRT_MAX, { #ifdef PIKE_DEBUG if(!cumulative_parse_error) { @@ -475,17 +456,13 @@ void free_all_nodes(void) tmp->refs = 1; debug_malloc_touch(tmp->type); free_node(tmp); - --n; } - } - } - } + }); #ifdef PIKE_DEBUG if(!cumulative_parse_error) - Pike_fatal("Failed to free %"PRINTSIZET"d nodes when compiling!\n",e2); -#endif + Pike_fatal("Failed to free %"PRINTSIZET"d nodes when compiling!\n",e); } -#ifndef PIKE_DEBUG +#else } #endif free_all_node_s_blocks(); diff --git a/src/mapping.c b/src/mapping.c index 33cb343baaae89cd52222a72b5f6389cdc3df3e8..43afd10c8e47790b1ae734a427af5438bb61d9d8 100644 --- a/src/mapping.c +++ b/src/mapping.c @@ -20,7 +20,7 @@ #include "gc.h" #include "stralloc.h" #include "pike_security.h" -#include "block_alloc.h" +#include "block_allocator.h" #include "opcodes.h" #include "stuff.h" @@ -42,39 +42,41 @@ static struct mapping *gc_mark_mapping_pos = 0; #define MAPPING_DATA_SIZE(HSIZE, KEYPAIRS) \ PTR_TO_INT(MD_KEYPAIRS(0, HSIZE) + KEYPAIRS) -#undef EXIT_BLOCK -#define EXIT_BLOCK(m) do{ \ -DO_IF_DEBUG( \ - if(m->refs) { \ - DO_IF_DMALLOC(describe_something(m, T_MAPPING, 0,2,0, NULL)); \ - Pike_fatal("really free mapping on mapping with %d refs.\n", m->refs); \ - } \ -) \ - \ - FREE_PROT(m); \ - \ - unlink_mapping_data(m->data); \ - \ - DOUBLEUNLINK(first_mapping, m); \ - \ - GC_FREE(m); \ -}while(0) - +static struct block_allocator mapping_allocator = BA_INIT_PAGES(sizeof(struct mapping), 2); +void count_memory_in_mappings(size_t * num, size_t * size) { + struct mapping *m; + double datasize = 0.0; + ba_count_all(&mapping_allocator, num, size); + for(m=first_mapping;m;m=m->next) { + datasize+=MAPPING_DATA_SIZE(m->data->hashsize, m->data->num_keypairs) / (double) m->data->refs; + } + *size += (size_t) datasize; +} -#undef COUNT_OTHER +void really_free_mapping(struct mapping * m) { +#ifdef PIKE_DEBUG + if (m->refs) { +# ifdef DEBUG_MALLOC + describe_something(m, T_MAPPING, 0,2,0, NULL); +# endif + Pike_fatal("really free mapping on mapping with %d refs.\n", m->refs); + } +#endif + FREE_PROT(m); + unlink_mapping_data(m->data); + DOUBLEUNLINK(first_mapping, m); + GC_FREE(m); + ba_free(&mapping_allocator, m); +} -#define COUNT_OTHER() do{ \ - struct mapping *m; \ - double datasize = 0.0; \ - for(m=first_mapping;m;m=m->next) \ - { \ - datasize+=MAPPING_DATA_SIZE(m->data->hashsize, m->data->num_keypairs) / \ - (double) m->data->refs; \ - } \ - size += (size_t) datasize; \ -}while(0) +ATTRIBUTE((malloc)) +static struct mapping * alloc_mapping() { + return ba_alloc(&mapping_allocator); +} -BLOCK_ALLOC_FILL_PAGES(mapping, 2) +void free_all_mapping_blocks() { + ba_destroy(&mapping_allocator); +} #ifndef PIKE_MAPPING_KEYPAIR_LOOP #define IF_ELSE_KEYPAIR_LOOP(X, Y) Y diff --git a/src/mapping.h b/src/mapping.h index 207e394c45979fc793cff6c24ebb26bf4452e138..c244a1a28f09e73f861eb8872f17804d31639d4a 100644 --- a/src/mapping.h +++ b/src/mapping.h @@ -9,7 +9,6 @@ #include "svalue.h" #include "dmalloc.h" -#include "block_alloc_h.h" /* Compatible with PIKE_WEAK_INDICES and PIKE_WEAK_VALUES. */ #define MAPPING_WEAK_INDICES 2 @@ -133,8 +132,8 @@ PMOD_EXPORT void really_free_mapping(struct mapping *md); }while(0) /* Prototypes begin here */ -BLOCK_ALLOC_FILL_PAGES(mapping, 2); - +void really_free_mapping(struct mapping * m); +void count_memory_in_mappings(size_t * num, size_t * size); @@ -387,6 +386,8 @@ void simple_describe_mapping(struct mapping *m); void debug_dump_mapping(struct mapping *m); int mapping_is_constant(struct mapping *m, struct processing *p); +void free_all_mapping_blocks(); + /* Prototypes end here */ #define allocate_mapping(X) dmalloc_touch(struct mapping *,debug_allocate_mapping(X)) diff --git a/src/modules/Parser/html.c b/src/modules/Parser/html.c index b9499428111eb2ff90191568bc6c9c558790b08e..a0d2544649c25dc67ac031d716e08fc9427ea4cc 100644 --- a/src/modules/Parser/html.c +++ b/src/modules/Parser/html.c @@ -88,12 +88,21 @@ struct piece struct piece *next; }; -#undef INIT_BLOCK -#define INIT_BLOCK(p) p->next = NULL; -#undef EXIT_BLOCK -#define EXIT_BLOCK(p) free_string (p->s); +#include "block_allocator.h" -BLOCK_ALLOC_FILL_PAGES (piece, 2); +static struct block_allocator piece_allocator + = BA_INIT_PAGES(sizeof(struct piece), 2); + +static INLINE struct piece * alloc_piece() { + struct piece * p = ba_alloc(&piece_allocator); + p->next = NULL; + return p; +} + +static INLINE void really_free_piece(struct piece * p) { + free_string(p->s); + ba_free(&piece_allocator, p); +} struct out_piece { @@ -101,12 +110,18 @@ struct out_piece struct out_piece *next; }; -#undef INIT_BLOCK -#define INIT_BLOCK(p) p->next = NULL -#undef EXIT_BLOCK -#define EXIT_BLOCK(p) free_svalue (&p->v) +static struct block_allocator out_piece_allocator + = BA_INIT_PAGES(sizeof(struct out_piece), 2); -BLOCK_ALLOC_FILL_PAGES (out_piece, 2); +static INLINE struct out_piece * alloc_out_piece() { + struct out_piece * p = ba_alloc(&out_piece_allocator); + p->next = NULL; + return p; +} +static INLINE void really_free_out_piece(struct out_piece * p) { + free_svalue(&p->v); + ba_free(&out_piece_allocator, p); +} struct feed_stack { @@ -128,20 +143,21 @@ struct feed_stack struct location pos; }; -#undef BLOCK_ALLOC_NEXT -#define BLOCK_ALLOC_NEXT prev -#undef INIT_BLOCK -#define INIT_BLOCK(p) p->local_feed = NULL; -#undef EXIT_BLOCK -#define EXIT_BLOCK(p) \ - while (p->local_feed) \ - { \ - struct piece *f=p->local_feed; \ - p->local_feed=f->next; \ - really_free_piece (f); \ - } - -BLOCK_ALLOC (feed_stack, 1); +static struct block_allocator feed_stack_allocator + = BA_INIT_PAGES(sizeof(struct feed_stack), 1); +static INLINE struct feed_stack * alloc_feed_stack() { + struct feed_stack * p = ba_alloc(&feed_stack_allocator); + p->local_feed = NULL; + return p; +} +static INLINE void really_free_feed_stack(struct feed_stack * p) { + while (p->local_feed) { + struct piece *f=p->local_feed; + p->local_feed=f->next; + really_free_piece (f); + } + ba_free(&feed_stack_allocator, p); +} enum types { TYPE_TAG, /* empty tag callback */ @@ -5310,9 +5326,6 @@ static void html_ignore_comments(INT32 args) void init_parser_html(void) { size_t offset; - init_piece_blocks(); - init_out_piece_blocks(); - init_feed_stack_blocks(); offset = ADD_STORAGE(struct parser_html_storage); @@ -5491,9 +5504,9 @@ void init_parser_html(void) void exit_parser_html() { - free_all_piece_blocks(); - free_all_out_piece_blocks(); - free_all_feed_stack_blocks(); + ba_destroy(&piece_allocator); + ba_destroy(&out_piece_allocator); + ba_destroy(&feed_stack_allocator); exit_calc_chars(); } diff --git a/src/modules/Parser/xml.cmod b/src/modules/Parser/xml.cmod index cd2e07ae4b91a598b2aa8a4286af326d5d3ef27c..869d9af85aa800d9811208cc13f9b7a707d9fcf5 100644 --- a/src/modules/Parser/xml.cmod +++ b/src/modules/Parser/xml.cmod @@ -22,7 +22,7 @@ #include "operators.h" #include "pike_error.h" #include "bignum.h" -#include "block_alloc.h" +#include "block_allocator.h" #define sp Pike_sp @@ -660,15 +660,20 @@ PIKECLASS Simple struct pike_string *entity; }; -#undef INIT_BLOCK -#define INIT_BLOCK(X) do { \ - (X)->next = NULL; \ - (X)->callbackinfo = NULL; \ - (X)->to_free = NULL; \ - (X)->entity = NULL; \ - } while(0) + static struct block_allocator xmlinput_allocator = BA_INIT(sizeof(struct xmlinput), 64); - BLOCK_ALLOC(xmlinput, 64) + static struct xmlinput * alloc_xmlinput() { + struct xmlinput * i = ba_alloc(&xmlinput_allocator); + i->next = NULL; + i->callbackinfo = NULL; + i->to_free = NULL; + i->entity = NULL; + return i; + } + + static void really_free_xmlinput(struct xmlinput * i) { + ba_free(&xmlinput_allocator, i); + } struct xmlinput *new_string_xmlinput(struct pike_string *s) { @@ -3482,7 +3487,6 @@ PIKEFUN string autoconvert(string s) void init_parser_xml(void) { - init_xmlinput_blocks(); push_text("location"); location_string_svalue=sp[-1]; sp--; @@ -3506,6 +3510,6 @@ void exit_parser_xml(void) { EXIT; - free_all_xmlinput_blocks(); + ba_destroy(&xmlinput_allocator); free_svalue(&location_string_svalue); } diff --git a/src/multiset.c b/src/multiset.c index 35555b33c5b9fbc444cf2956cbb1dd3d19cd1570..4de7b3ba04253c331e64f0c00a7bbf5665b4c486 100644 --- a/src/multiset.c +++ b/src/multiset.c @@ -29,7 +29,7 @@ #include "mapping.h" #endif -#include "block_alloc.h" +#include "block_allocator.h" /* FIXME: Optimize finds and searches on type fields? (But not when * objects are involved!) Well.. Although cheap I suspect it pays off @@ -252,37 +252,43 @@ void free_multiset_data (struct multiset_data *msd); } while (0) #endif -#undef EXIT_BLOCK -#define EXIT_BLOCK(L) do { \ - FREE_PROT (L); \ - DO_IF_DEBUG ( \ - if (L->refs) { \ - DO_IF_DMALLOC(describe_something (L, T_MULTISET, 0,2,0, NULL)); \ - Pike_fatal ("Too few refs %d to multiset.\n", L->refs); \ - } \ - if (L->node_refs) { \ - DO_IF_DMALLOC(describe_something (L, T_MULTISET, 0,2,0, NULL)); \ - Pike_fatal ("Freeing multiset with %d node refs.\n", L->node_refs); \ - } \ - ); \ - if (!sub_ref (L->msd)) free_multiset_data (L->msd); \ - DOUBLEUNLINK (first_multiset, L); \ - GC_FREE (L); \ - } while (0) +static struct block_allocator multiset_allocator = BA_INIT_PAGES(sizeof(struct multiset), 2); -#undef COUNT_OTHER -#define COUNT_OTHER() do { \ - struct multiset *l; \ - double datasize = 0.0; \ - for (l = first_multiset; l; l = l->next) \ - datasize += (l->msd->flags & MULTISET_INDVAL ? \ - NODE_OFFSET (msnode_indval, l->msd->allocsize) : \ - NODE_OFFSET (msnode_ind, l->msd->allocsize)) / \ - (double) l->msd->refs; \ - size += (size_t) datasize; \ - } while (0) +PMOD_EXPORT void really_free_multiset (struct multiset *l) { + FREE_PROT (l); +#ifdef PIKE_DEBUG + if (l->refs) { +# if DEBUG_MALLOC + describe_something (l, T_MULTISET, 0,2,0, NULL); +# endif + Pike_fatal ("Too few refs %d to multiset.n", l->refs); + } + if (l->node_refs) { +# if DEBUG_MALLOC + describe_something (l, T_MULTISET, 0,2,0, NULL); +# endif + Pike_fatal ("Freeing multiset with %d node refs.n", l->node_refs); + } +#endif + if (!sub_ref (l->msd)) free_multiset_data (l->msd); + DOUBLEUNLINK (first_multiset, l); + GC_FREE (l); + ba_free(&multiset_allocator, l); +} -BLOCK_ALLOC_FILL_PAGES (multiset, 2) +PMOD_EXPORT void count_memory_in_multisets (size_t * n, size_t * s) { + struct multiset *l; + double datasize = 0.0; + + ba_count_all(&multiset_allocator, n, s); + + for (l = first_multiset; l; l = l->next) + datasize += (l->msd->flags & MULTISET_INDVAL ? + NODE_OFFSET (msnode_indval, l->msd->allocsize) : + NODE_OFFSET (msnode_ind, l->msd->allocsize)) / + (double) l->msd->refs; + *s += (size_t) datasize; +} /* Note: The returned block has no refs. */ #ifdef PIKE_DEBUG @@ -872,7 +878,7 @@ PMOD_EXPORT struct multiset *real_allocate_multiset (int allocsize, int flags, struct svalue *cmp_less) { - struct multiset *l = alloc_multiset(); + struct multiset *l = ba_alloc(&multiset_allocator); /* FIXME: There's currently little use in making "inflated" * multisets with allocsize, since prepare_for_add shrinks them. */ @@ -1285,7 +1291,7 @@ PMOD_EXPORT struct multiset *mkmultiset_2 (struct array *indices, fix_free_list (new.msd, indices->size); } - l = alloc_multiset(); + l = ba_alloc(&multiset_allocator); l->msd = new.msd; add_ref (new.msd); INIT_MULTISET (l); @@ -3389,7 +3395,7 @@ PMOD_EXPORT struct multiset *copy_multiset (struct multiset *l) struct multiset_data *msd = l->msd; debug_malloc_touch (l); debug_malloc_touch (msd); - l = alloc_multiset(); + l = ba_alloc(&multiset_allocator); INIT_MULTISET (l); add_ref (l->msd = msd); return l; @@ -4890,13 +4896,11 @@ void init_multiset() dmalloc_accept_leak (&empty_indval_msd); #endif - init_multiset_blocks(); } /* Pike might exit without calling this. */ void exit_multiset() { - free_all_multiset_blocks(); } #if defined (PIKE_DEBUG) || defined (TEST_MULTISET) diff --git a/src/multiset.h b/src/multiset.h index 983caf87fbd12a2cb14d8a6c0842166f6c4a2ccd..70fa1b83bfa99dcd98e99a368bf0ab883fbd94b4 100644 --- a/src/multiset.h +++ b/src/multiset.h @@ -17,7 +17,6 @@ #include "svalue.h" #include "dmalloc.h" #include "rbtree.h" -#include "block_alloc_h.h" /* Keep this defined so that code can test which multiset API is in use. */ #define PIKE_NEW_MULTISETS @@ -231,6 +230,7 @@ PMOD_EXPORT INT32 multiset_sizeof (struct multiset *l); #else PMOD_EXPORT void really_free_multiset (struct multiset *l); +PMOD_EXPORT void count_memory_in_multisets (size_t * n, size_t * s); #define free_multiset(L) do { \ struct multiset *_ms_ = (L); \ @@ -261,8 +261,6 @@ PMOD_EXPORT union msnode *debug_check_msnode ( #endif -BLOCK_ALLOC_FILL_PAGES (multiset, 2); - /* See rbtree.h for a description of the operations. * * If cmp_less is used, it's a function pointer used as `< to compare diff --git a/src/object.c b/src/object.c index 0b81ff5b5d1ebe425e86ca80a4d8d45a11a36ff0..1f0c30f4a63ae5070f4798d55db1edadbd59b57e 100644 --- a/src/object.c +++ b/src/object.c @@ -33,6 +33,7 @@ #include "operators.h" #include "block_alloc.h" +#include "block_allocator.h" #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> @@ -83,22 +84,35 @@ PMOD_EXPORT struct object *first_object; struct object *gc_internal_object = 0; static struct object *gc_mark_object_pos = 0; -#undef COUNT_OTHER - -#define COUNT_OTHER() do{ \ - struct object *o; \ - for(o=first_object;o;o=o->next) \ - if(o->prog) \ - size+=o->prog->storage_needed; \ - \ - for(o=objects_to_destruct;o;o=o->next) \ - if(o->prog) \ - size+=o->prog->storage_needed; \ -}while(0) -BLOCK_ALLOC_FILL_PAGES(object, 2) - -#undef COUNT_OTHER -#define COUNT_OTHER() +static struct block_allocator object_allocator = BA_INIT_PAGES(sizeof(struct object), 2); + +void count_memory_in_objects(size_t *_num, size_t *_size) { + size_t size; + struct object *o; + + ba_count_all(&object_allocator, _num, &size); + + for(o=first_object;o;o=o->next) + if(o->prog) + size+=o->prog->storage_needed; + for(o=objects_to_destruct;o;o=o->next) + if(o->prog) + size+=o->prog->storage_needed; + *_size = size; +} + +void really_free_object(struct object * o) { + ba_free(&object_allocator, o); +} + +ATTRIBUTE((malloc)) +struct object * alloc_object() { + return ba_alloc(&object_allocator); +} + +void free_all_object_blocks() { + ba_destroy(&object_allocator); +} PMOD_EXPORT struct object *low_clone(struct program *p) { diff --git a/src/object.h b/src/object.h index df0a26742bfc7e69f375bfa67703cab8a384cdd4..2d214113430a20586efab4d6dbe93233b4a485aa 100644 --- a/src/object.h +++ b/src/object.h @@ -74,8 +74,11 @@ enum object_destruct_reason { }; #include "block_alloc_h.h" -/* Prototypes begin here */ -BLOCK_ALLOC_FILL_PAGES(object, 2); + +ATTRIBUTE((malloc)) struct object * alloc_object(); +void really_free_object(struct object * o); +void count_memory_in_objects(size_t *_num, size_t *_size); +void free_all_object_blocks(); PMOD_EXPORT struct object *low_clone(struct program *p); PMOD_EXPORT void call_c_initializers(struct object *o); PMOD_EXPORT void call_prog_event(struct object *o, int event); diff --git a/src/pike_embed.c b/src/pike_embed.c index 797fc88b70ebebb3c3c9c66570767ea6f8fd40c5..b5fd0f305bd59d70168b5e686abb41b1d9c3412f 100644 --- a/src/pike_embed.c +++ b/src/pike_embed.c @@ -160,27 +160,8 @@ void init_pike(char **argv, const char *file) fd_init(); { - extern void init_mapping_blocks(void); - extern void init_callable_blocks(void); - extern void init_gc_rec_frame_blocks(void); - extern void init_ba_mixed_frame_blocks(void); - extern void init_pike_frame_blocks(void); extern void init_node_s_blocks(void); - extern void init_object_blocks(void); - extern void init_callback_blocks(void); - - init_mapping_blocks(); - init_callable_blocks(); - init_gc_rec_frame_blocks(); - init_ba_mixed_frame_blocks(); - /* init_catch_context_blocks(); */ - /* init_pike_frame_blocks(); */ init_node_s_blocks(); - init_object_blocks(); -#if !defined(DEBUG_MALLOC) || !defined(_REENTRANT) - /* This has already been done by initialize_dmalloc(). */ - init_callback_blocks(); -#endif /* !DEBUG_MALLOC */ init_multiset(); init_builtin_constants(); } diff --git a/src/pike_memory.c b/src/pike_memory.c index 17d84748dfbeac8aa4a40f084e395b5dd2867738..3cde906160665182a93485d80bf57ce1a943a399 100644 --- a/src/pike_memory.c +++ b/src/pike_memory.c @@ -2998,16 +2998,6 @@ static void initialize_dmalloc(void) mt_init(&debug_malloc_mutex); #endif - /* NOTE: th_atfork() may be a simulated function, which - * utilizes callbacks. We thus need to initialize - * the callback blocks before we perform the call - * to th_atfork(). - */ - { - extern void init_callback_blocks(void); - init_callback_blocks(); - } - th_atfork(lock_da_lock, unlock_da_lock, unlock_da_lock); #endif #ifdef DMALLOC_USING_DLOPEN diff --git a/src/pike_types.c b/src/pike_types.c index 67d24d33d65079c74882ef852d11d3b9d1f4a8c1..654d86a2e93a049868a00d7354f5ef29385d7047 100644 --- a/src/pike_types.c +++ b/src/pike_types.c @@ -27,7 +27,7 @@ #include "cyclic.h" #include "gc.h" #include "pike_compiler.h" -#include "block_alloc.h" +#include "block_allocator.h" #ifdef PIKE_DEBUG #define PIKE_TYPE_DEBUG @@ -277,8 +277,20 @@ static void internal_parse_type(const char **s); * a many argument just have a MANY node, and no FUNCTION node. * */ -#define PIKE_TYPE_CHUNK 128 -BLOCK_ALLOC(pike_type, PIKE_TYPE_CHUNK) +static struct block_allocator type_allocator = BA_INIT(sizeof(struct pike_type), 128); + +PMOD_EXPORT void really_free_pike_type(struct pike_type * t) { + ba_free(&type_allocator, t); +} + +ATTRIBUTE((malloc)) +PMOD_EXPORT struct pike_type * alloc_pike_type() { + return ba_alloc(&type_allocator); +} + +PMOD_EXPORT void count_memory_in_pike_types(size_t *n, size_t *s) { + ba_count_all(&type_allocator, n, s); +} struct pike_type **pike_type_hash = NULL; size_t pike_type_hash_size = 0; @@ -316,7 +328,7 @@ void debug_free_type(struct pike_type *t) cdr = t->cdr; type = t->type; - really_free_pike_type((struct pike_type *)debug_malloc_pass(t)); + really_free_pike_type((struct pike_type*)debug_malloc_pass(t)); /* FIXME: Recursion: Should we use a stack? */ switch(type) { @@ -558,7 +570,7 @@ static inline struct pike_type *debug_mk_type(unsigned INT32 type, } #endif - debug_malloc_pass(t = alloc_pike_type()); + debug_malloc_pass(t = ba_alloc(&type_allocator)); #ifdef ATOMIC_SVALUE t->ref_type = PIKE_T_TYPE; @@ -8564,7 +8576,6 @@ void init_types(void) (PIKE_TYPE_HASH_SIZE+1)); MEMSET(pike_type_hash, 0, sizeof(struct pike_type *) * (PIKE_TYPE_HASH_SIZE+1)); pike_type_hash_size = PIKE_TYPE_HASH_SIZE; - init_pike_type_blocks(); int_type_string = CONSTTYPE(tInt); /* MUST come before string! */ string0_type_string = CONSTTYPE(tStr0); @@ -8664,7 +8675,7 @@ void cleanup_pike_type_table(void) pike_type_hash_size = 0; #ifdef DO_PIKE_CLEANUP - free_all_pike_type_blocks(); + ba_destroy(&type_allocator); #endif /* DO_PIKE_CLEANUP */ } diff --git a/src/pike_types.h b/src/pike_types.h index d0e5995fc5c13a5254eda415388dc4d7c55a736e..311c1c0d060ee65a08d3de2505248230eb5d46c8 100644 --- a/src/pike_types.h +++ b/src/pike_types.h @@ -41,9 +41,6 @@ extern size_t pike_type_hash_size; #define CAR_TO_INT(TYPE) ((char *) (TYPE)->car - (char *) 0) #define CDR_TO_INT(TYPE) ((char *) (TYPE)->cdr - (char *) 0) -#include "block_alloc_h.h" -BLOCK_ALLOC(pike_type, n/a); - /* * pike_type flags: */ @@ -210,6 +207,9 @@ void debug_push_reverse_type(unsigned int type); } while(0) /* Prototypes begin here */ +PMOD_EXPORT void really_free_pike_type(struct pike_type * t); +PMOD_EXPORT ATTRIBUTE((malloc)) struct pike_type * alloc_pike_type(); +PMOD_EXPORT void count_memory_in_pike_types(size_t *n, size_t *s); void debug_check_type_string(struct pike_type *s); void init_types(void); ptrdiff_t pop_stack_mark(void); diff --git a/src/post_modules/CritBit/Makefile.in b/src/post_modules/CritBit/Makefile.in index 63b26b423838b0c0965a8ecaafee1ffef46dc610..16e70d2b8350435f856db2589e9cbb99e95bb963 100644 --- a/src/post_modules/CritBit/Makefile.in +++ b/src/post_modules/CritBit/Makefile.in @@ -10,7 +10,7 @@ AUTODOC_SRC_IN=$(SRCDIR)/stringtree.c $(SRCDIR)/floattree.c $(SRCDIR)/inttree.c OBJS=glue.o inttree.o stringtree.o floattree.o bignumtree.o CONFIG_HEADERS=@CONFIG_HEADERS@ CMOD_HEADERS=redefine.H tree_header.H iterator_source.H tree_source.H prefix.H -COMMON_HEADERS=$(SRCDIR)/tree_high.c $(SRCDIR)/tree_low.h $(SRCDIR)/tree_low.c $(SRCDIR)/critbit/critbit.h $(SRCDIR)/common.h $(SRCDIR)/critbit/value_svalue.h $(SRCDIR)/bitvector.h +COMMON_HEADERS=$(SRCDIR)/tree_high.c $(SRCDIR)/tree_low.h $(SRCDIR)/tree_low.c $(SRCDIR)/critbit/critbit.h $(SRCDIR)/common.h $(SRCDIR)/critbit/value_svalue.h PRECOMPILER_ARGS=--api=4 diff --git a/src/program.c b/src/program.c index 5c7931069e52419ed8967848ef026b398030aa8b..ff626368b17aa2cfd051bf43d0c037e84a913633 100644 --- a/src/program.c +++ b/src/program.c @@ -32,6 +32,7 @@ #include "pike_types.h" #include "opcodes.h" #include "version.h" +#include "block_allocator.h" #include "block_alloc.h" #include "pikecode.h" #include "pike_compiler.h" @@ -51,20 +52,30 @@ static size_t add_xstorage(size_t size, size_t alignment, ptrdiff_t modulo_orig); -#undef EXIT_BLOCK -#define EXIT_BLOCK(P) exit_program_struct( (P) ) +static struct block_allocator program_allocator = BA_INIT_PAGES(sizeof(struct program), 4); -#undef COUNT_OTHER -#define COUNT_OTHER() do{ \ - struct program *p; \ - for(p=first_program;p;p=p->next) \ - { \ - size+=p->total_size - sizeof (struct program); \ - } \ -}while(0) +ATTRIBUTE((malloc)) +struct program * alloc_program() { + return ba_alloc(&program_allocator); +} -BLOCK_ALLOC_FILL_PAGES(program, 4) +void really_free_program(struct program * p) { + exit_program_struct(p); + ba_free(&program_allocator, p); +} +void count_memory_in_programs(size_t *num, size_t *_size) { + size_t size; + struct program *p; + ba_count_all(&program_allocator, num, &size); + for(p=first_program;p;p=p->next) { + size+=p->total_size - sizeof (struct program); + } +} + +void free_all_program_blocks() { + ba_destroy(&program_allocator); +} /* #define COMPILER_DEBUG */ /* #define PROGRAM_BUILD_DEBUG */ @@ -7970,11 +7981,6 @@ struct supporter_marker int level, verified; }; -#undef EXIT_BLOCK -#define EXIT_BLOCK(P) -#undef COUNT_OTHER -#define COUNT_OTHER() - #undef INIT_BLOCK #define INIT_BLOCK(X) do { (X)->level = (X)->verified = 0; }while(0) PTR_HASH_ALLOC(supporter_marker, 128); @@ -10607,7 +10613,6 @@ void init_program(void) struct svalue key; struct svalue val; struct svalue id; - init_program_blocks(); MAKE_CONST_STRING(this_function_string,"this_function"); MAKE_CONST_STRING(this_program_string,"this_program"); diff --git a/src/program.h b/src/program.h index f2f46607ca3d5f38c21ca5525c59de753dcc17f5..1e11644b7b92bf887b00f4a9e96127381fc69018 100644 --- a/src/program.h +++ b/src/program.h @@ -15,7 +15,6 @@ #include "time_stuff.h" #include "program_id.h" #include "pike_rusage.h" -#include "block_alloc_h.h" /* Needed to support dynamic loading on NT */ PMOD_EXPORT extern struct program_state * Pike_compiler; @@ -691,7 +690,11 @@ PMOD_EXPORT void gc_check_zapped (void *a, TYPE_T type, const char *file, INT_TY }while(0) #endif -BLOCK_ALLOC_FILL_PAGES(program, n/a); +ATTRIBUTE((malloc)) +PMOD_EXPORT struct program * alloc_program(); +PMOD_EXPORT void really_free_program(struct program * p); +PMOD_EXPORT void count_memory_in_programs(size_t *num, size_t *_size); +void free_all_program_blocks(); extern struct program *first_program; diff --git a/src/stralloc.c b/src/stralloc.c index f4c38130b3334db65a476e8089a1791bcf4f34b0..cf8d98e569477ff6010fa4ce156ff11bbdfba08a 100644 --- a/src/stralloc.c +++ b/src/stralloc.c @@ -18,6 +18,7 @@ #include "block_alloc.h" #include "operators.h" #include "pike_float.h" +#include "block_allocator.h" #include "port.h" #include <errno.h> @@ -667,26 +668,6 @@ struct pike_string_hdr { /* Allocate some fixed string sizes with BLOCK_ALLOC. */ -/* Use the BLOCK_ALLOC() stuff for short strings */ - -#undef INIT_BLOCK -#ifdef ATOMIC_SVALUE -#define INIT_BLOCK(NEW_STR) do { \ - (NEW_STR)->ref_type = T_STRING; \ - (NEW_STR)->refs = 0; \ - add_ref((NEW_STR)); \ - (NEW_STR)->flags = \ - STRING_NOT_HASHED|STRING_NOT_SHARED|STRING_IS_SHORT; \ - } while(0) -#else /* !ATOMIC_SVALUE */ -#define INIT_BLOCK(NEW_STR) do { \ - (NEW_STR)->refs = 0; \ - add_ref((NEW_STR)); \ - (NEW_STR)->flags = \ - STRING_NOT_HASHED|STRING_NOT_SHARED|STRING_IS_SHORT; \ - } while(0) -#endif - #define SHORT_STRING_BLOCK 256 #define SHORT_STRING_THRESHOLD 15 /* % 4 === -1 */ @@ -705,25 +686,30 @@ struct short_pike_string2 { p_wchar2 str[SHORT_STRING_THRESHOLD+1]; }; -BLOCK_ALLOC(short_pike_string0, SHORT_STRING_BLOCK) -BLOCK_ALLOC(short_pike_string1, SHORT_STRING_BLOCK) -BLOCK_ALLOC(short_pike_string2, SHORT_STRING_BLOCK) - -#undef INIT_BLOCK -#define INIT_BLOCK(x) - -#define really_free_short_pike_string(s) do { \ - if (!s->size_shift) { \ - really_free_short_pike_string0((struct short_pike_string0 *)s); \ - } else if (s->size_shift == 1) { \ - really_free_short_pike_string1((struct short_pike_string1 *)s); \ - DO_IF_DEBUG( \ - } else if (s->size_shift != 2) { \ - Pike_fatal("Unsupported string shift: %d\n", s->size_shift); \ - ) \ - } else { \ - really_free_short_pike_string2((struct short_pike_string2 *)s); \ - } \ +static struct block_allocator string_allocator[] = { + BA_INIT(sizeof(struct short_pike_string0), SHORT_STRING_BLOCK), + BA_INIT(sizeof(struct short_pike_string1), SHORT_STRING_BLOCK), + BA_INIT(sizeof(struct short_pike_string2), SHORT_STRING_BLOCK) +}; + +static struct pike_string * alloc_short_pike_string(unsigned int shift) { + struct pike_string * s = (struct pike_string *)ba_alloc(string_allocator+shift); + +#ifdef ATOMIC_SVALUE + s->ref_type = T_STRING; +#endif + s->refs = 0; + add_ref(s); /* For DMALLOC */ + s->flags = STRING_NOT_HASHED|STRING_NOT_SHARED|STRING_IS_SHORT; + return s; +} + +#define really_free_short_pike_string(s) do { \ + DO_IF_DEBUG( \ + if (s->size_shift > 2) \ + Pike_fatal("Unsupported string shift: %d\n", s->size_shift); \ + ) \ + ba_free(string_allocator + s->size_shift, s); \ } while(0) #define free_unlinked_pike_string(s) do { \ @@ -746,7 +732,8 @@ PMOD_EXPORT struct pike_string *debug_begin_shared_string(size_t len) verify_shared_strings_tables(); #endif if (len <= SHORT_STRING_THRESHOLD) { - t=(struct pike_string *)alloc_short_pike_string0(); + t=(struct pike_string *)ba_alloc(string_allocator); + t->flags = STRING_NOT_HASHED | STRING_NOT_SHARED | STRING_IS_SHORT; } else { t=(struct pike_string *)xalloc(len + 1 + sizeof(struct pike_string_hdr)); t->flags = STRING_NOT_HASHED | STRING_NOT_SHARED; @@ -876,17 +863,12 @@ PMOD_EXPORT struct pike_string *debug_begin_wide_shared_string(size_t len, int s verify_shared_strings_tables(); #endif if (len <= SHORT_STRING_THRESHOLD) { - if (!shift) { - t = (struct pike_string *)alloc_short_pike_string0(); - } else if (shift == 1) { - t = (struct pike_string *)alloc_short_pike_string1(); #ifdef PIKE_DEBUG - } else if (shift != 2) { + if (shift > 2) Pike_fatal("Unsupported string shift: %d\n", shift); #endif /* PIKE_DEBUG */ - } else { - t = (struct pike_string *)alloc_short_pike_string2(); - } + t=(struct pike_string *)ba_alloc(string_allocator+shift); + t->flags = STRING_NOT_HASHED|STRING_NOT_SHARED|STRING_IS_SHORT; } else { t=(struct pike_string *)xalloc(((len + 1)<<shift) + sizeof(struct pike_string_hdr)); @@ -1246,7 +1228,7 @@ PMOD_EXPORT void really_free_string(struct pike_string *s) if(((ptrdiff_t)s->next) & 1) Pike_fatal("Freeing shared string again, memory corrupt or other bug!\n"); } - if ((s->size_shift < 0) || (s->size_shift > 2)) { + if (s->size_shift > 2) { Pike_fatal("Freeing string with bad shift (0x%08x); could it be a type?\n", s->size_shift); } @@ -2316,9 +2298,6 @@ PMOD_EXPORT struct pike_string *string_replace(struct pike_string *str, /*** init/exit memory ***/ void init_shared_string_table(void) { - init_short_pike_string0_blocks(); - init_short_pike_string1_blocks(); - init_short_pike_string2_blocks(); for(hashprimes_entry=0;hashprimes[hashprimes_entry]<BEGIN_HASH_SIZE;hashprimes_entry++); SET_HSIZE(hashprimes_entry); base_table=(struct pike_string **)xalloc(sizeof(struct pike_string *)*htable_size); @@ -2394,9 +2373,9 @@ void cleanup_shared_string_table(void) num_strings=0; #ifdef DO_PIKE_CLEANUP - free_all_short_pike_string0_blocks(); - free_all_short_pike_string1_blocks(); - free_all_short_pike_string2_blocks(); + ba_destroy(string_allocator+0); + ba_destroy(string_allocator+1); + ba_destroy(string_allocator+2); #endif /* DO_PIKE_CLEANUP */ } @@ -2415,11 +2394,11 @@ static INLINE size_t memory_in_string (struct pike_string *s) void count_memory_in_short_pike_strings(size_t *num, size_t *size) { size_t num_=0, size_=0; - count_memory_in_short_pike_string0s(num, size); - count_memory_in_short_pike_string1s(&num_, &size_); + ba_count_all(string_allocator, num, size); + ba_count_all(string_allocator+1, &num_, &size_); *num += num_; *size += size_; - count_memory_in_short_pike_string2s(&num_, &size_); + ba_count_all(string_allocator+2, &num_, &size_); *num += num_; *size += size_; } diff --git a/src/stralloc.h b/src/stralloc.h index 79681fe166a1ce01d66a241f3f25ef8d74135b18..951d3f6c6dd61418f80dd30dc0308812e65cede1 100644 --- a/src/stralloc.h +++ b/src/stralloc.h @@ -9,7 +9,6 @@ #include "global.h" #include "pike_macros.h" -#include "block_alloc_h.h" #define STRINGS_ARE_SHARED @@ -276,10 +275,6 @@ struct pike_string *findstring(const char *foo); struct short_pike_string0; struct short_pike_string1; struct short_pike_string2; -BLOCK_ALLOC(short_pike_string0, SHORT_STRING_BLOCK); -BLOCK_ALLOC(short_pike_string1, SHORT_STRING_BLOCK); -BLOCK_ALLOC(short_pike_string2, SHORT_STRING_BLOCK); - PMOD_EXPORT struct pike_string *debug_begin_shared_string(size_t len) ATTRIBUTE((malloc)); PMOD_EXPORT struct pike_string *debug_begin_wide_shared_string(size_t len, int shift) ATTRIBUTE((malloc));