From 211f2d4afbd2201093ecbf5147b3c76a669e8236 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Wed, 15 Jun 2016 17:29:58 -0700 Subject: [PATCH] Revert base roll and its fallout. Updating base turns out to be more complicated than I thought. This reverts commit daa822aae70a8ab860ed8f085cdadf6987c28d03. This reverts commit c38428c7b98951e2cccf6b38881eabd87786da49. This reverts commit 4b73a8a0486d45081c5dde4e2c51c32d1376250b. --- DEPS | 14 +- build/secondary/testing/gtest/BUILD.gn | 14 + .../third_party/android_tools/BUILD.gn | 9 +- build/secondary/third_party/libsrtp/BUILD.gn | 391 ++++++ build/secondary/third_party/nss/BUILD.gn | 1211 +++++++++++++++++ build/secondary/tools/grit/grit_rule.gni | 173 ++- mojo/message_pump/handle_watcher.cc | 4 +- sky/dist/BUILD.gn | 2 +- sky/engine/core/BUILD.gn | 10 +- sky/engine/platform/BUILD.gn | 8 +- sky/engine/wtf/BUILD.gn | 9 +- sky/services/activity/BUILD.gn | 4 +- sky/services/editing/BUILD.gn | 4 +- sky/services/media/BUILD.gn | 4 +- sky/services/platform/BUILD.gn | 4 +- sky/services/vsync/BUILD.gn | 4 +- sky/shell/BUILD.gn | 125 +- sky/shell/dart/dart_library_provider_files.cc | 24 +- sky/shell/shell.cc | 9 +- sky/tools/sky_snapshot/loader.cc | 24 +- third_party/BUILD.gn | 4 +- third_party/harfbuzz-ng/BUILD.gn | 11 + third_party/libpng/BUILD.gn | 10 + third_party/libpng/libpng.gyp | 90 ++ third_party/tcmalloc/OWNERS | 3 - third_party/tcmalloc/README.chromium | 1 + .../src/base/arm_instruction_set_select.h | 7 +- .../tcmalloc/chromium/src/debugallocation.cc | 8 +- .../chromium/src/deep-heap-profile.cc | 1161 ++++++++++++++++ .../tcmalloc/chromium/src/deep-heap-profile.h | 407 ++++++ .../src/gperftools/type_profiler_map.h | 20 + .../chromium/src/heap-profile-table.cc | 63 +- .../chromium/src/heap-profile-table.h | 32 + .../tcmalloc/chromium/src/heap-profiler.cc | 83 +- .../chromium/src/type_profiler_map.cc | 112 ++ third_party/zlib/BUILD.gn | 20 +- third_party/zlib/google/DEPS | 4 + third_party/zlib/google/zip.cc | 2 +- third_party/zlib/google/zip.gyp | 27 + third_party/zlib/google/zip_reader.cc | 12 +- third_party/zlib/zlib.gyp | 148 ++ ui/gl/gl_version_info.cc | 4 +- 42 files changed, 4110 insertions(+), 166 deletions(-) create mode 100644 build/secondary/third_party/libsrtp/BUILD.gn create mode 100644 build/secondary/third_party/nss/BUILD.gn create mode 100644 third_party/libpng/libpng.gyp create mode 100644 third_party/tcmalloc/chromium/src/deep-heap-profile.cc create mode 100644 third_party/tcmalloc/chromium/src/deep-heap-profile.h create mode 100644 third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h create mode 100644 third_party/tcmalloc/chromium/src/type_profiler_map.cc create mode 100644 third_party/zlib/google/DEPS create mode 100644 third_party/zlib/google/zip.gyp create mode 100644 third_party/zlib/zlib.gyp diff --git a/DEPS b/DEPS index 644b0971e..3c4d826e0 100644 --- a/DEPS +++ b/DEPS @@ -20,7 +20,7 @@ vars = { 'chromium_git': 'https://chromium.googlesource.com', 'mojo_sdk_revision': 'fbe912aa65e0346382bc1e2874eb88fa3aad3358', - 'base_revision': 'ff0b4b505e01de0098fd6ed13cf6661fa58be851', + 'base_revision': '672b04e54b937ec899429a6bd5409c5a6300d151', 'skia_revision': '8cc209111876b7c78b5ec577c9221d8ed5e21024', # Note: When updating the Dart revision, ensure that all entries that are @@ -30,7 +30,7 @@ vars = { 'dart_observatory_packages_revision': 'cf90eb9077177d3d6b3fd5e8289477c2385c026a', 'dart_root_certificates_revision': 'aed07942ce98507d2be28cbd29e879525410c7fc', - 'buildtools_revision': '222bd42ce39d1bd8f08fe089b066f49c469e1cdf', + 'buildtools_revision': '565d04e8741429fb1b4f26d102f2c6c3b849edeb', } # Only these hosts are allowed for dependencies in this DEPS file. @@ -42,19 +42,19 @@ allowed_hosts = [ deps = { 'src/base': - 'https://github.com/domokit/base.git' + '@' + Var('base_revision'), + Var('chromium_git') + '/external/github.com/domokit/base' + '@' + Var('base_revision'), 'src/buildtools': Var('chromium_git') + '/chromium/buildtools.git' + '@' + Var('buildtools_revision'), 'src/testing/gtest': - Var('chromium_git') + '/external/googletest.git' + '@' + '9855a87157778d39b95eccfb201a9dc90f6d61c6', + Var('chromium_git') + '/external/googletest.git' + '@' + '23574bf2333f834ff665f894c97bef8a5b33a0a9', 'src/testing/gmock': - Var('chromium_git') + '/external/googlemock.git' + '@' + '0421b6f358139f02e102c9c332ce19a33faf75be', + Var('chromium_git') + '/external/googlemock.git' + '@' + '29763965ab52f24565299976b936d1265cb6a271', 'src/third_party/icu': - Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '94e4b770ce2f6065d4261d29c32683a6099b9d93', + Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'c3f79166089e5360c09e3053fce50e6e296c3204', 'src/dart': Var('chromium_git') + '/external/github.com/dart-lang/sdk.git' + '@' + Var('dart_revision'), @@ -80,7 +80,7 @@ deps = { Var('chromium_git') + '/skia.git' + '@' + Var('skia_revision'), 'src/third_party/yasm/source/patched-yasm': - Var('chromium_git') + '/chromium/deps/yasm/patched-yasm.git' + '@' + '7da28c6c7c6a1387217352ce02b31754deb54d2a', + Var('chromium_git') + '/chromium/deps/yasm/patched-yasm.git' + '@' + '4671120cd8558ce62ee8672ebf3eb6f5216f909b', 'src/third_party/libjpeg_turbo': Var('chromium_git') + '/chromium/deps/libjpeg_turbo.git' + '@' + 'f4631b6ee8b1dbb05e51ae335a7886f9ac598ab6', diff --git a/build/secondary/testing/gtest/BUILD.gn b/build/secondary/testing/gtest/BUILD.gn index d8b0ac86c..073faec56 100644 --- a/build/secondary/testing/gtest/BUILD.gn +++ b/build/secondary/testing/gtest/BUILD.gn @@ -20,6 +20,10 @@ config("gtest_config") { # Gtest headers need to be able to find themselves. include_dirs = [ "include" ] + if (is_win) { + cflags = [ "/wd4800" ] # Unused variable warning. + } + if (is_posix) { defines += [ # gtest isn't able to figure out when RTTI is disabled for gcc @@ -107,6 +111,16 @@ static_library("gtest") { configs -= [ "//build/config/compiler:chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code" ] + + config("gtest_warnings") { + if (is_win && is_clang) { + # The Mutex constructor initializer list in gtest-port.cc is incorrectly + # ordered. See + # https://groups.google.com/d/msg/googletestframework/S5uSV8L2TX8/U1FaTDa6J6sJ. + cflags = [ "-Wno-reorder" ] + } + } + configs += [ ":gtest_warnings" ] } source_set("gtest_main") { diff --git a/build/secondary/third_party/android_tools/BUILD.gn b/build/secondary/third_party/android_tools/BUILD.gn index 6dc2583a2..afafffc1e 100644 --- a/build/secondary/third_party/android_tools/BUILD.gn +++ b/build/secondary/third_party/android_tools/BUILD.gn @@ -28,8 +28,11 @@ android_java_prebuilt("uiautomator_java") { jar_path = "$android_sdk/uiautomator.jar" } +android_java_prebuilt("android_support_annotations_javalib") { + jar_path = "$android_sdk_root/extras/android/support/annotations/android-support-annotations.jar" +} + java_prebuilt("android_support_multidex_java") { - supports_android = true jar_path = "$android_sdk_root/extras/android/support/multidex/library/libs/android-support-multidex.jar" } @@ -64,8 +67,8 @@ android_resources("android_support_v7_mediarouter_resources") { android_java_prebuilt("android_support_v7_mediarouter_java") { deps = [ - ":android_support_v7_appcompat_java", ":android_support_v7_mediarouter_resources", + ":android_support_v7_appcompat_java", ] jar_path = "$android_sdk_root/extras/android/support/v7/mediarouter/libs/android-support-v7-mediarouter.jar" } @@ -93,7 +96,9 @@ android_resources("google_play_services_default_resources") { android_java_prebuilt("google_play_services_default_java") { deps = [ ":android_support_v13_java", + ":android_support_v7_mediarouter_java", ":google_play_services_default_resources", ] + proguard_preprocess = false jar_path = "$android_sdk_root/extras/google/google_play_services/libproject/google-play-services_lib/libs/google-play-services.jar" } diff --git a/build/secondary/third_party/libsrtp/BUILD.gn b/build/secondary/third_party/libsrtp/BUILD.gn new file mode 100644 index 000000000..7601bea0d --- /dev/null +++ b/build/secondary/third_party/libsrtp/BUILD.gn @@ -0,0 +1,391 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +declare_args() { + use_system_libsrtp = false + use_srtp_boringssl = true +} + +config("libsrtp_config") { + defines = [ + "HAVE_CONFIG_H", + "HAVE_STDLIB_H", + "HAVE_STRING_H", + "TESTAPP_SOURCE", + ] + + include_dirs = [ + "config", + "srtp/include", + "srtp/crypto/include", + ] + + if (use_srtp_boringssl) { + defines += [ "OPENSSL" ] + } + + if (is_posix) { + defines += [ + "HAVE_INT16_T", + "HAVE_INT32_T", + "HAVE_INT8_T", + "HAVE_UINT16_T", + "HAVE_UINT32_T", + "HAVE_UINT64_T", + "HAVE_UINT8_T", + "HAVE_STDINT_H", + "HAVE_INTTYPES_H", + "HAVE_NETINET_IN_H", + "HAVE_ARPA_INET_H", + "HAVE_UNISTD_H", + ] + cflags = [ "-Wno-unused-variable" ] + } + + if (is_win) { + defines += [ + "HAVE_BYTESWAP_METHODS_H", + + # All Windows architectures are this way. + "SIZEOF_UNSIGNED_LONG=4", + "SIZEOF_UNSIGNED_LONG_LONG=8", + ] + } + + if (current_cpu == "x64" || current_cpu == "x86" || current_cpu == "arm") { + defines += [ + # TODO(leozwang): CPU_RISC doesn"t work properly on android/arm + # platform for unknown reasons, need to investigate the root cause + # of it. CPU_RISC is used for optimization only, and CPU_CISC should + # just work just fine, it has been tested on android/arm with srtp + # test applications and libjingle. + "CPU_CISC", + ] + } + + if (current_cpu == "mipsel") { + defines += [ "CPU_RISC" ] + } +} + +config("system_libsrtp_config") { + defines = [ "USE_SYSTEM_LIBSRTP" ] + include_dirs = [ "/usr/include/srtp" ] +} + +if (use_system_libsrtp) { + group("libsrtp") { + public_configs = [ + ":libsrtp_config", + ":system_libsrtp_config", + ] + libs = [ "-lsrtp" ] + } +} else { + static_library("libsrtp") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + public_configs = [ ":libsrtp_config" ] + + sources = [ + # includes + "srtp/include/ekt.h", + "srtp/include/getopt_s.h", + "srtp/include/rtp.h", + "srtp/include/rtp_priv.h", + "srtp/include/srtp.h", + "srtp/include/srtp_priv.h", + "srtp/include/ut_sim.h", + + # headers + "srtp/crypto/include/aes.h", + "srtp/crypto/include/aes_cbc.h", + "srtp/crypto/include/aes_icm.h", + "srtp/crypto/include/alloc.h", + "srtp/crypto/include/auth.h", + "srtp/crypto/include/cipher.h", + "srtp/crypto/include/crypto.h", + "srtp/crypto/include/crypto_kernel.h", + "srtp/crypto/include/crypto_math.h", + "srtp/crypto/include/crypto_types.h", + "srtp/crypto/include/cryptoalg.h", + "srtp/crypto/include/datatypes.h", + "srtp/crypto/include/err.h", + "srtp/crypto/include/gf2_8.h", + "srtp/crypto/include/hmac.h", + "srtp/crypto/include/integers.h", + "srtp/crypto/include/kernel_compat.h", + "srtp/crypto/include/key.h", + "srtp/crypto/include/null_auth.h", + "srtp/crypto/include/null_cipher.h", + "srtp/crypto/include/prng.h", + "srtp/crypto/include/rand_source.h", + "srtp/crypto/include/rdb.h", + "srtp/crypto/include/rdbx.h", + "srtp/crypto/include/sha1.h", + "srtp/crypto/include/stat.h", + "srtp/crypto/include/xfm.h", + + # sources + "srtp/crypto/cipher/aes.c", + "srtp/crypto/cipher/aes_cbc.c", + "srtp/crypto/cipher/aes_icm.c", + "srtp/crypto/cipher/cipher.c", + "srtp/crypto/cipher/null_cipher.c", + "srtp/crypto/hash/auth.c", + "srtp/crypto/hash/hmac.c", + "srtp/crypto/hash/null_auth.c", + "srtp/crypto/hash/sha1.c", + "srtp/crypto/kernel/alloc.c", + "srtp/crypto/kernel/crypto_kernel.c", + "srtp/crypto/kernel/err.c", + "srtp/crypto/kernel/key.c", + "srtp/crypto/math/datatypes.c", + "srtp/crypto/math/gf2_8.c", + "srtp/crypto/math/stat.c", + "srtp/crypto/replay/rdb.c", + "srtp/crypto/replay/rdbx.c", + "srtp/crypto/replay/ut_sim.c", + "srtp/crypto/rng/ctr_prng.c", + "srtp/crypto/rng/prng.c", + "srtp/crypto/rng/rand_source.c", + "srtp/srtp/ekt.c", + "srtp/srtp/srtp.c", + ] + + if (is_clang) { + cflags = [ "-Wno-implicit-function-declaration" ] + } + + if (use_srtp_boringssl) { + deps = [ + "//third_party/boringssl:boringssl", + ] + public_deps = [ + "//third_party/boringssl:boringssl", + ] + sources -= [ + "srtp/crypto/cipher/aes_cbc.c", + "srtp/crypto/cipher/aes_icm.c", + "srtp/crypto/hash/hmac.c", + "srtp/crypto/hash/sha1.c", + "srtp/crypto/rng/ctr_prng.c", + "srtp/crypto/rng/prng.c", + ] + sources += [ + "srtp/crypto/cipher/aes_gcm_ossl.c", + "srtp/crypto/cipher/aes_icm_ossl.c", + "srtp/crypto/hash/hmac_ossl.c", + "srtp/crypto/include/aes_gcm_ossl.h", + "srtp/crypto/include/aes_icm_ossl.h", + ] + } + } + + # TODO(GYP): A bunch of these tests don't compile (in gyp either). They're + # not very broken, so could probably be made to work if it's useful. + if (!is_win) { + executable("rdbx_driver") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/include/getopt_s.h", + "srtp/test/getopt_s.c", + "srtp/test/rdbx_driver.c", + ] + } + + executable("srtp_driver") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/include/getopt_s.h", + "srtp/include/srtp_priv.h", + "srtp/test/getopt_s.c", + "srtp/test/srtp_driver.c", + ] + } + + executable("roc_driver") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/crypto/include/rdbx.h", + "srtp/include/ut_sim.h", + "srtp/test/roc_driver.c", + ] + } + + executable("replay_driver") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/crypto/include/rdbx.h", + "srtp/include/ut_sim.h", + "srtp/test/replay_driver.c", + ] + } + + executable("rtpw") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/crypto/include/datatypes.h", + "srtp/include/getopt_s.h", + "srtp/include/rtp.h", + "srtp/include/srtp.h", + "srtp/test/getopt_s.c", + "srtp/test/rtp.c", + "srtp/test/rtpw.c", + ] + if (is_android) { + defines = [ "HAVE_SYS_SOCKET_H" ] + } + if (is_clang) { + cflags = [ "-Wno-implicit-function-declaration" ] + } + } + + executable("srtp_test_cipher_driver") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/crypto/test/cipher_driver.c", + "srtp/include/getopt_s.h", + "srtp/test/getopt_s.c", + ] + } + + executable("srtp_test_datatypes_driver") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/crypto/test/datatypes_driver.c", + ] + } + + executable("srtp_test_stat_driver") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/crypto/test/stat_driver.c", + ] + } + + executable("srtp_test_sha1_driver") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/crypto/test/sha1_driver.c", + ] + } + + executable("srtp_test_kernel_driver") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/crypto/test/kernel_driver.c", + "srtp/include/getopt_s.h", + "srtp/test/getopt_s.c", + ] + } + + executable("srtp_test_aes_calc") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/crypto/test/aes_calc.c", + ] + } + + executable("srtp_test_rand_gen") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/crypto/test/rand_gen.c", + "srtp/include/getopt_s.h", + "srtp/test/getopt_s.c", + ] + } + + executable("srtp_test_rand_gen_soak") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/crypto/test/rand_gen_soak.c", + "srtp/include/getopt_s.h", + "srtp/test/getopt_s.c", + ] + } + + executable("srtp_test_env") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + deps = [ + ":libsrtp", + ] + sources = [ + "srtp/crypto/test/env.c", + ] + } + + group("srtp_runtest") { + deps = [ + ":rdbx_driver", + ":srtp_driver", + ":roc_driver", + ":replay_driver", + ":rtpw", + ":srtp_test_cipher_driver", + ":srtp_test_datatypes_driver", + ":srtp_test_stat_driver", + ":srtp_test_sha1_driver", + ":srtp_test_kernel_driver", + ":srtp_test_aes_calc", + ":srtp_test_rand_gen", + ":srtp_test_rand_gen_soak", + ":srtp_test_env", + ] + } + } +} diff --git a/build/secondary/third_party/nss/BUILD.gn b/build/secondary/third_party/nss/BUILD.gn new file mode 100644 index 000000000..25d449e14 --- /dev/null +++ b/build/secondary/third_party/nss/BUILD.gn @@ -0,0 +1,1211 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/linux/pkg_config.gni") + +if (is_linux) { + # This is a dependency on NSS with no libssl. On Linux we use a built-in SSL + # library but the system NSS libraries. Non-Linux platforms using NSS use the + # hermetic one in //third_party/nss. + # + # Generally you should depend on //crypto:platform instead of using this + # config since that will properly pick up NSS or OpenSSL depending on + # platform and build config. + pkg_config("system_nss_no_ssl_config") { + packages = [ "nss" ] + extra_args = [ + "-v", + "-lssl3", + ] + } +} else { + include_nss_root_certs = is_ios + include_nss_libpkix = is_ios + + config("nspr_config") { + defines = [ "NO_NSPR_10_SUPPORT" ] + include_dirs = [ + "nspr/pr/include", + "nspr/lib/ds", + "nspr/lib/libc/include", + ] + + if (component_mode != "shared_library") { + defines += [ "NSPR_STATIC" ] + } + } + + component("nspr") { + output_name = "crnspr" + sources = [ + "nspr/lib/ds/plarena.c", + "nspr/lib/ds/plarena.h", + "nspr/lib/ds/plarenas.h", + "nspr/lib/ds/plhash.c", + "nspr/lib/ds/plhash.h", + "nspr/lib/libc/include/plbase64.h", + "nspr/lib/libc/include/plerror.h", + "nspr/lib/libc/include/plgetopt.h", + "nspr/lib/libc/include/plstr.h", + "nspr/lib/libc/src/base64.c", + "nspr/lib/libc/src/plerror.c", + "nspr/lib/libc/src/plgetopt.c", + "nspr/lib/libc/src/strcase.c", + "nspr/lib/libc/src/strcat.c", + "nspr/lib/libc/src/strchr.c", + "nspr/lib/libc/src/strcmp.c", + "nspr/lib/libc/src/strcpy.c", + "nspr/lib/libc/src/strdup.c", + "nspr/lib/libc/src/strlen.c", + "nspr/lib/libc/src/strpbrk.c", + "nspr/lib/libc/src/strstr.c", + "nspr/lib/libc/src/strtok.c", + "nspr/pr/include/md/_darwin.cfg", + "nspr/pr/include/md/_darwin.h", + "nspr/pr/include/md/_pcos.h", + "nspr/pr/include/md/_pth.h", + "nspr/pr/include/md/_unix_errors.h", + "nspr/pr/include/md/_unixos.h", + "nspr/pr/include/md/_win32_errors.h", + "nspr/pr/include/md/_win95.cfg", + "nspr/pr/include/md/_win95.h", + "nspr/pr/include/md/prosdep.h", + "nspr/pr/include/nspr.h", + "nspr/pr/include/obsolete/pralarm.h", + "nspr/pr/include/obsolete/probslet.h", + "nspr/pr/include/obsolete/protypes.h", + "nspr/pr/include/obsolete/prsem.h", + "nspr/pr/include/pratom.h", + "nspr/pr/include/prbit.h", + "nspr/pr/include/prclist.h", + "nspr/pr/include/prcmon.h", + "nspr/pr/include/prcountr.h", + "nspr/pr/include/prcpucfg.h", + "nspr/pr/include/prcvar.h", + "nspr/pr/include/prdtoa.h", + "nspr/pr/include/prenv.h", + "nspr/pr/include/prerr.h", + "nspr/pr/include/prerror.h", + "nspr/pr/include/prinet.h", + "nspr/pr/include/prinit.h", + "nspr/pr/include/prinrval.h", + "nspr/pr/include/prio.h", + "nspr/pr/include/pripcsem.h", + "nspr/pr/include/private/pprio.h", + "nspr/pr/include/private/pprmwait.h", + "nspr/pr/include/private/pprthred.h", + "nspr/pr/include/private/primpl.h", + "nspr/pr/include/private/prpriv.h", + "nspr/pr/include/prlink.h", + "nspr/pr/include/prlock.h", + "nspr/pr/include/prlog.h", + "nspr/pr/include/prlong.h", + "nspr/pr/include/prmem.h", + "nspr/pr/include/prmon.h", + "nspr/pr/include/prmwait.h", + "nspr/pr/include/prnetdb.h", + "nspr/pr/include/prolock.h", + "nspr/pr/include/prpdce.h", + "nspr/pr/include/prprf.h", + "nspr/pr/include/prproces.h", + "nspr/pr/include/prrng.h", + "nspr/pr/include/prrwlock.h", + "nspr/pr/include/prshm.h", + "nspr/pr/include/prshma.h", + "nspr/pr/include/prsystem.h", + "nspr/pr/include/prthread.h", + "nspr/pr/include/prtime.h", + "nspr/pr/include/prtpool.h", + "nspr/pr/include/prtrace.h", + "nspr/pr/include/prtypes.h", + "nspr/pr/include/prvrsion.h", + "nspr/pr/include/prwin16.h", + "nspr/pr/src/io/prdir.c", + "nspr/pr/src/io/prfdcach.c", + "nspr/pr/src/io/prfile.c", + "nspr/pr/src/io/prio.c", + "nspr/pr/src/io/priometh.c", + "nspr/pr/src/io/pripv6.c", + "nspr/pr/src/io/prlayer.c", + "nspr/pr/src/io/prlog.c", + "nspr/pr/src/io/prmapopt.c", + "nspr/pr/src/io/prmmap.c", + "nspr/pr/src/io/prmwait.c", + "nspr/pr/src/io/prpolevt.c", + "nspr/pr/src/io/prprf.c", + "nspr/pr/src/io/prscanf.c", + "nspr/pr/src/io/prsocket.c", + "nspr/pr/src/io/prstdio.c", + "nspr/pr/src/linking/prlink.c", + "nspr/pr/src/malloc/prmalloc.c", + "nspr/pr/src/malloc/prmem.c", + "nspr/pr/src/md/prosdep.c", + "nspr/pr/src/md/unix/darwin.c", + "nspr/pr/src/md/unix/os_Darwin.s", + "nspr/pr/src/md/unix/unix.c", + "nspr/pr/src/md/unix/unix_errors.c", + "nspr/pr/src/md/unix/uxproces.c", + "nspr/pr/src/md/unix/uxrng.c", + "nspr/pr/src/md/unix/uxshm.c", + "nspr/pr/src/md/unix/uxwrap.c", + "nspr/pr/src/md/windows/ntgc.c", + "nspr/pr/src/md/windows/ntinrval.c", + "nspr/pr/src/md/windows/ntmisc.c", + "nspr/pr/src/md/windows/ntsec.c", + "nspr/pr/src/md/windows/ntsem.c", + "nspr/pr/src/md/windows/w32ipcsem.c", + "nspr/pr/src/md/windows/w32poll.c", + "nspr/pr/src/md/windows/w32rng.c", + "nspr/pr/src/md/windows/w32shm.c", + "nspr/pr/src/md/windows/w95cv.c", + "nspr/pr/src/md/windows/w95dllmain.c", + "nspr/pr/src/md/windows/w95io.c", + "nspr/pr/src/md/windows/w95sock.c", + "nspr/pr/src/md/windows/w95thred.c", + "nspr/pr/src/md/windows/win32_errors.c", + "nspr/pr/src/memory/prseg.c", + "nspr/pr/src/memory/prshm.c", + "nspr/pr/src/memory/prshma.c", + "nspr/pr/src/misc/pralarm.c", + "nspr/pr/src/misc/pratom.c", + "nspr/pr/src/misc/praton.c", + "nspr/pr/src/misc/prcountr.c", + "nspr/pr/src/misc/prdtoa.c", + "nspr/pr/src/misc/prenv.c", + "nspr/pr/src/misc/prerr.c", + "nspr/pr/src/misc/prerror.c", + "nspr/pr/src/misc/prerrortable.c", + "nspr/pr/src/misc/prinit.c", + "nspr/pr/src/misc/prinrval.c", + "nspr/pr/src/misc/pripc.c", + "nspr/pr/src/misc/pripcsem.c", + "nspr/pr/src/misc/prlog2.c", + "nspr/pr/src/misc/prlong.c", + "nspr/pr/src/misc/prnetdb.c", + "nspr/pr/src/misc/prolock.c", + "nspr/pr/src/misc/prrng.c", + "nspr/pr/src/misc/prsystem.c", + "nspr/pr/src/misc/prthinfo.c", + "nspr/pr/src/misc/prtime.c", + "nspr/pr/src/misc/prtpool.c", + "nspr/pr/src/misc/prtrace.c", + "nspr/pr/src/pthreads/ptio.c", + "nspr/pr/src/pthreads/ptmisc.c", + "nspr/pr/src/pthreads/ptsynch.c", + "nspr/pr/src/pthreads/ptthread.c", + "nspr/pr/src/threads/combined/prucpu.c", + "nspr/pr/src/threads/combined/prucv.c", + "nspr/pr/src/threads/combined/prulock.c", + "nspr/pr/src/threads/combined/prustack.c", + "nspr/pr/src/threads/combined/pruthr.c", + "nspr/pr/src/threads/prcmon.c", + "nspr/pr/src/threads/prcthr.c", + "nspr/pr/src/threads/prdump.c", + "nspr/pr/src/threads/prmon.c", + "nspr/pr/src/threads/prrwlock.c", + "nspr/pr/src/threads/prsem.c", + "nspr/pr/src/threads/prtpd.c", + ] + + public_configs = [ ":nspr_config" ] + + configs -= [ "//build/config/compiler:chromium_code" ] + if (is_win) { + configs -= [ + "//build/config/win:unicode", # Requires 8-bit mode. + "//build/config/win:lean_and_mean", # Won"t compile with lean and mean. + ] + } + configs += [ + "//build/config/compiler:no_chromium_code", + "//build/config/compiler:no_size_t_to_int_warning", + ] + + cflags = [] + defines = [ + "_NSPR_BUILD_", + "FORCE_PR_LOG", + ] + + include_dirs = [ "nspr/pr/include/private" ] + + if (is_win) { + cflags = [ "/wd4554" ] # Check precidence. + defines += [ + "XP_PC", + "WIN32", + "WIN95", + "_PR_GLOBAL_THREADS_ONLY", + "_CRT_SECURE_NO_WARNINGS", + ] + } else { + sources -= [ + "nspr/pr/src/md/windows/ntgc.c", + "nspr/pr/src/md/windows/ntinrval.c", + "nspr/pr/src/md/windows/ntmisc.c", + "nspr/pr/src/md/windows/ntsec.c", + "nspr/pr/src/md/windows/ntsem.c", + "nspr/pr/src/md/windows/w32ipcsem.c", + "nspr/pr/src/md/windows/w32poll.c", + "nspr/pr/src/md/windows/w32rng.c", + "nspr/pr/src/md/windows/w32shm.c", + "nspr/pr/src/md/windows/w95cv.c", + "nspr/pr/src/md/windows/w95dllmain.c", + "nspr/pr/src/md/windows/w95io.c", + "nspr/pr/src/md/windows/w95sock.c", + "nspr/pr/src/md/windows/w95thred.c", + "nspr/pr/src/md/windows/win32_errors.c", + "nspr/pr/src/threads/combined/prucpu.c", + "nspr/pr/src/threads/combined/prucv.c", + "nspr/pr/src/threads/combined/prulock.c", + "nspr/pr/src/threads/combined/prustack.c", + "nspr/pr/src/threads/combined/pruthr.c", + ] + } + + if (!is_posix) { + sources -= [ + "nspr/pr/src/md/unix/darwin.c", + "nspr/pr/src/md/unix/os_Darwin.s", + "nspr/pr/src/md/unix/unix.c", + "nspr/pr/src/md/unix/unix_errors.c", + "nspr/pr/src/md/unix/uxproces.c", + "nspr/pr/src/md/unix/uxrng.c", + "nspr/pr/src/md/unix/uxshm.c", + "nspr/pr/src/md/unix/uxwrap.c", + "nspr/pr/src/pthreads/ptio.c", + "nspr/pr/src/pthreads/ptmisc.c", + "nspr/pr/src/pthreads/ptsynch.c", + "nspr/pr/src/pthreads/ptthread.c", + ] + } + + if (current_cpu == "x86") { + defines += [ "_X86_" ] + } else if (current_cpu == "x64") { + defines += [ "_AMD64_" ] + } + + if (is_mac || is_ios) { + sources -= [ + "nspr/pr/src/io/prdir.c", + "nspr/pr/src/io/prfile.c", + "nspr/pr/src/io/prio.c", + "nspr/pr/src/io/prsocket.c", + "nspr/pr/src/misc/pripcsem.c", + "nspr/pr/src/threads/prcthr.c", + "nspr/pr/src/threads/prdump.c", + "nspr/pr/src/threads/prmon.c", + "nspr/pr/src/threads/prsem.c", + ] + defines += [ + "XP_UNIX", + "DARWIN", + "XP_MACOSX", + "_PR_PTHREADS", + "HAVE_BSD_FLOCK", + "HAVE_DLADDR", + "HAVE_LCHOWN", + "HAVE_SOCKLEN_T", + "HAVE_STRERROR", + ] + } + + if (is_mac) { + defines += [ "HAVE_CRT_EXTERNS_H" ] + libs = [ + "CoreFoundation.framework", + "CoreServices.framework", + ] + } + + if (is_clang) { + cflags += [ + # nspr uses a bunch of deprecated functions (NSLinkModule etc) in + # prlink.c on mac. + "-Wno-deprecated-declarations", + + # nspr passes "const char*" through "void*". + "-Wno-incompatible-pointer-types", + + # nspr passes "int*" through "unsigned int*". + "-Wno-pointer-sign", + ] + + # nspr uses assert(!"foo") instead of assert(false && "foo"). + configs -= [ "//build/config/clang:extra_warnings" ] + } + } + + component("nss") { + output_name = "crnss" + sources = [ + # Ensure at least one object file is produced, so that MSVC does not + # warn when creating the static/shared library. See the note for + # the "nssckbi" target for why the "nss" target was split as such. + "nss/lib/nss/nssver.c", + ] + + public_deps = [ + ":nss_static", + ] + + if (include_nss_root_certs) { + public_deps += [ ":nssckbi" ] + } + + if (component_mode == "shared_library") { + if (is_mac) { + ldflags = [ "-all_load" ] + } else if (is_win) { + # Pass the def file to the linker. + ldflags = + [ "/DEF:" + rebase_path("nss/exports_win.def", root_build_dir) ] + } + } + } + + config("nssckbi_config") { + include_dirs = [ "nss/lib/ckfw/builtins" ] + } + + # This is really more of a pseudo-target to work around the fact that + # a single static_library target cannot contain two object files of the + # same name (hash.o / hash.obj). Logically, this is part of the + # "nss_static" target. By separating it out, it creates a possible + # circular dependency between "nss_static" and "nssckbi" when + # "exclude_nss_root_certs" is not specified, as "nss_static" depends on + # the "builtinsC_GetFunctionList" exported by this target. This is an + # artifact of how NSS is being statically built, which is not an + # officially supported configuration - normally, "nssckbi.dll/so" would + # depend on libnss3.dll/so, and the higher layer caller would instruct + # libnss3.dll to dynamically load nssckbi.dll, breaking the circle. + # + # TODO(rsleevi): http://crbug.com/128134 - Break the circular dependency + # without requiring nssckbi to be built as a shared library. + source_set("nssckbi") { + visibility = [ ":nss" ] # This target is internal implementation detail. + + sources = [ + "nss/lib/ckfw/builtins/anchor.c", + "nss/lib/ckfw/builtins/bfind.c", + "nss/lib/ckfw/builtins/binst.c", + "nss/lib/ckfw/builtins/bobject.c", + "nss/lib/ckfw/builtins/bsession.c", + "nss/lib/ckfw/builtins/bslot.c", + "nss/lib/ckfw/builtins/btoken.c", + "nss/lib/ckfw/builtins/builtins.h", + "nss/lib/ckfw/builtins/certdata.c", + "nss/lib/ckfw/builtins/ckbiver.c", + "nss/lib/ckfw/builtins/constants.c", + "nss/lib/ckfw/builtins/nssckbi.h", + "nss/lib/ckfw/ck.h", + "nss/lib/ckfw/ckfw.h", + "nss/lib/ckfw/ckfwm.h", + "nss/lib/ckfw/ckfwtm.h", + "nss/lib/ckfw/ckmd.h", + "nss/lib/ckfw/ckt.h", + "nss/lib/ckfw/crypto.c", + "nss/lib/ckfw/find.c", + "nss/lib/ckfw/hash.c", + "nss/lib/ckfw/instance.c", + "nss/lib/ckfw/mechanism.c", + "nss/lib/ckfw/mutex.c", + "nss/lib/ckfw/nssck.api", + "nss/lib/ckfw/nssckepv.h", + "nss/lib/ckfw/nssckft.h", + "nss/lib/ckfw/nssckfw.h", + "nss/lib/ckfw/nssckfwc.h", + "nss/lib/ckfw/nssckfwt.h", + "nss/lib/ckfw/nssckg.h", + "nss/lib/ckfw/nssckmdt.h", + "nss/lib/ckfw/nssckt.h", + "nss/lib/ckfw/object.c", + "nss/lib/ckfw/session.c", + "nss/lib/ckfw/sessobj.c", + "nss/lib/ckfw/slot.c", + "nss/lib/ckfw/token.c", + "nss/lib/ckfw/wrap.c", + ] + + configs -= [ "//build/config/compiler:chromium_code" ] + + if (is_win) { + configs -= [ "//build/config/win:unicode" ] # Requires 8-bit mode. + } + configs += [ "//build/config/compiler:no_chromium_code" ] + + include_dirs = [ "nss/lib/ckfw" ] + public_configs = [ ":nssckbi_config" ] + + public_deps = [ + ":nss_static", + ] + } + + config("nss_static_config") { + defines = [ + "NSS_STATIC", + "NSS_USE_STATIC_LIBS", + "USE_UTIL_DIRECTLY", + ] + if (is_win) { + defines += [ "_WINDOWS" ] + } + include_dirs = [ + "nspr/pr/include", + "nspr/lib/ds", + "nspr/lib/libc/include", + "nss/lib/base", + "nss/lib/certdb", + "nss/lib/certhigh", + "nss/lib/cryptohi", + "nss/lib/dev", + "nss/lib/freebl", + "nss/lib/freebl/ecl", + "nss/lib/nss", + "nss/lib/pk11wrap", + "nss/lib/pkcs7", + "nss/lib/pki", + "nss/lib/smime", + "nss/lib/softoken", + "nss/lib/util", + ] + } + + if (is_win && current_cpu == "x86") { + source_set("nss_static_avx") { + sources = [ + "nss/lib/freebl/intel-gcm-wrap.c", + "nss/lib/freebl/intel-gcm-x86-masm.asm", + "nss/lib/freebl/intel-gcm.h", + ] + defines = [ + "_WINDOWS", + "_X86_", + "INTEL_GCM", + "MP_API_COMPATIBLE", + "MP_ASSEMBLY_DIV_2DX1D", + "MP_ASSEMBLY_MULTIPLY", + "MP_ASSEMBLY_SQUARE", + "MP_NO_MP_WORD", + "MP_USE_UINT_DIGIT", + "NSS_DISABLE_DBM", + "NSS_STATIC", + "NSS_USE_STATIC_LIBS", + "NSS_X86", + "NSS_X86_OR_X64", + "RIJNDAEL_INCLUDE_TABLES", + "SHLIB_PREFIX=\"\"", + "SHLIB_SUFFIX=\"dll\"", + "SHLIB_VERSION=\"3\"", + "SOFTOKEN_LIB_NAME=\"softokn3.dll\"", + "SOFTOKEN_SHLIB_VERSION=\"3\"", + "USE_HW_AES", + "USE_UTIL_DIRECTLY", + "WIN32", + "WIN95", + "XP_PC", + ] + include_dirs = [ + "nspr/pr/include", + "nspr/lib/ds", + "nspr/lib/libc/include", + "nss/lib/freebl/ecl", + "nss/lib/util", + ] + } + } + + source_set("nss_static") { + visibility = [ ":*" ] # Internal implementation detail. + + sources = [ + "nss/lib/base/arena.c", + "nss/lib/base/base.h", + "nss/lib/base/baset.h", + "nss/lib/base/error.c", + "nss/lib/base/errorval.c", + "nss/lib/base/hash.c", + "nss/lib/base/hashops.c", + "nss/lib/base/item.c", + "nss/lib/base/libc.c", + "nss/lib/base/list.c", + "nss/lib/base/nssbase.h", + "nss/lib/base/nssbaset.h", + "nss/lib/base/nssutf8.c", + "nss/lib/base/tracker.c", + "nss/lib/certdb/alg1485.c", + "nss/lib/certdb/cert.h", + "nss/lib/certdb/certdb.c", + "nss/lib/certdb/certdb.h", + "nss/lib/certdb/certi.h", + "nss/lib/certdb/certt.h", + "nss/lib/certdb/certv3.c", + "nss/lib/certdb/certxutl.c", + "nss/lib/certdb/certxutl.h", + "nss/lib/certdb/crl.c", + "nss/lib/certdb/genname.c", + "nss/lib/certdb/genname.h", + "nss/lib/certdb/polcyxtn.c", + "nss/lib/certdb/secname.c", + "nss/lib/certdb/stanpcertdb.c", + "nss/lib/certdb/xauthkid.c", + "nss/lib/certdb/xbsconst.c", + "nss/lib/certdb/xconst.c", + "nss/lib/certdb/xconst.h", + "nss/lib/certhigh/certhigh.c", + "nss/lib/certhigh/certhtml.c", + "nss/lib/certhigh/certreq.c", + "nss/lib/certhigh/certvfy.c", + "nss/lib/certhigh/crlv2.c", + "nss/lib/certhigh/ocsp.c", + "nss/lib/certhigh/ocsp.h", + "nss/lib/certhigh/ocspi.h", + "nss/lib/certhigh/ocspsig.c", + "nss/lib/certhigh/ocspt.h", + "nss/lib/certhigh/ocspti.h", + "nss/lib/certhigh/xcrldist.c", + "nss/lib/cryptohi/cryptohi.h", + "nss/lib/cryptohi/cryptoht.h", + "nss/lib/cryptohi/dsautil.c", + "nss/lib/cryptohi/key.h", + "nss/lib/cryptohi/keyhi.h", + "nss/lib/cryptohi/keyi.h", + "nss/lib/cryptohi/keyt.h", + "nss/lib/cryptohi/keythi.h", + "nss/lib/cryptohi/sechash.c", + "nss/lib/cryptohi/sechash.h", + "nss/lib/cryptohi/seckey.c", + "nss/lib/cryptohi/secsign.c", + "nss/lib/cryptohi/secvfy.c", + "nss/lib/dev/ckhelper.c", + "nss/lib/dev/ckhelper.h", + "nss/lib/dev/dev.h", + "nss/lib/dev/devm.h", + "nss/lib/dev/devslot.c", + "nss/lib/dev/devt.h", + "nss/lib/dev/devtm.h", + "nss/lib/dev/devtoken.c", + "nss/lib/dev/devutil.c", + "nss/lib/dev/nssdev.h", + "nss/lib/dev/nssdevt.h", + "nss/lib/freebl/aeskeywrap.c", + "nss/lib/freebl/alg2268.c", + "nss/lib/freebl/alghmac.c", + "nss/lib/freebl/alghmac.h", + "nss/lib/freebl/arcfive.c", + "nss/lib/freebl/arcfour.c", + "nss/lib/freebl/blapi.h", + "nss/lib/freebl/blapii.h", + "nss/lib/freebl/blapit.h", + "nss/lib/freebl/camellia.c", + "nss/lib/freebl/camellia.h", + "nss/lib/freebl/chacha20/chacha20.c", + "nss/lib/freebl/chacha20/chacha20.h", + "nss/lib/freebl/chacha20/chacha20_vec.c", + "nss/lib/freebl/chacha20poly1305.c", + "nss/lib/freebl/chacha20poly1305.h", + "nss/lib/freebl/ctr.c", + "nss/lib/freebl/ctr.h", + "nss/lib/freebl/cts.c", + "nss/lib/freebl/cts.h", + "nss/lib/freebl/des.c", + "nss/lib/freebl/des.h", + "nss/lib/freebl/desblapi.c", + "nss/lib/freebl/dh.c", + "nss/lib/freebl/drbg.c", + "nss/lib/freebl/dsa.c", + "nss/lib/freebl/ec.c", + "nss/lib/freebl/ec.h", + "nss/lib/freebl/ecdecode.c", + "nss/lib/freebl/ecl/ec2.h", + "nss/lib/freebl/ecl/ec_naf.c", + "nss/lib/freebl/ecl/ecl-curve.h", + "nss/lib/freebl/ecl/ecl-exp.h", + "nss/lib/freebl/ecl/ecl-priv.h", + "nss/lib/freebl/ecl/ecl.c", + "nss/lib/freebl/ecl/ecl.h", + "nss/lib/freebl/ecl/ecl_curve.c", + "nss/lib/freebl/ecl/ecl_gf.c", + "nss/lib/freebl/ecl/ecl_mult.c", + "nss/lib/freebl/ecl/ecp.h", + "nss/lib/freebl/ecl/ecp_256.c", + "nss/lib/freebl/ecl/ecp_256_32.c", + "nss/lib/freebl/ecl/ecp_384.c", + "nss/lib/freebl/ecl/ecp_521.c", + "nss/lib/freebl/ecl/ecp_aff.c", + "nss/lib/freebl/ecl/ecp_jac.c", + "nss/lib/freebl/ecl/ecp_jm.c", + "nss/lib/freebl/ecl/ecp_mont.c", + "nss/lib/freebl/gcm.c", + "nss/lib/freebl/gcm.h", + "nss/lib/freebl/hmacct.c", + "nss/lib/freebl/hmacct.h", + "nss/lib/freebl/intel-aes-x86-masm.asm", + "nss/lib/freebl/intel-aes.h", + "nss/lib/freebl/jpake.c", + "nss/lib/freebl/md2.c", + "nss/lib/freebl/md5.c", + "nss/lib/freebl/mpi/logtab.h", + "nss/lib/freebl/mpi/mp_gf2m-priv.h", + "nss/lib/freebl/mpi/mp_gf2m.c", + "nss/lib/freebl/mpi/mp_gf2m.h", + "nss/lib/freebl/mpi/mpcpucache.c", + "nss/lib/freebl/mpi/mpi-config.h", + "nss/lib/freebl/mpi/mpi-priv.h", + "nss/lib/freebl/mpi/mpi.c", + "nss/lib/freebl/mpi/mpi.h", + "nss/lib/freebl/mpi/mpi_amd64.c", + "nss/lib/freebl/mpi/mpi_arm.c", + "nss/lib/freebl/mpi/mpi_arm_mac.c", + "nss/lib/freebl/mpi/mpi_x86_asm.c", + "nss/lib/freebl/mpi/mplogic.c", + "nss/lib/freebl/mpi/mplogic.h", + "nss/lib/freebl/mpi/mpmontg.c", + "nss/lib/freebl/mpi/mpprime.c", + "nss/lib/freebl/mpi/mpprime.h", + "nss/lib/freebl/mpi/primes.c", + "nss/lib/freebl/nss_build_config_mac.h", + "nss/lib/freebl/poly1305/poly1305-donna-x64-sse2-incremental-source.c", + "nss/lib/freebl/poly1305/poly1305.c", + "nss/lib/freebl/poly1305/poly1305.h", + "nss/lib/freebl/pqg.c", + "nss/lib/freebl/pqg.h", + "nss/lib/freebl/rawhash.c", + "nss/lib/freebl/rijndael.c", + "nss/lib/freebl/rijndael.h", + "nss/lib/freebl/rijndael32.tab", + "nss/lib/freebl/rsa.c", + "nss/lib/freebl/rsapkcs.c", + "nss/lib/freebl/secmpi.h", + "nss/lib/freebl/secrng.h", + "nss/lib/freebl/seed.c", + "nss/lib/freebl/seed.h", + "nss/lib/freebl/sha256.h", + "nss/lib/freebl/sha512.c", + "nss/lib/freebl/sha_fast.c", + "nss/lib/freebl/sha_fast.h", + "nss/lib/freebl/shsign.h", + "nss/lib/freebl/shvfy.c", + "nss/lib/freebl/sysrand.c", + "nss/lib/freebl/tlsprfalg.c", + "nss/lib/freebl/unix_rand.c", + "nss/lib/freebl/win_rand.c", + "nss/lib/nss/nss.h", + "nss/lib/nss/nssinit.c", + "nss/lib/nss/nssrenam.h", + "nss/lib/nss/utilwrap.c", + "nss/lib/pk11wrap/debug_module.c", + "nss/lib/pk11wrap/dev3hack.c", + "nss/lib/pk11wrap/dev3hack.h", + "nss/lib/pk11wrap/pk11akey.c", + "nss/lib/pk11wrap/pk11auth.c", + "nss/lib/pk11wrap/pk11cert.c", + "nss/lib/pk11wrap/pk11cxt.c", + "nss/lib/pk11wrap/pk11err.c", + "nss/lib/pk11wrap/pk11func.h", + "nss/lib/pk11wrap/pk11kea.c", + "nss/lib/pk11wrap/pk11list.c", + "nss/lib/pk11wrap/pk11load.c", + "nss/lib/pk11wrap/pk11mech.c", + "nss/lib/pk11wrap/pk11merge.c", + "nss/lib/pk11wrap/pk11nobj.c", + "nss/lib/pk11wrap/pk11obj.c", + "nss/lib/pk11wrap/pk11pars.c", + "nss/lib/pk11wrap/pk11pbe.c", + "nss/lib/pk11wrap/pk11pk12.c", + "nss/lib/pk11wrap/pk11pqg.c", + "nss/lib/pk11wrap/pk11pqg.h", + "nss/lib/pk11wrap/pk11priv.h", + "nss/lib/pk11wrap/pk11pub.h", + "nss/lib/pk11wrap/pk11sdr.c", + "nss/lib/pk11wrap/pk11sdr.h", + "nss/lib/pk11wrap/pk11skey.c", + "nss/lib/pk11wrap/pk11slot.c", + "nss/lib/pk11wrap/pk11util.c", + "nss/lib/pk11wrap/secmod.h", + "nss/lib/pk11wrap/secmodi.h", + "nss/lib/pk11wrap/secmodt.h", + "nss/lib/pk11wrap/secmodti.h", + "nss/lib/pk11wrap/secpkcs5.h", + "nss/lib/pkcs7/certread.c", + "nss/lib/pkcs7/p7common.c", + "nss/lib/pkcs7/p7create.c", + "nss/lib/pkcs7/p7decode.c", + "nss/lib/pkcs7/p7encode.c", + "nss/lib/pkcs7/p7local.c", + "nss/lib/pkcs7/p7local.h", + "nss/lib/pkcs7/pkcs7t.h", + "nss/lib/pkcs7/secmime.c", + "nss/lib/pkcs7/secmime.h", + "nss/lib/pkcs7/secpkcs7.h", + "nss/lib/pki/asymmkey.c", + "nss/lib/pki/certdecode.c", + "nss/lib/pki/certificate.c", + "nss/lib/pki/cryptocontext.c", + "nss/lib/pki/nsspki.h", + "nss/lib/pki/nsspkit.h", + "nss/lib/pki/pki.h", + "nss/lib/pki/pki3hack.c", + "nss/lib/pki/pki3hack.h", + "nss/lib/pki/pkibase.c", + "nss/lib/pki/pkim.h", + "nss/lib/pki/pkistore.c", + "nss/lib/pki/pkistore.h", + "nss/lib/pki/pkit.h", + "nss/lib/pki/pkitm.h", + "nss/lib/pki/symmkey.c", + "nss/lib/pki/tdcache.c", + "nss/lib/pki/trustdomain.c", + "nss/lib/smime/cms.h", + "nss/lib/smime/cmslocal.h", + "nss/lib/smime/cmsreclist.h", + "nss/lib/smime/cmst.h", + "nss/lib/smime/smime.h", + "nss/lib/softoken/fipsaudt.c", + "nss/lib/softoken/fipstest.c", + "nss/lib/softoken/fipstokn.c", + "nss/lib/softoken/jpakesftk.c", + "nss/lib/softoken/lgglue.c", + "nss/lib/softoken/lgglue.h", + "nss/lib/softoken/lowkey.c", + "nss/lib/softoken/lowkeyi.h", + "nss/lib/softoken/lowkeyti.h", + "nss/lib/softoken/lowpbe.c", + "nss/lib/softoken/lowpbe.h", + "nss/lib/softoken/padbuf.c", + "nss/lib/softoken/pkcs11.c", + "nss/lib/softoken/pkcs11c.c", + "nss/lib/softoken/pkcs11i.h", + "nss/lib/softoken/pkcs11ni.h", + "nss/lib/softoken/pkcs11u.c", + "nss/lib/softoken/sdb.c", + "nss/lib/softoken/sdb.h", + "nss/lib/softoken/sftkdb.c", + "nss/lib/softoken/sftkdb.h", + "nss/lib/softoken/sftkdbt.h", + "nss/lib/softoken/sftkdbti.h", + "nss/lib/softoken/sftkhmac.c", + "nss/lib/softoken/sftkpars.c", + "nss/lib/softoken/sftkpars.h", + "nss/lib/softoken/sftkpwd.c", + "nss/lib/softoken/softkver.c", + "nss/lib/softoken/softkver.h", + "nss/lib/softoken/softoken.h", + "nss/lib/softoken/softoknt.h", + "nss/lib/softoken/tlsprf.c", + "nss/lib/ssl/sslerr.h", + "nss/lib/util/SECerrs.h", + "nss/lib/util/base64.h", + "nss/lib/util/ciferfam.h", + "nss/lib/util/derdec.c", + "nss/lib/util/derenc.c", + "nss/lib/util/dersubr.c", + "nss/lib/util/dertime.c", + "nss/lib/util/errstrs.c", + "nss/lib/util/hasht.h", + "nss/lib/util/nssb64.h", + "nss/lib/util/nssb64d.c", + "nss/lib/util/nssb64e.c", + "nss/lib/util/nssb64t.h", + "nss/lib/util/nssilckt.h", + "nss/lib/util/nssilock.c", + "nss/lib/util/nssilock.h", + "nss/lib/util/nsslocks.h", + "nss/lib/util/nssrwlk.c", + "nss/lib/util/nssrwlk.h", + "nss/lib/util/nssrwlkt.h", + "nss/lib/util/nssutil.h", + "nss/lib/util/oidstring.c", + "nss/lib/util/pkcs11.h", + "nss/lib/util/pkcs11f.h", + "nss/lib/util/pkcs11n.h", + "nss/lib/util/pkcs11p.h", + "nss/lib/util/pkcs11t.h", + "nss/lib/util/pkcs11u.h", + "nss/lib/util/pkcs1sig.c", + "nss/lib/util/pkcs1sig.h", + "nss/lib/util/portreg.c", + "nss/lib/util/portreg.h", + "nss/lib/util/quickder.c", + "nss/lib/util/secalgid.c", + "nss/lib/util/secasn1.h", + "nss/lib/util/secasn1d.c", + "nss/lib/util/secasn1e.c", + "nss/lib/util/secasn1t.h", + "nss/lib/util/secasn1u.c", + "nss/lib/util/seccomon.h", + "nss/lib/util/secder.h", + "nss/lib/util/secdert.h", + "nss/lib/util/secdig.c", + "nss/lib/util/secdig.h", + "nss/lib/util/secdigt.h", + "nss/lib/util/secerr.h", + "nss/lib/util/secitem.c", + "nss/lib/util/secitem.h", + "nss/lib/util/secoid.c", + "nss/lib/util/secoid.h", + "nss/lib/util/secoidt.h", + "nss/lib/util/secport.c", + "nss/lib/util/secport.h", + "nss/lib/util/sectime.c", + "nss/lib/util/templates.c", + "nss/lib/util/utf8.c", + "nss/lib/util/utilmod.c", + "nss/lib/util/utilmodt.h", + "nss/lib/util/utilpars.c", + "nss/lib/util/utilpars.h", + "nss/lib/util/utilparst.h", + "nss/lib/util/utilrename.h", + ] + + sources -= [ + # mpi_arm.c is included by mpi_arm_mac.c. + # NOTE: mpi_arm.c can be used directly on Linux. mpi_arm.c will need + # to be excluded conditionally if we start to build NSS on Linux. + "nss/lib/freebl/mpi/mpi_arm.c", + + # primes.c is included by mpprime.c. + "nss/lib/freebl/mpi/primes.c", + + # unix_rand.c and win_rand.c are included by sysrand.c. + "nss/lib/freebl/unix_rand.c", + "nss/lib/freebl/win_rand.c", + + # debug_module.c is included by pk11load.c. + "nss/lib/pk11wrap/debug_module.c", + ] + + configs -= [ "//build/config/compiler:chromium_code" ] + if (is_win) { + configs -= [ "//build/config/win:unicode" ] # Requires 8-bit mode. + } + configs += [ + "//build/config/compiler:no_chromium_code", + "//build/config/compiler:no_size_t_to_int_warning", + ] + public_configs = [ ":nss_static_config" ] + + cflags = [] + + # Only need the defines and includes not in nss_static_config. + defines = [ + "MP_API_COMPATIBLE", + "NSS_DISABLE_DBM", + "RIJNDAEL_INCLUDE_TABLES", + "SHLIB_VERSION=\"3\"", + "SOFTOKEN_SHLIB_VERSION=\"3\"", + ] + include_dirs = [ + "nss/lib/freebl/mpi", + "nss/lib/ssl", + ] + + if (is_win) { + cflags += [ "/wd4101" ] # Unreferenced local variable. + } + + if (include_nss_libpkix) { + sources += [ + "nss/lib/certhigh/certvfypkix.c", + "nss/lib/certhigh/certvfypkixprint.c", + "nss/lib/libpkix/include/pkix.h", + "nss/lib/libpkix/include/pkix_certsel.h", + "nss/lib/libpkix/include/pkix_certstore.h", + "nss/lib/libpkix/include/pkix_checker.h", + "nss/lib/libpkix/include/pkix_crlsel.h", + "nss/lib/libpkix/include/pkix_errorstrings.h", + "nss/lib/libpkix/include/pkix_params.h", + "nss/lib/libpkix/include/pkix_pl_pki.h", + "nss/lib/libpkix/include/pkix_pl_system.h", + "nss/lib/libpkix/include/pkix_results.h", + "nss/lib/libpkix/include/pkix_revchecker.h", + "nss/lib/libpkix/include/pkix_sample_modules.h", + "nss/lib/libpkix/include/pkix_util.h", + "nss/lib/libpkix/include/pkixt.h", + "nss/lib/libpkix/pkix/certsel/pkix_certselector.c", + "nss/lib/libpkix/pkix/certsel/pkix_certselector.h", + "nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.c", + "nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.h", + "nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.c", + "nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.h", + "nss/lib/libpkix/pkix/checker/pkix_certchainchecker.c", + "nss/lib/libpkix/pkix/checker/pkix_certchainchecker.h", + "nss/lib/libpkix/pkix/checker/pkix_crlchecker.c", + "nss/lib/libpkix/pkix/checker/pkix_crlchecker.h", + "nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c", + "nss/lib/libpkix/pkix/checker/pkix_ekuchecker.h", + "nss/lib/libpkix/pkix/checker/pkix_expirationchecker.c", + "nss/lib/libpkix/pkix/checker/pkix_expirationchecker.h", + "nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.c", + "nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.h", + "nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.c", + "nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.h", + "nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c", + "nss/lib/libpkix/pkix/checker/pkix_ocspchecker.h", + "nss/lib/libpkix/pkix/checker/pkix_policychecker.c", + "nss/lib/libpkix/pkix/checker/pkix_policychecker.h", + "nss/lib/libpkix/pkix/checker/pkix_revocationchecker.c", + "nss/lib/libpkix/pkix/checker/pkix_revocationchecker.h", + "nss/lib/libpkix/pkix/checker/pkix_revocationmethod.c", + "nss/lib/libpkix/pkix/checker/pkix_revocationmethod.h", + "nss/lib/libpkix/pkix/checker/pkix_signaturechecker.c", + "nss/lib/libpkix/pkix/checker/pkix_signaturechecker.h", + "nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c", + "nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.h", + "nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.c", + "nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.h", + "nss/lib/libpkix/pkix/crlsel/pkix_crlselector.c", + "nss/lib/libpkix/pkix/crlsel/pkix_crlselector.h", + "nss/lib/libpkix/pkix/params/pkix_procparams.c", + "nss/lib/libpkix/pkix/params/pkix_procparams.h", + "nss/lib/libpkix/pkix/params/pkix_resourcelimits.c", + "nss/lib/libpkix/pkix/params/pkix_resourcelimits.h", + "nss/lib/libpkix/pkix/params/pkix_trustanchor.c", + "nss/lib/libpkix/pkix/params/pkix_trustanchor.h", + "nss/lib/libpkix/pkix/params/pkix_valparams.c", + "nss/lib/libpkix/pkix/params/pkix_valparams.h", + "nss/lib/libpkix/pkix/results/pkix_buildresult.c", + "nss/lib/libpkix/pkix/results/pkix_buildresult.h", + "nss/lib/libpkix/pkix/results/pkix_policynode.c", + "nss/lib/libpkix/pkix/results/pkix_policynode.h", + "nss/lib/libpkix/pkix/results/pkix_valresult.c", + "nss/lib/libpkix/pkix/results/pkix_valresult.h", + "nss/lib/libpkix/pkix/results/pkix_verifynode.c", + "nss/lib/libpkix/pkix/results/pkix_verifynode.h", + "nss/lib/libpkix/pkix/store/pkix_store.c", + "nss/lib/libpkix/pkix/store/pkix_store.h", + "nss/lib/libpkix/pkix/top/pkix_build.c", + "nss/lib/libpkix/pkix/top/pkix_build.h", + "nss/lib/libpkix/pkix/top/pkix_lifecycle.c", + "nss/lib/libpkix/pkix/top/pkix_lifecycle.h", + "nss/lib/libpkix/pkix/top/pkix_validate.c", + "nss/lib/libpkix/pkix/top/pkix_validate.h", + "nss/lib/libpkix/pkix/util/pkix_error.c", + "nss/lib/libpkix/pkix/util/pkix_error.h", + "nss/lib/libpkix/pkix/util/pkix_errpaths.c", + "nss/lib/libpkix/pkix/util/pkix_list.c", + "nss/lib/libpkix/pkix/util/pkix_list.h", + "nss/lib/libpkix/pkix/util/pkix_logger.c", + "nss/lib/libpkix/pkix/util/pkix_logger.h", + "nss/lib/libpkix/pkix/util/pkix_tools.c", + "nss/lib/libpkix/pkix/util/pkix_tools.h", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.h", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.c", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.h", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.h", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.h", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.c", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.h", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.c", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.h", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c", + "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.h", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.c", + "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.h", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.h", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.h", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.h", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_error.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.h", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.h", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.h", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.h", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.h", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.h", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.h", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.h", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.c", + "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.h", + ] + + # Disable the LDAP code in libpkix. + defines += [ "NSS_PKIX_NO_LDAP" ] + + include_dirs += [ + "nss/lib/libpkix/include", + "nss/lib/libpkix/pkix/certsel", + "nss/lib/libpkix/pkix/checker", + "nss/lib/libpkix/pkix/crlsel", + "nss/lib/libpkix/pkix/params", + "nss/lib/libpkix/pkix/results", + "nss/lib/libpkix/pkix/store", + "nss/lib/libpkix/pkix/top", + "nss/lib/libpkix/pkix/util", + "nss/lib/libpkix/pkix_pl_nss/module", + "nss/lib/libpkix/pkix_pl_nss/pki", + "nss/lib/libpkix/pkix_pl_nss/system", + ] + } else { + defines += [ "NSS_DISABLE_LIBPKIX" ] + } + + if (!include_nss_root_certs) { + defines += [ "NSS_DISABLE_ROOT_CERTS" ] + } + + if (current_cpu == "x64" && !is_win) { + sources -= [ + "nss/lib/freebl/chacha20/chacha20.c", + "nss/lib/freebl/poly1305/poly1305.c", + ] + } else { + sources -= [ + "nss/lib/freebl/chacha20/chacha20_vec.c", + "nss/lib/freebl/poly1305/poly1305-donna-x64-sse2-incremental-source.c", + ] + } + + if (is_mac || is_ios) { + sources -= [ "nss/lib/freebl/mpi/mpi_amd64.c" ] + cflags += [ + "-include", + rebase_path("//third_party/nss/nss/lib/freebl/nss_build_config_mac.h", + root_build_dir), + ] + defines += [ + "XP_UNIX", + "DARWIN", + "HAVE_STRERROR", + "HAVE_BSD_FLOCK", + "SHLIB_SUFFIX=\"dylib\"", + "SHLIB_PREFIX=\"lib\"", + "SOFTOKEN_LIB_NAME=\"libsoftokn3.dylib\"", + ] + + configs -= [ "//build/config/gcc:symbol_visibility_hidden" ] + } else { + # Not Mac/iOS. + sources -= [ "nss/lib/freebl/mpi/mpi_arm_mac.c" ] + } + + if (is_win) { + defines += [ + "SHLIB_SUFFIX=\"dll\"", + "SHLIB_PREFIX=\"\"", + "SOFTOKEN_LIB_NAME=\"softokn3.dll\"", + "XP_PC", + "WIN32", + "WIN95", + ] + + if (current_cpu == "x86") { + defines += [ + "NSS_X86_OR_X64", + "NSS_X86", + "_X86_", + "MP_ASSEMBLY_MULTIPLY", + "MP_ASSEMBLY_SQUARE", + "MP_ASSEMBLY_DIV_2DX1D", + "MP_USE_UINT_DIGIT", + "MP_NO_MP_WORD", + "USE_HW_AES", + "INTEL_GCM", + ] + sources -= [ "nss/lib/freebl/mpi/mpi_amd64.c" ] + } else if (current_cpu == "x64") { + sources -= [ + "nss/lib/freebl/intel-aes-x86-masm.asm", + "nss/lib/freebl/mpi/mpi_amd64.c", + "nss/lib/freebl/mpi/mpi_x86_asm.c", + ] + defines += [ + "NSS_USE_64", + "NSS_X86_OR_X64", + "NSS_X64", + "_AMD64_", + "MP_CHAR_STORE_SLOW", + "MP_IS_LITTLE_ENDIAN", + "WIN64", + ] + } + } else { + # Not Windows. + sources -= [ + # mpi_x86_asm.c contains MSVC inline assembly code. + "nss/lib/freebl/mpi/mpi_x86_asm.c", + ] + } + + if (is_clang) { + cflags += [ + # nss doesn"t explicitly cast between different enum types. + "-Wno-conversion", + + # nss passes "const char*" through "void*". + "-Wno-incompatible-pointer-types", + + # nss prefers `a && b || c` over `(a && b) || c`. + "-Wno-logical-op-parentheses", + + # nss doesn"t use exhaustive switches on enums + "-Wno-switch", + + # nss has some `unsigned < 0` checks. + "-Wno-tautological-compare", + ] + } + + public_deps = [ + ":nspr", + ] + deps = [ + ":nspr", + "//third_party/sqlite", + ] + + if (is_win && current_cpu == "x86") { + deps += [ ":nss_static_avx" ] + } + } +} # Windows/Mac/iOS. diff --git a/build/secondary/tools/grit/grit_rule.gni b/build/secondary/tools/grit/grit_rule.gni index 6b3d70a14..bdf812f21 100644 --- a/build/secondary/tools/grit/grit_rule.gni +++ b/build/secondary/tools/grit/grit_rule.gni @@ -11,11 +11,10 @@ # Path to .grd file. # # outputs (required) -# List of outputs from grit, relative to the target_gen_dir. If supplied, -# a call to Grit to compute the outputs can be skipped which will make -# GN run faster. Grit will verify at build time that this list is correct -# and will fail if there is a mismatch between the outputs specified by -# the .grd file and the outputs list here. +# List of outputs from grit, relative to the target_gen_dir. Grit will +# verify at build time that this list is correct and will fail if there +# is a mismatch between the outputs specified by the .grd file and the +# outputs list here. # # To get this list, you can look in the .grd file for # Requests; - friend struct base::DefaultSingletonTraits; + friend struct DefaultSingletonTraits; WatcherThreadManager(); @@ -221,7 +221,7 @@ WatcherThreadManager::~WatcherThreadManager() { } WatcherThreadManager* WatcherThreadManager::GetInstance() { - return base::Singleton::get(); + return Singleton::get(); } WatcherID WatcherThreadManager::StartWatching( diff --git a/sky/dist/BUILD.gn b/sky/dist/BUILD.gn index af5ed2fdf..3818ddcac 100644 --- a/sky/dist/BUILD.gn +++ b/sky/dist/BUILD.gn @@ -22,7 +22,7 @@ copy("sky_shell") { ] deps = [ - "//sky/shell:shell_application_struct", + "//sky/shell", ] } else if (!is_ios) { sources = [ diff --git a/sky/engine/core/BUILD.gn b/sky/engine/core/BUILD.gn index 67a49c2b6..b26dd3176 100644 --- a/sky/engine/core/BUILD.gn +++ b/sky/engine/core/BUILD.gn @@ -23,7 +23,6 @@ source_set("libraries") { "//mojo/public/platform/dart:mojo_internal_impl", "//skia", "//sky/engine/wtf", - "//third_party:jpeg", "//third_party/iccjpeg", "//third_party/libpng", "//third_party/qcms", @@ -39,14 +38,13 @@ source_set("libraries") { source_set("prerequisites") { deps = [ + ":libraries", "//sky/engine/platform", ] - public_deps = [ - ":libraries", - ] + forward_dependent_configs_from = [ ":libraries" ] - public_configs = [ + direct_dependent_configs = [ "//sky/engine:config", "//sky/engine:inside_blink", "//build/config/compiler:wexit_time_destructors", @@ -102,7 +100,7 @@ static_library("core") { rebase_path("//dart/runtime"), ] - public_deps = [ ":libraries" ] + forward_dependent_configs_from = [ ":libraries" ] # core and core_generated are really the same thing. allow_circular_includes_from = [ diff --git a/sky/engine/platform/BUILD.gn b/sky/engine/platform/BUILD.gn index 525d886c8..1d225a90c 100644 --- a/sky/engine/platform/BUILD.gn +++ b/sky/engine/platform/BUILD.gn @@ -354,13 +354,17 @@ source_set("platform") { "//mojo/public/cpp/system", "//mojo/public/cpp/utility", "//mojo/services/network/interfaces", + "//skia", "//sky/engine/wtf", "//third_party/harfbuzz-ng", + "//third_party/iccjpeg", "//third_party/icu", + "//third_party/libpng", "//third_party/qcms", + "//third_party:jpeg", ] - public_deps = [ + forward_dependent_configs_from = [ "//skia", "//third_party:jpeg", "//third_party/iccjpeg", @@ -379,7 +383,7 @@ source_set("platform") { } if (is_linux) { - public_configs = [ "//build/config/linux:fontconfig" ] + direct_dependent_configs = [ "//build/config/linux:fontconfig" ] } } diff --git a/sky/engine/wtf/BUILD.gn b/sky/engine/wtf/BUILD.gn index 767821f2c..28ffb107b 100644 --- a/sky/engine/wtf/BUILD.gn +++ b/sky/engine/wtf/BUILD.gn @@ -4,7 +4,7 @@ import("//testing/test.gni") -source_set("wtf") { +component("wtf") { sources = [ "ASCIICType.h", "AddressSpaceRandomization.cpp", @@ -225,16 +225,15 @@ source_set("wtf") { defines = [ "WTF_IMPLEMENTATION=1" ] - public_configs = [ "//sky/engine:features" ] + direct_dependent_configs = [ "//sky/engine:features" ] deps = [ "//base", - ] - - public_deps = [ "//third_party/icu", ] + forward_dependent_configs_from = [ "//third_party/icu" ] + if (is_android) { libs = [ "log" ] } diff --git a/sky/services/activity/BUILD.gn b/sky/services/activity/BUILD.gn index 5d47ba1e1..821937497 100644 --- a/sky/services/activity/BUILD.gn +++ b/sky/services/activity/BUILD.gn @@ -5,12 +5,12 @@ import("//mojo/public/tools/bindings/mojom.gni") group("activity") { - public_deps = [ + deps = [ ":interfaces", ] if (is_android || is_ios) { - public_deps += [ ":activity_lib" ] + deps += [ ":activity_lib" ] } } diff --git a/sky/services/editing/BUILD.gn b/sky/services/editing/BUILD.gn index 9c11444e6..383be36b7 100644 --- a/sky/services/editing/BUILD.gn +++ b/sky/services/editing/BUILD.gn @@ -5,12 +5,12 @@ import("//mojo/public/tools/bindings/mojom.gni") group("editing") { - public_deps = [ + deps = [ ":interfaces", ] if (is_android || is_ios) { - public_deps += [ ":editing_lib" ] + deps += [ ":editing_lib" ] } } diff --git a/sky/services/media/BUILD.gn b/sky/services/media/BUILD.gn index aad04b174..f42b0f70d 100644 --- a/sky/services/media/BUILD.gn +++ b/sky/services/media/BUILD.gn @@ -5,12 +5,12 @@ import("//mojo/public/tools/bindings/mojom.gni") group("media") { - public_deps = [ + deps = [ ":interfaces", ] if (is_android || is_ios) { - public_deps += [ ":media_lib" ] + deps += [ ":media_lib" ] } } diff --git a/sky/services/platform/BUILD.gn b/sky/services/platform/BUILD.gn index f8353ca55..efaedb79a 100644 --- a/sky/services/platform/BUILD.gn +++ b/sky/services/platform/BUILD.gn @@ -60,10 +60,10 @@ if (is_ios) { } group("platform") { - public_deps = [ + deps = [ ":interfaces" ] if (is_android || is_ios) { - public_deps += [ ":platform_lib" ] + deps += [ ":platform_lib" ] } } diff --git a/sky/services/vsync/BUILD.gn b/sky/services/vsync/BUILD.gn index f8d072553..885d34ee8 100644 --- a/sky/services/vsync/BUILD.gn +++ b/sky/services/vsync/BUILD.gn @@ -5,10 +5,10 @@ import("//mojo/public/tools/bindings/mojom.gni") group("vsync") { - public_deps = [] + deps = [] if (is_android || is_ios) { - public_deps += [ ":vsync_lib" ] + deps += [ ":vsync_lib" ] } } diff --git a/sky/shell/BUILD.gn b/sky/shell/BUILD.gn index ac0c92b96..5c1e927ef 100644 --- a/sky/shell/BUILD.gn +++ b/sky/shell/BUILD.gn @@ -67,8 +67,6 @@ source_set("common") { "//sky/engine", "//sky/engine/bindings", "//sky/engine/core:core", - "//sky/engine/platform", - "//sky/engine/public/sky", "//sky/engine/wtf", "//sky/services/editing:interfaces", "//sky/services/engine:interfaces", @@ -315,71 +313,71 @@ if (is_android) { ] } - framework_dir = "$root_out_dir/Flutter.framework" + group("flutter_framework") { + framework_dir = "$root_out_dir/Flutter.framework" - copy("framework_dylib") { - sources = [ "$root_out_dir/libFlutter.dylib" ] - outputs = [ "$framework_dir/Flutter" ] + copy("framework_dylib") { + sources = [ "$root_out_dir/libFlutter.dylib" ] + outputs = [ "$framework_dir/Flutter" ] - deps = [ - ":flutter_framework_dylib", - ] - } + deps = [ + ":flutter_framework_dylib", + ] + } - action("framework_install_name") { - stamp_file = "$root_out_dir/flutter_install_name_stamp" - script = "//sky/tools/change_install_name.py" + action("framework_install_name") { + stamp_file = "$root_out_dir/flutter_install_name_stamp" + script = "//sky/tools/change_install_name.py" - inputs = [ "$framework_dir/Flutter" ] - outputs = [ stamp_file ] + inputs = [ "$framework_dir/Flutter" ] + outputs = [ stamp_file ] - args = [ - "--dylib", - rebase_path("$framework_dir/Flutter"), - "--install_name", - "@rpath/Flutter.framework/Flutter", - "--stamp", - rebase_path(stamp_file), - ] + args = [ + "--dylib", + rebase_path("$framework_dir/Flutter"), + "--install_name", + "@rpath/Flutter.framework/Flutter", + "--stamp", + rebase_path(stamp_file), + ] - deps = [ - ":framework_dylib" - ] - } + deps = [ + ":framework_dylib" + ] + } - copy("framework_info_plist") { - sources = [ "platform/ios/framework/Info.plist" ] - outputs = [ "$framework_dir/Info.plist" ] - } + copy("framework_info_plist") { + sources = [ "platform/ios/framework/Info.plist" ] + outputs = [ "$framework_dir/Info.plist" ] + } - copy("framework_module_map") { - sources = [ "platform/ios/framework/module.modulemap" ] - outputs = [ "$framework_dir/Modules/module.modulemap" ] - } + copy("framework_module_map") { + sources = [ "platform/ios/framework/module.modulemap" ] + outputs = [ "$framework_dir/Modules/module.modulemap" ] + } - copy("framework_headers") { - sources = [ - "platform/ios/framework/Headers/Flutter.h", - "platform/ios/framework/Headers/FlutterAppDelegate.h", - "platform/ios/framework/Headers/FlutterAsyncMessageListener.h", - "platform/ios/framework/Headers/FlutterDartProject.h", - "platform/ios/framework/Headers/FlutterMacros.h", - "platform/ios/framework/Headers/FlutterMessageListener.h", - "platform/ios/framework/Headers/FlutterViewController.h", - ] - outputs = [ "$framework_dir/Headers/{{source_file_part}}" ] - } + copy("framework_headers") { + sources = [ + "platform/ios/framework/Headers/Flutter.h", + "platform/ios/framework/Headers/FlutterAppDelegate.h", + "platform/ios/framework/Headers/FlutterAsyncMessageListener.h", + "platform/ios/framework/Headers/FlutterDartProject.h", + "platform/ios/framework/Headers/FlutterMacros.h", + "platform/ios/framework/Headers/FlutterMessageListener.h", + "platform/ios/framework/Headers/FlutterViewController.h", + ] + outputs = [ "$framework_dir/Headers/{{source_file_part}}" ] + } - copy("framework_icu") { - set_sources_assignment_filter([]) - sources = [ - "//third_party/icu/android/icudtl.dat", - ] - set_sources_assignment_filter(sources_assignment_filter) - outputs = [ "$framework_dir/{{source_file_part}}" ] - } + copy("framework_icu") { + set_sources_assignment_filter([]) + sources = [ + "//third_party/icu/android/icudtl.dat", + ] + set_sources_assignment_filter(sources_assignment_filter) + outputs = [ "$framework_dir/{{source_file_part}}" ] + } - group("flutter_framework") { public_deps = [ ":framework_dylib", ":framework_headers", @@ -471,20 +469,19 @@ if (is_android) { ] } - resource_copy_mac("sky_resources") { - app_name = "SkyShell" - resources = [ - "//third_party/icu/android/icudtl.dat", - ] - bundle_directory = "." - } - mac_app("shell_application") { app_name = "SkyShell" info_plist = "platform/mac/Info.plist" xibs = [ "platform/mac/sky_mac.xib" ] + resource_copy_mac("sky_resources") { + resources = [ + "//third_party/icu/android/icudtl.dat", + ] + bundle_directory = "." + } + deps = [ ":mac_scaffolding", ":sky_resources", diff --git a/sky/shell/dart/dart_library_provider_files.cc b/sky/shell/dart/dart_library_provider_files.cc index 8e98eb1ae..cd12a36da 100644 --- a/sky/shell/dart/dart_library_provider_files.cc +++ b/sky/shell/dart/dart_library_provider_files.cc @@ -24,9 +24,9 @@ void CopyComplete(base::FilePath file, std::string uri, bool success) { // Extract the scheme prefix ('package:' or 'file:' from ) static std::string ExtractSchemePrefix(std::string url) { - if (base::StartsWith(url, "package:", base::CompareCase::SENSITIVE)) { + if (base::StartsWithASCII(url, "package:", true)) { return "package:"; - } else if (base::StartsWith(url, "file:", base::CompareCase::SENSITIVE)) { + } else if (base::StartsWithASCII(url, "file:", true)) { return "file:"; } return ""; @@ -34,9 +34,9 @@ static std::string ExtractSchemePrefix(std::string url) { // Extract the path from a package: or file: url. static std::string ExtractPath(std::string url) { - if (base::StartsWith(url, "package:", base::CompareCase::SENSITIVE)) { + if (base::StartsWithASCII(url, "package:", true)) { base::ReplaceFirstSubstringAfterOffset(&url, 0, "package:", ""); - } else if (base::StartsWith(url, "file:", base::CompareCase::SENSITIVE)) { + } else if (base::StartsWithASCII(url, "file:", true)) { base::ReplaceFirstSubstringAfterOffset(&url, 0, "file:", ""); } return url; @@ -100,11 +100,11 @@ void DartLibraryProviderFiles::GetLibraryAsStream( Dart_Handle DartLibraryProviderFiles::CanonicalizeURL(Dart_Handle library, Dart_Handle url) { std::string string = blink::StdStringFromDart(url); - if (base::StartsWith(string, "dart:", base::CompareCase::SENSITIVE)) + if (base::StartsWithASCII(string, "dart:", true)) return url; - if (base::StartsWith(string, "package:", base::CompareCase::SENSITIVE)) + if (base::StartsWithASCII(string, "package:", true)) return url; - if (base::StartsWith(string, "file:", base::CompareCase::SENSITIVE)) { + if (base::StartsWithASCII(string, "file:", true)) { base::ReplaceFirstSubstringAfterOffset(&string, 0, "file:", ""); return blink::StdStringToDart(string);; } @@ -119,9 +119,9 @@ Dart_Handle DartLibraryProviderFiles::CanonicalizeURL(Dart_Handle library, } std::string DartLibraryProviderFiles::GetFilePathForURL(std::string url) { - if (base::StartsWith(url, "package:", base::CompareCase::SENSITIVE)) + if (base::StartsWithASCII(url, "package:", true)) return GetFilePathForPackageURL(url); - if (base::StartsWith(url, "file:", base::CompareCase::SENSITIVE)) + if (base::StartsWithASCII(url, "file:", true)) return GetFilePathForFileURL(url); return url; @@ -129,7 +129,7 @@ std::string DartLibraryProviderFiles::GetFilePathForURL(std::string url) { std::string DartLibraryProviderFiles::GetFilePathForPackageURL( std::string url) { - DCHECK(base::StartsWith(url, "package:", base::CompareCase::SENSITIVE)); + DCHECK(base::StartsWithASCII(url, "package:", true)); base::ReplaceFirstSubstringAfterOffset(&url, 0, "package:", ""); size_t slash = url.find('/'); if (slash == std::string::npos) @@ -139,7 +139,7 @@ std::string DartLibraryProviderFiles::GetFilePathForPackageURL( std::string package_path = packages_map_.Resolve(package); if (package_path.empty()) return std::string(); - if (base::StartsWith(package_path, "file://", base::CompareCase::SENSITIVE)) { + if (base::StartsWithASCII(package_path, "file://", true)) { base::ReplaceFirstSubstringAfterOffset(&package_path, 0, "file://", ""); return package_path + library_path; } @@ -148,7 +148,7 @@ std::string DartLibraryProviderFiles::GetFilePathForPackageURL( } std::string DartLibraryProviderFiles::GetFilePathForFileURL(std::string url) { - DCHECK(base::StartsWith(url, "file://", base::CompareCase::SENSITIVE)); + DCHECK(base::StartsWithASCII(url, "file://", true)); base::ReplaceFirstSubstringAfterOffset(&url, 0, "file://", ""); return url; } diff --git a/sky/shell/shell.cc b/sky/shell/shell.cc index dbfd78b28..4ac90fcea 100644 --- a/sky/shell/shell.cc +++ b/sky/shell/shell.cc @@ -12,11 +12,10 @@ #include "base/command_line.h" #include "base/i18n/icu_util.h" #include "base/lazy_instance.h" -#include "base/memory/discardable_memory_allocator.h" #include "base/memory/discardable_memory.h" +#include "base/memory/discardable_memory_allocator.h" #include "base/posix/eintr_wrapper.h" #include "base/single_thread_task_runner.h" -#include "base/trace_event/process_memory_dump.h" #include "base/trace_event/trace_event.h" #include "mojo/message_pump/message_pump_mojo.h" #include "sky/engine/core/script/dart_init.h" @@ -46,12 +45,6 @@ class NonDiscardableMemory : public base::DiscardableMemory { void Unlock() override {} void* data() const override { return data_.get(); } - base::trace_event::MemoryAllocatorDump* CreateMemoryAllocatorDump( - const char* name, - base::trace_event::ProcessMemoryDump* pmd) const override { - return pmd->CreateAllocatorDump(name); - } - private: std::unique_ptr data_; }; diff --git a/sky/tools/sky_snapshot/loader.cc b/sky/tools/sky_snapshot/loader.cc index 9a5965177..e0fd3acfe 100644 --- a/sky/tools/sky_snapshot/loader.cc +++ b/sky/tools/sky_snapshot/loader.cc @@ -20,9 +20,9 @@ namespace { // Extract the scheme prefix ('package:' or 'file:' from ) static std::string ExtractSchemePrefix(std::string url) { - if (base::StartsWith(url, "package:", base::CompareCase::SENSITIVE)) { + if (base::StartsWithASCII(url, "package:", true)) { return "package:"; - } else if (base::StartsWith(url, "file:", base::CompareCase::SENSITIVE)) { + } else if (base::StartsWithASCII(url, "file:", true)) { return "file:"; } return ""; @@ -30,9 +30,9 @@ static std::string ExtractSchemePrefix(std::string url) { // Extract the path from a package: or file: url. static std::string ExtractPath(std::string url) { - if (base::StartsWith(url, "package:", base::CompareCase::SENSITIVE)) { + if (base::StartsWithASCII(url, "package:", true)) { base::ReplaceFirstSubstringAfterOffset(&url, 0, "package:", ""); - } else if (base::StartsWith(url, "file:", base::CompareCase::SENSITIVE)) { + } else if (base::StartsWithASCII(url, "file:", true)) { base::ReplaceFirstSubstringAfterOffset(&url, 0, "file:", ""); } return url; @@ -107,11 +107,11 @@ void Loader::LoadPackagesMap(const base::FilePath& packages) { Dart_Handle Loader::CanonicalizeURL(Dart_Handle library, Dart_Handle url) { std::string string = StringFromDart(url); - if (base::StartsWith(string, "dart:", base::CompareCase::SENSITIVE)) + if (base::StartsWithASCII(string, "dart:", true)) return url; - if (base::StartsWith(string, "package:", base::CompareCase::SENSITIVE)) + if (base::StartsWithASCII(string, "package:", true)) return url; - if (base::StartsWith(string, "file:", base::CompareCase::SENSITIVE)) { + if (base::StartsWithASCII(string, "file:", true)) { base::ReplaceFirstSubstringAfterOffset(&string, 0, "file:", ""); return StringToDart(string);; } @@ -126,9 +126,9 @@ Dart_Handle Loader::CanonicalizeURL(Dart_Handle library, Dart_Handle url) { } std::string Loader::GetFilePathForURL(std::string url) { - if (base::StartsWith(url, "package:", base::CompareCase::SENSITIVE)) + if (base::StartsWithASCII(url, "package:", true)) return GetFilePathForPackageURL(url); - if (base::StartsWith(url, "file:", base::CompareCase::SENSITIVE)) + if (base::StartsWithASCII(url, "file:", true)) return GetFilePathForFileURL(url); return url; @@ -136,7 +136,7 @@ std::string Loader::GetFilePathForURL(std::string url) { std::string Loader::GetFilePathForPackageURL( std::string url) { - DCHECK(base::StartsWith(url, "package:", base::CompareCase::SENSITIVE)); + DCHECK(base::StartsWithASCII(url, "package:", true)); base::ReplaceFirstSubstringAfterOffset(&url, 0, "package:", ""); size_t slash = url.find('/'); if (slash == std::string::npos) @@ -146,7 +146,7 @@ std::string Loader::GetFilePathForPackageURL( std::string package_path = packages_map_->Resolve(package); if (package_path.empty()) return std::string(); - if (base::StartsWith(package_path, "file://", base::CompareCase::SENSITIVE)) { + if (base::StartsWithASCII(package_path, "file://", true)) { base::ReplaceFirstSubstringAfterOffset(&package_path, 0, "file://", ""); return package_path + library_path; } @@ -155,7 +155,7 @@ std::string Loader::GetFilePathForPackageURL( } std::string Loader::GetFilePathForFileURL(std::string url) { - DCHECK(base::StartsWith(url, "file://", base::CompareCase::SENSITIVE)); + DCHECK(base::StartsWithASCII(url, "file://", true)); base::ReplaceFirstSubstringAfterOffset(&url, 0, "file://", ""); return url; } diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn index 1e168c496..261cb1fec 100644 --- a/third_party/BUILD.gn +++ b/third_party/BUILD.gn @@ -31,12 +31,12 @@ group("jpeg") { libs = [ "jpeg" ] public_configs = [ ":system_libjpeg_config" ] } else if (use_libjpeg_turbo) { - public_deps = [ + deps = [ "//third_party/libjpeg_turbo:libjpeg", ] public_configs = [ ":libjpeg_turbo_config" ] } else { - public_deps = [ + deps = [ "//third_party/libjpeg:libjpeg", ] } diff --git a/third_party/harfbuzz-ng/BUILD.gn b/third_party/harfbuzz-ng/BUILD.gn index 611190860..4cfe106fa 100644 --- a/third_party/harfbuzz-ng/BUILD.gn +++ b/third_party/harfbuzz-ng/BUILD.gn @@ -180,5 +180,16 @@ if (use_system_harfbuzz) { "src/hb-glib.h", ] } + + # See also chrome/browser/ui/libgtk2ui/BUILD.gn which pulls this. + config("pangoft2_link_hack") { + if (is_linux && use_pango && !is_chromeos && !is_official_build && + current_cpu != "arm" && !is_component_build) { + # These symbols are referenced from libpangoft2, which will be + # dynamically linked later. + ldflags = + [ "-Wl,-uhb_ft_face_create_cached,-uhb_glib_get_unicode_funcs" ] + } + } } } diff --git a/third_party/libpng/BUILD.gn b/third_party/libpng/BUILD.gn index 787d4fa7d..056d91d61 100644 --- a/third_party/libpng/BUILD.gn +++ b/third_party/libpng/BUILD.gn @@ -61,6 +61,16 @@ source_set("libpng_sources") { public_deps = [ "//third_party/zlib", ] + + # Must be in a config because of how GN orders flags (otherwise -Wall will + # appear after this, and turn it back on). + config("clang_warnings") { + if (is_clang) { + # Upstream uses self-assignment to avoid warnings. + cflags = [ "-Wno-self-assign" ] + } + } + configs += [ ":clang_warnings" ] } if (is_win) { diff --git a/third_party/libpng/libpng.gyp b/third_party/libpng/libpng.gyp new file mode 100644 index 000000000..48b3fa409 --- /dev/null +++ b/third_party/libpng/libpng.gyp @@ -0,0 +1,90 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'targets': [ + { + 'target_name': 'libpng', + 'dependencies': [ + '../zlib/zlib.gyp:zlib', + ], + 'variables': { + # Upstream uses self-assignment to avoid warnings. + 'clang_warning_flags': [ '-Wno-self-assign' ] + }, + 'defines': [ + 'CHROME_PNG_WRITE_SUPPORT', + 'PNG_USER_CONFIG', + ], + 'sources': [ + 'png.c', + 'png.h', + 'pngconf.h', + 'pngerror.c', + 'pnggccrd.c', + 'pngget.c', + 'pngmem.c', + 'pngpread.c', + 'pngread.c', + 'pngrio.c', + 'pngrtran.c', + 'pngrutil.c', + 'pngset.c', + 'pngtrans.c', + 'pngusr.h', + 'pngvcrd.c', + 'pngwio.c', + 'pngwrite.c', + 'pngwtran.c', + 'pngwutil.c', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '.', + ], + 'defines': [ + 'CHROME_PNG_WRITE_SUPPORT', + 'PNG_USER_CONFIG', + ], + }, + 'export_dependent_settings': [ + '../zlib/zlib.gyp:zlib', + ], + # TODO(jschuh): http://crbug.com/167187 + 'msvs_disabled_warnings': [ 4267 ], + 'conditions': [ + ['OS!="win"', {'product_name': 'png'}], + ['OS=="win"', { + 'type': '<(component)', + }, { + # Chromium libpng does not support building as a shared_library + # on non-Windows platforms. + 'type': 'static_library', + }], + ['OS=="win" and component=="shared_library"', { + 'defines': [ + 'PNG_BUILD_DLL', + 'PNG_NO_MODULEDEF', + ], + 'direct_dependent_settings': { + 'defines': [ + 'PNG_USE_DLL', + ], + }, + }], + ['OS=="android"', { + 'toolsets': ['target', 'host'], + 'defines': [ + 'CHROME_PNG_READ_PACK_SUPPORT', # Required by freetype. + ], + 'direct_dependent_settings': { + 'defines': [ + 'CHROME_PNG_READ_PACK_SUPPORT', + ], + }, + }], + ], + }, + ] +} diff --git a/third_party/tcmalloc/OWNERS b/third_party/tcmalloc/OWNERS index ba4b694e2..8b39a5406 100644 --- a/third_party/tcmalloc/OWNERS +++ b/third_party/tcmalloc/OWNERS @@ -1,4 +1 @@ jar@chromium.org - -# On extended leave. -willchan@chromium.org diff --git a/third_party/tcmalloc/README.chromium b/third_party/tcmalloc/README.chromium index 2ea6e69d0..10800df43 100644 --- a/third_party/tcmalloc/README.chromium +++ b/third_party/tcmalloc/README.chromium @@ -98,3 +98,4 @@ Modifications: - Changed DEFINE_foo macros to ignore envname unless ENABLE_PROFILING is defined - Changed DEFINE_string to define const char*s instead of strings - Disabled HEAPPROFILE envvar unless ENABLE_PROFILING is defined +- Add "ARMv8-a" to the supporting list of ARM architecture diff --git a/third_party/tcmalloc/chromium/src/base/arm_instruction_set_select.h b/third_party/tcmalloc/chromium/src/base/arm_instruction_set_select.h index a47e6bbd2..6fde68527 100644 --- a/third_party/tcmalloc/chromium/src/base/arm_instruction_set_select.h +++ b/third_party/tcmalloc/chromium/src/base/arm_instruction_set_select.h @@ -35,7 +35,12 @@ #ifndef ARM_INSTRUCTION_SET_SELECT_H_ #define ARM_INSTRUCTION_SET_SELECT_H_ -#if defined(__ARM_ARCH_7__) || \ +#if defined(__ARM_ARCH_8A__) +# define ARMV8 1 +#endif + +#if defined(ARMV8) || \ + defined(__ARM_ARCH_7__) || \ defined(__ARM_ARCH_7R__) || \ defined(__ARM_ARCH_7A__) # define ARMV7 1 diff --git a/third_party/tcmalloc/chromium/src/debugallocation.cc b/third_party/tcmalloc/chromium/src/debugallocation.cc index 932d69e5e..6a4f2865d 100644 --- a/third_party/tcmalloc/chromium/src/debugallocation.cc +++ b/third_party/tcmalloc/chromium/src/debugallocation.cc @@ -486,7 +486,7 @@ class MallocBlock { // the address space could take more. static size_t max_size_t = ~0; if (size > max_size_t - sizeof(MallocBlock)) { - RAW_LOG(ERROR, "Massive size passed to malloc: %" PRIuS "", size); + RAW_LOG(ERROR, "Massive size passed to malloc: %"PRIuS"", size); return NULL; } MallocBlock* b = NULL; @@ -965,7 +965,7 @@ static SpinLock malloc_trace_lock(SpinLock::LINKER_INITIALIZED); do { \ if (FLAGS_malloctrace) { \ SpinLockHolder l(&malloc_trace_lock); \ - TracePrintf(TraceFd(), "%s\t%" PRIuS "\t%p\t%" GPRIuPTHREAD, \ + TracePrintf(TraceFd(), "%s\t%"PRIuS"\t%p\t%"GPRIuPTHREAD, \ name, size, addr, PRINTABLE_PTHREAD(pthread_self())); \ TraceStack(); \ TracePrintf(TraceFd(), "\n"); \ @@ -1227,7 +1227,7 @@ extern "C" PERFTOOLS_DLL_DECL void* tc_new(size_t size) { void* ptr = debug_cpp_alloc(size, MallocBlock::kNewType, false); MallocHook::InvokeNewHook(ptr, size); if (ptr == NULL) { - RAW_LOG(FATAL, "Unable to allocate %" PRIuS " bytes: new failed.", size); + RAW_LOG(FATAL, "Unable to allocate %"PRIuS" bytes: new failed.", size); } return ptr; } @@ -1254,7 +1254,7 @@ extern "C" PERFTOOLS_DLL_DECL void* tc_newarray(size_t size) { void* ptr = debug_cpp_alloc(size, MallocBlock::kArrayNewType, false); MallocHook::InvokeNewHook(ptr, size); if (ptr == NULL) { - RAW_LOG(FATAL, "Unable to allocate %" PRIuS " bytes: new[] failed.", size); + RAW_LOG(FATAL, "Unable to allocate %"PRIuS" bytes: new[] failed.", size); } return ptr; } diff --git a/third_party/tcmalloc/chromium/src/deep-heap-profile.cc b/third_party/tcmalloc/chromium/src/deep-heap-profile.cc new file mode 100644 index 000000000..bbf002a6c --- /dev/null +++ b/third_party/tcmalloc/chromium/src/deep-heap-profile.cc @@ -0,0 +1,1161 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// --- +// Author: Sainbayar Sukhbaatar +// Dai Mikurube +// + +#include "deep-heap-profile.h" + +#ifdef USE_DEEP_HEAP_PROFILE +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include // for getpagesize and getpid +#endif // HAVE_UNISTD_H + +#if defined(__linux__) +#include +#if !defined(__LITTLE_ENDIAN__) and !defined(__BIG_ENDIAN__) +#if __BYTE_ORDER == __BIG_ENDIAN +#define __BIG_ENDIAN__ +#endif // __BYTE_ORDER == __BIG_ENDIAN +#endif // !defined(__LITTLE_ENDIAN__) and !defined(__BIG_ENDIAN__) +#if defined(__BIG_ENDIAN__) +#include +#endif // defined(__BIG_ENDIAN__) +#endif // defined(__linux__) +#if defined(COMPILER_MSVC) +#include // for gethostname +#endif // defined(COMPILER_MSVC) + +#include "base/cycleclock.h" +#include "base/sysinfo.h" +#include "internal_logging.h" // for ASSERT, etc + +static const int kProfilerBufferSize = 1 << 20; +static const int kHashTableSize = 179999; // Same as heap-profile-table.cc. + +static const int PAGEMAP_BYTES = 8; +static const int KPAGECOUNT_BYTES = 8; +static const uint64 MAX_ADDRESS = kuint64max; + +// Tag strings in heap profile dumps. +static const char kProfileHeader[] = "heap profile: "; +static const char kProfileVersion[] = "DUMP_DEEP_6"; +static const char kMetaInformationHeader[] = "META:\n"; +static const char kMMapListHeader[] = "MMAP_LIST:\n"; +static const char kGlobalStatsHeader[] = "GLOBAL_STATS:\n"; +static const char kStacktraceHeader[] = "STACKTRACES:\n"; +static const char kProcSelfMapsHeader[] = "\nMAPPED_LIBRARIES:\n"; + +static const char kVirtualLabel[] = "virtual"; +static const char kCommittedLabel[] = "committed"; + +#if defined(__linux__) +#define OS_NAME "linux" +#elif defined(_WIN32) || defined(_WIN64) +#define OS_NAME "windows" +#else +#define OS_NAME "unknown-os" +#endif + +bool DeepHeapProfile::AppendCommandLine(TextBuffer* buffer) { +#if defined(__linux__) + RawFD fd; + char filename[100]; + char cmdline[4096]; + snprintf(filename, sizeof(filename), "/proc/%d/cmdline", + static_cast(getpid())); + fd = open(filename, O_RDONLY); + if (fd == kIllegalRawFD) { + RAW_VLOG(0, "Failed to open /proc/self/cmdline"); + return false; + } + + size_t length = read(fd, cmdline, sizeof(cmdline) - 1); + close(fd); + + for (int i = 0; i < length; ++i) + if (cmdline[i] == '\0') + cmdline[i] = ' '; + cmdline[length] = '\0'; + + buffer->AppendString("CommandLine: ", 0); + buffer->AppendString(cmdline, 0); + buffer->AppendChar('\n'); + + return true; +#else + return false; +#endif +} + +#if defined(_WIN32) || defined(_WIN64) + +// TODO(peria): Implement this function. +void DeepHeapProfile::MemoryInfoGetterWindows::Initialize() { +} + +// TODO(peria): Implement this function. +size_t DeepHeapProfile::MemoryInfoGetterWindows::CommittedSize( + uint64 first_address, + uint64 last_address, + TextBuffer* buffer) const { + return 0; +} + +// TODO(peria): Implement this function. +bool DeepHeapProfile::MemoryInfoGetterWindows::IsPageCountAvailable() const { + return false; +} + +#endif // defined(_WIN32) || defined(_WIN64) + +#if defined(__linux__) + +void DeepHeapProfile::MemoryInfoGetterLinux::Initialize() { + char filename[100]; + snprintf(filename, sizeof(filename), "/proc/%d/pagemap", + static_cast(getpid())); + pagemap_fd_ = open(filename, O_RDONLY); + RAW_CHECK(pagemap_fd_ != -1, "Failed to open /proc/self/pagemap"); + + if (pageframe_type_ == DUMP_PAGECOUNT) { + snprintf(filename, sizeof(filename), "/proc/kpagecount"); + kpagecount_fd_ = open(filename, O_RDONLY); + if (kpagecount_fd_ == -1) + RAW_VLOG(0, "Failed to open /proc/kpagecount"); + } +} + +size_t DeepHeapProfile::MemoryInfoGetterLinux::CommittedSize( + uint64 first_address, + uint64 last_address, + DeepHeapProfile::TextBuffer* buffer) const { + int page_size = getpagesize(); + uint64 page_address = (first_address / page_size) * page_size; + size_t committed_size = 0; + size_t pageframe_list_length = 0; + + Seek(first_address); + + // Check every page on which the allocation resides. + while (page_address <= last_address) { + // Read corresponding physical page. + State state; + // TODO(dmikurube): Read pagemap in bulk for speed. + // TODO(dmikurube): Consider using mincore(2). + if (Read(&state, pageframe_type_ != DUMP_NO_PAGEFRAME) == false) { + // We can't read the last region (e.g vsyscall). +#ifndef NDEBUG + RAW_VLOG(0, "pagemap read failed @ %#llx %" PRId64 " bytes", + first_address, last_address - first_address + 1); +#endif + return 0; + } + + // Dump pageframes of resident pages. Non-resident pages are just skipped. + if (pageframe_type_ != DUMP_NO_PAGEFRAME && + buffer != NULL && state.pfn != 0) { + if (pageframe_list_length == 0) { + buffer->AppendString(" PF:", 0); + pageframe_list_length = 5; + } + buffer->AppendChar(' '); + if (page_address < first_address) + buffer->AppendChar('<'); + buffer->AppendBase64(state.pfn, 4); + pageframe_list_length += 5; + if (pageframe_type_ == DUMP_PAGECOUNT && IsPageCountAvailable()) { + uint64 pagecount = ReadPageCount(state.pfn); + // Assume pagecount == 63 if the pageframe is mapped more than 63 times. + if (pagecount > 63) + pagecount = 63; + buffer->AppendChar('#'); + buffer->AppendBase64(pagecount, 1); + pageframe_list_length += 2; + } + if (last_address < page_address - 1 + page_size) + buffer->AppendChar('>'); + // Begins a new line every 94 characters. + if (pageframe_list_length > 94) { + buffer->AppendChar('\n'); + pageframe_list_length = 0; + } + } + + if (state.is_committed) { + // Calculate the size of the allocation part in this page. + size_t bytes = page_size; + + // If looking at the last page in a given region. + if (last_address <= page_address - 1 + page_size) { + bytes = last_address - page_address + 1; + } + + // If looking at the first page in a given region. + if (page_address < first_address) { + bytes -= first_address - page_address; + } + + committed_size += bytes; + } + if (page_address > MAX_ADDRESS - page_size) { + break; + } + page_address += page_size; + } + + if (pageframe_type_ != DUMP_NO_PAGEFRAME && + buffer != NULL && pageframe_list_length != 0) { + buffer->AppendChar('\n'); + } + + return committed_size; +} + +uint64 DeepHeapProfile::MemoryInfoGetterLinux::ReadPageCount(uint64 pfn) const { + int64 index = pfn * KPAGECOUNT_BYTES; + int64 offset = lseek64(kpagecount_fd_, index, SEEK_SET); + RAW_DCHECK(offset == index, "Failed in seeking in kpagecount."); + + uint64 kpagecount_value; + int result = read(kpagecount_fd_, &kpagecount_value, KPAGECOUNT_BYTES); + if (result != KPAGECOUNT_BYTES) + return 0; + + return kpagecount_value; +} + +bool DeepHeapProfile::MemoryInfoGetterLinux::Seek(uint64 address) const { + int64 index = (address / getpagesize()) * PAGEMAP_BYTES; + RAW_DCHECK(pagemap_fd_ != -1, "Failed to seek in /proc/self/pagemap"); + int64 offset = lseek64(pagemap_fd_, index, SEEK_SET); + RAW_DCHECK(offset == index, "Failed in seeking."); + return offset >= 0; +} + +bool DeepHeapProfile::MemoryInfoGetterLinux::Read( + State* state, bool get_pfn) const { + static const uint64 U64_1 = 1; + static const uint64 PFN_FILTER = (U64_1 << 55) - U64_1; + static const uint64 PAGE_PRESENT = U64_1 << 63; + static const uint64 PAGE_SWAP = U64_1 << 62; + static const uint64 PAGE_RESERVED = U64_1 << 61; + static const uint64 FLAG_NOPAGE = U64_1 << 20; + static const uint64 FLAG_KSM = U64_1 << 21; + static const uint64 FLAG_MMAP = U64_1 << 11; + + uint64 pagemap_value; + RAW_DCHECK(pagemap_fd_ != -1, "Failed to read from /proc/self/pagemap"); + int result = read(pagemap_fd_, &pagemap_value, PAGEMAP_BYTES); + if (result != PAGEMAP_BYTES) { + return false; + } + + // Check if the page is committed. + state->is_committed = (pagemap_value & (PAGE_PRESENT | PAGE_SWAP)); + + state->is_present = (pagemap_value & PAGE_PRESENT); + state->is_swapped = (pagemap_value & PAGE_SWAP); + state->is_shared = false; + + if (get_pfn && state->is_present && !state->is_swapped) + state->pfn = (pagemap_value & PFN_FILTER); + else + state->pfn = 0; + + return true; +} + +bool DeepHeapProfile::MemoryInfoGetterLinux::IsPageCountAvailable() const { + return kpagecount_fd_ != -1; +} + +#endif // defined(__linux__) + +DeepHeapProfile::MemoryResidenceInfoGetterInterface:: + MemoryResidenceInfoGetterInterface() {} + +DeepHeapProfile::MemoryResidenceInfoGetterInterface:: + ~MemoryResidenceInfoGetterInterface() {} + +DeepHeapProfile::MemoryResidenceInfoGetterInterface* + DeepHeapProfile::MemoryResidenceInfoGetterInterface::Create( + PageFrameType pageframe_type) { +#if defined(_WIN32) || defined(_WIN64) + return new MemoryInfoGetterWindows(pageframe_type); +#elif defined(__linux__) + return new MemoryInfoGetterLinux(pageframe_type); +#else + return NULL; +#endif +} + +DeepHeapProfile::DeepHeapProfile(HeapProfileTable* heap_profile, + const char* prefix, + enum PageFrameType pageframe_type) + : memory_residence_info_getter_( + MemoryResidenceInfoGetterInterface::Create(pageframe_type)), + most_recent_pid_(-1), + stats_(), + dump_count_(0), + filename_prefix_(NULL), + deep_table_(kHashTableSize, heap_profile->alloc_, heap_profile->dealloc_), + pageframe_type_(pageframe_type), + heap_profile_(heap_profile) { + // Copy filename prefix. + const int prefix_length = strlen(prefix); + filename_prefix_ = + reinterpret_cast(heap_profile_->alloc_(prefix_length + 1)); + memcpy(filename_prefix_, prefix, prefix_length); + filename_prefix_[prefix_length] = '\0'; + + strncpy(run_id_, "undetermined-run-id", sizeof(run_id_)); +} + +DeepHeapProfile::~DeepHeapProfile() { + heap_profile_->dealloc_(filename_prefix_); + delete memory_residence_info_getter_; +} + +// Global malloc() should not be used in this function. +// Use LowLevelAlloc if required. +void DeepHeapProfile::DumpOrderedProfile(const char* reason, + char raw_buffer[], + int buffer_size, + RawFD fd) { + TextBuffer buffer(raw_buffer, buffer_size, fd); + +#ifndef NDEBUG + int64 starting_cycles = CycleClock::Now(); +#endif + + // Get the time before starting snapshot. + // TODO(dmikurube): Consider gettimeofday if available. + time_t time_value = time(NULL); + + ++dump_count_; + + // Re-open files in /proc/pid/ if the process is newly forked one. + if (most_recent_pid_ != getpid()) { + char hostname[64]; + if (0 == gethostname(hostname, sizeof(hostname))) { + char* dot = strchr(hostname, '.'); + if (dot != NULL) + *dot = '\0'; + } else { + strcpy(hostname, "unknown"); + } + + most_recent_pid_ = getpid(); + + snprintf(run_id_, sizeof(run_id_), "%s-" OS_NAME "-%d-%lu", + hostname, most_recent_pid_, time(NULL)); + + if (memory_residence_info_getter_) + memory_residence_info_getter_->Initialize(); + deep_table_.ResetIsLogged(); + + // Write maps into "|filename_prefix_|..maps". + WriteProcMaps(filename_prefix_, raw_buffer, buffer_size); + } + + // Reset committed sizes of buckets. + deep_table_.ResetCommittedSize(); + + // Record committed sizes. + stats_.SnapshotAllocations(this); + + // TODO(dmikurube): Eliminate dynamic memory allocation caused by snprintf. + // glibc's snprintf internally allocates memory by alloca normally, but it + // allocates memory by malloc if large memory is required. + + buffer.AppendString(kProfileHeader, 0); + buffer.AppendString(kProfileVersion, 0); + buffer.AppendString("\n", 0); + + // Fill buffer with meta information. + buffer.AppendString(kMetaInformationHeader, 0); + + buffer.AppendString("Time: ", 0); + buffer.AppendUnsignedLong(time_value, 0); + buffer.AppendChar('\n'); + + if (reason != NULL) { + buffer.AppendString("Reason: ", 0); + buffer.AppendString(reason, 0); + buffer.AppendChar('\n'); + } + + AppendCommandLine(&buffer); + + buffer.AppendString("RunID: ", 0); + buffer.AppendString(run_id_, 0); + buffer.AppendChar('\n'); + + buffer.AppendString("PageSize: ", 0); + buffer.AppendInt(getpagesize(), 0, 0); + buffer.AppendChar('\n'); + + // Assumes the physical memory <= 64GB (PFN < 2^24). + if (pageframe_type_ == DUMP_PAGECOUNT && memory_residence_info_getter_ && + memory_residence_info_getter_->IsPageCountAvailable()) { + buffer.AppendString("PageFrame: 24,Base64,PageCount", 0); + buffer.AppendChar('\n'); + } else if (pageframe_type_ != DUMP_NO_PAGEFRAME) { + buffer.AppendString("PageFrame: 24,Base64", 0); + buffer.AppendChar('\n'); + } + + // Fill buffer with the global stats. + buffer.AppendString(kMMapListHeader, 0); + + stats_.SnapshotMaps(memory_residence_info_getter_, this, &buffer); + + // Fill buffer with the global stats. + buffer.AppendString(kGlobalStatsHeader, 0); + + stats_.Unparse(&buffer); + + buffer.AppendString(kStacktraceHeader, 0); + buffer.AppendString(kVirtualLabel, 10); + buffer.AppendChar(' '); + buffer.AppendString(kCommittedLabel, 10); + buffer.AppendString("\n", 0); + + // Fill buffer. + deep_table_.UnparseForStats(&buffer); + + buffer.Flush(); + + // Write the bucket listing into a .bucket file. + deep_table_.WriteForBucketFile( + filename_prefix_, dump_count_, raw_buffer, buffer_size); + +#ifndef NDEBUG + int64 elapsed_cycles = CycleClock::Now() - starting_cycles; + double elapsed_seconds = elapsed_cycles / CyclesPerSecond(); + RAW_VLOG(0, "Time spent on DeepProfiler: %.3f sec\n", elapsed_seconds); +#endif +} + +int DeepHeapProfile::TextBuffer::Size() { + return size_; +} + +int DeepHeapProfile::TextBuffer::FilledBytes() { + return cursor_; +} + +void DeepHeapProfile::TextBuffer::Clear() { + cursor_ = 0; +} + +void DeepHeapProfile::TextBuffer::Flush() { + RawWrite(fd_, buffer_, cursor_); + cursor_ = 0; +} + +// TODO(dmikurube): These Append* functions should not use snprintf. +bool DeepHeapProfile::TextBuffer::AppendChar(char value) { + return ForwardCursor(snprintf(buffer_ + cursor_, size_ - cursor_, + "%c", value)); +} + +bool DeepHeapProfile::TextBuffer::AppendString(const char* value, int width) { + char* position = buffer_ + cursor_; + int available = size_ - cursor_; + int appended; + if (width == 0) + appended = snprintf(position, available, "%s", value); + else + appended = snprintf(position, available, "%*s", + width, value); + return ForwardCursor(appended); +} + +bool DeepHeapProfile::TextBuffer::AppendInt(int value, int width, + bool leading_zero) { + char* position = buffer_ + cursor_; + int available = size_ - cursor_; + int appended; + if (width == 0) + appended = snprintf(position, available, "%d", value); + else if (leading_zero) + appended = snprintf(position, available, "%0*d", width, value); + else + appended = snprintf(position, available, "%*d", width, value); + return ForwardCursor(appended); +} + +bool DeepHeapProfile::TextBuffer::AppendLong(long value, int width) { + char* position = buffer_ + cursor_; + int available = size_ - cursor_; + int appended; + if (width == 0) + appended = snprintf(position, available, "%ld", value); + else + appended = snprintf(position, available, "%*ld", width, value); + return ForwardCursor(appended); +} + +bool DeepHeapProfile::TextBuffer::AppendUnsignedLong(unsigned long value, + int width) { + char* position = buffer_ + cursor_; + int available = size_ - cursor_; + int appended; + if (width == 0) + appended = snprintf(position, available, "%lu", value); + else + appended = snprintf(position, available, "%*lu", width, value); + return ForwardCursor(appended); +} + +bool DeepHeapProfile::TextBuffer::AppendInt64(int64 value, int width) { + char* position = buffer_ + cursor_; + int available = size_ - cursor_; + int appended; + if (width == 0) + appended = snprintf(position, available, "%" PRId64, value); + else + appended = snprintf(position, available, "%*" PRId64, width, value); + return ForwardCursor(appended); +} + +bool DeepHeapProfile::TextBuffer::AppendPtr(uint64 value, int width) { + char* position = buffer_ + cursor_; + int available = size_ - cursor_; + int appended; + if (width == 0) + appended = snprintf(position, available, "%" PRIx64, value); + else + appended = snprintf(position, available, "%0*" PRIx64, width, value); + return ForwardCursor(appended); +} + +bool DeepHeapProfile::TextBuffer::AppendBase64(uint64 value, int width) { + static const char base64[65] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +#if defined(__BIG_ENDIAN__) + value = bswap_64(value); +#endif + for (int shift = (width - 1) * 6; shift >= 0; shift -= 6) { + if (!AppendChar(base64[(value >> shift) & 0x3f])) + return false; + } + return true; +} + +bool DeepHeapProfile::TextBuffer::ForwardCursor(int appended) { + if (appended < 0 || appended >= size_ - cursor_) + return false; + cursor_ += appended; + if (cursor_ > size_ * 4 / 5) + Flush(); + return true; +} + +void DeepHeapProfile::DeepBucket::UnparseForStats(TextBuffer* buffer) { + buffer->AppendInt64(bucket->alloc_size - bucket->free_size, 10); + buffer->AppendChar(' '); + buffer->AppendInt64(committed_size, 10); + buffer->AppendChar(' '); + buffer->AppendInt(bucket->allocs, 6, false); + buffer->AppendChar(' '); + buffer->AppendInt(bucket->frees, 6, false); + buffer->AppendString(" @ ", 0); + buffer->AppendInt(id, 0, false); + buffer->AppendString("\n", 0); +} + +void DeepHeapProfile::DeepBucket::UnparseForBucketFile(TextBuffer* buffer) { + buffer->AppendInt(id, 0, false); + buffer->AppendChar(' '); + buffer->AppendString(is_mmap ? "mmap" : "malloc", 0); + +#if defined(TYPE_PROFILING) + buffer->AppendString(" t0x", 0); + buffer->AppendPtr(reinterpret_cast(type), 0); + if (type == NULL) { + buffer->AppendString(" nno_typeinfo", 0); + } else { + buffer->AppendString(" n", 0); + buffer->AppendString(type->name(), 0); + } +#endif + + for (int depth = 0; depth < bucket->depth; depth++) { + buffer->AppendString(" 0x", 0); + buffer->AppendPtr(reinterpret_cast(bucket->stack[depth]), 8); + } + buffer->AppendString("\n", 0); +} + +DeepHeapProfile::DeepBucketTable::DeepBucketTable( + int table_size, + HeapProfileTable::Allocator alloc, + HeapProfileTable::DeAllocator dealloc) + : table_(NULL), + table_size_(table_size), + alloc_(alloc), + dealloc_(dealloc), + bucket_id_(0) { + const int bytes = table_size * sizeof(DeepBucket*); + table_ = reinterpret_cast(alloc(bytes)); + memset(table_, 0, bytes); +} + +DeepHeapProfile::DeepBucketTable::~DeepBucketTable() { + ASSERT(table_ != NULL); + for (int db = 0; db < table_size_; db++) { + for (DeepBucket* x = table_[db]; x != 0; /**/) { + DeepBucket* db = x; + x = x->next; + dealloc_(db); + } + } + dealloc_(table_); +} + +DeepHeapProfile::DeepBucket* DeepHeapProfile::DeepBucketTable::Lookup( + Bucket* bucket, +#if defined(TYPE_PROFILING) + const std::type_info* type, +#endif + bool is_mmap) { + // Make hash-value + uintptr_t h = 0; + + AddToHashValue(reinterpret_cast(bucket), &h); + if (is_mmap) { + AddToHashValue(1, &h); + } else { + AddToHashValue(0, &h); + } + +#if defined(TYPE_PROFILING) + if (type == NULL) { + AddToHashValue(0, &h); + } else { + AddToHashValue(reinterpret_cast(type->name()), &h); + } +#endif + + FinishHashValue(&h); + + // Lookup stack trace in table + unsigned int buck = ((unsigned int) h) % table_size_; + for (DeepBucket* db = table_[buck]; db != 0; db = db->next) { + if (db->bucket == bucket) { + return db; + } + } + + // Create a new bucket + DeepBucket* db = reinterpret_cast(alloc_(sizeof(DeepBucket))); + memset(db, 0, sizeof(*db)); + db->bucket = bucket; +#if defined(TYPE_PROFILING) + db->type = type; +#endif + db->committed_size = 0; + db->is_mmap = is_mmap; + db->id = (bucket_id_++); + db->is_logged = false; + db->next = table_[buck]; + table_[buck] = db; + return db; +} + +// TODO(dmikurube): Eliminate dynamic memory allocation caused by snprintf. +void DeepHeapProfile::DeepBucketTable::UnparseForStats(TextBuffer* buffer) { + for (int i = 0; i < table_size_; i++) { + for (DeepBucket* deep_bucket = table_[i]; + deep_bucket != NULL; + deep_bucket = deep_bucket->next) { + Bucket* bucket = deep_bucket->bucket; + if (bucket->alloc_size - bucket->free_size == 0) { + continue; // Skip empty buckets. + } + deep_bucket->UnparseForStats(buffer); + } + } +} + +void DeepHeapProfile::DeepBucketTable::WriteForBucketFile( + const char* prefix, int dump_count, char raw_buffer[], int buffer_size) { + char filename[100]; + snprintf(filename, sizeof(filename), + "%s.%05d.%04d.buckets", prefix, getpid(), dump_count); + RawFD fd = RawOpenForWriting(filename); + RAW_DCHECK(fd != kIllegalRawFD, ""); + + TextBuffer buffer(raw_buffer, buffer_size, fd); + + for (int i = 0; i < table_size_; i++) { + for (DeepBucket* deep_bucket = table_[i]; + deep_bucket != NULL; + deep_bucket = deep_bucket->next) { + Bucket* bucket = deep_bucket->bucket; + if (deep_bucket->is_logged) { + continue; // Skip the bucket if it is already logged. + } + if (!deep_bucket->is_mmap && + bucket->alloc_size - bucket->free_size <= 64) { + continue; // Skip small malloc buckets. + } + + deep_bucket->UnparseForBucketFile(&buffer); + deep_bucket->is_logged = true; + } + } + + buffer.Flush(); + RawClose(fd); +} + +void DeepHeapProfile::DeepBucketTable::ResetCommittedSize() { + for (int i = 0; i < table_size_; i++) { + for (DeepBucket* deep_bucket = table_[i]; + deep_bucket != NULL; + deep_bucket = deep_bucket->next) { + deep_bucket->committed_size = 0; + } + } +} + +void DeepHeapProfile::DeepBucketTable::ResetIsLogged() { + for (int i = 0; i < table_size_; i++) { + for (DeepBucket* deep_bucket = table_[i]; + deep_bucket != NULL; + deep_bucket = deep_bucket->next) { + deep_bucket->is_logged = false; + } + } +} + +// This hash function is from HeapProfileTable::GetBucket. +// static +void DeepHeapProfile::DeepBucketTable::AddToHashValue( + uintptr_t add, uintptr_t* hash_value) { + *hash_value += add; + *hash_value += *hash_value << 10; + *hash_value ^= *hash_value >> 6; +} + +// This hash function is from HeapProfileTable::GetBucket. +// static +void DeepHeapProfile::DeepBucketTable::FinishHashValue(uintptr_t* hash_value) { + *hash_value += *hash_value << 3; + *hash_value ^= *hash_value >> 11; +} + +void DeepHeapProfile::RegionStats::Initialize() { + virtual_bytes_ = 0; + committed_bytes_ = 0; +} + +uint64 DeepHeapProfile::RegionStats::Record( + const MemoryResidenceInfoGetterInterface* memory_residence_info_getter, + uint64 first_address, + uint64 last_address, + TextBuffer* buffer) { + uint64 committed = 0; + virtual_bytes_ += static_cast(last_address - first_address + 1); + if (memory_residence_info_getter) + committed = memory_residence_info_getter->CommittedSize(first_address, + last_address, + buffer); + committed_bytes_ += committed; + return committed; +} + +void DeepHeapProfile::RegionStats::Unparse(const char* name, + TextBuffer* buffer) { + buffer->AppendString(name, 25); + buffer->AppendChar(' '); + buffer->AppendLong(virtual_bytes_, 12); + buffer->AppendChar(' '); + buffer->AppendLong(committed_bytes_, 12); + buffer->AppendString("\n", 0); +} + +// Snapshots all virtual memory mapping stats by merging mmap(2) records from +// MemoryRegionMap and /proc/maps, the OS-level memory mapping information. +// Memory regions described in /proc/maps, but which are not created by mmap, +// are accounted as "unhooked" memory regions. +// +// This function assumes that every memory region created by mmap is covered +// by VMA(s) described in /proc/maps except for http://crbug.com/189114. +// Note that memory regions created with mmap don't align with borders of VMAs +// in /proc/maps. In other words, a memory region by mmap can cut across many +// VMAs. Also, of course a VMA can include many memory regions by mmap. +// It means that the following situation happens: +// +// => Virtual address +// <----- VMA #1 -----><----- VMA #2 ----->...<----- VMA #3 -----><- VMA #4 -> +// ..< mmap #1 >.<- mmap #2 -><- mmap #3 ->...<- mmap #4 ->..<-- mmap #5 -->.. +// +// It can happen easily as permission can be changed by mprotect(2) for a part +// of a memory region. A change in permission splits VMA(s). +// +// To deal with the situation, this function iterates over MemoryRegionMap and +// /proc/maps independently. The iterator for MemoryRegionMap is initialized +// at the top outside the loop for /proc/maps, and it goes forward inside the +// loop while comparing their addresses. +// +// TODO(dmikurube): Eliminate dynamic memory allocation caused by snprintf. +void DeepHeapProfile::GlobalStats::SnapshotMaps( + const MemoryResidenceInfoGetterInterface* memory_residence_info_getter, + DeepHeapProfile* deep_profile, + TextBuffer* mmap_dump_buffer) { + MemoryRegionMap::LockHolder lock_holder; + ProcMapsIterator::Buffer procmaps_iter_buffer; + ProcMapsIterator procmaps_iter(0, &procmaps_iter_buffer); + uint64 vma_start_addr, vma_last_addr, offset; + int64 inode; + char* flags; + char* filename; + enum MapsRegionType type; + + for (int i = 0; i < NUMBER_OF_MAPS_REGION_TYPES; ++i) { + all_[i].Initialize(); + unhooked_[i].Initialize(); + } + profiled_mmap_.Initialize(); + + MemoryRegionMap::RegionIterator mmap_iter = + MemoryRegionMap::BeginRegionLocked(); + DeepBucket* deep_bucket = NULL; + if (mmap_iter != MemoryRegionMap::EndRegionLocked()) { + deep_bucket = GetInformationOfMemoryRegion( + mmap_iter, memory_residence_info_getter, deep_profile); + } + + while (procmaps_iter.Next(&vma_start_addr, &vma_last_addr, + &flags, &offset, &inode, &filename)) { + if (mmap_dump_buffer) { + char buffer[1024]; + int written = procmaps_iter.FormatLine(buffer, sizeof(buffer), + vma_start_addr, vma_last_addr, + flags, offset, inode, filename, 0); + mmap_dump_buffer->AppendString(buffer, 0); + } + + // 'vma_last_addr' should be the last inclusive address of the region. + vma_last_addr -= 1; + if (strcmp("[vsyscall]", filename) == 0) { + continue; // Reading pagemap will fail in [vsyscall]. + } + + // TODO(dmikurube): |type| will be deprecated in the dump. + // See http://crbug.com/245603. + type = ABSENT; + if (filename[0] == '/') { + if (flags[2] == 'x') + type = FILE_EXEC; + else + type = FILE_NONEXEC; + } else if (filename[0] == '\0' || filename[0] == '\n') { + type = ANONYMOUS; + } else if (strcmp(filename, "[stack]") == 0) { + type = STACK; + } else { + type = OTHER; + } + // TODO(dmikurube): This |all_| count should be removed in future soon. + // See http://crbug.com/245603. + uint64 vma_total = all_[type].Record( + memory_residence_info_getter, vma_start_addr, vma_last_addr, NULL); + uint64 vma_subtotal = 0; + + // TODO(dmikurube): Stop double-counting pagemap. + // It will be fixed when http://crbug.com/245603 finishes. + if (MemoryRegionMap::IsRecordingLocked()) { + uint64 cursor = vma_start_addr; + bool first = true; + + // Iterates over MemoryRegionMap until the iterator moves out of the VMA. + do { + if (!first) { + cursor = mmap_iter->end_addr; + ++mmap_iter; + // Don't break here even if mmap_iter == EndRegionLocked(). + + if (mmap_iter != MemoryRegionMap::EndRegionLocked()) { + deep_bucket = GetInformationOfMemoryRegion( + mmap_iter, memory_residence_info_getter, deep_profile); + } + } + first = false; + + uint64 last_address_of_unhooked; + // If the next mmap entry is away from the current VMA. + if (mmap_iter == MemoryRegionMap::EndRegionLocked() || + mmap_iter->start_addr > vma_last_addr) { + last_address_of_unhooked = vma_last_addr; + } else { + last_address_of_unhooked = mmap_iter->start_addr - 1; + } + + if (last_address_of_unhooked + 1 > cursor) { + RAW_CHECK(cursor >= vma_start_addr, + "Wrong calculation for unhooked"); + RAW_CHECK(last_address_of_unhooked <= vma_last_addr, + "Wrong calculation for unhooked"); + uint64 committed_size = unhooked_[type].Record( + memory_residence_info_getter, + cursor, + last_address_of_unhooked, + mmap_dump_buffer); + vma_subtotal += committed_size; + if (mmap_dump_buffer) { + mmap_dump_buffer->AppendString(" ", 0); + mmap_dump_buffer->AppendPtr(cursor, 0); + mmap_dump_buffer->AppendString(" - ", 0); + mmap_dump_buffer->AppendPtr(last_address_of_unhooked + 1, 0); + mmap_dump_buffer->AppendString(" unhooked ", 0); + mmap_dump_buffer->AppendInt64(committed_size, 0); + mmap_dump_buffer->AppendString(" / ", 0); + mmap_dump_buffer->AppendInt64( + last_address_of_unhooked - cursor + 1, 0); + mmap_dump_buffer->AppendString("\n", 0); + } + cursor = last_address_of_unhooked + 1; + } + + if (mmap_iter != MemoryRegionMap::EndRegionLocked() && + mmap_iter->start_addr <= vma_last_addr && + mmap_dump_buffer) { + bool trailing = mmap_iter->start_addr < vma_start_addr; + bool continued = mmap_iter->end_addr - 1 > vma_last_addr; + uint64 partial_first_address, partial_last_address; + if (trailing) + partial_first_address = vma_start_addr; + else + partial_first_address = mmap_iter->start_addr; + if (continued) + partial_last_address = vma_last_addr; + else + partial_last_address = mmap_iter->end_addr - 1; + uint64 committed_size = 0; + if (memory_residence_info_getter) + committed_size = memory_residence_info_getter->CommittedSize( + partial_first_address, partial_last_address, mmap_dump_buffer); + vma_subtotal += committed_size; + mmap_dump_buffer->AppendString(trailing ? " (" : " ", 0); + mmap_dump_buffer->AppendPtr(mmap_iter->start_addr, 0); + mmap_dump_buffer->AppendString(trailing ? ")" : " ", 0); + mmap_dump_buffer->AppendString("-", 0); + mmap_dump_buffer->AppendString(continued ? "(" : " ", 0); + mmap_dump_buffer->AppendPtr(mmap_iter->end_addr, 0); + mmap_dump_buffer->AppendString(continued ? ")" : " ", 0); + mmap_dump_buffer->AppendString(" hooked ", 0); + mmap_dump_buffer->AppendInt64(committed_size, 0); + mmap_dump_buffer->AppendString(" / ", 0); + mmap_dump_buffer->AppendInt64( + partial_last_address - partial_first_address + 1, 0); + mmap_dump_buffer->AppendString(" @ ", 0); + if (deep_bucket != NULL) { + mmap_dump_buffer->AppendInt(deep_bucket->id, 0, false); + } else { + mmap_dump_buffer->AppendInt(0, 0, false); + } + mmap_dump_buffer->AppendString("\n", 0); + } + } while (mmap_iter != MemoryRegionMap::EndRegionLocked() && + mmap_iter->end_addr - 1 <= vma_last_addr); + } + + if (vma_total != vma_subtotal) { + char buffer[1024]; + int written = procmaps_iter.FormatLine(buffer, sizeof(buffer), + vma_start_addr, vma_last_addr, + flags, offset, inode, filename, 0); + RAW_VLOG(0, "[%d] Mismatched total in VMA %" PRId64 ":" + "%" PRId64 " (%" PRId64 ")", + getpid(), vma_total, vma_subtotal, vma_total - vma_subtotal); + RAW_VLOG(0, "[%d] in %s", getpid(), buffer); + } + } + + // TODO(dmikurube): Investigate and fix http://crbug.com/189114. + // + // The total committed memory usage in all_ (from /proc//maps) is + // sometimes smaller than the sum of the committed mmap'ed addresses and + // unhooked regions. Within our observation, the difference was only 4KB + // in committed usage, zero in reserved virtual addresses + // + // A guess is that an uncommitted (but reserved) page may become committed + // during counting memory usage in the loop above. + // + // The difference is accounted as "ABSENT" to investigate such cases. + // + // It will be fixed when http://crbug.com/245603 finishes (no double count). + + RegionStats all_total; + RegionStats unhooked_total; + for (int i = 0; i < NUMBER_OF_MAPS_REGION_TYPES; ++i) { + all_total.AddAnotherRegionStat(all_[i]); + unhooked_total.AddAnotherRegionStat(unhooked_[i]); + } + + size_t absent_virtual = profiled_mmap_.virtual_bytes() + + unhooked_total.virtual_bytes() - + all_total.virtual_bytes(); + if (absent_virtual > 0) + all_[ABSENT].AddToVirtualBytes(absent_virtual); + + size_t absent_committed = profiled_mmap_.committed_bytes() + + unhooked_total.committed_bytes() - + all_total.committed_bytes(); + if (absent_committed > 0) + all_[ABSENT].AddToCommittedBytes(absent_committed); +} + +void DeepHeapProfile::GlobalStats::SnapshotAllocations( + DeepHeapProfile* deep_profile) { + profiled_malloc_.Initialize(); + + deep_profile->heap_profile_->address_map_->Iterate(RecordAlloc, deep_profile); +} + +void DeepHeapProfile::GlobalStats::Unparse(TextBuffer* buffer) { + RegionStats all_total; + RegionStats unhooked_total; + for (int i = 0; i < NUMBER_OF_MAPS_REGION_TYPES; ++i) { + all_total.AddAnotherRegionStat(all_[i]); + unhooked_total.AddAnotherRegionStat(unhooked_[i]); + } + + // "# total (%lu) %c= profiled-mmap (%lu) + nonprofiled-* (%lu)\n" + buffer->AppendString("# total (", 0); + buffer->AppendUnsignedLong(all_total.committed_bytes(), 0); + buffer->AppendString(") ", 0); + buffer->AppendChar(all_total.committed_bytes() == + profiled_mmap_.committed_bytes() + + unhooked_total.committed_bytes() ? '=' : '!'); + buffer->AppendString("= profiled-mmap (", 0); + buffer->AppendUnsignedLong(profiled_mmap_.committed_bytes(), 0); + buffer->AppendString(") + nonprofiled-* (", 0); + buffer->AppendUnsignedLong(unhooked_total.committed_bytes(), 0); + buffer->AppendString(")\n", 0); + + // " virtual committed" + buffer->AppendString("", 26); + buffer->AppendString(kVirtualLabel, 12); + buffer->AppendChar(' '); + buffer->AppendString(kCommittedLabel, 12); + buffer->AppendString("\n", 0); + + all_total.Unparse("total", buffer); + all_[ABSENT].Unparse("absent", buffer); + all_[FILE_EXEC].Unparse("file-exec", buffer); + all_[FILE_NONEXEC].Unparse("file-nonexec", buffer); + all_[ANONYMOUS].Unparse("anonymous", buffer); + all_[STACK].Unparse("stack", buffer); + all_[OTHER].Unparse("other", buffer); + unhooked_total.Unparse("nonprofiled-total", buffer); + unhooked_[ABSENT].Unparse("nonprofiled-absent", buffer); + unhooked_[ANONYMOUS].Unparse("nonprofiled-anonymous", buffer); + unhooked_[FILE_EXEC].Unparse("nonprofiled-file-exec", buffer); + unhooked_[FILE_NONEXEC].Unparse("nonprofiled-file-nonexec", buffer); + unhooked_[STACK].Unparse("nonprofiled-stack", buffer); + unhooked_[OTHER].Unparse("nonprofiled-other", buffer); + profiled_mmap_.Unparse("profiled-mmap", buffer); + profiled_malloc_.Unparse("profiled-malloc", buffer); +} + +// static +void DeepHeapProfile::GlobalStats::RecordAlloc(const void* pointer, + AllocValue* alloc_value, + DeepHeapProfile* deep_profile) { + uint64 address = reinterpret_cast(pointer); + size_t committed = deep_profile->memory_residence_info_getter_->CommittedSize( + address, address + alloc_value->bytes - 1, NULL); + + DeepBucket* deep_bucket = deep_profile->deep_table_.Lookup( + alloc_value->bucket(), +#if defined(TYPE_PROFILING) + LookupType(pointer), +#endif + /* is_mmap */ false); + deep_bucket->committed_size += committed; + deep_profile->stats_.profiled_malloc_.AddToVirtualBytes(alloc_value->bytes); + deep_profile->stats_.profiled_malloc_.AddToCommittedBytes(committed); +} + +DeepHeapProfile::DeepBucket* + DeepHeapProfile::GlobalStats::GetInformationOfMemoryRegion( + const MemoryRegionMap::RegionIterator& mmap_iter, + const MemoryResidenceInfoGetterInterface* memory_residence_info_getter, + DeepHeapProfile* deep_profile) { + size_t committed = deep_profile->memory_residence_info_getter_-> + CommittedSize(mmap_iter->start_addr, mmap_iter->end_addr - 1, NULL); + + // TODO(dmikurube): Store a reference to the bucket in region. + Bucket* bucket = MemoryRegionMap::GetBucket( + mmap_iter->call_stack_depth, mmap_iter->call_stack); + DeepBucket* deep_bucket = NULL; + if (bucket != NULL) { + deep_bucket = deep_profile->deep_table_.Lookup( + bucket, +#if defined(TYPE_PROFILING) + NULL, // No type information for memory regions by mmap. +#endif + /* is_mmap */ true); + if (deep_bucket != NULL) + deep_bucket->committed_size += committed; + } + + profiled_mmap_.AddToVirtualBytes( + mmap_iter->end_addr - mmap_iter->start_addr); + profiled_mmap_.AddToCommittedBytes(committed); + + return deep_bucket; +} + +// static +void DeepHeapProfile::WriteProcMaps(const char* prefix, + char raw_buffer[], + int buffer_size) { + char filename[100]; + snprintf(filename, sizeof(filename), + "%s.%05d.maps", prefix, static_cast(getpid())); + + RawFD fd = RawOpenForWriting(filename); + RAW_DCHECK(fd != kIllegalRawFD, ""); + + int length; + bool wrote_all; + length = tcmalloc::FillProcSelfMaps(raw_buffer, buffer_size, &wrote_all); + RAW_DCHECK(wrote_all, ""); + RAW_DCHECK(length <= buffer_size, ""); + RawWrite(fd, raw_buffer, length); + RawClose(fd); +} +#else // USE_DEEP_HEAP_PROFILE + +DeepHeapProfile::DeepHeapProfile(HeapProfileTable* heap_profile, + const char* prefix, + enum PageFrameType pageframe_type) + : heap_profile_(heap_profile) { +} + +DeepHeapProfile::~DeepHeapProfile() { +} + +void DeepHeapProfile::DumpOrderedProfile(const char* reason, + char raw_buffer[], + int buffer_size, + RawFD fd) { +} + +#endif // USE_DEEP_HEAP_PROFILE diff --git a/third_party/tcmalloc/chromium/src/deep-heap-profile.h b/third_party/tcmalloc/chromium/src/deep-heap-profile.h new file mode 100644 index 000000000..0544b31c7 --- /dev/null +++ b/third_party/tcmalloc/chromium/src/deep-heap-profile.h @@ -0,0 +1,407 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// --- +// Author: Sainbayar Sukhbaatar +// Dai Mikurube +// +// This file contains a class DeepHeapProfile and its public function +// DeepHeapProfile::DumpOrderedProfile(). The function works like +// HeapProfileTable::FillOrderedProfile(), but dumps directory to files. +// +// DeepHeapProfile::DumpOrderedProfile() dumps more detailed information about +// heap usage, which includes OS-level information such as memory residency and +// type information if the type profiler is available. +// +// DeepHeapProfile::DumpOrderedProfile() uses data stored in HeapProfileTable. +// Any code in DeepHeapProfile runs only when DumpOrderedProfile() is called. +// It has overhead in dumping, but no overhead in logging. +// +// It currently works only on Linux including Android. It does nothing in +// non-Linux environments. + +// Note that uint64 is used to represent addresses instead of uintptr_t, and +// int is used to represent buffer sizes instead of size_t. +// It's for consistency with other TCMalloc functions. ProcMapsIterator uses +// uint64 for addresses, and HeapProfileTable::DumpOrderedProfile uses int +// for buffer sizes. + +#ifndef BASE_DEEP_HEAP_PROFILE_H_ +#define BASE_DEEP_HEAP_PROFILE_H_ + +#include "config.h" + +#if defined(TYPE_PROFILING) +#include +#endif + +#if defined(__linux__) || defined(_WIN32) || defined(_WIN64) +#define USE_DEEP_HEAP_PROFILE 1 +#endif + +#include "addressmap-inl.h" +#include "heap-profile-table.h" +#include "memory_region_map.h" + +class DeepHeapProfile { + public: + enum PageFrameType { + DUMP_NO_PAGEFRAME = 0, // Dumps nothing about pageframes + DUMP_PFN = 1, // Dumps only pageframe numbers (PFNs) + DUMP_PAGECOUNT = 2, // Dumps PFNs and pagecounts + }; + + // Constructs a DeepHeapProfile instance. It works as a wrapper of + // HeapProfileTable. + // + // |heap_profile| is a pointer to HeapProfileTable. DeepHeapProfile reads + // data in |heap_profile| and forwards operations to |heap_profile| if + // DeepHeapProfile is not available (non-Linux). + // |prefix| is a prefix of dumped file names. + // |pageframe_type| means what information is dumped for pageframes. + DeepHeapProfile(HeapProfileTable* heap_profile, + const char* prefix, + enum PageFrameType pageframe_type); + ~DeepHeapProfile(); + + // Dumps a deep profile into |fd| with using |raw_buffer| of |buffer_size|. + // + // In addition, a list of buckets is dumped into a ".buckets" file in + // descending order of allocated bytes. + void DumpOrderedProfile(const char* reason, + char raw_buffer[], + int buffer_size, + RawFD fd); + + private: +#ifdef USE_DEEP_HEAP_PROFILE + typedef HeapProfileTable::Stats Stats; + typedef HeapProfileTable::Bucket Bucket; + typedef HeapProfileTable::AllocValue AllocValue; + typedef HeapProfileTable::AllocationMap AllocationMap; + + enum MapsRegionType { + // Bytes of memory which were not recognized with /proc//maps. + // This size should be 0. + ABSENT, + + // Bytes of memory which is mapped anonymously. + // Regions which contain nothing in the last column of /proc//maps. + ANONYMOUS, + + // Bytes of memory which is mapped to a executable/non-executable file. + // Regions which contain file paths in the last column of /proc//maps. + FILE_EXEC, + FILE_NONEXEC, + + // Bytes of memory which is labeled [stack] in /proc//maps. + STACK, + + // Bytes of memory which is labeled, but not mapped to any file. + // Regions which contain non-path strings in the last column of + // /proc//maps. + OTHER, + + NUMBER_OF_MAPS_REGION_TYPES + }; + + static const char* kMapsRegionTypeDict[NUMBER_OF_MAPS_REGION_TYPES]; + + // Manages a buffer to keep a text to be dumped to a file. + class TextBuffer { + public: + TextBuffer(char *raw_buffer, int size, RawFD fd) + : buffer_(raw_buffer), + size_(size), + cursor_(0), + fd_(fd) { + } + + int Size(); + int FilledBytes(); + void Clear(); + void Flush(); + + bool AppendChar(char value); + bool AppendString(const char* value, int width); + bool AppendInt(int value, int width, bool leading_zero); + bool AppendLong(long value, int width); + bool AppendUnsignedLong(unsigned long value, int width); + bool AppendInt64(int64 value, int width); + bool AppendBase64(uint64 value, int width); + bool AppendPtr(uint64 value, int width); + + private: + bool ForwardCursor(int appended); + + char *buffer_; + int size_; + int cursor_; + RawFD fd_; + DISALLOW_COPY_AND_ASSIGN(TextBuffer); + }; + + // Defines an interface for getting info about memory residence. + class MemoryResidenceInfoGetterInterface { + public: + virtual ~MemoryResidenceInfoGetterInterface(); + + // Initializes the instance. + virtual void Initialize() = 0; + + // Returns the number of resident (including swapped) bytes of the given + // memory region from |first_address| to |last_address| inclusive. + virtual size_t CommittedSize(uint64 first_address, + uint64 last_address, + TextBuffer* buffer) const = 0; + + // Creates a new platform specific MemoryResidenceInfoGetterInterface. + static MemoryResidenceInfoGetterInterface* Create( + PageFrameType pageframe_type); + + virtual bool IsPageCountAvailable() const = 0; + + protected: + MemoryResidenceInfoGetterInterface(); + }; + +#if defined(_WIN32) || defined(_WIN64) + // TODO(peria): Implement this class. + class MemoryInfoGetterWindows : public MemoryResidenceInfoGetterInterface { + public: + MemoryInfoGetterWindows(PageFrameType) {} + virtual ~MemoryInfoGetterWindows() {} + + virtual void Initialize(); + + virtual size_t CommittedSize(uint64 first_address, + uint64 last_address, + TextBuffer* buffer) const; + + virtual bool IsPageCountAvailable() const; + }; +#endif // defined(_WIN32) || defined(_WIN64) + +#if defined(__linux__) + // Implements MemoryResidenceInfoGetterInterface for Linux. + class MemoryInfoGetterLinux : public MemoryResidenceInfoGetterInterface { + public: + MemoryInfoGetterLinux(PageFrameType pageframe_type) + : pageframe_type_(pageframe_type), + pagemap_fd_(kIllegalRawFD), + kpagecount_fd_(kIllegalRawFD) {} + virtual ~MemoryInfoGetterLinux() {} + + // Opens /proc//pagemap and stores its file descriptor. + // It keeps open while the process is running. + // + // Note that file descriptors need to be refreshed after fork. + virtual void Initialize(); + + // Returns the number of resident (including swapped) bytes of the given + // memory region from |first_address| to |last_address| inclusive. + virtual size_t CommittedSize(uint64 first_address, + uint64 last_address, + TextBuffer* buffer) const; + + virtual bool IsPageCountAvailable() const; + + private: + struct State { + uint64 pfn; + bool is_committed; // Currently, we use only this + bool is_present; + bool is_swapped; + bool is_shared; + bool is_mmap; + }; + + uint64 ReadPageCount(uint64 pfn) const; + + // Seeks to the offset of the open pagemap file. + // It returns true if succeeded. + bool Seek(uint64 address) const; + + // Reads a pagemap state from the current offset. + // It returns true if succeeded. + bool Read(State* state, bool get_pfn) const; + + PageFrameType pageframe_type_; + RawFD pagemap_fd_; + RawFD kpagecount_fd_; + }; +#endif // defined(__linux__) + + // Contains extended information for HeapProfileTable::Bucket. These objects + // are managed in a hash table (DeepBucketTable) whose key is an address of + // a Bucket and other additional information. + struct DeepBucket { + public: + void UnparseForStats(TextBuffer* buffer); + void UnparseForBucketFile(TextBuffer* buffer); + + Bucket* bucket; +#if defined(TYPE_PROFILING) + const std::type_info* type; // A type of the object +#endif + size_t committed_size; // A resident size of this bucket + bool is_mmap; // True if the bucket represents a mmap region + int id; // A unique ID of the bucket + bool is_logged; // True if the stracktrace is logged to a file + DeepBucket* next; // A reference to the next entry in the hash table + }; + + // Manages a hash table for DeepBucket. + class DeepBucketTable { + public: + DeepBucketTable(int size, + HeapProfileTable::Allocator alloc, + HeapProfileTable::DeAllocator dealloc); + ~DeepBucketTable(); + + // Finds a DeepBucket instance corresponding to the given |bucket|, or + // creates a new DeepBucket object if it doesn't exist. + DeepBucket* Lookup(Bucket* bucket, +#if defined(TYPE_PROFILING) + const std::type_info* type, +#endif + bool is_mmap); + + // Writes stats of the hash table to |buffer| for DumpOrderedProfile. + void UnparseForStats(TextBuffer* buffer); + + // Writes all buckets for a bucket file with using |buffer|. + void WriteForBucketFile(const char* prefix, + int dump_count, + char raw_buffer[], + int buffer_size); + + // Resets 'committed_size' members in DeepBucket objects. + void ResetCommittedSize(); + + // Resets all 'is_loggeed' flags in DeepBucket objects. + void ResetIsLogged(); + + private: + // Adds |add| to a |hash_value| for Lookup. + inline static void AddToHashValue(uintptr_t add, uintptr_t* hash_value); + inline static void FinishHashValue(uintptr_t* hash_value); + + DeepBucket** table_; + size_t table_size_; + HeapProfileTable::Allocator alloc_; + HeapProfileTable::DeAllocator dealloc_; + int bucket_id_; + }; + + class RegionStats { + public: + RegionStats(): virtual_bytes_(0), committed_bytes_(0) {} + ~RegionStats() {} + + // Initializes 'virtual_bytes_' and 'committed_bytes_'. + void Initialize(); + + // Updates itself to contain the tallies of 'virtual_bytes' and + // 'committed_bytes' in the region from |first_adress| to |last_address| + // inclusive. + uint64 Record( + const MemoryResidenceInfoGetterInterface* memory_residence_info_getter, + uint64 first_address, + uint64 last_address, + TextBuffer* buffer); + + // Writes stats of the region into |buffer| with |name|. + void Unparse(const char* name, TextBuffer* buffer); + + size_t virtual_bytes() const { return virtual_bytes_; } + size_t committed_bytes() const { return committed_bytes_; } + void AddToVirtualBytes(size_t additional_virtual_bytes) { + virtual_bytes_ += additional_virtual_bytes; + } + void AddToCommittedBytes(size_t additional_committed_bytes) { + committed_bytes_ += additional_committed_bytes; + } + void AddAnotherRegionStat(const RegionStats& other) { + virtual_bytes_ += other.virtual_bytes_; + committed_bytes_ += other.committed_bytes_; + } + + private: + size_t virtual_bytes_; + size_t committed_bytes_; + DISALLOW_COPY_AND_ASSIGN(RegionStats); + }; + + class GlobalStats { + public: + // Snapshots and calculates global stats from /proc//maps and pagemap. + void SnapshotMaps( + const MemoryResidenceInfoGetterInterface* memory_residence_info_getter, + DeepHeapProfile* deep_profile, + TextBuffer* mmap_dump_buffer); + + // Snapshots allocations by malloc and mmap. + void SnapshotAllocations(DeepHeapProfile* deep_profile); + + // Writes global stats into |buffer|. + void Unparse(TextBuffer* buffer); + + private: + // Records both virtual and committed byte counts of malloc and mmap regions + // as callback functions for AllocationMap::Iterate(). + static void RecordAlloc(const void* pointer, + AllocValue* alloc_value, + DeepHeapProfile* deep_profile); + + DeepBucket* GetInformationOfMemoryRegion( + const MemoryRegionMap::RegionIterator& mmap_iter, + const MemoryResidenceInfoGetterInterface* memory_residence_info_getter, + DeepHeapProfile* deep_profile); + + // All RegionStats members in this class contain the bytes of virtual + // memory and committed memory. + // TODO(dmikurube): These regions should be classified more precisely later + // for more detailed analysis. + RegionStats all_[NUMBER_OF_MAPS_REGION_TYPES]; + + RegionStats unhooked_[NUMBER_OF_MAPS_REGION_TYPES]; + + // Total bytes of malloc'ed regions. + RegionStats profiled_malloc_; + + // Total bytes of mmap'ed regions. + RegionStats profiled_mmap_; + }; + + // Writes reformatted /proc//maps into a file "|prefix|..maps" + // with using |raw_buffer| of |buffer_size|. + static void WriteProcMaps(const char* prefix, + char raw_buffer[], + int buffer_size); + + // Appends the command line (/proc/pid/cmdline on Linux) into |buffer|. + bool AppendCommandLine(TextBuffer* buffer); + + MemoryResidenceInfoGetterInterface* memory_residence_info_getter_; + + // Process ID of the last dump. This can change by fork. + pid_t most_recent_pid_; + + GlobalStats stats_; // Stats about total memory. + int dump_count_; // The number of dumps. + char* filename_prefix_; // Output file prefix. + char run_id_[128]; + + DeepBucketTable deep_table_; + + enum PageFrameType pageframe_type_; +#endif // USE_DEEP_HEAP_PROFILE + + HeapProfileTable* heap_profile_; + + DISALLOW_COPY_AND_ASSIGN(DeepHeapProfile); +}; + +#endif // BASE_DEEP_HEAP_PROFILE_H_ diff --git a/third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h b/third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h new file mode 100644 index 000000000..1236258f6 --- /dev/null +++ b/third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h @@ -0,0 +1,20 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef TYPE_PROFILER_MAP_H_ +#define TYPE_PROFILER_MAP_H_ + +#if defined(TYPE_PROFILING) + +#include + +// PERFTOOLS_DLL_DECL is unnecessary, as it is Windows specific. + +void InsertType(void* address, size_t size, const std::type_info& type); +void EraseType(void* address); +const std::type_info* LookupType(const void* address); + +#endif // defined(TYPE_PROFILING) + +#endif // TYPE_PROFILER_MAP_H_ diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.cc b/third_party/tcmalloc/chromium/src/heap-profile-table.cc index cb96d91f0..1e0eea5e1 100644 --- a/third_party/tcmalloc/chromium/src/heap-profile-table.cc +++ b/third_party/tcmalloc/chromium/src/heap-profile-table.cc @@ -92,6 +92,9 @@ DEFINE_int32(heap_check_max_leaks, // header of the dumped heap profile static const char kProfileHeader[] = "heap profile: "; static const char kProcSelfMapsHeader[] = "\nMAPPED_LIBRARIES:\n"; +#if defined(TYPE_PROFILING) +static const char kTypeProfileStatsHeader[] = "type statistics:\n"; +#endif // defined(TYPE_PROFILING) //---------------------------------------------------------------------- @@ -358,6 +361,29 @@ void HeapProfileTable::DumpMarkedObjects(AllocationMark mark, RawClose(fd); } +#if defined(TYPE_PROFILING) +void HeapProfileTable::DumpTypeStatistics(const char* file_name) const { + RawFD fd = RawOpenForWriting(file_name); + if (fd == kIllegalRawFD) { + RAW_LOG(ERROR, "Failed dumping type statistics to %s", file_name); + return; + } + + AddressMap* type_size_map; + type_size_map = new(alloc_(sizeof(AddressMap))) + AddressMap(alloc_, dealloc_); + address_map_->Iterate(TallyTypesItererator, type_size_map); + + RawWrite(fd, kTypeProfileStatsHeader, strlen(kTypeProfileStatsHeader)); + const DumpArgs args(fd, NULL); + type_size_map->Iterate(DumpTypesIterator, args); + RawClose(fd); + + type_size_map->~AddressMap(); + dealloc_(type_size_map); +} +#endif // defined(TYPE_PROFILING) + void HeapProfileTable::IterateOrderedAllocContexts( AllocContextIterator callback) const { Bucket** list = MakeSortedBucketList(); @@ -425,6 +451,41 @@ void HeapProfileTable::DumpBucketIterator(const Bucket* bucket, "", NULL); } +#if defined(TYPE_PROFILING) +// static +void HeapProfileTable::TallyTypesItererator( + const void* ptr, + AllocValue* value, + AddressMap* type_size_map) { + const std::type_info* type = LookupType(ptr); + + const void* key = NULL; + if (type) + key = type->name(); + + TypeCount* count = type_size_map->FindMutable(key); + if (count) { + count->bytes += value->bytes; + ++count->objects; + } else { + type_size_map->Insert(key, TypeCount(value->bytes, 1)); + } +} + +// static +void HeapProfileTable::DumpTypesIterator(const void* ptr, + TypeCount* count, + const DumpArgs& args) { + char buf[1024]; + int len; + const char* mangled_type_name = static_cast(ptr); + len = snprintf(buf, sizeof(buf), "%6d: %8" PRId64 " @ %s\n", + count->objects, count->bytes, + mangled_type_name ? mangled_type_name : "(no_typeinfo)"); + RawWrite(args.fd, buf, len); +} +#endif // defined(TYPE_PROFILING) + inline void HeapProfileTable::DumpNonLiveIterator(const void* ptr, AllocValue* v, const DumpArgs& args) { @@ -458,7 +519,7 @@ void HeapProfileTable::DumpMarkedIterator(const void* ptr, AllocValue* v, b.depth = v->bucket()->depth; b.stack = v->bucket()->stack; char addr[16]; - snprintf(addr, 16, "0x%08" PRIxPTR, ptr); + snprintf(addr, 16, "0x%08" PRIxPTR, reinterpret_cast(ptr)); char buf[1024]; int len = UnparseBucket(b, buf, 0, sizeof(buf), addr, NULL); RawWrite(args.fd, buf, len); diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.h b/third_party/tcmalloc/chromium/src/heap-profile-table.h index b0c369566..c2ad39f91 100644 --- a/third_party/tcmalloc/chromium/src/heap-profile-table.h +++ b/third_party/tcmalloc/chromium/src/heap-profile-table.h @@ -40,6 +40,10 @@ #include "base/logging.h" // for RawFD #include "heap-profile-stats.h" +#if defined(TYPE_PROFILING) +#include +#endif // defined(TYPE_PROFILING) + // Table to maintain a heap profile data inside, // i.e. the set of currently active heap memory allocations. // thread-unsafe and non-reentrant code: @@ -219,7 +223,13 @@ class HeapProfileTable { // used for leak checking (using HeapLeakChecker). void DumpMarkedObjects(AllocationMark mark, const char* file_name); +#if defined(TYPE_PROFILING) + void DumpTypeStatistics(const char* file_name) const; +#endif // defined(TYPE_PROFILING) + private: + friend class DeepHeapProfile; + // data types ---------------------------- // Hash table bucket to hold (de)allocation stats @@ -318,6 +328,18 @@ class HeapProfileTable { // mark unmarked allocations. }; +#if defined(TYPE_PROFILING) + struct TypeCount { + TypeCount(size_t bytes_arg, unsigned int objects_arg) + : bytes(bytes_arg), + objects(objects_arg) { + } + + size_t bytes; + unsigned int objects; + }; +#endif // defined(TYPE_PROFILING) + struct AllocationAddressIteratorArgs { AllocationAddressIteratorArgs(AddressIterator callback_arg, void* data_arg) : callback(callback_arg), @@ -387,6 +409,16 @@ class HeapProfileTable { inline static void DumpMarkedIterator(const void* ptr, AllocValue* v, const DumpMarkedArgs& args); +#if defined(TYPE_PROFILING) + inline static void TallyTypesItererator(const void* ptr, + AllocValue* value, + AddressMap* type_size_map); + + inline static void DumpTypesIterator(const void* ptr, + TypeCount* size, + const DumpArgs& args); +#endif // defined(TYPE_PROFILING) + // Helper for IterateOrderedAllocContexts and FillOrderedProfile. // Creates a sorted list of Buckets whose length is num_buckets_. // The caller is responsible for deallocating the returned list. diff --git a/third_party/tcmalloc/chromium/src/heap-profiler.cc b/third_party/tcmalloc/chromium/src/heap-profiler.cc index a49f63dbf..46a81a499 100644 --- a/third_party/tcmalloc/chromium/src/heap-profiler.cc +++ b/third_party/tcmalloc/chromium/src/heap-profiler.cc @@ -68,6 +68,7 @@ #include "base/spinlock.h" #include "base/low_level_alloc.h" #include "base/sysinfo.h" // for GetUniquePathFromEnv() +#include "deep-heap-profile.h" #include "heap-profile-table.h" #include "memory_region_map.h" @@ -80,6 +81,38 @@ #endif #endif +#if defined(__ANDROID__) || defined(ANDROID) +// On android, there are no environment variables. +// Instead, we use system properties, set via: +// adb shell setprop prop_name prop_value +// From , +// PROP_NAME_MAX 32 +// PROP_VALUE_MAX 92 +#define HEAPPROFILE "heapprof" +#define HEAP_PROFILE_ALLOCATION_INTERVAL "heapprof.allocation_interval" +#define HEAP_PROFILE_DEALLOCATION_INTERVAL "heapprof.deallocation_interval" +#define HEAP_PROFILE_INUSE_INTERVAL "heapprof.inuse_interval" +#define HEAP_PROFILE_TIME_INTERVAL "heapprof.time_interval" +#define HEAP_PROFILE_MMAP_LOG "heapprof.mmap_log" +#define HEAP_PROFILE_MMAP "heapprof.mmap" +#define HEAP_PROFILE_ONLY_MMAP "heapprof.only_mmap" +#define DEEP_HEAP_PROFILE "heapprof.deep_heap_profile" +#define DEEP_HEAP_PROFILE_PAGEFRAME "heapprof.deep.pageframe" +#define HEAP_PROFILE_TYPE_STATISTICS "heapprof.type_statistics" +#else // defined(__ANDROID__) || defined(ANDROID) +#define HEAPPROFILE "HEAPPROFILE" +#define HEAP_PROFILE_ALLOCATION_INTERVAL "HEAP_PROFILE_ALLOCATION_INTERVAL" +#define HEAP_PROFILE_DEALLOCATION_INTERVAL "HEAP_PROFILE_DEALLOCATION_INTERVAL" +#define HEAP_PROFILE_INUSE_INTERVAL "HEAP_PROFILE_INUSE_INTERVAL" +#define HEAP_PROFILE_TIME_INTERVAL "HEAP_PROFILE_TIME_INTERVAL" +#define HEAP_PROFILE_MMAP_LOG "HEAP_PROFILE_MMAP_LOG" +#define HEAP_PROFILE_MMAP "HEAP_PROFILE_MMAP" +#define HEAP_PROFILE_ONLY_MMAP "HEAP_PROFILE_ONLY_MMAP" +#define DEEP_HEAP_PROFILE "DEEP_HEAP_PROFILE" +#define DEEP_HEAP_PROFILE_PAGEFRAME "DEEP_HEAP_PROFILE_PAGEFRAME" +#define HEAP_PROFILE_TYPE_STATISTICS "HEAP_PROFILE_TYPE_STATISTICS" +#endif // defined(__ANDROID__) || defined(ANDROID) + using STL_NAMESPACE::string; using STL_NAMESPACE::sort; @@ -121,6 +154,20 @@ DEFINE_bool(only_mmap_profile, EnvToBool(HEAP_PROFILE_ONLY_MMAP, false), "If heap-profiling is on, only profile mmap, mremap, and sbrk; " "do not profile malloc/new/etc"); +DEFINE_bool(deep_heap_profile, + EnvToBool(DEEP_HEAP_PROFILE, false), + "If heap-profiling is on, profile deeper (Linux and Android)"); +DEFINE_int32(deep_heap_profile_pageframe, + EnvToInt(DEEP_HEAP_PROFILE_PAGEFRAME, 0), + "Needs deeper profile. If 1, dump page frame numbers (PFNs). " + "If 2, dump page counts (/proc/kpagecount) with PFNs."); +#if defined(TYPE_PROFILING) +DEFINE_bool(heap_profile_type_statistics, + EnvToBool(HEAP_PROFILE_TYPE_STATISTICS, false), + "If heap-profiling is on, dump type statistics."); +#endif // defined(TYPE_PROFILING) + + //---------------------------------------------------------------------- // Locking //---------------------------------------------------------------------- @@ -173,6 +220,7 @@ static int64 high_water_mark = 0; // In-use-bytes at last high-water dump static int64 last_dump_time = 0; // The time of the last dump static HeapProfileTable* heap_profile = NULL; // the heap profile table +static DeepHeapProfile* deep_profile = NULL; // deep memory profiler // Callback to generate a stack trace for an allocation. May be overriden // by an application to provide its own pseudo-stacks. @@ -253,11 +301,25 @@ static void DumpProfileLocked(const char* reason) { reinterpret_cast(ProfilerMalloc(kProfileBufferSize)); } - char* profile = - DoGetHeapProfileLocked(global_profiler_buffer, kProfileBufferSize); - RawWrite(fd, profile, strlen(profile)); + if (deep_profile) { + deep_profile->DumpOrderedProfile(reason, global_profiler_buffer, + kProfileBufferSize, fd); + } else { + char* profile = DoGetHeapProfileLocked(global_profiler_buffer, + kProfileBufferSize); + RawWrite(fd, profile, strlen(profile)); + } RawClose(fd); +#if defined(TYPE_PROFILING) + if (FLAGS_heap_profile_type_statistics) { + snprintf(file_name, sizeof(file_name), "%s.%05d.%04d.type", + filename_prefix, getpid(), dump_count); + RAW_VLOG(0, "Dumping type statistics to %s", file_name); + heap_profile->DumpTypeStatistics(file_name); + } +#endif // defined(TYPE_PROFILING) + dumping = false; } @@ -467,6 +529,14 @@ extern "C" void HeapProfilerStart(const char* prefix) { high_water_mark = 0; last_dump_time = 0; + if (FLAGS_deep_heap_profile) { + // Initialize deep memory profiler + RAW_VLOG(0, "[%d] Starting a deep memory profiler", getpid()); + deep_profile = new(ProfilerMalloc(sizeof(DeepHeapProfile))) + DeepHeapProfile(heap_profile, prefix, DeepHeapProfile::PageFrameType( + FLAGS_deep_heap_profile_pageframe)); + } + // We do not reset dump_count so if the user does a sequence of // HeapProfilerStart/HeapProfileStop, we will get a continuous // sequence of profiles. @@ -528,6 +598,13 @@ extern "C" void HeapProfilerStop() { RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), ""); } + if (deep_profile) { + // free deep memory profiler + deep_profile->~DeepHeapProfile(); + ProfilerFree(deep_profile); + deep_profile = NULL; + } + // free profile heap_profile->~HeapProfileTable(); ProfilerFree(heap_profile); diff --git a/third_party/tcmalloc/chromium/src/type_profiler_map.cc b/third_party/tcmalloc/chromium/src/type_profiler_map.cc new file mode 100644 index 000000000..a2f21f82b --- /dev/null +++ b/third_party/tcmalloc/chromium/src/type_profiler_map.cc @@ -0,0 +1,112 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#if defined(TYPE_PROFILING) + +#include + +#include +#include +#include + +#include + +#include "addressmap-inl.h" +#include "base/logging.h" +#include "base/low_level_alloc.h" +#include "base/spinlock.h" +#include "tcmalloc_guard.h" + +namespace { + +const TCMallocGuard tcmalloc_initializer; + +//---------------------------------------------------------------------- +// A struct to store size and type_info of an object +//---------------------------------------------------------------------- + +struct ObjectInfo { + public: + ObjectInfo(): size(0), type(NULL) {} + ObjectInfo(size_t size_arg, const std::type_info* type_arg) + : size(size_arg), + type(type_arg) { + } + + size_t size; + const std::type_info* type; +}; + +//---------------------------------------------------------------------- +// Locking +//---------------------------------------------------------------------- + +SpinLock g_type_profiler_lock(SpinLock::LINKER_INITIALIZED); + +//---------------------------------------------------------------------- +// Simple allocator for type_info map's internal memory +//---------------------------------------------------------------------- + +LowLevelAlloc::Arena* g_type_profiler_map_memory = NULL; + +void* TypeProfilerMalloc(size_t bytes) { + return LowLevelAlloc::AllocWithArena(bytes, g_type_profiler_map_memory); +} + +void TypeProfilerFree(void* p) { + LowLevelAlloc::Free(p); +} + +//---------------------------------------------------------------------- +// Profiling control/state data +//---------------------------------------------------------------------- + +AddressMap* g_type_profiler_map = NULL; + +//---------------------------------------------------------------------- +// Manage type_info map +//---------------------------------------------------------------------- + +void InitializeTypeProfilerMemory() { + if (g_type_profiler_map_memory != NULL) { + RAW_DCHECK(g_type_profiler_map != NULL, "TypeProfilerMap is NULL"); + return; + } + + g_type_profiler_map_memory = + LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena()); + + g_type_profiler_map = + new(TypeProfilerMalloc(sizeof(*g_type_profiler_map))) + AddressMap(TypeProfilerMalloc, TypeProfilerFree); +} + +} // namespace + +void InsertType(void* address, size_t size, const std::type_info& type) { + SpinLockHolder lock(&g_type_profiler_lock); + InitializeTypeProfilerMemory(); + + g_type_profiler_map->Insert(address, ObjectInfo(size, &type)); +} + +void EraseType(void* address) { + SpinLockHolder lock(&g_type_profiler_lock); + InitializeTypeProfilerMemory(); + + ObjectInfo obj; + g_type_profiler_map->FindAndRemove(address, &obj); +} + +const std::type_info* LookupType(const void* address) { + SpinLockHolder lock(&g_type_profiler_lock); + InitializeTypeProfilerMemory(); + + const ObjectInfo* found = g_type_profiler_map->Find(address); + if (found == NULL) + return NULL; + return found->type; +} + +#endif // defined(TYPE_PROFILING) diff --git a/third_party/zlib/BUILD.gn b/third_party/zlib/BUILD.gn index 1cea9acb9..0d592189c 100644 --- a/third_party/zlib/BUILD.gn +++ b/third_party/zlib/BUILD.gn @@ -67,6 +67,13 @@ static_library("zlib") { if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) { sources += [ "x86.c" ] + + config("zlib_warnings") { + if (is_clang) { + cflags = [ "-Wno-incompatible-pointer-types" ] + } + } + configs += [ ":zlib_warnings" ] } configs -= [ "//build/config/compiler:chromium_code" ] @@ -102,17 +109,20 @@ static_library("minizip") { defines = [ "USE_FILE32API" ] } - if (is_clang) { - # zlib uses `if ((a == b))` for some reason. - cflags = [ "-Wno-parentheses-equality" ] - } - deps = [ ":zlib", ] + config("minizip_warnings") { + if (is_clang) { + # zlib uses `if ((a == b))` for some reason. + cflags = [ "-Wno-parentheses-equality" ] + } + } + configs -= [ "//build/config/compiler:chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code" ] + configs += [ ":minizip_warnings" ] public_configs = [ ":zlib_config" ] } diff --git a/third_party/zlib/google/DEPS b/third_party/zlib/google/DEPS new file mode 100644 index 000000000..e616fe28c --- /dev/null +++ b/third_party/zlib/google/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + '+base', + '+testing', +] diff --git a/third_party/zlib/google/zip.cc b/third_party/zlib/google/zip.cc index 726df33b4..39e2e534c 100644 --- a/third_party/zlib/google/zip.cc +++ b/third_party/zlib/google/zip.cc @@ -56,7 +56,7 @@ bool AddEntryToZip(zipFile zip_file, const base::FilePath& path, DCHECK(result); std::string str_path = relative_path.AsUTF8Unsafe(); #if defined(OS_WIN) - ReplaceSubstringsAfterOffset(&str_path, 0u, "\\", "/"); + base::ReplaceSubstringsAfterOffset(&str_path, 0u, "\\", "/"); #endif bool is_directory = base::DirectoryExists(path); diff --git a/third_party/zlib/google/zip.gyp b/third_party/zlib/google/zip.gyp new file mode 100644 index 000000000..9542f9cd6 --- /dev/null +++ b/third_party/zlib/google/zip.gyp @@ -0,0 +1,27 @@ +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'targets': [ + { + 'target_name': 'zip', + 'type': 'static_library', + 'dependencies': [ + '../zlib.gyp:minizip', + '../../../base/base.gyp:base', + ], + 'include_dirs': [ + '../../..', + ], + 'sources': [ + 'zip.cc', + 'zip.h', + 'zip_internal.cc', + 'zip_internal.h', + 'zip_reader.cc', + 'zip_reader.h', + ], + }, + ], +} diff --git a/third_party/zlib/google/zip_reader.cc b/third_party/zlib/google/zip_reader.cc index 7df46e741..e0871c853 100644 --- a/third_party/zlib/google/zip_reader.cc +++ b/third_party/zlib/google/zip_reader.cc @@ -131,8 +131,8 @@ ZipReader::EntryInfo::EntryInfo(const std::string& file_name_in_zip, original_size_ = raw_file_info.uncompressed_size; // Directory entries in zip files end with "/". - is_directory_ = - base::EndsWith(file_name_in_zip, "/", base::CompareCase::SENSITIVE); + is_directory_ = base::EndsWith(file_name_in_zip, "/", + base::CompareCase::INSENSITIVE_ASCII); // Check the file name here for directory traversal issues. is_unsafe_ = file_path_.ReferencesParent(); @@ -147,7 +147,7 @@ ZipReader::EntryInfo::EntryInfo(const std::string& file_name_in_zip, // We also consider that the file name is unsafe, if it's absolute. // On Windows, IsAbsolute() returns false for paths starting with "/". if (file_path_.IsAbsolute() || - base::StartsWith(file_name_in_zip, "/", base::CompareCase::SENSITIVE)) + base::StartsWithASCII(file_name_in_zip, "/", false)) is_unsafe_ = true; // Construct the last modified time. The timezone info is not present in @@ -358,12 +358,10 @@ void ZipReader::ExtractCurrentEntryToFilePathAsync( // If this is a directory, just create it and return. if (current_entry_info()->is_directory()) { if (base::CreateDirectory(output_file_path)) { - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - success_callback); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, success_callback); } else { DVLOG(1) << "Unzip failed: unable to create directory."; - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - failure_callback); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, failure_callback); } return; } diff --git a/third_party/zlib/zlib.gyp b/third_party/zlib/zlib.gyp new file mode 100644 index 000000000..42e4e9508 --- /dev/null +++ b/third_party/zlib/zlib.gyp @@ -0,0 +1,148 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'targets': [ + { + 'target_name' : 'zlib_x86_simd', + 'type': 'static_library', + 'conditions': [ + ['OS!="ios" and (target_arch=="ia32" or target_arch=="x64")', { + 'cflags' : ['-msse4.2', '-mpclmul'], + 'xcode_settings' : { + 'OTHER_CFLAGS' : ['-msse4.2', '-mpclmul'], + }, + 'sources' : [ + 'crc_folding.c', + 'fill_window_sse.c', + ], + 'conditions': [ + ['OS=="win" and clang==1', { + 'msvs_settings': { + 'VCCLCompilerTool': { + 'AdditionalOptions': [ '-msse4.2', '-mpclmul' ], + }, + }, + }], + ], + }, { + 'sources' : [ 'simd_stub.c' ], + }], + ['OS=="android"', { + 'toolsets': ['target', 'host'], + }], + ], + }, + { + 'target_name': 'zlib', + 'type': 'static_library', + 'sources': [ + 'adler32.c', + 'compress.c', + 'crc32.c', + 'crc32.h', + 'deflate.c', + 'deflate.h', + 'gzclose.c', + 'gzguts.h', + 'gzlib.c', + 'gzread.c', + 'gzwrite.c', + 'infback.c', + 'inffast.c', + 'inffast.h', + 'inffixed.h', + 'inflate.c', + 'inflate.h', + 'inftrees.c', + 'inftrees.h', + 'mozzconf.h', + 'trees.c', + 'trees.h', + 'uncompr.c', + 'x86.h', + 'zconf.h', + 'zlib.h', + 'zutil.c', + 'zutil.h', + ], + 'dependencies' : [ + 'zlib_x86_simd' + ], + 'include_dirs': [ + '.', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '.', + ], + }, + 'conditions': [ + ['OS!="ios" and (target_arch=="ia32" or target_arch=="x64")', { + 'sources' : [ 'x86.c', ], + 'variables': { + 'clang_warning_flags': [ + '-Wno-incompatible-pointer-types', + ], + }, + }], + ['OS!="win"', { + 'product_name': 'chrome_zlib', + }], ['OS=="android"', { + 'toolsets': ['target', 'host'], + }], + ], + }, + { + 'target_name': 'minizip', + 'type': 'static_library', + 'sources': [ + 'contrib/minizip/ioapi.c', + 'contrib/minizip/ioapi.h', + 'contrib/minizip/iowin32.c', + 'contrib/minizip/iowin32.h', + 'contrib/minizip/unzip.c', + 'contrib/minizip/unzip.h', + 'contrib/minizip/zip.c', + 'contrib/minizip/zip.h', + ], + 'dependencies': [ + 'zlib', + ], + 'include_dirs': [ + '.', + '../..', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '.', + ], + }, + 'variables': { + 'clang_warning_flags': [ + # zlib uses `if ((a == b))` for some reason. + '-Wno-parentheses-equality', + ], + }, + 'conditions': [ + ['OS!="win"', { + 'sources!': [ + 'contrib/minizip/iowin32.c' + ], + }], + ['OS=="android"', { + 'toolsets': ['target', 'host'], + }], + ['OS=="mac" or OS=="ios" or os_bsd==1 or OS=="android"', { + # Mac, Android and the BSDs don't have fopen64, ftello64, or + # fseeko64. We use fopen, ftell, and fseek instead on these + # systems. + 'defines': [ + 'USE_FILE32API' + ], + }], + ], + }, + ], +} diff --git a/ui/gl/gl_version_info.cc b/ui/gl/gl_version_info.cc index 2bf9ac5fc..02409694f 100644 --- a/ui/gl/gl_version_info.cc +++ b/ui/gl/gl_version_info.cc @@ -17,7 +17,7 @@ GLVersionInfo::GLVersionInfo(const char* version_str, const char* renderer_str) minor_version(0), is_es3(false) { if (version_str) { - std::string lstr(base::ToLowerASCII(std::string(version_str))); + std::string lstr(base::StringToLowerASCII(std::string(version_str))); is_es = (lstr.length() > 12) && (lstr.substr(0, 9) == "opengl es"); if (is_es) lstr = lstr.substr(10, 3); @@ -35,7 +35,7 @@ GLVersionInfo::GLVersionInfo(const char* version_str, const char* renderer_str) is_es3 = true; } if (renderer_str) { - is_angle = base::StartsWith(renderer_str, "ANGLE", base::CompareCase::SENSITIVE); + is_angle = base::StartsWithASCII(renderer_str, "ANGLE", true); } } -- GitLab