From: Nikita Popov Date: Mon, 22 Feb 2016 17:40:45 +0000 (+0100) Subject: Move free_chunk and resize_chunk into memory pool X-Git-Tag: php-7.1.0alpha1~582 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2d1559f827477963a3f8a40af64212a409ba9457;p=php Move free_chunk and resize_chunk into memory pool Drops 24 bytes from each chunk. For the example in bug #71468 it reduces memory usage by 30%. --- diff --git a/ext/mysqlnd/mysqlnd_block_alloc.c b/ext/mysqlnd/mysqlnd_block_alloc.c index d92fd755d8..8729606ade 100644 --- a/ext/mysqlnd/mysqlnd_block_alloc.c +++ b/ext/mysqlnd/mysqlnd_block_alloc.c @@ -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); diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index 907ddb46e1..1e37f79bf4 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -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); diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index 2b709264a5..d649efcbb9 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -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) { diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index f3813eeb31..4832cb1381 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -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; }; diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index b174e62687..9e96d508e9 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -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);