diff options
Diffstat (limited to 'chromium/third_party/zlib')
-rw-r--r-- | chromium/third_party/zlib/BUILD.gn | 3 | ||||
-rw-r--r-- | chromium/third_party/zlib/arm_features.c | 71 | ||||
-rw-r--r-- | chromium/third_party/zlib/contrib/bench/zlib_bench.cc | 113 | ||||
-rw-r--r-- | chromium/third_party/zlib/google/compression_utils.cc | 43 | ||||
-rw-r--r-- | chromium/third_party/zlib/google/compression_utils.h | 6 |
5 files changed, 126 insertions, 110 deletions
diff --git a/chromium/third_party/zlib/BUILD.gn b/chromium/third_party/zlib/BUILD.gn index 51d477a331b..9f7897ab75b 100644 --- a/chromium/third_party/zlib/BUILD.gn +++ b/chromium/third_party/zlib/BUILD.gn @@ -120,6 +120,9 @@ config("zlib_inflate_chunk_simd_config") { if (use_arm_neon_optimizations) { defines = [ "INFLATE_CHUNK_SIMD_NEON" ] + if (current_cpu == "arm64") { + defines += [ "INFLATE_CHUNK_READ_64LE" ] + } } } diff --git a/chromium/third_party/zlib/arm_features.c b/chromium/third_party/zlib/arm_features.c index a91030daa2c..f91897dc6f9 100644 --- a/chromium/third_party/zlib/arm_features.c +++ b/chromium/third_party/zlib/arm_features.c @@ -4,14 +4,15 @@ * Use of this source code is governed by a BSD-style license that can be * found in the Chromium source repository LICENSE file. */ -#include "arm_features.h" +#include "arm_features.h" #include "zutil.h" int ZLIB_INTERNAL arm_cpu_enable_crc32 = 0; int ZLIB_INTERNAL arm_cpu_enable_pmull = 0; #if !defined(_MSC_VER) + #include <pthread.h> #include <stdint.h> @@ -21,53 +22,54 @@ int ZLIB_INTERNAL arm_cpu_enable_pmull = 0; #include <asm/hwcap.h> #include <sys/auxv.h> #else -#error ### No ARM CPU features detection in your platform/OS +#error arm_features.c ARM feature detection in not defined for your platform #endif static pthread_once_t cpu_check_inited_once = PTHREAD_ONCE_INIT; -static void init_arm_features(void) -{ - uint64_t flag_crc32 = 0, flag_pmull = 0, capabilities = 0; - -#if defined(ARMV8_OS_ANDROID) - flag_crc32 = ANDROID_CPU_ARM_FEATURE_CRC32; - flag_pmull = ANDROID_CPU_ARM_FEATURE_PMULL; - capabilities = android_getCpuFeatures(); -#elif defined(ARMV8_OS_LINUX) - #if defined(__aarch64__) - flag_crc32 = HWCAP_CRC32; - flag_pmull = HWCAP_PMULL; - capabilities = getauxval(AT_HWCAP); - #elif defined(__ARM_NEON) || defined(__ARM_NEON__) - /* The use of HWCAP2 is for getting features of newer ARMv8-A SoCs - * while running in 32bits mode (i.e. aarch32). - */ - flag_crc32 = HWCAP2_CRC32; - flag_pmull = HWCAP2_PMULL; - capabilities = getauxval(AT_HWCAP2); - #endif -#endif - - if (capabilities & flag_crc32) - arm_cpu_enable_crc32 = 1; +static void _arm_check_features(void); - if (capabilities & flag_pmull) - arm_cpu_enable_pmull = 1; +void ZLIB_INTERNAL arm_check_features(void) +{ + pthread_once(&cpu_check_inited_once, _arm_check_features); } -void ZLIB_INTERNAL arm_check_features(void) +/* + * See http://bit.ly/2CcoEsr for run-time detection of ARM features and also + * crbug.com/931275 for android_getCpuFeatures() use in the Android sandbox. + */ +static void _arm_check_features(void) { - pthread_once(&cpu_check_inited_once, init_arm_features); +#if defined(ARMV8_OS_ANDROID) && defined(__aarch64__) + uint64_t features = android_getCpuFeatures(); + arm_cpu_enable_crc32 = !!(features & ANDROID_CPU_ARM64_FEATURE_CRC32); + arm_cpu_enable_pmull = !!(features & ANDROID_CPU_ARM64_FEATURE_PMULL); +#elif defined(ARMV8_OS_ANDROID) /* aarch32 */ + uint64_t features = android_getCpuFeatures(); + arm_cpu_enable_crc32 = !!(features & ANDROID_CPU_ARM_FEATURE_CRC32); + arm_cpu_enable_pmull = !!(features & ANDROID_CPU_ARM_FEATURE_PMULL); +#elif defined(ARMV8_OS_LINUX) && defined(__aarch64__) + unsigned long features = getauxval(AT_HWCAP); + arm_cpu_enable_crc32 = !!(features & HWCAP_CRC32); + arm_cpu_enable_pmull = !!(features & HWCAP_PMULL); +#elif defined(ARMV8_OS_LINUX) && (defined(__ARM_NEON) || defined(__ARM_NEON__)) + /* Query HWCAP2 for ARMV8-A SoCs running in aarch32 mode */ + unsigned long features = getauxval(AT_HWCAP2); + arm_cpu_enable_crc32 = !!(features & HWCAP2_CRC32); + arm_cpu_enable_pmull = !!(features & HWCAP2_PMULL); +#endif + /* TODO(crbug.com/810125): add ARMV8_OS_ZIRCON support for fucshia */ } -#else + +#else /* _MSC_VER */ + #include <windows.h> +static INIT_ONCE cpu_check_inited_once = INIT_ONCE_STATIC_INIT; + static BOOL CALLBACK _arm_check_features(PINIT_ONCE once, PVOID param, PVOID *context); -static INIT_ONCE cpu_check_inited_once = INIT_ONCE_STATIC_INIT; - void ZLIB_INTERNAL arm_check_features(void) { @@ -87,4 +89,5 @@ static BOOL CALLBACK _arm_check_features(PINIT_ONCE once, return TRUE; } + #endif /* _MSC_VER */ diff --git a/chromium/third_party/zlib/contrib/bench/zlib_bench.cc b/chromium/third_party/zlib/contrib/bench/zlib_bench.cc index 452e42e6929..5dcdef09f36 100644 --- a/chromium/third_party/zlib/contrib/bench/zlib_bench.cc +++ b/chromium/third_party/zlib/contrib/bench/zlib_bench.cc @@ -48,9 +48,7 @@ struct Data { }; Data read_file_data_or_exit(const char* name) { - std::ifstream file; - - file.open(name, std::ios::in | std::ios::binary); + std::ifstream file(name, std::ios::in | std::ios::binary); if (!file) { perror(name); exit(1); @@ -63,11 +61,8 @@ Data read_file_data_or_exit(const char* name) { if (file && data.data) file.read(data.data.get(), data.size); - if (!file || !data.data) { - perror((std::string("error reading ") + name).c_str()); - exit(1); - } else if (!data.size) { - fprintf(stderr, "%s is empty\n", name); + if (!file || !data.data || !data.size) { + perror((std::string("failed: reading ") + name).c_str()); exit(1); } @@ -107,12 +102,13 @@ const char* zlib_wrapper_name(zlib_wrapper type) { return 0; } +static int zlib_compression_level; + void zlib_compress( const zlib_wrapper type, const char* input, const size_t input_size, std::string* output, - const int compression_level, bool resize_output = false) { if (resize_output) @@ -122,7 +118,7 @@ void zlib_compress( z_stream stream; memset(&stream, 0, sizeof(stream)); - int result = deflateInit2(&stream, compression_level, Z_DEFLATED, + int result = deflateInit2(&stream, zlib_compression_level, Z_DEFLATED, zlib_stream_wrapper_type(type), MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); if (result != Z_OK) error_exit("deflateInit2 failed", result); @@ -182,8 +178,7 @@ void verify_equal(const char* input, size_t size, std::string* output) { exit(3); } -void zlib_file(const char* name, const zlib_wrapper type, - const int compression_level) { +void zlib_file(const char* name, const zlib_wrapper type) { /* * Read the file data. */ @@ -231,15 +226,13 @@ void zlib_file(const char* name, const zlib_wrapper type, auto start = now(); for (int b = 0; b < blocks; ++b) for (int r = 0; r < repeats; ++r) - zlib_compress(type, input[b], input_length[b], &compressed[b], - compression_level); + zlib_compress(type, input[b], input_length[b], &compressed[b]); ctime[run] = std::chrono::duration<double>(now() - start).count(); // Compress again, resizing compressed, so we don't leave junk at the // end of the compressed string that could confuse zlib_uncompress(). for (int b = 0; b < blocks; ++b) - zlib_compress(type, input[b], input_length[b], &compressed[b], - compression_level, true); + zlib_compress(type, input[b], input_length[b], &compressed[b], true); for (int b = 0; b < blocks; ++b) output[b].resize(input_length[b]); @@ -279,59 +272,45 @@ void zlib_file(const char* name, const zlib_wrapper type, deflate_rate_med, deflate_rate_max, inflate_rate_med, inflate_rate_max); } -int main(int argc, char* argv[]) { - zlib_wrapper type = kWrapperNONE; - int file_index = 3; - // DEFAULT is equivalent to level 6. Compression level ranges from 1 to 9, - // being 0 used for Z_NO_COMPRESSION. - int compression_level = Z_DEFAULT_COMPRESSION; - - auto help_msg_exit = [&argv] { - printf("usage: %s -wrapper gzip|zlib|raw -compression [0:9] files...\n", argv[0]); - exit(1); - }; - - // If no arguments were passed, print usage and exit. - if (argc == 1) - help_msg_exit(); - - if (argc > 1) { - if (strcmp(argv[1], "-wrapper") || !(strcmp(argv[1], "-h")) || - !(strcmp(argv[1], "--help"))) - help_msg_exit(); - - // Got check the argument count before reading. - if (argc < 3) - help_msg_exit(); - - if (!strcmp(argv[2], "zlib")) - type = kWrapperZLIB; - else if (!strcmp(argv[2], "gzip")) - type = kWrapperGZIP; - else if (!strcmp(argv[2], "raw")) - type = kWrapperZRAW; - else - help_msg_exit(); - } +static int argn = 1; - if (argc >= 4) { - if (!strcmp(argv[3], "-compression")) { - int user_level = atoi(argv[4]); - if ((user_level <= 9) && (user_level >= 0)) { - compression_level = user_level; - file_index = 5; - } else - help_msg_exit(); - } - } +char* get_option(int argc, char* argv[], const char* option) { + if (argn < argc) + return !strcmp(argv[argn], option) ? argv[argn++] : 0; + return 0; +} - if ((type != kWrapperNONE) && (argc > 2)) { - while (file_index < argc) { - // TODO: return a status (e.g. success | fail). - zlib_file(argv[file_index], type, compression_level); - ++file_index; - } - } +bool get_compression(int argc, char* argv[], int* value) { + if (argn < argc) + *value = atoi(argv[argn++]); + return *value >= 1 && *value <= 9; +} + +void usage_exit(const char* program) { + printf("usage: %s gzip|zlib|raw [--compression 1:9] files...\n", program); + exit(1); +} + +int main(int argc, char* argv[]) { + zlib_wrapper type; + if (get_option(argc, argv, "zlib")) + type = kWrapperZLIB; + else if (get_option(argc, argv, "gzip")) + type = kWrapperGZIP; + else if (get_option(argc, argv, "raw")) + type = kWrapperZRAW; + else + usage_exit(argv[0]); + + if (!get_option(argc, argv, "--compression")) + zlib_compression_level = Z_DEFAULT_COMPRESSION; + else if (!get_compression(argc, argv, &zlib_compression_level)) + usage_exit(argv[0]); + + if (argn >= argc) + usage_exit(argv[0]); + while (argn < argc) + zlib_file(argv[argn++], type); return 0; } diff --git a/chromium/third_party/zlib/google/compression_utils.cc b/chromium/third_party/zlib/google/compression_utils.cc index ede785d9e42..ae8a517af48 100644 --- a/chromium/third_party/zlib/google/compression_utils.cc +++ b/chromium/third_party/zlib/google/compression_utils.cc @@ -40,7 +40,9 @@ const int kZlibMemoryLevel = 8; int GzipCompressHelper(Bytef* dest, uLongf* dest_length, const Bytef* source, - uLong source_length) { + uLong source_length, + void* (*malloc_fn)(size_t), + void (*free_fn)(void*)) { z_stream stream; stream.next_in = bit_cast<Bytef*>(source); @@ -50,9 +52,31 @@ int GzipCompressHelper(Bytef* dest, if (static_cast<uLong>(stream.avail_out) != *dest_length) return Z_BUF_ERROR; - stream.zalloc = static_cast<alloc_func>(0); - stream.zfree = static_cast<free_func>(0); - stream.opaque = static_cast<voidpf>(0); + // Cannot convert capturing lambdas to function pointers directly, hence the + // structure. + struct MallocFreeFunctions { + void* (*malloc_fn)(size_t); + void (*free_fn)(void*); + } malloc_free = {malloc_fn, free_fn}; + + if (malloc_fn) { + DCHECK(free_fn); + auto zalloc = [](void* opaque, uInt items, uInt size) { + return reinterpret_cast<MallocFreeFunctions*>(opaque)->malloc_fn(items * + size); + }; + auto zfree = [](void* opaque, void* address) { + return reinterpret_cast<MallocFreeFunctions*>(opaque)->free_fn(address); + }; + + stream.zalloc = static_cast<alloc_func>(zalloc); + stream.zfree = static_cast<free_func>(zfree); + stream.opaque = static_cast<voidpf>(&malloc_free); + } else { + stream.zalloc = static_cast<alloc_func>(0); + stream.zfree = static_cast<free_func>(0); + stream.opaque = static_cast<voidpf>(0); + } gz_header gzip_header; memset(&gzip_header, 0, sizeof(gzip_header)); @@ -126,14 +150,17 @@ namespace compression { bool GzipCompress(base::StringPiece input, char* output_buffer, size_t output_buffer_size, - size_t* compressed_size) { + size_t* compressed_size, + void* (*malloc_fn)(size_t), + void (*free_fn)(void*)) { static_assert(sizeof(Bytef) == 1, ""); // uLongf can be larger than size_t. uLongf compressed_size_long = static_cast<uLongf>(output_buffer_size); if (GzipCompressHelper(bit_cast<Bytef*>(output_buffer), &compressed_size_long, bit_cast<const Bytef*>(input.data()), - static_cast<uLongf>(input.size())) != Z_OK) { + static_cast<uLongf>(input.size()), malloc_fn, + free_fn) != Z_OK) { return false; } // No overflow, as compressed_size_long <= output.size() which is a size_t. @@ -156,8 +183,8 @@ bool GzipCompress(base::StringPiece input, std::string* output) { } if (GzipCompressHelper(compressed_data, &compressed_data_size, - bit_cast<const Bytef*>(input.data()), - input_size) != Z_OK) { + bit_cast<const Bytef*>(input.data()), input_size, + nullptr, nullptr) != Z_OK) { free(compressed_data); return false; } diff --git a/chromium/third_party/zlib/google/compression_utils.h b/chromium/third_party/zlib/google/compression_utils.h index e84bfc49753..fe741d0c53e 100644 --- a/chromium/third_party/zlib/google/compression_utils.h +++ b/chromium/third_party/zlib/google/compression_utils.h @@ -15,11 +15,15 @@ namespace compression { // |output_buffer|, of size |output_buffer_size|. If the buffer is large enough // and compression succeeds, |compressed_size| points to the compressed data // size after the call. +// |malloc_fn| and |free_fn| are pointers to malloc() and free()-like functions, +// or nullptr to use the standard ones. // Returns true for success. bool GzipCompress(base::StringPiece input, char* output_buffer, size_t output_buffer_size, - size_t* compressed_size); + size_t* compressed_size, + void* (*malloc_fn)(size_t), + void (*free_fn)(void*)); // Compresses the data in |input| using gzip, storing the result in |output|. // |input| and |output| are allowed to point to the same string (in-place |