diff --git a/src/compilation.h b/src/compilation.h index 15d62542526319a85a8cf20514e765449114bd55..8582d8fa246504534f8c2faccc4a836ccd4b508c 100644 --- a/src/compilation.h +++ b/src/compilation.h @@ -175,6 +175,7 @@ IMEMBER(int, compat_minor, PIKE_MINOR_VERSION) ZMEMBER(int, flags, 0) ZMEMBER(struct compilation *,compiler,0) + ZMEMBER(struct block_allocator, node_allocator, BA_INIT_PAGES(sizeof(struct node_s), 2)) SEND #undef PCODE diff --git a/src/las.c b/src/las.c index fe88ef323319a6056cffe3b9ba865a2c5677c12b..4d3b1b1737981b8346df5d9192c00634f5099c58 100644 --- a/src/las.c +++ b/src/las.c @@ -30,7 +30,7 @@ #include "pikecode.h" #include "gc.h" #include "pike_compiler.h" -#include "block_alloc.h" +#include "block_allocator.h" /* Define this if you want the optimizer to be paranoid about aliasing * effects to to indexing. @@ -455,75 +455,91 @@ static int check_node_type(node *n, struct pike_type *t, const char *msg) return 1; } -#undef BLOCK_ALLOC_NEXT -#define BLOCK_ALLOC_NEXT u.node.a +void init_node_s_blocks() { } -#undef PRE_INIT_BLOCK -#define PRE_INIT_BLOCK(NODE) do { \ - (NODE)->token = USHRT_MAX; \ - } while (0) +void really_free_node_s(node * n) { + ba_free(&Pike_compiler->node_allocator, n); +} -BLOCK_ALLOC_FILL_PAGES(node_s, 2) +MALLOC_FUNCTION +node * alloc_node_s() { + return (node*)ba_alloc(&Pike_compiler->node_allocator); +} -#undef BLOCK_ALLOC_NEXT -#define BLOCK_ALLOC_NEXT next +void count_memory_in_node_ss(size_t * num, size_t * size) { + struct program_state * state = Pike_compiler; -void free_all_nodes(void) -{ - if(!Pike_compiler->previous) - { - node *tmp; + *num = 0; + *size = 0; + + while (state) { + size_t _num, _size; + ba_count_all(&state->node_allocator, &_num, &_size); + *num += _num; + *size += _size; + state = state->previous; + } +} + +void node_walker(struct ba_iterator * it, void * data) { + do { + node * tmp = ba_it_val(it); + + /* + * since we free nodes from here, we might iterate over them again. + * to avoid that we check for the free mark. + */ + if (tmp->token == USHRT_MAX) continue; -#ifndef PIKE_DEBUG - if(cumulative_parse_error) { -#else - size_t e=0, s=0; - count_memory_in_node_ss(&e, &s); - if(e) { -#endif - WALK_NONFREE_BLOCKS(node_s, tmp, tmp->token != USHRT_MAX, { #ifdef PIKE_DEBUG - if(!cumulative_parse_error) - { - fprintf(stderr,"Free node at %p, (%s:%ld) (token=%d).\n", - (void *)tmp, - tmp->current_file->str, (long)tmp->line_number, - tmp->token); + if(!cumulative_parse_error) + { + fprintf(stderr,"Free node at %p, (%s:%ld) (token=%d).\n", + (void *)tmp, + tmp->current_file->str, (long)tmp->line_number, + tmp->token); - debug_malloc_dump_references(tmp,0,2,0); + debug_malloc_dump_references(tmp,0,2,0); - if(tmp->token==F_CONSTANT) - print_tree(tmp); - } - /* else */ + if(tmp->token==F_CONSTANT) + print_tree(tmp); + } + /* else */ #endif - { - /* Free the node and be happy */ - /* Make sure we don't free any nodes twice */ - if(car_is_node(tmp)) _CAR(tmp)=0; - if(cdr_is_node(tmp)) _CDR(tmp)=0; -#ifdef PIKE_DEBUG - if (l_flag > 3) { - fprintf(stderr, "Freeing node that had %d refs.\n", - tmp->refs); - } -#endif /* PIKE_DEBUG */ - /* Force the node to be freed. */ - tmp->refs = 1; - debug_malloc_touch(tmp->type); - free_node(tmp); - } - }); + { + /* Free the node and be happy */ + /* Make sure we don't free any nodes twice */ + if(car_is_node(tmp)) _CAR(tmp)=0; + if(cdr_is_node(tmp)) _CDR(tmp)=0; #ifdef PIKE_DEBUG - if(!cumulative_parse_error) - Pike_fatal("Failed to free %"PRINTSIZET"d nodes when compiling!\n",e); + if (l_flag > 3) { + fprintf(stderr, "Freeing node that had %d refs.\n", + tmp->refs); } -#else +#endif /* PIKE_DEBUG */ + /* Force the node to be freed. */ + tmp->refs = 1; + debug_malloc_touch(tmp->type); + free_node(tmp); } + } while (ba_it_step(it)); +} + +void free_all_nodes(void) +{ + node *tmp; + +#ifndef PIKE_DEBUG + if(cumulative_parse_error) { #endif - free_all_node_s_blocks(); - cumulative_parse_error=0; + ba_walk(&Pike_compiler->node_allocator, &node_walker, NULL); +#ifdef PIKE_DEBUG + if(!cumulative_parse_error) + Pike_fatal("Failed to free %"PRINTSIZET"d nodes when compiling!\n",e); +#else } +#endif + cumulative_parse_error=0; } void debug_free_node(node *n) diff --git a/src/las.h b/src/las.h index 2bbfc8d1f726212d5734f929bc008b14d2b30ca5..63e09cddadb15b491e19e952c9170074188ee9e9 100644 --- a/src/las.h +++ b/src/las.h @@ -10,7 +10,7 @@ #include "global.h" #include "svalue.h" #include "dynamic_buffer.h" -#include "block_alloc_h.h" +#include "block_allocator.h" #define MAX_GLOBAL_VARIABLES 1000 typedef void (*c_fun)(INT32); @@ -154,7 +154,7 @@ struct node_s #define SCOPE_SCOPED 2 #define SCOPE_SCOPE_USED 4 -BLOCK_ALLOC_FILL_PAGES(node_s, 2); +void count_memory_in_node_ss(size_t *num, size_t *size); /* Prototypes begin here */ int car_is_node(node *n); diff --git a/src/program.c b/src/program.c index 15eb4a1a504e14fd70547a767e9725b386a60670..5c10c2344b74d6a9e510fd72b81cb16bd26ccc8f 100644 --- a/src/program.c +++ b/src/program.c @@ -2771,10 +2771,6 @@ void low_start_new_program(struct program *p, c->compilation_depth++; - if (!Pike_compiler->compiler_frame) { - new_node_s_context(); - } - SET_SVAL_TYPE(tmp, T_PROGRAM); if(!p) { @@ -2826,6 +2822,8 @@ void low_start_new_program(struct program *p, #define PUSH #include "compilation.h" + ba_init(&Pike_compiler->node_allocator, sizeof(struct node_s), 512); + Pike_compiler->parent_identifier=id; Pike_compiler->compiler_pass = pass; @@ -3315,6 +3313,10 @@ static void toss_compilation_resources(void) } unuse_modules(Pike_compiler->num_used_modules); + + free_all_nodes(); + + ba_destroy(&Pike_compiler->node_allocator); } int sizeof_variable(int run_time_type) @@ -4025,7 +4027,6 @@ struct program *end_first_pass(int finish) exit_type_stack(); - free_all_nodes(); CDFPRINTF((stderr, "th(%ld) %p end_first_pass(%d): " diff --git a/src/program.h b/src/program.h index 0b0ce0b98eb67aa3ed6e4a89d8825d26119d54e7..0c64c608a927f5cee1aed2f429cb5ad8072b5549 100644 --- a/src/program.h +++ b/src/program.h @@ -15,6 +15,7 @@ #include "time_stuff.h" #include "program_id.h" #include "pike_rusage.h" +#include "block_allocator.h" /* Needed to support dynamic loading on NT */ PMOD_EXPORT extern struct program_state * Pike_compiler;