# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @depends(target, js_package) def jemalloc_default(target, js_package): if js_package: return False return target.kernel in ("Darwin", "Linux", "WINNT") # mozjemalloc doesn't work with these sanitisers, it mostly-works with ubsan # (so we leave that enabled) except for loading the configuration from the # environment, it will fall-back to default settings. imply_option("--enable-jemalloc", False, when=asan | msan | tsan) option( "--enable-jemalloc", env="MOZ_MEMORY", default=jemalloc_default, help="{Replace|Do not replace} memory allocator with jemalloc", ) set_config("MOZ_MEMORY", True, when="--enable-jemalloc") set_define("MOZ_MEMORY", True, when="--enable-jemalloc") @depends("--enable-jemalloc", moz_debug, win32_redist_dir) def check_redist(jemalloc, debug, win32_redist_dir): if not jemalloc and not win32_redist_dir and not debug: log.warning( "When not building jemalloc, you need to build with --with-redist or set WIN32_REDIST_DIR." ) @depends(milestone, build_project) def replace_malloc_default(milestone, build_project): if build_project == "memory": return True if milestone.is_early_beta_or_earlier and build_project != "js": return True option( "--enable-replace-malloc", default=replace_malloc_default, when="--enable-jemalloc", help="{Enable|Disable} ability to dynamically replace the malloc implementation", ) set_config("MOZ_REPLACE_MALLOC", True, when="--enable-replace-malloc") set_define("MOZ_REPLACE_MALLOC", True, when="--enable-replace-malloc") @depends(build_project, when="--enable-replace-malloc") def replace_malloc_static(build_project): # Default to statically linking replace-malloc libraries that can be # statically linked, except when building with --enable-project=memory. if build_project != "memory": return True set_config("MOZ_REPLACE_MALLOC_STATIC", replace_malloc_static) # PHC (Probabilistic Heap Checker) # ============================================================== # In general, it only makes sense for PHC to run on the platforms that have a # crash reporter. @depends( build_project, milestone, target, when="--enable-jemalloc", ) def phc_default(build_project, milestone, target): if build_project == "js": return False # Win32 has frequent crashes when stack tracing (for unclear reasons), # so PHC is enabled only on 64-bit. MacOS doesn't have a 32-bit version. # Therefore we've only been testing on 64bit processors. return (target.cpu in ("x86_64", "aarch64")) and ( (target.os == "GNU" and target.kernel == "Linux") or (target.kernel == "WINNT") or (target.os == "OSX") or (target.os == "Android" and milestone.is_early_beta_or_earlier) ) option( "--enable-phc", env="MOZ_PHC", default=phc_default, when="--enable-jemalloc", help="{Enable|Disable} PHC (Probabilistic Memory Checker). " "Also enables frame pointers when needed", ) set_config("MOZ_PHC", True, when="--enable-phc") # PHC parses stacks using frame pointers on these systems. @depends("--enable-phc", target, have_unwind, when="--enable-jemalloc") def phc_implies_frame_pointers(phc, target, have_unwind): if not phc: return False # This should be kept in sync with the ifdefs in memory/build/PHC.cpp # that control stack walking. # This is true for the first two options in PHC.cpp if (target.os == "WINNT" and target.cpu == "x86") or target.kernel == "Darwin": return True # This should match the #defines in mozglue/misc/StackWalk.cpp if (target.cpu in ("x86", "ppc")) and (target.kernel in ("Darwin", "Linux")): return not have_unwind return False imply_option("--enable-frame-pointers", True, when=phc_implies_frame_pointers) with only_when(depends(target.os)(lambda os: os != "WINNT")): set_define("HAVE_STRNDUP", check_symbol("strndup")) set_define("HAVE_POSIX_MEMALIGN", check_symbol("posix_memalign")) set_define("HAVE_MEMALIGN", check_symbol("memalign")) have_malloc_usable_size = check_symbol("malloc_usable_size") set_define("HAVE_MALLOC_USABLE_SIZE", have_malloc_usable_size) @template def check_malloc_header(): found_header = dependable(None) malloc_headers = ("malloc.h", "malloc_np.h", "malloc/malloc.h", "sys/malloc.h") for malloc_h in malloc_headers: have_malloc_h = check_header(malloc_h, when=~found_header) found_header = depends(have_malloc_h, found_header)( lambda h, f: malloc_h if h else f ) return found_header malloc_h = check_malloc_header() have_malloc_h = depends(malloc_h)(lambda h: h == "malloc.h") set_define("MALLOC_H", depends_if(malloc_h)(lambda h: f"<{h}>")) usable_size_constness = c_compiler.try_compile( includes=depends(malloc_h)(lambda h: [h, "stddef.h"]), body=""" extern size_t malloc_usable_size(const void *ptr); return malloc_usable_size(0); """, check_msg="whether malloc_usable_size definition can use const argument", when=have_malloc_usable_size, ) set_define( "MALLOC_USABLE_SIZE_CONST_PTR", depends(usable_size_constness, have_malloc_h)( lambda u, h: "const" if (u or not h) else "" ), )