gawk-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gawk-diffs] [SCM] gawk branch, feature/memleak, updated. gawk-4.1.0-246


From: Andrew J. Schorr
Subject: [gawk-diffs] [SCM] gawk branch, feature/memleak, updated. gawk-4.1.0-2466-g22bfbd1
Date: Fri, 7 Apr 2017 11:30:56 -0400 (EDT)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".

The branch, feature/memleak has been updated
       via  22bfbd1057c2fa9d5e5b2401d6b1ab60737452d9 (commit)
      from  4eb9f5be22cc4e63d0ef360ea6ba2ac850d7293e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=22bfbd1057c2fa9d5e5b2401d6b1ab60737452d9

commit 22bfbd1057c2fa9d5e5b2401d6b1ab60737452d9
Author: Andrew J. Schorr <address@hidden>
Date:   Fri Apr 7 11:30:22 2017 -0400

    Patch INSTRUCTION allocator to malloc instruction blocks and eliminate 
leaks.

diff --git a/ChangeLog b/ChangeLog
index 7926246..ba5bba5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2017-04-07         Andrew J. Schorr     <address@hidden>
+
+       * awk.h (INSTRUCTION_POOL): Redefine as an array of structures so we
+       can track allocated blocks.
+       * symbol.c (pools): Make it a pointer to avoid copying.
+       (struct instruction_block): Define structure to hold a block of
+       allocated instructions.
+       (bcfree): Update to use new INSTRUCTION_POOL definition.
+       (bcalloc): Allocate an instruction by searching first on the free
+       list, second for free space in the current block, or third by
+       allocating a new block.
+       (set_context): Update to reflect that pools is now a pointer.
+       (free_bc_mempool): New helper function to free a pool of a certain size.
+       (fre_bcpool): Call free_bc_mempool for each pool.
+
 2017-04-04         Arnold D. Robbins     <address@hidden>
 
        * awk.h (INSTRUCTION): Add pool_size member.
diff --git a/awk.h b/awk.h
index 6b7cdb7..c7bfec2 100644
--- a/awk.h
+++ b/awk.h
@@ -1035,7 +1035,11 @@ typedef struct srcfile {
 // structure for INSTRUCTION pool, needed mainly for debugger
 typedef struct instruction_pool {
 #define MAX_INSTRUCTION_ALLOC  3       // we don't call bcalloc with more than 
this
-       INSTRUCTION pool[MAX_INSTRUCTION_ALLOC + 1];
+       struct instruction_mem_pool {
+               struct instruction_block *block_list;
+               INSTRUCTION *free_space;        // free location in active block
+               INSTRUCTION *free_list;
+       } pool[MAX_INSTRUCTION_ALLOC];
 } INSTRUCTION_POOL;
 
 /* structure for execution context */
diff --git a/symbol.c b/symbol.c
index b2a6a6c..d63277b 100644
--- a/symbol.c
+++ b/symbol.c
@@ -693,8 +693,19 @@ check_param_names(void)
        return result;
 }
 
-#define freei          x.xi
-static INSTRUCTION_POOL pools;
+static INSTRUCTION_POOL *pools;
+
+/*
+ * For best performance, the INSTR_CHUNK value should be divisible by all
+ * possible sizes, i.e. 1 through MAX_INSTRUCTION_ALLOC. Otherwise, there
+ * will be wasted space at the end of the block.
+ */
+#define INSTR_CHUNK (2*3*21)
+
+struct instruction_block {
+       struct instruction_block *next;
+       INSTRUCTION i[INSTR_CHUNK];
+};
 
 /* bcfree --- deallocate instruction */
 
@@ -704,8 +715,8 @@ bcfree(INSTRUCTION *cp)
        assert(cp->pool_size >= 1 && cp->pool_size <= MAX_INSTRUCTION_ALLOC);
 
        cp->opcode = 0;
-       cp->nexti = pools.pool[cp->pool_size].freei;
-       pools.pool[cp->pool_size].freei = cp;
+       cp->nexti = pools->pool[cp->pool_size - 1].free_list;
+       pools->pool[cp->pool_size - 1].free_list = cp;
 }
 
 /* bcalloc --- allocate a new instruction */
@@ -714,13 +725,24 @@ INSTRUCTION *
 bcalloc(OPCODE op, int size, int srcline)
 {
        INSTRUCTION *cp;
+       struct instruction_mem_pool *pool;
 
        assert(size >= 1 && size <= MAX_INSTRUCTION_ALLOC);
-
-       if ((cp = pools.pool[size].freei) != NULL) {
-               pools.pool[size].freei = cp->nexti;
+       pool = &pools->pool[size - 1];
+
+       if (pool->free_list != NULL) {
+               cp = pool->free_list;
+               pool->free_list = cp->nexti;
+       } else if (pool->free_space && pool->free_space + size <= & 
pool->block_list->i[INSTR_CHUNK]) {
+               cp = pool->free_space;
+               pool->free_space += size;
        } else {
-               emalloc(cp, INSTRUCTION *, (size + 1) * sizeof(INSTRUCTION), 
"bcalloc");
+               struct instruction_block *block;
+               emalloc(block, struct instruction_block *, sizeof(struct 
instruction_block), "bcalloc");
+               block->next = pool->block_list;
+               pool->block_list = block;
+               cp = &block->i[0];
+               pool->free_space = &block->i[size];
        }
 
        memset(cp, 0, size * sizeof(INSTRUCTION));
@@ -750,7 +772,7 @@ new_context()
 static void
 set_context(AWK_CONTEXT *ctxt)
 {
-       pools = ctxt->pools;
+       pools = & ctxt->pools;
        symbol_list = & ctxt->symbols;
        srcfiles = & ctxt->srcfiles;
        rule_list = & ctxt->rule_list;
@@ -889,19 +911,36 @@ free_bc_internal(INSTRUCTION *cp)
        }
 }
 
-/* free_bcpool --- free list of instruction memory pools */
+/* free_bc_mempool --- free a single pool */
 
 static void
-free_bcpool(INSTRUCTION_POOL *pl)
+free_bc_mempool(struct instruction_mem_pool *pool, int size)
 {
-       INSTRUCTION *cp, *next;
-       int i;
+       int first = 1;
+       struct instruction_block *block, *next;
 
-       for (i = 1; i <= MAX_INSTRUCTION_ALLOC; i++) {
-               for (cp = pl->pool[i].nexti; cp != NULL; cp = next) {
-                       next = cp->nexti;
+       for (block = pool->block_list; block; block = next) {
+               INSTRUCTION *cp, *end;
+
+               end = (first ? pool->free_space : & block->i[INSTR_CHUNK]);
+               for (cp = & block->i[0]; cp + size <= end; cp += size) {
                        if (cp->opcode != 0)
                                free_bc_internal(cp);
                }
+               next = block->next;
+               efree(block);
+               first = 0;
        }
 }
+
+
+/* free_bcpool --- free list of instruction memory pools */
+
+static void
+free_bcpool(INSTRUCTION_POOL *pl)
+{
+       int i;
+
+       for (i = 0; i < MAX_INSTRUCTION_ALLOC; i++)
+               free_bc_mempool(& pl->pool[i], i + 1);
+}

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog | 15 ++++++++++++++
 awk.h     |  6 +++++-
 symbol.c  | 71 +++++++++++++++++++++++++++++++++++++++++++++++++--------------
 3 files changed, 75 insertions(+), 17 deletions(-)


hooks/post-receive
-- 
gawk



reply via email to

[Prev in Thread] Current Thread [Next in Thread]