]> granicus.if.org Git - php/commitdiff
Move free_chunk and resize_chunk into memory pool
authorNikita Popov <nikic@php.net>
Mon, 22 Feb 2016 17:40:45 +0000 (18:40 +0100)
committerNikita Popov <nikic@php.net>
Mon, 22 Feb 2016 18:40:32 +0000 (19:40 +0100)
Drops 24 bytes from each chunk. For the example in bug #71468 it
reduces memory usage by 30%.

ext/mysqlnd/mysqlnd_block_alloc.c
ext/mysqlnd/mysqlnd_ps.c
ext/mysqlnd/mysqlnd_result.c
ext/mysqlnd/mysqlnd_structs.h
ext/mysqlnd/mysqlnd_wireprotocol.c

index d92fd755d89baa1b0d18afe2462ccb55bbd1f2e2..8729606adeb378916dbd93ccb5d015384a9a6183 100644 (file)
@@ -28,9 +28,8 @@
 
 /* {{{ mysqlnd_mempool_free_chunk */
 static void
-mysqlnd_mempool_free_chunk(MYSQLND_MEMORY_POOL_CHUNK * chunk)
+mysqlnd_mempool_free_chunk(MYSQLND_MEMORY_POOL * pool, MYSQLND_MEMORY_POOL_CHUNK * chunk)
 {
-       MYSQLND_MEMORY_POOL * pool = chunk->pool;
        DBG_ENTER("mysqlnd_mempool_free_chunk");
        if (chunk->from_pool) {
                /* Try to back-off and guess if this is the last block allocated */
@@ -52,11 +51,10 @@ mysqlnd_mempool_free_chunk(MYSQLND_MEMORY_POOL_CHUNK * chunk)
 
 /* {{{ mysqlnd_mempool_resize_chunk */
 static enum_func_status
-mysqlnd_mempool_resize_chunk(MYSQLND_MEMORY_POOL_CHUNK * chunk, unsigned int size)
+mysqlnd_mempool_resize_chunk(MYSQLND_MEMORY_POOL * pool, MYSQLND_MEMORY_POOL_CHUNK * chunk, unsigned int size)
 {
        DBG_ENTER("mysqlnd_mempool_resize_chunk");
        if (chunk->from_pool) {
-               MYSQLND_MEMORY_POOL * pool = chunk->pool;
                /* Try to back-off and guess if this is the last block allocated */
                if (chunk->ptr == (pool->arena + (pool->arena_size - pool->free_size - chunk->size))) {
                        /*
@@ -115,20 +113,17 @@ MYSQLND_MEMORY_POOL_CHUNK * mysqlnd_mempool_get_chunk(MYSQLND_MEMORY_POOL * pool
 
        chunk = mnd_emalloc(sizeof(MYSQLND_MEMORY_POOL_CHUNK));
        if (chunk) {
-               chunk->free_chunk = mysqlnd_mempool_free_chunk;
-               chunk->resize_chunk = mysqlnd_mempool_resize_chunk;
                chunk->size = size;
                /*
                  Should not go over MYSQLND_MAX_PACKET_SIZE, since we
                  expect non-arena memory in mysqlnd_wireprotocol.c . We
                  realloc the non-arena memory.
                */
-               chunk->pool = pool;
                if (size > pool->free_size) {
                        chunk->from_pool = FALSE;
                        chunk->ptr = mnd_emalloc(size);
                        if (!chunk->ptr) {
-                               chunk->free_chunk(chunk);
+                               pool->free_chunk(pool, chunk);
                                chunk = NULL;
                        }
                } else {
@@ -152,6 +147,8 @@ mysqlnd_mempool_create(size_t arena_size)
        DBG_ENTER("mysqlnd_mempool_create");
        if (ret) {
                ret->get_chunk = mysqlnd_mempool_get_chunk;
+               ret->free_chunk = mysqlnd_mempool_free_chunk;
+               ret->resize_chunk = mysqlnd_mempool_resize_chunk;
                ret->free_size = ret->arena_size = arena_size ? arena_size : 0;
                /* OOM ? */
                ret->arena = mnd_emalloc(ret->arena_size);
index 907ddb46e153b20950b4dd0f708620acaaba4100..1e37f79bf46493cf2e551861f95933b9bf6f99ea 100644 (file)
@@ -947,7 +947,8 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, const unsi
                          the bound variables. Thus we need to do part of what it does or Zend will
                          report leaks.
                        */
-                       row_packet->row_buffer->free_chunk(row_packet->row_buffer);
+                       row_packet->result_set_memory_pool->free_chunk(
+                               row_packet->result_set_memory_pool, row_packet->row_buffer);
                        row_packet->row_buffer = NULL;
                }
 
@@ -1141,13 +1142,15 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned int f
                          the bound variables. Thus we need to do part of what it does or Zend will
                          report leaks.
                        */
-                       row_packet->row_buffer->free_chunk(row_packet->row_buffer);
+                       row_packet->result_set_memory_pool->free_chunk(
+                               row_packet->result_set_memory_pool, row_packet->row_buffer);
                        row_packet->row_buffer = NULL;
                }
                /* We asked for one row, the next one should be EOF, eat it */
                ret = PACKET_READ(row_packet);
                if (row_packet->row_buffer) {
-                       row_packet->row_buffer->free_chunk(row_packet->row_buffer);
+                       row_packet->result_set_memory_pool->free_chunk(
+                               row_packet->result_set_memory_pool, row_packet->row_buffer);
                        row_packet->row_buffer = NULL;
                }
                MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_PS_CURSOR);
index 2b709264a5c4ecdae791b976bc2cca4a2b714bc5..d649efcbb9a26535723a3097f34988bde55271fe 100644 (file)
@@ -166,7 +166,8 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, free_last_data)(MYSQLND_RES_UNBUFFERED
        if (unbuf->last_row_buffer) {
                DBG_INF("Freeing last row buffer");
                /* Nothing points to this buffer now, free it */
-               unbuf->last_row_buffer->free_chunk(unbuf->last_row_buffer);
+               unbuf->result_set_memory_pool->free_chunk(
+                       unbuf->result_set_memory_pool, unbuf->last_row_buffer);
                unbuf->last_row_buffer = NULL;
        }
 
@@ -253,6 +254,7 @@ static void
 MYSQLND_METHOD(mysqlnd_result_buffered, free_result)(MYSQLND_RES_BUFFERED * const set)
 {
        int64_t row;
+       MYSQLND_MEMORY_POOL * pool;
 
        DBG_ENTER("mysqlnd_result_buffered::free_result");
        DBG_INF_FMT("Freeing "MYSQLND_LLU_SPEC" row(s)", set->row_count);
@@ -263,9 +265,10 @@ MYSQLND_METHOD(mysqlnd_result_buffered, free_result)(MYSQLND_RES_BUFFERED * cons
                MYSQLND_METHOD(mysqlnd_result_buffered_c, free_result)((MYSQLND_RES_BUFFERED_C *) set);
        }
 
+       pool = set->result_set_memory_pool;
        for (row = set->row_count - 1; row >= 0; row--) {
                MYSQLND_MEMORY_POOL_CHUNK *current_buffer = set->row_buffers[row];
-               current_buffer->free_chunk(current_buffer);
+               pool->free_chunk(pool, current_buffer);
        }
 
        if (set->lengths) {
index f3813eeb31ff690c52c48a0f503c0d980069769e..4832cb1381cd0da17150f70acf97971da67aea3e 100644 (file)
@@ -63,15 +63,14 @@ struct st_mysqlnd_memory_pool
        unsigned int free_size;
 
        MYSQLND_MEMORY_POOL_CHUNK*      (*get_chunk)(MYSQLND_MEMORY_POOL * pool, unsigned int size);
+       enum_func_status        (*resize_chunk)(MYSQLND_MEMORY_POOL * pool, MYSQLND_MEMORY_POOL_CHUNK * chunk, unsigned int size);
+       void                            (*free_chunk)(MYSQLND_MEMORY_POOL * pool, MYSQLND_MEMORY_POOL_CHUNK * chunk);
 };
 
 struct st_mysqlnd_memory_pool_chunk
 {
        size_t                          app;
-       MYSQLND_MEMORY_POOL     *pool;
        zend_uchar                      *ptr;
-       enum_func_status        (*resize_chunk)(MYSQLND_MEMORY_POOL_CHUNK * chunk, unsigned int size);
-       void                            (*free_chunk)(MYSQLND_MEMORY_POOL_CHUNK * chunk);
        unsigned int            size;
        zend_bool                       from_pool;
 };
index b174e626874edacf9de1ebf504a7d9eac7e55c91..9e96d508e9e40c52e91bbd1ea75b183ca6a3e412 100644 (file)
@@ -1458,7 +1458,7 @@ php_mysqlnd_read_row_ex(MYSQLND_PFC * pfc,
                                                MYSQLND_VIO * vio,
                                                MYSQLND_STATS * stats,
                                                MYSQLND_ERROR_INFO * error_info,
-                                               MYSQLND_MEMORY_POOL * result_set_memory_pool,
+                                               MYSQLND_MEMORY_POOL * pool,
                                                MYSQLND_MEMORY_POOL_CHUNK ** buffer,
                                                size_t * data_size, zend_bool persistent_alloc,
                                                unsigned int prealloc_more_bytes)
@@ -1489,7 +1489,7 @@ php_mysqlnd_read_row_ex(MYSQLND_PFC * pfc,
 
                if (first_iteration) {
                        first_iteration = FALSE;
-                       *buffer = result_set_memory_pool->get_chunk(result_set_memory_pool, *data_size);
+                       *buffer = pool->get_chunk(pool, *data_size);
                        if (!*buffer) {
                                ret = FAIL;
                                break;
@@ -1504,7 +1504,7 @@ php_mysqlnd_read_row_ex(MYSQLND_PFC * pfc,
                        /*
                          We have to realloc the buffer.
                        */
-                       if (FAIL == (*buffer)->resize_chunk((*buffer), *data_size)) {
+                       if (FAIL == pool->resize_chunk(pool, *buffer, *data_size)) {
                                SET_OOM_ERROR(error_info);
                                ret = FAIL;
                                break;
@@ -1524,7 +1524,7 @@ php_mysqlnd_read_row_ex(MYSQLND_PFC * pfc,
                }
        }
        if (ret == FAIL && *buffer) {
-               (*buffer)->free_chunk((*buffer));
+               pool->free_chunk(pool, *buffer);
                *buffer = NULL;
        }
        *data_size -= prealloc_more_bytes;
@@ -1915,7 +1915,7 @@ php_mysqlnd_rowp_free_mem(void * _packet, zend_bool stack_allocation)
        DBG_ENTER("php_mysqlnd_rowp_free_mem");
        p = (MYSQLND_PACKET_ROW *) _packet;
        if (p->row_buffer) {
-               p->row_buffer->free_chunk(p->row_buffer);
+               p->result_set_memory_pool->free_chunk(p->result_set_memory_pool, p->row_buffer);
                p->row_buffer = NULL;
        }
        DBG_INF_FMT("stack_allocation=%u persistent=%u", (int)stack_allocation, (int)p->header.persistent);