From: Mika Lindqvist Date: Wed, 3 May 2017 17:14:57 +0000 (+0300) Subject: Lazily initialize functable members. (#108) X-Git-Tag: 1.9.9-b1~660^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5adc2052ebdd2578fde4ee3ebc500d71e967b8ae;p=thirdparty%2Fzlib-ng.git Lazily initialize functable members. (#108) - Split functableInit() function as separate functions for each functable member, so we don't need to initialize full functable in multiple places in the zlib-ng code, or to check for NULL on every invocation. - Optimized function for each functable member is detected on first invocation and the functable item is updated for subsequent invocations. - Remove NULL check in adler32() and adler32_z() as it is no longer needed. --- diff --git a/adler32.c b/adler32.c index dcfeecdf2..f84c73cd1 100644 --- a/adler32.c +++ b/adler32.c @@ -145,15 +145,11 @@ uint32_t adler32_c(uint32_t adler, const unsigned char *buf, size_t len) { } uint32_t ZEXPORT adler32_z(uint32_t adler, const unsigned char *buf, size_t len) { - if (functable.adler32 == NULL) - functableInit(); return functable.adler32(adler, buf, len); } /* ========================================================================= */ uint32_t ZEXPORT adler32(uint32_t adler, const unsigned char *buf, uint32_t len) { - if (functable.adler32 == NULL) - functableInit(); return functable.adler32(adler, buf, len); } diff --git a/deflate.c b/deflate.c index 7de68bbde..ab5b69714 100644 --- a/deflate.c +++ b/deflate.c @@ -241,8 +241,6 @@ int ZEXPORT deflateInit2_(z_stream *strm, int level, int method, int windowBits, x86_check_features(); #endif - functableInit(); - if (version == NULL || version[0] != my_version[0] || stream_size != sizeof(z_stream)) { return Z_VERSION_ERROR; } diff --git a/functable.c b/functable.c index 7d34fad74..5ebd3559d 100644 --- a/functable.c +++ b/functable.c @@ -12,37 +12,36 @@ #endif +/* insert_string */ +ZLIB_INTERNAL Pos insert_string_stub(deflate_state *const s, const Pos str, unsigned int count); #ifdef X86_SSE4_2_CRC_HASH extern Pos insert_string_sse(deflate_state *const s, const Pos str, unsigned int count); #elif defined(ARM_ACLE_CRC_HASH) extern Pos insert_string_acle(deflate_state *const s, const Pos str, unsigned int count); #endif +/* fill_window */ +ZLIB_INTERNAL void fill_window_stub(deflate_state *s); #ifdef X86_SSE2_FILL_WINDOW extern void fill_window_sse(deflate_state *s); #elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) extern void fill_window_arm(deflate_state *s); #endif +/* adler32 */ +ZLIB_INTERNAL uint32_t adler32_stub(uint32_t adler, const unsigned char *buf, size_t len); #if (defined(__ARM_NEON__) || defined(__ARM_NEON)) extern uint32_t adler32_neon(uint32_t adler, const unsigned char *buf, size_t len); #endif -/* ========================================================================= - * Initialize functable - */ - -struct functable_s functable = {NULL,NULL,NULL}; +struct functable_s functable = {fill_window_stub,insert_string_stub,adler32_stub}; - -ZLIB_INTERNAL void functableInit() { - // Initialize defaults +/* stub functions */ +ZLIB_INTERNAL Pos insert_string_stub(deflate_state *const s, const Pos str, unsigned int count) { + // Initialize default functable.insert_string=&insert_string_c; - functable.fill_window=&fill_window_c; - functable.adler32=&adler32_c; - // insert_string #ifdef X86_SSE4_2_CRC_HASH if (x86_cpu_has_sse42) functable.insert_string=&insert_string_sse; @@ -50,7 +49,13 @@ ZLIB_INTERNAL void functableInit() { functable.insert_string=&insert_string_acle; #endif - // fill_window + return functable.insert_string(s, str, count); +} + +ZLIB_INTERNAL void fill_window_stub(deflate_state *s) { + // Initialize default + functable.fill_window=&fill_window_c; + #ifdef X86_SSE2_FILL_WINDOW # ifndef X86_NOCHECK_SSE2 if (x86_cpu_has_sse2) @@ -60,8 +65,16 @@ ZLIB_INTERNAL void functableInit() { functable.fill_window=&fill_window_arm; #endif - // adler32 + functable.fill_window(s); +} + +ZLIB_INTERNAL uint32_t adler32_stub(uint32_t adler, const unsigned char *buf, size_t len) { + // Initialize default + functable.adler32=&adler32_c; + #if (defined(__ARM_NEON__) || defined(__ARM_NEON)) functable.adler32=&adler32_neon; #endif + + return functable.adler32(adler, buf, len); } diff --git a/functable.h b/functable.h index b7d026e56..3b01f7cb6 100644 --- a/functable.h +++ b/functable.h @@ -10,8 +10,6 @@ uint32_t adler32_c(uint32_t adler, const unsigned char *buf, size_t len); -void functableInit(); - struct functable_s { void (* fill_window) (deflate_state *s); Pos (* insert_string) (deflate_state *const s, const Pos str, unsigned int count); diff --git a/inflate.c b/inflate.c index 68a41acf4..1b5a55480 100644 --- a/inflate.c +++ b/inflate.c @@ -187,8 +187,6 @@ int ZEXPORT inflateInit2_(z_stream *strm, int windowBits, const char *version, i int ret; struct inflate_state *state; - functableInit(); - if (version == NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) return Z_VERSION_ERROR; if (strm == NULL)