From: Hans Kristian Rosbach Date: Fri, 4 Jul 2025 18:58:28 +0000 (+0200) Subject: Use a single malloc call for both in and out buffers in gzopen/gzread/gzwrite. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=03a91e6e52154047ca106bfaa3c792e7b2768063;p=thirdparty%2Fzlib-ng.git Use a single malloc call for both in and out buffers in gzopen/gzread/gzwrite. Also start aligning the allocation to 64 bytes (on a cacheline border). --- diff --git a/gzguts.h b/gzguts.h index 1f9adbfc..a5a0b40b 100644 --- a/gzguts.h +++ b/gzguts.h @@ -112,6 +112,7 @@ typedef struct { unsigned want; /* requested buffer size, default is GZBUFSIZE */ unsigned char *in; /* input buffer (double-sized when writing) */ unsigned char *out; /* output buffer (double-sized when reading) */ + unsigned char *buffers; /* Pointer to the real input/output buffer allocation */ int direct; /* 0 if processing gzip, 1 if transparent */ /* just for reading */ int how; /* 0: get header, 1: copy, 2: decompress */ diff --git a/gzlib.c b/gzlib.c index 56815c20..5fd6ca40 100644 --- a/gzlib.c +++ b/gzlib.c @@ -4,6 +4,7 @@ */ #include "zbuild.h" +#include "zutil.h" #include "zutil_p.h" #include "gzguts.h" @@ -70,21 +71,23 @@ static void gz_reset(gz_state *state) { /* Allocate in/out buffers for gzFile */ int Z_INTERNAL gz_buffer_alloc(gz_state *state) { int in_mult = 1, out_mult = 1; - int skip_outbuff = (state->mode == GZ_WRITE && state->direct); - if (state->mode == GZ_WRITE) - in_mult = 2; // double imput buffer for compression (ref: gzprintf) - else if (state->mode == GZ_READ) + if (state->mode == GZ_WRITE) { + in_mult = 2; // double input buffer for compression (ref: gzprintf) + if (state->direct) + out_mult = 0; // output buffer not needed in write + direct mode + } else if (state->mode == GZ_READ) { out_mult = 2; // double output buffer for decompression + } - state->in = (unsigned char *)zng_alloc(state->want * in_mult); - /* Don't need output buffer if compressing with state->direct set */ - if ( !skip_outbuff ) { - state->out = (unsigned char *)zng_alloc(state->want * out_mult); + state->buffers = (unsigned char *)zng_alloc_aligned(state->want * (in_mult + out_mult), 64); + state->in = state->buffers; + if (out_mult >= 1) { + state->out = state->buffers + (state->want * in_mult); // Outbuffer goes after inbuffer } /* Return error if memory allocation failed */ - if (state->in == NULL || (!skip_outbuff && state->out == NULL) ) { + if (state->in == NULL || (out_mult >= 1 && state->out == NULL) ) { gz_buffer_free(state); gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; @@ -96,8 +99,10 @@ int Z_INTERNAL gz_buffer_alloc(gz_state *state) { } void Z_INTERNAL gz_buffer_free(gz_state *state) { - zng_free(state->out); - zng_free(state->in); + zng_free_aligned(state->buffers); + state->buffers = NULL; + state->out = NULL; + state->in = NULL; state->size = 0; }