Unverified Commit f63e81c2 authored by Chris Lamb's avatar Chris Lamb Committed by GitHub
Browse files

Merge branch 'unstable' into config-set-maxmemory-grammar

parents eaeba1b2 39c70e72
/* Drop in replacement for zmalloc.h in order to just use libc malloc without
* any wrappering. */
#ifndef ZMALLOC_H
#define ZMALLOC_H
#define zmalloc malloc
#define zrealloc realloc
#define zcalloc(x) calloc(x,1)
#define zfree free
#define zstrdup strdup
#endif
version: '{build}'
environment:
matrix:
- MSYSTEM: MINGW64
CPU: x86_64
MSVC: amd64
- MSYSTEM: MINGW32
CPU: i686
MSVC: x86
- MSYSTEM: MINGW64
CPU: x86_64
- MSYSTEM: MINGW32
CPU: i686
- MSYSTEM: MINGW64
CPU: x86_64
MSVC: amd64
CONFIG_FLAGS: --enable-debug
- MSYSTEM: MINGW32
CPU: i686
MSVC: x86
CONFIG_FLAGS: --enable-debug
- MSYSTEM: MINGW64
CPU: x86_64
CONFIG_FLAGS: --enable-debug
- MSYSTEM: MINGW32
CPU: i686
CONFIG_FLAGS: --enable-debug
install:
- set PATH=c:\msys64\%MSYSTEM%\bin;c:\msys64\usr\bin;%PATH%
- if defined MSVC call "c:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %MSVC%
- if defined MSVC pacman --noconfirm -Rsc mingw-w64-%CPU%-gcc gcc
- pacman --noconfirm -Suy mingw-w64-%CPU%-make
build_script:
- bash -c "autoconf"
- bash -c "./configure $CONFIG_FLAGS"
- mingw32-make
- file lib/jemalloc.dll
- mingw32-make tests
- mingw32-make -k check
begin-language: "Autoconf-without-aclocal-m4"
args: --no-cache
end-language: "Autoconf-without-aclocal-m4"
/*.gcov.* /bin/jemalloc-config
/autom4te.cache/
/bin/jemalloc.sh /bin/jemalloc.sh
/bin/jeprof
/config.stamp /config.stamp
/config.log /config.log
...@@ -15,14 +13,20 @@ ...@@ -15,14 +13,20 @@
/doc/jemalloc.html /doc/jemalloc.html
/doc/jemalloc.3 /doc/jemalloc.3
/jemalloc.pc
/lib/ /lib/
/Makefile /Makefile
/include/jemalloc/internal/jemalloc_internal.h /include/jemalloc/internal/jemalloc_preamble.h
/include/jemalloc/internal/jemalloc_internal_defs.h /include/jemalloc/internal/jemalloc_internal_defs.h
/include/jemalloc/internal/private_namespace.gen.h
/include/jemalloc/internal/private_namespace.h /include/jemalloc/internal/private_namespace.h
/include/jemalloc/internal/private_unnamespace.h /include/jemalloc/internal/private_namespace_jet.gen.h
/include/jemalloc/internal/private_namespace_jet.h
/include/jemalloc/internal/private_symbols.awk
/include/jemalloc/internal/private_symbols_jet.awk
/include/jemalloc/internal/public_namespace.h /include/jemalloc/internal/public_namespace.h
/include/jemalloc/internal/public_symbols.txt /include/jemalloc/internal/public_symbols.txt
/include/jemalloc/internal/public_unnamespace.h /include/jemalloc/internal/public_unnamespace.h
...@@ -35,10 +39,12 @@ ...@@ -35,10 +39,12 @@
/include/jemalloc/jemalloc_protos.h /include/jemalloc/jemalloc_protos.h
/include/jemalloc/jemalloc_protos_jet.h /include/jemalloc/jemalloc_protos_jet.h
/include/jemalloc/jemalloc_rename.h /include/jemalloc/jemalloc_rename.h
/include/jemalloc/jemalloc_typedefs.h
/src/*.[od] /src/*.[od]
/src/*.gcda /src/*.sym
/src/*.gcno
/run_tests.out/
/test/test.sh /test/test.sh
test/include/test/jemalloc_test.h test/include/test/jemalloc_test.h
...@@ -47,26 +53,41 @@ test/include/test/jemalloc_test_defs.h ...@@ -47,26 +53,41 @@ test/include/test/jemalloc_test_defs.h
/test/integration/[A-Za-z]* /test/integration/[A-Za-z]*
!/test/integration/[A-Za-z]*.* !/test/integration/[A-Za-z]*.*
/test/integration/*.[od] /test/integration/*.[od]
/test/integration/*.gcda
/test/integration/*.gcno
/test/integration/*.out /test/integration/*.out
/test/integration/cpp/[A-Za-z]*
!/test/integration/cpp/[A-Za-z]*.*
/test/integration/cpp/*.[od]
/test/integration/cpp/*.out
/test/src/*.[od] /test/src/*.[od]
/test/src/*.gcda
/test/src/*.gcno
/test/stress/[A-Za-z]* /test/stress/[A-Za-z]*
!/test/stress/[A-Za-z]*.* !/test/stress/[A-Za-z]*.*
/test/stress/*.[od] /test/stress/*.[od]
/test/stress/*.gcda
/test/stress/*.gcno
/test/stress/*.out /test/stress/*.out
/test/unit/[A-Za-z]* /test/unit/[A-Za-z]*
!/test/unit/[A-Za-z]*.* !/test/unit/[A-Za-z]*.*
/test/unit/*.[od] /test/unit/*.[od]
/test/unit/*.gcda
/test/unit/*.gcno
/test/unit/*.out /test/unit/*.out
/VERSION /VERSION
*.pdb
*.sdf
*.opendb
*.VC.db
*.opensdf
*.cachefile
*.suo
*.user
*.sln.docstates
*.tmp
.vs/
/msvc/Win32/
/msvc/x64/
/msvc/projects/*/*/Debug*/
/msvc/projects/*/*/Release*/
/msvc/projects/*/*/Win32/
/msvc/projects/*/*/x64/
language: generic
dist: precise
matrix:
include:
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: osx
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=clang CXX=clang++ COMPILER_FLAGS="" CONFIGURE_FLAGS="" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
addons:
apt:
packages:
- gcc-multilib
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-prof" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-stats" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=tcache:false" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=dss:primary" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=percpu_arena:percpu" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=background_thread:true" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: osx
env: CC=clang CXX=clang++ COMPILER_FLAGS="" CONFIGURE_FLAGS="" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: osx
env: CC=gcc CXX=g++ COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: osx
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: osx
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-stats" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: osx
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=tcache:false" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=clang CXX=clang++ COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
addons:
apt:
packages:
- gcc-multilib
- os: linux
env: CC=clang CXX=clang++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=clang CXX=clang++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-prof" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=clang CXX=clang++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-stats" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=clang CXX=clang++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=tcache:false" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=clang CXX=clang++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=dss:primary" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=clang CXX=clang++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=percpu_arena:percpu" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=clang CXX=clang++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=background_thread:true" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="--enable-debug" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
addons:
apt:
packages:
- gcc-multilib
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="--enable-prof" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
addons:
apt:
packages:
- gcc-multilib
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="--disable-stats" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
addons:
apt:
packages:
- gcc-multilib
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="--with-malloc-conf=tcache:false" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
addons:
apt:
packages:
- gcc-multilib
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="--with-malloc-conf=dss:primary" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
addons:
apt:
packages:
- gcc-multilib
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="--with-malloc-conf=percpu_arena:percpu" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
addons:
apt:
packages:
- gcc-multilib
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="--with-malloc-conf=background_thread:true" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
addons:
apt:
packages:
- gcc-multilib
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug --enable-prof" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug --disable-stats" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug --with-malloc-conf=tcache:false" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug --with-malloc-conf=dss:primary" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug --with-malloc-conf=percpu_arena:percpu" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug --with-malloc-conf=background_thread:true" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-prof --disable-stats" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-prof --with-malloc-conf=tcache:false" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-prof --with-malloc-conf=dss:primary" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-prof --with-malloc-conf=percpu_arena:percpu" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-prof --with-malloc-conf=background_thread:true" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-stats --with-malloc-conf=tcache:false" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-stats --with-malloc-conf=dss:primary" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-stats --with-malloc-conf=percpu_arena:percpu" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-stats --with-malloc-conf=background_thread:true" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=tcache:false,dss:primary" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=tcache:false,percpu_arena:percpu" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=tcache:false,background_thread:true" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=dss:primary,percpu_arena:percpu" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=dss:primary,background_thread:true" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
- os: linux
env: CC=gcc CXX=g++ COMPILER_FLAGS="" CONFIGURE_FLAGS="--with-malloc-conf=percpu_arena:percpu,background_thread:true" EXTRA_CFLAGS="-Werror -Wno-array-bounds"
before_script:
- autoconf
- ./configure ${COMPILER_FLAGS:+ CC="$CC $COMPILER_FLAGS" CXX="$CXX $COMPILER_FLAGS" } $CONFIGURE_FLAGS
- make -j3
- make -j3 tests
script:
- make check
Unless otherwise specified, files in the jemalloc source distribution are Unless otherwise specified, files in the jemalloc source distribution are
subject to the following license: subject to the following license:
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Copyright (C) 2002-2014 Jason Evans <jasone@canonware.com>. Copyright (C) 2002-2018 Jason Evans <jasone@canonware.com>.
All rights reserved. All rights reserved.
Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved. Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved.
Copyright (C) 2009-2014 Facebook, Inc. All rights reserved. Copyright (C) 2009-2018 Facebook, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
......
Following are change highlights associated with official releases. Important Following are change highlights associated with official releases. Important
bug fixes are all mentioned, but internal enhancements are omitted here for bug fixes are all mentioned, but some internal enhancements are omitted here for
brevity (even though they are more fun to write about). Much more detail can be brevity. Much more detail can be found in the git revision history:
found in the git revision history:
https://github.com/jemalloc/jemalloc https://github.com/jemalloc/jemalloc
* 5.1.0 (May 4th, 2018)
This release is primarily about fine-tuning, ranging from several new features
to numerous notable performance and portability enhancements. The release and
prior dev versions have been running in multiple large scale applications for
months, and the cumulative improvements are substantial in many cases.
Given the long and successful production runs, this release is likely a good
candidate for applications to upgrade, from both jemalloc 5.0 and before. For
performance-critical applications, the newly added TUNING.md provides
guidelines on jemalloc tuning.
New features:
- Implement transparent huge page support for internal metadata. (@interwq)
- Add opt.thp to allow enabling / disabling transparent huge pages for all
mappings. (@interwq)
- Add maximum background thread count option. (@djwatson)
- Allow prof_active to control opt.lg_prof_interval and prof.gdump.
(@interwq)
- Allow arena index lookup based on allocation addresses via mallctl.
(@lionkov)
- Allow disabling initial-exec TLS model. (@davidtgoldblatt, @KenMacD)
- Add opt.lg_extent_max_active_fit to set the max ratio between the size of
the active extent selected (to split off from) and the size of the requested
allocation. (@interwq, @davidtgoldblatt)
- Add retain_grow_limit to set the max size when growing virtual address
space. (@interwq)
- Add mallctl interfaces:
+ arena.<i>.retain_grow_limit (@interwq)
+ arenas.lookup (@lionkov)
+ max_background_threads (@djwatson)
+ opt.lg_extent_max_active_fit (@interwq)
+ opt.max_background_threads (@djwatson)
+ opt.metadata_thp (@interwq)
+ opt.thp (@interwq)
+ stats.metadata_thp (@interwq)
Portability improvements:
- Support GNU/kFreeBSD configuration. (@paravoid)
- Support m68k, nios2 and SH3 architectures. (@paravoid)
- Fall back to FD_CLOEXEC when O_CLOEXEC is unavailable. (@zonyitoo)
- Fix symbol listing for cross-compiling. (@tamird)
- Fix high bits computation on ARM. (@davidtgoldblatt, @paravoid)
- Disable the CPU_SPINWAIT macro for Power. (@davidtgoldblatt, @marxin)
- Fix MSVC 2015 & 2017 builds. (@rustyx)
- Improve RISC-V support. (@EdSchouten)
- Set name mangling script in strict mode. (@nicolov)
- Avoid MADV_HUGEPAGE on ARM. (@marxin)
- Modify configure to determine return value of strerror_r.
(@davidtgoldblatt, @cferris1000)
- Make sure CXXFLAGS is tested with CPP compiler. (@nehaljwani)
- Fix 32-bit build on MSVC. (@rustyx)
- Fix external symbol on MSVC. (@maksqwe)
- Avoid a printf format specifier warning. (@jasone)
- Add configure option --disable-initial-exec-tls which can allow jemalloc to
be dynamically loaded after program startup. (@davidtgoldblatt, @KenMacD)
- AArch64: Add ILP32 support. (@cmuellner)
- Add --with-lg-vaddr configure option to support cross compiling.
(@cmuellner, @davidtgoldblatt)
Optimizations and refactors:
- Improve active extent fit with extent_max_active_fit. This considerably
reduces fragmentation over time and improves virtual memory and metadata
usage. (@davidtgoldblatt, @interwq)
- Eagerly coalesce large extents to reduce fragmentation. (@interwq)
- sdallocx: only read size info when page aligned (i.e. possibly sampled),
which speeds up the sized deallocation path significantly. (@interwq)
- Avoid attempting new mappings for in place expansion with retain, since
it rarely succeeds in practice and causes high overhead. (@interwq)
- Refactor OOM handling in newImpl. (@wqfish)
- Add internal fine-grained logging functionality for debugging use.
(@davidtgoldblatt)
- Refactor arena / tcache interactions. (@davidtgoldblatt)
- Refactor extent management with dumpable flag. (@davidtgoldblatt)
- Add runtime detection of lazy purging. (@interwq)
- Use pairing heap instead of red-black tree for extents_avail. (@djwatson)
- Use sysctl on startup in FreeBSD. (@trasz)
- Use thread local prng state instead of atomic. (@djwatson)
- Make decay to always purge one more extent than before, because in
practice large extents are usually the ones that cross the decay threshold.
Purging the additional extent helps save memory as well as reduce VM
fragmentation. (@interwq)
- Fast division by dynamic values. (@davidtgoldblatt)
- Improve the fit for aligned allocation. (@interwq, @edwinsmith)
- Refactor extent_t bitpacking. (@rkmisra)
- Optimize the generated assembly for ticker operations. (@davidtgoldblatt)
- Convert stats printing to use a structured text emitter. (@davidtgoldblatt)
- Remove preserve_lru feature for extents management. (@djwatson)
- Consolidate two memory loads into one on the fast deallocation path.
(@davidtgoldblatt, @interwq)
Bug fixes (most of the issues are only relevant to jemalloc 5.0):
- Fix deadlock with multithreaded fork in OS X. (@davidtgoldblatt)
- Validate returned file descriptor before use. (@zonyitoo)
- Fix a few background thread initialization and shutdown issues. (@interwq)
- Fix an extent coalesce + decay race by taking both coalescing extents off
the LRU list. (@interwq)
- Fix potentially unbound increase during decay, caused by one thread keep
stashing memory to purge while other threads generating new pages. The
number of pages to purge is checked to prevent this. (@interwq)
- Fix a FreeBSD bootstrap assertion. (@strejda, @interwq)
- Handle 32 bit mutex counters. (@rkmisra)
- Fix a indexing bug when creating background threads. (@davidtgoldblatt,
@binliu19)
- Fix arguments passed to extent_init. (@yuleniwo, @interwq)
- Fix addresses used for ordering mutexes. (@rkmisra)
- Fix abort_conf processing during bootstrap. (@interwq)
- Fix include path order for out-of-tree builds. (@cmuellner)
Incompatible changes:
- Remove --disable-thp. (@interwq)
- Remove mallctl interfaces:
+ config.thp (@interwq)
Documentation:
- Add TUNING.md. (@interwq, @davidtgoldblatt, @djwatson)
* 5.0.1 (July 1, 2017)
This bugfix release fixes several issues, most of which are obscure enough
that typical applications are not impacted.
Bug fixes:
- Update decay->nunpurged before purging, in order to avoid potential update
races and subsequent incorrect purging volume. (@interwq)
- Only abort on dlsym(3) error if the failure impacts an enabled feature (lazy
locking and/or background threads). This mitigates an initialization
failure bug for which we still do not have a clear reproduction test case.
(@interwq)
- Modify tsd management so that it neither crashes nor leaks if a thread's
only allocation activity is to call free() after TLS destructors have been
executed. This behavior was observed when operating with GNU libc, and is
unlikely to be an issue with other libc implementations. (@interwq)
- Mask signals during background thread creation. This prevents signals from
being inadvertently delivered to background threads. (@jasone,
@davidtgoldblatt, @interwq)
- Avoid inactivity checks within background threads, in order to prevent
recursive mutex acquisition. (@interwq)
- Fix extent_grow_retained() to use the specified hooks when the
arena.<i>.extent_hooks mallctl is used to override the default hooks.
(@interwq)
- Add missing reentrancy support for custom extent hooks which allocate.
(@interwq)
- Post-fork(2), re-initialize the list of tcaches associated with each arena
to contain no tcaches except the forking thread's. (@interwq)
- Add missing post-fork(2) mutex reinitialization for extent_grow_mtx. This
fixes potential deadlocks after fork(2). (@interwq)
- Enforce minimum autoconf version (currently 2.68), since 2.63 is known to
generate corrupt configure scripts. (@jasone)
- Ensure that the configured page size (--with-lg-page) is no larger than the
configured huge page size (--with-lg-hugepage). (@jasone)
* 5.0.0 (June 13, 2017)
Unlike all previous jemalloc releases, this release does not use naturally
aligned "chunks" for virtual memory management, and instead uses page-aligned
"extents". This change has few externally visible effects, but the internal
impacts are... extensive. Many other internal changes combine to make this
the most cohesively designed version of jemalloc so far, with ample
opportunity for further enhancements.
Continuous integration is now an integral aspect of development thanks to the
efforts of @davidtgoldblatt, and the dev branch tends to remain reasonably
stable on the tested platforms (Linux, FreeBSD, macOS, and Windows). As a
side effect the official release frequency may decrease over time.
New features:
- Implement optional per-CPU arena support; threads choose which arena to use
based on current CPU rather than on fixed thread-->arena associations.
(@interwq)
- Implement two-phase decay of unused dirty pages. Pages transition from
dirty-->muzzy-->clean, where the first phase transition relies on
madvise(... MADV_FREE) semantics, and the second phase transition discards
pages such that they are replaced with demand-zeroed pages on next access.
(@jasone)
- Increase decay time resolution from seconds to milliseconds. (@jasone)
- Implement opt-in per CPU background threads, and use them for asynchronous
decay-driven unused dirty page purging. (@interwq)
- Add mutex profiling, which collects a variety of statistics useful for
diagnosing overhead/contention issues. (@interwq)
- Add C++ new/delete operator bindings. (@djwatson)
- Support manually created arena destruction, such that all data and metadata
are discarded. Add MALLCTL_ARENAS_DESTROYED for accessing merged stats
associated with destroyed arenas. (@jasone)
- Add MALLCTL_ARENAS_ALL as a fixed index for use in accessing
merged/destroyed arena statistics via mallctl. (@jasone)
- Add opt.abort_conf to optionally abort if invalid configuration options are
detected during initialization. (@interwq)
- Add opt.stats_print_opts, so that e.g. JSON output can be selected for the
stats dumped during exit if opt.stats_print is true. (@jasone)
- Add --with-version=VERSION for use when embedding jemalloc into another
project's git repository. (@jasone)
- Add --disable-thp to support cross compiling. (@jasone)
- Add --with-lg-hugepage to support cross compiling. (@jasone)
- Add mallctl interfaces (various authors):
+ background_thread
+ opt.abort_conf
+ opt.retain
+ opt.percpu_arena
+ opt.background_thread
+ opt.{dirty,muzzy}_decay_ms
+ opt.stats_print_opts
+ arena.<i>.initialized
+ arena.<i>.destroy
+ arena.<i>.{dirty,muzzy}_decay_ms
+ arena.<i>.extent_hooks
+ arenas.{dirty,muzzy}_decay_ms
+ arenas.bin.<i>.slab_size
+ arenas.nlextents
+ arenas.lextent.<i>.size
+ arenas.create
+ stats.background_thread.{num_threads,num_runs,run_interval}
+ stats.mutexes.{ctl,background_thread,prof,reset}.
{num_ops,num_spin_acq,num_wait,max_wait_time,total_wait_time,max_num_thds,
num_owner_switch}
+ stats.arenas.<i>.{dirty,muzzy}_decay_ms
+ stats.arenas.<i>.uptime
+ stats.arenas.<i>.{pmuzzy,base,internal,resident}
+ stats.arenas.<i>.{dirty,muzzy}_{npurge,nmadvise,purged}
+ stats.arenas.<i>.bins.<j>.{nslabs,reslabs,curslabs}
+ stats.arenas.<i>.bins.<j>.mutex.
{num_ops,num_spin_acq,num_wait,max_wait_time,total_wait_time,max_num_thds,
num_owner_switch}
+ stats.arenas.<i>.lextents.<j>.{nmalloc,ndalloc,nrequests,curlextents}
+ stats.arenas.i.mutexes.{large,extent_avail,extents_dirty,extents_muzzy,
extents_retained,decay_dirty,decay_muzzy,base,tcache_list}.
{num_ops,num_spin_acq,num_wait,max_wait_time,total_wait_time,max_num_thds,
num_owner_switch}
Portability improvements:
- Improve reentrant allocation support, such that deadlock is less likely if
e.g. a system library call in turn allocates memory. (@davidtgoldblatt,
@interwq)
- Support static linking of jemalloc with glibc. (@djwatson)
Optimizations and refactors:
- Organize virtual memory as "extents" of virtual memory pages, rather than as
naturally aligned "chunks", and store all metadata in arbitrarily distant
locations. This reduces virtual memory external fragmentation, and will
interact better with huge pages (not yet explicitly supported). (@jasone)
- Fold large and huge size classes together; only small and large size classes
remain. (@jasone)
- Unify the allocation paths, and merge most fast-path branching decisions.
(@davidtgoldblatt, @interwq)
- Embed per thread automatic tcache into thread-specific data, which reduces
conditional branches and dereferences. Also reorganize tcache to increase
fast-path data locality. (@interwq)
- Rewrite atomics to closely model the C11 API, convert various
synchronization from mutex-based to atomic, and use the explicit memory
ordering control to resolve various hypothetical races without increasing
synchronization overhead. (@davidtgoldblatt)
- Extensively optimize rtree via various methods:
+ Add multiple layers of rtree lookup caching, since rtree lookups are now
part of fast-path deallocation. (@interwq)
+ Determine rtree layout at compile time. (@jasone)
+ Make the tree shallower for common configurations. (@jasone)
+ Embed the root node in the top-level rtree data structure, thus avoiding
one level of indirection. (@jasone)
+ Further specialize leaf elements as compared to internal node elements,
and directly embed extent metadata needed for fast-path deallocation.
(@jasone)
+ Ignore leading always-zero address bits (architecture-specific).
(@jasone)
- Reorganize headers (ongoing work) to make them hermetic, and disentangle
various module dependencies. (@davidtgoldblatt)
- Convert various internal data structures such as size class metadata from
boot-time-initialized to compile-time-initialized. Propagate resulting data
structure simplifications, such as making arena metadata fixed-size.
(@jasone)
- Simplify size class lookups when constrained to size classes that are
multiples of the page size. This speeds lookups, but the primary benefit is
complexity reduction in code that was the source of numerous regressions.
(@jasone)
- Lock individual extents when possible for localized extent operations,
rather than relying on a top-level arena lock. (@davidtgoldblatt, @jasone)
- Use first fit layout policy instead of best fit, in order to improve
packing. (@jasone)
- If munmap(2) is not in use, use an exponential series to grow each arena's
virtual memory, so that the number of disjoint virtual memory mappings
remains low. (@jasone)
- Implement per arena base allocators, so that arenas never share any virtual
memory pages. (@jasone)
- Automatically generate private symbol name mangling macros. (@jasone)
Incompatible changes:
- Replace chunk hooks with an expanded/normalized set of extent hooks.
(@jasone)
- Remove ratio-based purging. (@jasone)
- Remove --disable-tcache. (@jasone)
- Remove --disable-tls. (@jasone)
- Remove --enable-ivsalloc. (@jasone)
- Remove --with-lg-size-class-group. (@jasone)
- Remove --with-lg-tiny-min. (@jasone)
- Remove --disable-cc-silence. (@jasone)
- Remove --enable-code-coverage. (@jasone)
- Remove --disable-munmap (replaced by opt.retain). (@jasone)
- Remove Valgrind support. (@jasone)
- Remove quarantine support. (@jasone)
- Remove redzone support. (@jasone)
- Remove mallctl interfaces (various authors):
+ config.munmap
+ config.tcache
+ config.tls
+ config.valgrind
+ opt.lg_chunk
+ opt.purge
+ opt.lg_dirty_mult
+ opt.decay_time
+ opt.quarantine
+ opt.redzone
+ opt.thp
+ arena.<i>.lg_dirty_mult
+ arena.<i>.decay_time
+ arena.<i>.chunk_hooks
+ arenas.initialized
+ arenas.lg_dirty_mult
+ arenas.decay_time
+ arenas.bin.<i>.run_size
+ arenas.nlruns
+ arenas.lrun.<i>.size
+ arenas.nhchunks
+ arenas.hchunk.<i>.size
+ arenas.extend
+ stats.cactive
+ stats.arenas.<i>.lg_dirty_mult
+ stats.arenas.<i>.decay_time
+ stats.arenas.<i>.metadata.{mapped,allocated}
+ stats.arenas.<i>.{npurge,nmadvise,purged}
+ stats.arenas.<i>.huge.{allocated,nmalloc,ndalloc,nrequests}
+ stats.arenas.<i>.bins.<j>.{nruns,reruns,curruns}
+ stats.arenas.<i>.lruns.<j>.{nmalloc,ndalloc,nrequests,curruns}
+ stats.arenas.<i>.hchunks.<j>.{nmalloc,ndalloc,nrequests,curhchunks}
Bug fixes:
- Improve interval-based profile dump triggering to dump only one profile when
a single allocation's size exceeds the interval. (@jasone)
- Use prefixed function names (as controlled by --with-jemalloc-prefix) when
pruning backtrace frames in jeprof. (@jasone)
* 4.5.0 (February 28, 2017)
This is the first release to benefit from much broader continuous integration
testing, thanks to @davidtgoldblatt. Had we had this testing infrastructure
in place for prior releases, it would have caught all of the most serious
regressions fixed by this release.
New features:
- Add --disable-thp and the opt.thp mallctl to provide opt-out mechanisms for
transparent huge page integration. (@jasone)
- Update zone allocator integration to work with macOS 10.12. (@glandium)
- Restructure *CFLAGS configuration, so that CFLAGS behaves typically, and
EXTRA_CFLAGS provides a way to specify e.g. -Werror during building, but not
during configuration. (@jasone, @ronawho)
Bug fixes:
- Fix DSS (sbrk(2)-based) allocation. This regression was first released in
4.3.0. (@jasone)
- Handle race in per size class utilization computation. This functionality
was first released in 4.0.0. (@interwq)
- Fix lock order reversal during gdump. (@jasone)
- Fix/refactor tcache synchronization. This regression was first released in
4.0.0. (@jasone)
- Fix various JSON-formatted malloc_stats_print() bugs. This functionality
was first released in 4.3.0. (@jasone)
- Fix huge-aligned allocation. This regression was first released in 4.4.0.
(@jasone)
- When transparent huge page integration is enabled, detect what state pages
start in according to the kernel's current operating mode, and only convert
arena chunks to non-huge during purging if that is not their initial state.
This functionality was first released in 4.4.0. (@jasone)
- Fix lg_chunk clamping for the --enable-cache-oblivious --disable-fill case.
This regression was first released in 4.0.0. (@jasone, @428desmo)
- Properly detect sparc64 when building for Linux. (@glaubitz)
* 4.4.0 (December 3, 2016)
New features:
- Add configure support for *-*-linux-android. (@cferris1000, @jasone)
- Add the --disable-syscall configure option, for use on systems that place
security-motivated limitations on syscall(2). (@jasone)
- Add support for Debian GNU/kFreeBSD. (@thesam)
Optimizations:
- Add extent serial numbers and use them where appropriate as a sort key that
is higher priority than address, so that the allocation policy prefers older
extents. This tends to improve locality (decrease fragmentation) when
memory grows downward. (@jasone)
- Refactor madvise(2) configuration so that MADV_FREE is detected and utilized
on Linux 4.5 and newer. (@jasone)
- Mark partially purged arena chunks as non-huge-page. This improves
interaction with Linux's transparent huge page functionality. (@jasone)
Bug fixes:
- Fix size class computations for edge conditions involving extremely large
allocations. This regression was first released in 4.0.0. (@jasone,
@ingvarha)
- Remove overly restrictive assertions related to the cactive statistic. This
regression was first released in 4.1.0. (@jasone)
- Implement a more reliable detection scheme for os_unfair_lock on macOS.
(@jszakmeister)
* 4.3.1 (November 7, 2016)
Bug fixes:
- Fix a severe virtual memory leak. This regression was first released in
4.3.0. (@interwq, @jasone)
- Refactor atomic and prng APIs to restore support for 32-bit platforms that
use pre-C11 toolchains, e.g. FreeBSD's mips. (@jasone)
* 4.3.0 (November 4, 2016)
This is the first release that passes the test suite for multiple Windows
configurations, thanks in large part to @glandium setting up continuous
integration via AppVeyor (and Travis CI for Linux and OS X).
New features:
- Add "J" (JSON) support to malloc_stats_print(). (@jasone)
- Add Cray compiler support. (@ronawho)
Optimizations:
- Add/use adaptive spinning for bootstrapping and radix tree node
initialization. (@jasone)
Bug fixes:
- Fix large allocation to search starting in the optimal size class heap,
which can substantially reduce virtual memory churn and fragmentation. This
regression was first released in 4.0.0. (@mjp41, @jasone)
- Fix stats.arenas.<i>.nthreads accounting. (@interwq)
- Fix and simplify decay-based purging. (@jasone)
- Make DSS (sbrk(2)-related) operations lockless, which resolves potential
deadlocks during thread exit. (@jasone)
- Fix over-sized allocation of radix tree leaf nodes. (@mjp41, @ogaun,
@jasone)
- Fix over-sized allocation of arena_t (plus associated stats) data
structures. (@jasone, @interwq)
- Fix EXTRA_CFLAGS to not affect configuration. (@jasone)
- Fix a Valgrind integration bug. (@ronawho)
- Disallow 0x5a junk filling when running in Valgrind. (@jasone)
- Fix a file descriptor leak on Linux. This regression was first released in
4.2.0. (@vsarunas, @jasone)
- Fix static linking of jemalloc with glibc. (@djwatson)
- Use syscall(2) rather than {open,read,close}(2) during boot on Linux. This
works around other libraries' system call wrappers performing reentrant
allocation. (@kspinka, @Whissi, @jasone)
- Fix OS X default zone replacement to work with OS X 10.12. (@glandium,
@jasone)
- Fix cached memory management to avoid needless commit/decommit operations
during purging, which resolves permanent virtual memory map fragmentation
issues on Windows. (@mjp41, @jasone)
- Fix TSD fetches to avoid (recursive) allocation. This is relevant to
non-TLS and Windows configurations. (@jasone)
- Fix malloc_conf overriding to work on Windows. (@jasone)
- Forcibly disable lazy-lock on Windows (was forcibly *enabled*). (@jasone)
* 4.2.1 (June 8, 2016)
Bug fixes:
- Fix bootstrapping issues for configurations that require allocation during
tsd initialization (e.g. --disable-tls). (@cferris1000, @jasone)
- Fix gettimeofday() version of nstime_update(). (@ronawho)
- Fix Valgrind regressions in calloc() and chunk_alloc_wrapper(). (@ronawho)
- Fix potential VM map fragmentation regression. (@jasone)
- Fix opt_zero-triggered in-place huge reallocation zeroing. (@jasone)
- Fix heap profiling context leaks in reallocation edge cases. (@jasone)
* 4.2.0 (May 12, 2016)
New features:
- Add the arena.<i>.reset mallctl, which makes it possible to discard all of
an arena's allocations in a single operation. (@jasone)
- Add the stats.retained and stats.arenas.<i>.retained statistics. (@jasone)
- Add the --with-version configure option. (@jasone)
- Support --with-lg-page values larger than actual page size. (@jasone)
Optimizations:
- Use pairing heaps rather than red-black trees for various hot data
structures. (@djwatson, @jasone)
- Streamline fast paths of rtree operations. (@jasone)
- Optimize the fast paths of calloc() and [m,d,sd]allocx(). (@jasone)
- Decommit unused virtual memory if the OS does not overcommit. (@jasone)
- Specify MAP_NORESERVE on Linux if [heuristic] overcommit is active, in order
to avoid unfortunate interactions during fork(2). (@jasone)
Bug fixes:
- Fix chunk accounting related to triggering gdump profiles. (@jasone)
- Link against librt for clock_gettime(2) if glibc < 2.17. (@jasone)
- Scale leak report summary according to sampling probability. (@jasone)
* 4.1.1 (May 3, 2016)
This bugfix release resolves a variety of mostly minor issues, though the
bitmap fix is critical for 64-bit Windows.
Bug fixes:
- Fix the linear scan version of bitmap_sfu() to shift by the proper amount
even when sizeof(long) is not the same as sizeof(void *), as on 64-bit
Windows. (@jasone)
- Fix hashing functions to avoid unaligned memory accesses (and resulting
crashes). This is relevant at least to some ARM-based platforms.
(@rkmisra)
- Fix fork()-related lock rank ordering reversals. These reversals were
unlikely to cause deadlocks in practice except when heap profiling was
enabled and active. (@jasone)
- Fix various chunk leaks in OOM code paths. (@jasone)
- Fix malloc_stats_print() to print opt.narenas correctly. (@jasone)
- Fix MSVC-specific build/test issues. (@rustyx, @yuslepukhin)
- Fix a variety of test failures that were due to test fragility rather than
core bugs. (@jasone)
* 4.1.0 (February 28, 2016)
This release is primarily about optimizations, but it also incorporates a lot
of portability-motivated refactoring and enhancements. Many people worked on
this release, to an extent that even with the omission here of minor changes
(see git revision history), and of the people who reported and diagnosed
issues, so much of the work was contributed that starting with this release,
changes are annotated with author credits to help reflect the collaborative
effort involved.
New features:
- Implement decay-based unused dirty page purging, a major optimization with
mallctl API impact. This is an alternative to the existing ratio-based
unused dirty page purging, and is intended to eventually become the sole
purging mechanism. New mallctls:
+ opt.purge
+ opt.decay_time
+ arena.<i>.decay
+ arena.<i>.decay_time
+ arenas.decay_time
+ stats.arenas.<i>.decay_time
(@jasone, @cevans87)
- Add --with-malloc-conf, which makes it possible to embed a default
options string during configuration. This was motivated by the desire to
specify --with-malloc-conf=purge:decay , since the default must remain
purge:ratio until the 5.0.0 release. (@jasone)
- Add MS Visual Studio 2015 support. (@rustyx, @yuslepukhin)
- Make *allocx() size class overflow behavior defined. The maximum
size class is now less than PTRDIFF_MAX to protect applications against
numerical overflow, and all allocation functions are guaranteed to indicate
errors rather than potentially crashing if the request size exceeds the
maximum size class. (@jasone)
- jeprof:
+ Add raw heap profile support. (@jasone)
+ Add --retain and --exclude for backtrace symbol filtering. (@jasone)
Optimizations:
- Optimize the fast path to combine various bootstrapping and configuration
checks and execute more streamlined code in the common case. (@interwq)
- Use linear scan for small bitmaps (used for small object tracking). In
addition to speeding up bitmap operations on 64-bit systems, this reduces
allocator metadata overhead by approximately 0.2%. (@djwatson)
- Separate arena_avail trees, which substantially speeds up run tree
operations. (@djwatson)
- Use memoization (boot-time-computed table) for run quantization. Separate
arena_avail trees reduced the importance of this optimization. (@jasone)
- Attempt mmap-based in-place huge reallocation. This can dramatically speed
up incremental huge reallocation. (@jasone)
Incompatible changes:
- Make opt.narenas unsigned rather than size_t. (@jasone)
Bug fixes:
- Fix stats.cactive accounting regression. (@rustyx, @jasone)
- Handle unaligned keys in hash(). This caused problems for some ARM systems.
(@jasone, @cferris1000)
- Refactor arenas array. In addition to fixing a fork-related deadlock, this
makes arena lookups faster and simpler. (@jasone)
- Move retained memory allocation out of the default chunk allocation
function, to a location that gets executed even if the application installs
a custom chunk allocation function. This resolves a virtual memory leak.
(@buchgr)
- Fix a potential tsd cleanup leak. (@cferris1000, @jasone)
- Fix run quantization. In practice this bug had no impact unless
applications requested memory with alignment exceeding one page.
(@jasone, @djwatson)
- Fix LinuxThreads-specific bootstrapping deadlock. (Cosmin Paraschiv)
- jeprof:
+ Don't discard curl options if timeout is not defined. (@djwatson)
+ Detect failed profile fetches. (@djwatson)
- Fix stats.arenas.<i>.{dss,lg_dirty_mult,decay_time,pactive,pdirty} for
--disable-stats case. (@jasone)
* 4.0.4 (October 24, 2015)
This bugfix release fixes another xallocx() regression. No other regressions
have come to light in over a month, so this is likely a good starting point
for people who prefer to wait for "dot one" releases with all the major issues
shaken out.
Bug fixes:
- Fix xallocx(..., MALLOCX_ZERO to zero the last full trailing page of large
allocations that have been randomly assigned an offset of 0 when
--enable-cache-oblivious configure option is enabled.
* 4.0.3 (September 24, 2015)
This bugfix release continues the trend of xallocx() and heap profiling fixes.
Bug fixes:
- Fix xallocx(..., MALLOCX_ZERO) to zero all trailing bytes of large
allocations when --enable-cache-oblivious configure option is enabled.
- Fix xallocx(..., MALLOCX_ZERO) to zero trailing bytes of huge allocations
when resizing from/to a size class that is not a multiple of the chunk size.
- Fix prof_tctx_dump_iter() to filter out nodes that were created after heap
profile dumping started.
- Work around a potentially bad thread-specific data initialization
interaction with NPTL (glibc's pthreads implementation).
* 4.0.2 (September 21, 2015)
This bugfix release addresses a few bugs specific to heap profiling.
Bug fixes:
- Fix ixallocx_prof_sample() to never modify nor create sampled small
allocations. xallocx() is in general incapable of moving small allocations,
so this fix removes buggy code without loss of generality.
- Fix irallocx_prof_sample() to always allocate large regions, even when
alignment is non-zero.
- Fix prof_alloc_rollback() to read tdata from thread-specific data rather
than dereferencing a potentially invalid tctx.
* 4.0.1 (September 15, 2015)
This is a bugfix release that is somewhat high risk due to the amount of
refactoring required to address deep xallocx() problems. As a side effect of
these fixes, xallocx() now tries harder to partially fulfill requests for
optional extra space. Note that a couple of minor heap profiling
optimizations are included, but these are better thought of as performance
fixes that were integral to discovering most of the other bugs.
Optimizations:
- Avoid a chunk metadata read in arena_prof_tctx_set(), since it is in the
fast path when heap profiling is enabled. Additionally, split a special
case out into arena_prof_tctx_reset(), which also avoids chunk metadata
reads.
- Optimize irallocx_prof() to optimistically update the sampler state. The
prior implementation appears to have been a holdover from when
rallocx()/xallocx() functionality was combined as rallocm().
Bug fixes:
- Fix TLS configuration such that it is enabled by default for platforms on
which it works correctly.
- Fix arenas_cache_cleanup() and arena_get_hard() to handle
allocation/deallocation within the application's thread-specific data
cleanup functions even after arenas_cache is torn down.
- Fix xallocx() bugs related to size+extra exceeding HUGE_MAXCLASS.
- Fix chunk purge hook calls for in-place huge shrinking reallocation to
specify the old chunk size rather than the new chunk size. This bug caused
no correctness issues for the default chunk purge function, but was
visible to custom functions set via the "arena.<i>.chunk_hooks" mallctl.
- Fix heap profiling bugs:
+ Fix heap profiling to distinguish among otherwise identical sample sites
with interposed resets (triggered via the "prof.reset" mallctl). This bug
could cause data structure corruption that would most likely result in a
segfault.
+ Fix irealloc_prof() to prof_alloc_rollback() on OOM.
+ Make one call to prof_active_get_unlocked() per allocation event, and use
the result throughout the relevant functions that handle an allocation
event. Also add a missing check in prof_realloc(). These fixes protect
allocation events against concurrent prof_active changes.
+ Fix ixallocx_prof() to pass usize_max and zero to ixallocx_prof_sample()
in the correct order.
+ Fix prof_realloc() to call prof_free_sampled_object() after calling
prof_malloc_sample_object(). Prior to this fix, if tctx and old_tctx were
the same, the tctx could have been prematurely destroyed.
- Fix portability bugs:
+ Don't bitshift by negative amounts when encoding/decoding run sizes in
chunk header maps. This affected systems with page sizes greater than 8
KiB.
+ Rename index_t to szind_t to avoid an existing type on Solaris.
+ Add JEMALLOC_CXX_THROW to the memalign() function prototype, in order to
match glibc and avoid compilation errors when including both
jemalloc/jemalloc.h and malloc.h in C++ code.
+ Don't assume that /bin/sh is appropriate when running size_classes.sh
during configuration.
+ Consider __sparcv9 a synonym for __sparc64__ when defining LG_QUANTUM.
+ Link tests to librt if it contains clock_gettime(2).
* 4.0.0 (August 17, 2015)
This version contains many speed and space optimizations, both minor and
major. The major themes are generalization, unification, and simplification.
Although many of these optimizations cause no visible behavior change, their
cumulative effect is substantial.
New features:
- Normalize size class spacing to be consistent across the complete size
range. By default there are four size classes per size doubling, but this
is now configurable via the --with-lg-size-class-group option. Also add the
--with-lg-page, --with-lg-page-sizes, --with-lg-quantum, and
--with-lg-tiny-min options, which can be used to tweak page and size class
settings. Impacts:
+ Worst case performance for incrementally growing/shrinking reallocation
is improved because there are far fewer size classes, and therefore
copying happens less often.
+ Internal fragmentation is limited to 20% for all but the smallest size
classes (those less than four times the quantum). (1B + 4 KiB)
and (1B + 4 MiB) previously suffered nearly 50% internal fragmentation.
+ Chunk fragmentation tends to be lower because there are fewer distinct run
sizes to pack.
- Add support for explicit tcaches. The "tcache.create", "tcache.flush", and
"tcache.destroy" mallctls control tcache lifetime and flushing, and the
MALLOCX_TCACHE(tc) and MALLOCX_TCACHE_NONE flags to the *allocx() API
control which tcache is used for each operation.
- Implement per thread heap profiling, as well as the ability to
enable/disable heap profiling on a per thread basis. Add the "prof.reset",
"prof.lg_sample", "thread.prof.name", "thread.prof.active",
"opt.prof_thread_active_init", "prof.thread_active_init", and
"thread.prof.active" mallctls.
- Add support for per arena application-specified chunk allocators, configured
via the "arena.<i>.chunk_hooks" mallctl.
- Refactor huge allocation to be managed by arenas, so that arenas now
function as general purpose independent allocators. This is important in
the context of user-specified chunk allocators, aside from the scalability
benefits. Related new statistics:
+ The "stats.arenas.<i>.huge.allocated", "stats.arenas.<i>.huge.nmalloc",
"stats.arenas.<i>.huge.ndalloc", and "stats.arenas.<i>.huge.nrequests"
mallctls provide high level per arena huge allocation statistics.
+ The "arenas.nhchunks", "arenas.hchunk.<i>.size",
"stats.arenas.<i>.hchunks.<j>.nmalloc",
"stats.arenas.<i>.hchunks.<j>.ndalloc",
"stats.arenas.<i>.hchunks.<j>.nrequests", and
"stats.arenas.<i>.hchunks.<j>.curhchunks" mallctls provide per size class
statistics.
- Add the 'util' column to malloc_stats_print() output, which reports the
proportion of available regions that are currently in use for each small
size class.
- Add "alloc" and "free" modes for for junk filling (see the "opt.junk"
mallctl), so that it is possible to separately enable junk filling for
allocation versus deallocation.
- Add the jemalloc-config script, which provides information about how
jemalloc was configured, and how to integrate it into application builds.
- Add metadata statistics, which are accessible via the "stats.metadata",
"stats.arenas.<i>.metadata.mapped", and
"stats.arenas.<i>.metadata.allocated" mallctls.
- Add the "stats.resident" mallctl, which reports the upper limit of
physically resident memory mapped by the allocator.
- Add per arena control over unused dirty page purging, via the
"arenas.lg_dirty_mult", "arena.<i>.lg_dirty_mult", and
"stats.arenas.<i>.lg_dirty_mult" mallctls.
- Add the "prof.gdump" mallctl, which makes it possible to toggle the gdump
feature on/off during program execution.
- Add sdallocx(), which implements sized deallocation. The primary
optimization over dallocx() is the removal of a metadata read, which often
suffers an L1 cache miss.
- Add missing header includes in jemalloc/jemalloc.h, so that applications
only have to #include <jemalloc/jemalloc.h>.
- Add support for additional platforms:
+ Bitrig
+ Cygwin
+ DragonFlyBSD
+ iOS
+ OpenBSD
+ OpenRISC/or1k
Optimizations:
- Maintain dirty runs in per arena LRUs rather than in per arena trees of
dirty-run-containing chunks. In practice this change significantly reduces
dirty page purging volume.
- Integrate whole chunks into the unused dirty page purging machinery. This
reduces the cost of repeated huge allocation/deallocation, because it
effectively introduces a cache of chunks.
- Split the arena chunk map into two separate arrays, in order to increase
cache locality for the frequently accessed bits.
- Move small run metadata out of runs, into arena chunk headers. This reduces
run fragmentation, smaller runs reduce external fragmentation for small size
classes, and packed (less uniformly aligned) metadata layout improves CPU
cache set distribution.
- Randomly distribute large allocation base pointer alignment relative to page
boundaries in order to more uniformly utilize CPU cache sets. This can be
disabled via the --disable-cache-oblivious configure option, and queried via
the "config.cache_oblivious" mallctl.
- Micro-optimize the fast paths for the public API functions.
- Refactor thread-specific data to reside in a single structure. This assures
that only a single TLS read is necessary per call into the public API.
- Implement in-place huge allocation growing and shrinking.
- Refactor rtree (radix tree for chunk lookups) to be lock-free, and make
additional optimizations that reduce maximum lookup depth to one or two
levels. This resolves what was a concurrency bottleneck for per arena huge
allocation, because a global data structure is critical for determining
which arenas own which huge allocations.
Incompatible changes:
- Replace --enable-cc-silence with --disable-cc-silence to suppress spurious
warnings by default.
- Assure that the constness of malloc_usable_size()'s return type matches that
of the system implementation.
- Change the heap profile dump format to support per thread heap profiling,
rename pprof to jeprof, and enhance it with the --thread=<n> option. As a
result, the bundled jeprof must now be used rather than the upstream
(gperftools) pprof.
- Disable "opt.prof_final" by default, in order to avoid atexit(3), which can
internally deadlock on some platforms.
- Change the "arenas.nlruns" mallctl type from size_t to unsigned.
- Replace the "stats.arenas.<i>.bins.<j>.allocated" mallctl with
"stats.arenas.<i>.bins.<j>.curregs".
- Ignore MALLOC_CONF in set{uid,gid,cap} binaries.
- Ignore MALLOCX_ARENA(a) in dallocx(), in favor of using the
MALLOCX_TCACHE(tc) and MALLOCX_TCACHE_NONE flags to control tcache usage.
Removed features:
- Remove the *allocm() API, which is superseded by the *allocx() API.
- Remove the --enable-dss options, and make dss non-optional on all platforms
which support sbrk(2).
- Remove the "arenas.purge" mallctl, which was obsoleted by the
"arena.<i>.purge" mallctl in 3.1.0.
- Remove the unnecessary "opt.valgrind" mallctl; jemalloc automatically
detects whether it is running inside Valgrind.
- Remove the "stats.huge.allocated", "stats.huge.nmalloc", and
"stats.huge.ndalloc" mallctls.
- Remove the --enable-mremap option.
- Remove the "stats.chunks.current", "stats.chunks.total", and
"stats.chunks.high" mallctls.
Bug fixes:
- Fix the cactive statistic to decrease (rather than increase) when active
memory decreases. This regression was first released in 3.5.0.
- Fix OOM handling in memalign() and valloc(). A variant of this bug existed
in all releases since 2.0.0, which introduced these functions.
- Fix an OOM-related regression in arena_tcache_fill_small(), which could
cause cache corruption on OOM. This regression was present in all releases
from 2.2.0 through 3.6.0.
- Fix size class overflow handling for malloc(), posix_memalign(), memalign(),
calloc(), and realloc() when profiling is enabled.
- Fix the "arena.<i>.dss" mallctl to return an error if "primary" or
"secondary" precedence is specified, but sbrk(2) is not supported.
- Fix fallback lg_floor() implementations to handle extremely large inputs.
- Ensure the default purgeable zone is after the default zone on OS X.
- Fix latent bugs in atomic_*().
- Fix the "arena.<i>.dss" mallctl to handle read-only calls.
- Fix tls_model configuration to enable the initial-exec model when possible.
- Mark malloc_conf as a weak symbol so that the application can override it.
- Correctly detect glibc's adaptive pthread mutexes.
- Fix the --without-export configure option.
* 3.6.0 (March 31, 2014) * 3.6.0 (March 31, 2014)
This version contains a critical bug fix for a regression present in 3.5.0 and This version contains a critical bug fix for a regression present in 3.5.0 and
...@@ -21,7 +855,7 @@ found in the git revision history: ...@@ -21,7 +855,7 @@ found in the git revision history:
backtracing to be reliable. backtracing to be reliable.
- Use dss allocation precedence for huge allocations as well as small/large - Use dss allocation precedence for huge allocations as well as small/large
allocations. allocations.
- Fix test assertion failure message formatting. This bug did not manifect on - Fix test assertion failure message formatting. This bug did not manifest on
x86_64 systems because of implementation subtleties in va_list. x86_64 systems because of implementation subtleties in va_list.
- Fix inconsequential test failures for hash and SFMT code. - Fix inconsequential test failures for hash and SFMT code.
...@@ -516,7 +1350,7 @@ found in the git revision history: ...@@ -516,7 +1350,7 @@ found in the git revision history:
- Make it possible for the application to manually flush a thread's cache, via - Make it possible for the application to manually flush a thread's cache, via
the "tcache.flush" mallctl. the "tcache.flush" mallctl.
- Base maximum dirty page count on proportion of active memory. - Base maximum dirty page count on proportion of active memory.
- Compute various addtional run-time statistics, including per size class - Compute various additional run-time statistics, including per size class
statistics for large objects. statistics for large objects.
- Expose malloc_stats_print(), which can be called repeatedly by the - Expose malloc_stats_print(), which can be called repeatedly by the
application. application.
......
Building and installing jemalloc can be as simple as typing the following while Building and installing a packaged release of jemalloc can be as simple as
in the root directory of the source tree: typing the following while in the root directory of the source tree:
./configure ./configure
make make
make install make install
=== Advanced configuration ===================================================== If building from unpackaged developer sources, the simplest command sequence
that might work is:
./autogen.sh
make dist
make
make install
Note that documentation is not built by the default target because doing so
would create a dependency on xsltproc in packaged releases, hence the
requirement to either run 'make dist' or avoid installing docs via the various
install_* targets documented below.
## Advanced configuration
The 'configure' script supports numerous options that allow control of which The 'configure' script supports numerous options that allow control of which
functionality is enabled, where jemalloc is installed, etc. Optionally, pass functionality is enabled, where jemalloc is installed, etc. Optionally, pass
any of the following arguments (not a definitive list) to 'configure': any of the following arguments (not a definitive list) to 'configure':
--help * `--help`
Print a definitive list of options. Print a definitive list of options.
--prefix=<install-root-dir> * `--prefix=<install-root-dir>`
Set the base directory in which to install. For example: Set the base directory in which to install. For example:
./configure --prefix=/usr/local ./configure --prefix=/usr/local
...@@ -22,11 +38,29 @@ any of the following arguments (not a definitive list) to 'configure': ...@@ -22,11 +38,29 @@ any of the following arguments (not a definitive list) to 'configure':
will cause files to be installed into /usr/local/include, /usr/local/lib, will cause files to be installed into /usr/local/include, /usr/local/lib,
and /usr/local/man. and /usr/local/man.
--with-rpath=<colon-separated-rpath> * `--with-version=(<major>.<minor>.<bugfix>-<nrev>-g<gid>|VERSION)`
The VERSION file is mandatory for successful configuration, and the
following steps are taken to assure its presence:
1) If --with-version=<major>.<minor>.<bugfix>-<nrev>-g<gid> is specified,
generate VERSION using the specified value.
2) If --with-version is not specified in either form and the source
directory is inside a git repository, try to generate VERSION via 'git
describe' invocations that pattern-match release tags.
3) If VERSION is missing, generate it with a bogus version:
0.0.0-0-g0000000000000000000000000000000000000000
Note that --with-version=VERSION bypasses (1) and (2), which simplifies
VERSION configuration when embedding a jemalloc release into another
project's git repository.
* `--with-rpath=<colon-separated-rpath>`
Embed one or more library paths, so that libjemalloc can find the libraries Embed one or more library paths, so that libjemalloc can find the libraries
it is linked to. This works only on ELF-based systems. it is linked to. This works only on ELF-based systems.
--with-mangling=<map> * `--with-mangling=<map>`
Mangle public symbols specified in <map> which is a comma-separated list of Mangle public symbols specified in <map> which is a comma-separated list of
name:mangled pairs. name:mangled pairs.
...@@ -39,7 +73,8 @@ any of the following arguments (not a definitive list) to 'configure': ...@@ -39,7 +73,8 @@ any of the following arguments (not a definitive list) to 'configure':
--with-jemalloc-prefix, and mangled symbols are then ignored when applying --with-jemalloc-prefix, and mangled symbols are then ignored when applying
the prefix. the prefix.
--with-jemalloc-prefix=<prefix> * `--with-jemalloc-prefix=<prefix>`
Prefix all public APIs with <prefix>. For example, if <prefix> is Prefix all public APIs with <prefix>. For example, if <prefix> is
"prefix_", API changes like the following occur: "prefix_", API changes like the following occur:
...@@ -55,55 +90,46 @@ any of the following arguments (not a definitive list) to 'configure': ...@@ -55,55 +90,46 @@ any of the following arguments (not a definitive list) to 'configure':
jemalloc overlays the default malloc zone, but makes no attempt to actually jemalloc overlays the default malloc zone, but makes no attempt to actually
replace the "malloc", "calloc", etc. symbols. replace the "malloc", "calloc", etc. symbols.
--without-export * `--without-export`
Don't export public APIs. This can be useful when building jemalloc as a
Don't export public APIs. This can be useful when building jemalloc as a
static library, or to avoid exporting public APIs when using the zone static library, or to avoid exporting public APIs when using the zone
allocator on OSX. allocator on OSX.
--with-private-namespace=<prefix> * `--with-private-namespace=<prefix>`
Prefix all library-private APIs with <prefix>je_. For shared libraries, Prefix all library-private APIs with <prefix>je_. For shared libraries,
symbol visibility mechanisms prevent these symbols from being exported, but symbol visibility mechanisms prevent these symbols from being exported, but
for static libraries, naming collisions are a real possibility. By for static libraries, naming collisions are a real possibility. By
default, <prefix> is empty, which results in a symbol prefix of je_ . default, <prefix> is empty, which results in a symbol prefix of je_ .
--with-install-suffix=<suffix> * `--with-install-suffix=<suffix>`
Append <suffix> to the base name of all installed files, such that multiple Append <suffix> to the base name of all installed files, such that multiple
versions of jemalloc can coexist in the same installation directory. For versions of jemalloc can coexist in the same installation directory. For
example, libjemalloc.so.0 becomes libjemalloc<suffix>.so.0. example, libjemalloc.so.0 becomes libjemalloc<suffix>.so.0.
--enable-cc-silence * `--with-malloc-conf=<malloc_conf>`
Enable code that silences non-useful compiler warnings. This is helpful
when trying to tell serious warnings from those due to compiler
limitations, but it potentially incurs a performance penalty.
--enable-debug Embed `<malloc_conf>` as a run-time options string that is processed prior to
Enable assertions and validation code. This incurs a substantial the malloc_conf global variable, the /etc/malloc.conf symlink, and the
performance hit, but is very useful during application development. MALLOC_CONF environment variable. For example, to change the default decay
Implies --enable-ivsalloc. time to 30 seconds:
--enable-code-coverage --with-malloc-conf=decay_ms:30000
Enable code coverage support, for use during jemalloc test development.
Additional testing targets are available if this option is enabled:
coverage * `--enable-debug`
coverage_unit
coverage_integration
coverage_stress
These targets do not clear code coverage results from previous runs, and Enable assertions and validation code. This incurs a substantial
there are interactions between the various coverage targets, so it is performance hit, but is very useful during application development.
usually advisable to run 'make clean' between repeated code coverage runs.
--enable-ivsalloc * `--disable-stats`
Enable validation code, which verifies that pointers reside within
jemalloc-owned chunks before dereferencing them. This incurs a substantial
performance hit.
--disable-stats
Disable statistics gathering functionality. See the "opt.stats_print" Disable statistics gathering functionality. See the "opt.stats_print"
option documentation for usage details. option documentation for usage details.
--enable-prof * `--enable-prof`
Enable heap profiling and leak detection functionality. See the "opt.prof" Enable heap profiling and leak detection functionality. See the "opt.prof"
option documentation for usage details. When enabled, there are several option documentation for usage details. When enabled, there are several
approaches to backtracing, and the configure script chooses the first one approaches to backtracing, and the configure script chooses the first one
...@@ -113,113 +139,191 @@ any of the following arguments (not a definitive list) to 'configure': ...@@ -113,113 +139,191 @@ any of the following arguments (not a definitive list) to 'configure':
+ libgcc (unless --disable-prof-libgcc) + libgcc (unless --disable-prof-libgcc)
+ gcc intrinsics (unless --disable-prof-gcc) + gcc intrinsics (unless --disable-prof-gcc)
--enable-prof-libunwind * `--enable-prof-libunwind`
Use the libunwind library (http://www.nongnu.org/libunwind/) for stack Use the libunwind library (http://www.nongnu.org/libunwind/) for stack
backtracing. backtracing.
--disable-prof-libgcc * `--disable-prof-libgcc`
Disable the use of libgcc's backtracing functionality. Disable the use of libgcc's backtracing functionality.
--disable-prof-gcc * `--disable-prof-gcc`
Disable the use of gcc intrinsics for backtracing. Disable the use of gcc intrinsics for backtracing.
--with-static-libunwind=<libunwind.a> * `--with-static-libunwind=<libunwind.a>`
Statically link against the specified libunwind.a rather than dynamically Statically link against the specified libunwind.a rather than dynamically
linking with -lunwind. linking with -lunwind.
--disable-tcache * `--disable-fill`
Disable thread-specific caches for small objects. Objects are cached and
released in bulk, thus reducing the total number of mutex operations. See Disable support for junk/zero filling of memory. See the "opt.junk" and
the "opt.tcache" option for usage details. "opt.zero" option documentation for usage details.
--enable-mremap * `--disable-zone-allocator`
Enable huge realloc() via mremap(2). mremap() is disabled by default
because the flavor used is specific to Linux, which has a quirk in its Disable zone allocator for Darwin. This means jemalloc won't be hooked as
virtual memory allocation algorithm that causes semi-permanent VM map holes
under normal jemalloc operation.
--disable-munmap
Disable virtual memory deallocation via munmap(2); instead keep track of
the virtual memory for later use. munmap() is disabled by default (i.e.
--disable-munmap is implied) on Linux, which has a quirk in its virtual
memory allocation algorithm that causes semi-permanent VM map holes under
normal jemalloc operation.
--enable-dss
Enable support for page allocation/deallocation via sbrk(2), in addition to
mmap(2).
--disable-fill
Disable support for junk/zero filling of memory, quarantine, and redzones.
See the "opt.junk", "opt.zero", "opt.quarantine", and "opt.redzone" option
documentation for usage details.
--disable-valgrind
Disable support for Valgrind.
--disable-experimental
Disable support for the experimental API (*allocm()).
--disable-zone-allocator
Disable zone allocator for Darwin. This means jemalloc won't be hooked as
the default allocator on OSX/iOS. the default allocator on OSX/iOS.
--enable-utrace * `--enable-utrace`
Enable utrace(2)-based allocation tracing. This feature is not broadly Enable utrace(2)-based allocation tracing. This feature is not broadly
portable (FreeBSD has it, but Linux and OS X do not). portable (FreeBSD has it, but Linux and OS X do not).
--enable-xmalloc * `--enable-xmalloc`
Enable support for optional immediate termination due to out-of-memory Enable support for optional immediate termination due to out-of-memory
errors, as is commonly implemented by "xmalloc" wrapper function for malloc. errors, as is commonly implemented by "xmalloc" wrapper function for malloc.
See the "opt.xmalloc" option documentation for usage details. See the "opt.xmalloc" option documentation for usage details.
--enable-lazy-lock * `--enable-lazy-lock`
Enable code that wraps pthread_create() to detect when an application Enable code that wraps pthread_create() to detect when an application
switches from single-threaded to multi-threaded mode, so that it can avoid switches from single-threaded to multi-threaded mode, so that it can avoid
mutex locking/unlocking operations while in single-threaded mode. In mutex locking/unlocking operations while in single-threaded mode. In
practice, this feature usually has little impact on performance unless practice, this feature usually has little impact on performance unless
thread-specific caching is disabled. thread-specific caching is disabled.
--disable-tls * `--disable-cache-oblivious`
Disable thread-local storage (TLS), which allows for fast access to
thread-local variables via the __thread keyword. If TLS is available, Disable cache-oblivious large allocation alignment for large allocation
jemalloc uses it for several purposes. requests with no alignment constraints. If this feature is disabled, all
large allocations are page-aligned as an implementation artifact, which can
severely harm CPU cache utilization. However, the cache-oblivious layout
comes at the cost of one extra page per large allocation, which in the
most extreme case increases physical memory usage for the 16 KiB size class
to 20 KiB.
* `--disable-syscall`
Disable use of syscall(2) rather than {open,read,write,close}(2). This is
intended as a workaround for systems that place security limitations on
syscall(2).
* `--disable-cxx`
Disable C++ integration. This will cause new and delete operator
implementations to be omitted.
* `--with-xslroot=<path>`
--with-xslroot=<path>
Specify where to find DocBook XSL stylesheets when building the Specify where to find DocBook XSL stylesheets when building the
documentation. documentation.
* `--with-lg-page=<lg-page>`
Specify the base 2 log of the allocator page size, which must in turn be at
least as large as the system page size. By default the configure script
determines the host's page size and sets the allocator page size equal to
the system page size, so this option need not be specified unless the
system page size may change between configuration and execution, e.g. when
cross compiling.
* `--with-lg-page-sizes=<lg-page-sizes>`
Specify the comma-separated base 2 logs of the page sizes to support. This
option may be useful when cross compiling in combination with
`--with-lg-page`, but its primary use case is for integration with FreeBSD's
libc, wherein jemalloc is embedded.
* `--with-lg-hugepage=<lg-hugepage>`
Specify the base 2 log of the system huge page size. This option is useful
when cross compiling, or when overriding the default for systems that do
not explicitly support huge pages.
* `--with-lg-quantum=<lg-quantum>`
Specify the base 2 log of the minimum allocation alignment. jemalloc needs
to know the minimum alignment that meets the following C standard
requirement (quoted from the April 12, 2011 draft of the C11 standard):
> The pointer returned if the allocation succeeds is suitably aligned so
that it may be assigned to a pointer to any type of object with a
fundamental alignment requirement and then used to access such an object
or an array of such objects in the space allocated [...]
This setting is architecture-specific, and although jemalloc includes known
safe values for the most commonly used modern architectures, there is a
wrinkle related to GNU libc (glibc) that may impact your choice of
<lg-quantum>. On most modern architectures, this mandates 16-byte
alignment (<lg-quantum>=4), but the glibc developers chose not to meet this
requirement for performance reasons. An old discussion can be found at
<https://sourceware.org/bugzilla/show_bug.cgi?id=206> . Unlike glibc,
jemalloc does follow the C standard by default (caveat: jemalloc
technically cheats for size classes smaller than the quantum), but the fact
that Linux systems already work around this allocator noncompliance means
that it is generally safe in practice to let jemalloc's minimum alignment
follow glibc's lead. If you specify `--with-lg-quantum=3` during
configuration, jemalloc will provide additional size classes that are not
16-byte-aligned (24, 40, and 56).
* `--with-lg-vaddr=<lg-vaddr>`
Specify the number of significant virtual address bits. By default, the
configure script attempts to detect virtual address size on those platforms
where it knows how, and picks a default otherwise. This option may be
useful when cross-compiling.
* `--disable-initial-exec-tls`
Disable the initial-exec TLS model for jemalloc's internal thread-local
storage (on those platforms that support explicit settings). This can allow
jemalloc to be dynamically loaded after program startup (e.g. using dlopen).
Note that in this case, there will be two malloc implementations operating
in the same process, which will almost certainly result in confusing runtime
crashes if pointers leak from one implementation to the other.
The following environment variables (not a definitive list) impact configure's The following environment variables (not a definitive list) impact configure's
behavior: behavior:
CFLAGS="?" * `CFLAGS="?"`
Pass these flags to the compiler. You probably shouldn't define this unless * `CXXFLAGS="?"`
you know what you are doing. (Use EXTRA_CFLAGS instead.)
Pass these flags to the C/C++ compiler. Any flags set by the configure
script are prepended, which means explicitly set flags generally take
precedence. Take care when specifying flags such as -Werror, because
configure tests may be affected in undesirable ways.
EXTRA_CFLAGS="?" * `EXTRA_CFLAGS="?"`
Append these flags to CFLAGS. This makes it possible to add flags such as * `EXTRA_CXXFLAGS="?"`
-Werror, while allowing the configure script to determine what other flags
are appropriate for the specified configuration.
The configure script specifically checks whether an optimization flag (-O*) Append these flags to CFLAGS/CXXFLAGS, without passing them to the
is specified in EXTRA_CFLAGS, and refrains from specifying an optimization compiler(s) during configuration. This makes it possible to add flags such
level if it finds that one has already been specified. as -Werror, while allowing the configure script to determine what other
flags are appropriate for the specified configuration.
* `CPPFLAGS="?"`
CPPFLAGS="?"
Pass these flags to the C preprocessor. Note that CFLAGS is not passed to Pass these flags to the C preprocessor. Note that CFLAGS is not passed to
'cpp' when 'configure' is looking for include files, so you must use 'cpp' when 'configure' is looking for include files, so you must use
CPPFLAGS instead if you need to help 'configure' find header files. CPPFLAGS instead if you need to help 'configure' find header files.
LD_LIBRARY_PATH="?" * `LD_LIBRARY_PATH="?"`
'ld' uses this colon-separated list to find libraries. 'ld' uses this colon-separated list to find libraries.
LDFLAGS="?" * `LDFLAGS="?"`
Pass these flags when linking. Pass these flags when linking.
PATH="?" * `PATH="?"`
'configure' uses this to find programs. 'configure' uses this to find programs.
=== Advanced compilation ======================================================= In some cases it may be necessary to work around configuration results that do
not match reality. For example, Linux 4.5 added support for the MADV_FREE flag
to madvise(2), which can cause problems if building on a host with MADV_FREE
support and deploying to a target without. To work around this, use a cache
file to override the relevant configuration variable defined in configure.ac,
e.g.:
echo "je_cv_madv_free=no" > config.cache && ./configure -C
## Advanced compilation
To build only parts of jemalloc, use the following targets: To build only parts of jemalloc, use the following targets:
...@@ -236,6 +340,7 @@ To install only parts of jemalloc, use the following targets: ...@@ -236,6 +340,7 @@ To install only parts of jemalloc, use the following targets:
install_include install_include
install_lib_shared install_lib_shared
install_lib_static install_lib_static
install_lib_pc
install_lib install_lib
install_doc_html install_doc_html
install_doc_man install_doc_man
...@@ -247,40 +352,51 @@ To clean up build results to varying degrees, use the following make targets: ...@@ -247,40 +352,51 @@ To clean up build results to varying degrees, use the following make targets:
distclean distclean
relclean relclean
=== Advanced installation ======================================================
## Advanced installation
Optionally, define make variables when invoking make, including (not Optionally, define make variables when invoking make, including (not
exclusively): exclusively):
INCLUDEDIR="?" * `INCLUDEDIR="?"`
Use this as the installation prefix for header files. Use this as the installation prefix for header files.
LIBDIR="?" * `LIBDIR="?"`
Use this as the installation prefix for libraries. Use this as the installation prefix for libraries.
MANDIR="?" * `MANDIR="?"`
Use this as the installation prefix for man pages. Use this as the installation prefix for man pages.
DESTDIR="?" * `DESTDIR="?"`
Prepend DESTDIR to INCLUDEDIR, LIBDIR, DATADIR, and MANDIR. This is useful Prepend DESTDIR to INCLUDEDIR, LIBDIR, DATADIR, and MANDIR. This is useful
when installing to a different path than was specified via --prefix. when installing to a different path than was specified via --prefix.
CC="?" * `CC="?"`
Use this to invoke the C compiler. Use this to invoke the C compiler.
CFLAGS="?" * `CFLAGS="?"`
Pass these flags to the compiler. Pass these flags to the compiler.
CPPFLAGS="?" * `CPPFLAGS="?"`
Pass these flags to the C preprocessor. Pass these flags to the C preprocessor.
LDFLAGS="?" * `LDFLAGS="?"`
Pass these flags when linking. Pass these flags when linking.
PATH="?" * `PATH="?"`
Use this to search for programs used during configuration and building. Use this to search for programs used during configuration and building.
=== Development ================================================================
## Development
If you intend to make non-trivial changes to jemalloc, use the 'autogen.sh' If you intend to make non-trivial changes to jemalloc, use the 'autogen.sh'
script rather than 'configure'. This re-generates 'configure', enables script rather than 'configure'. This re-generates 'configure', enables
...@@ -297,7 +413,8 @@ directory, issue configuration and build commands: ...@@ -297,7 +413,8 @@ directory, issue configuration and build commands:
../configure --enable-autogen ../configure --enable-autogen
make make
=== Documentation ==============================================================
## Documentation
The manual page is generated in both html and roff formats. Any web browser The manual page is generated in both html and roff formats. Any web browser
can be used to view the html manual. The roff manual page can be formatted can be used to view the html manual. The roff manual page can be formatted
......
...@@ -9,6 +9,7 @@ vpath % . ...@@ -9,6 +9,7 @@ vpath % .
SHELL := /bin/sh SHELL := /bin/sh
CC := @CC@ CC := @CC@
CXX := @CXX@
# Configuration parameters. # Configuration parameters.
DESTDIR = DESTDIR =
...@@ -23,8 +24,15 @@ abs_srcroot := @abs_srcroot@ ...@@ -23,8 +24,15 @@ abs_srcroot := @abs_srcroot@
abs_objroot := @abs_objroot@ abs_objroot := @abs_objroot@
# Build parameters. # Build parameters.
CPPFLAGS := @CPPFLAGS@ -I$(srcroot)include -I$(objroot)include CPPFLAGS := @CPPFLAGS@ -I$(objroot)include -I$(srcroot)include
CFLAGS := @CFLAGS@ CONFIGURE_CFLAGS := @CONFIGURE_CFLAGS@
SPECIFIED_CFLAGS := @SPECIFIED_CFLAGS@
EXTRA_CFLAGS := @EXTRA_CFLAGS@
CFLAGS := $(strip $(CONFIGURE_CFLAGS) $(SPECIFIED_CFLAGS) $(EXTRA_CFLAGS))
CONFIGURE_CXXFLAGS := @CONFIGURE_CXXFLAGS@
SPECIFIED_CXXFLAGS := @SPECIFIED_CXXFLAGS@
EXTRA_CXXFLAGS := @EXTRA_CXXFLAGS@
CXXFLAGS := $(strip $(CONFIGURE_CXXFLAGS) $(SPECIFIED_CXXFLAGS) $(EXTRA_CXXFLAGS))
LDFLAGS := @LDFLAGS@ LDFLAGS := @LDFLAGS@
EXTRA_LDFLAGS := @EXTRA_LDFLAGS@ EXTRA_LDFLAGS := @EXTRA_LDFLAGS@
LIBS := @LIBS@ LIBS := @LIBS@
...@@ -42,23 +50,29 @@ XSLTPROC := @XSLTPROC@ ...@@ -42,23 +50,29 @@ XSLTPROC := @XSLTPROC@
AUTOCONF := @AUTOCONF@ AUTOCONF := @AUTOCONF@
_RPATH = @RPATH@ _RPATH = @RPATH@
RPATH = $(if $(1),$(call _RPATH,$(1))) RPATH = $(if $(1),$(call _RPATH,$(1)))
cfghdrs_in := @cfghdrs_in@ cfghdrs_in := $(addprefix $(srcroot),@cfghdrs_in@)
cfghdrs_out := @cfghdrs_out@ cfghdrs_out := @cfghdrs_out@
cfgoutputs_in := @cfgoutputs_in@ cfgoutputs_in := $(addprefix $(srcroot),@cfgoutputs_in@)
cfgoutputs_out := @cfgoutputs_out@ cfgoutputs_out := @cfgoutputs_out@
enable_autogen := @enable_autogen@ enable_autogen := @enable_autogen@
enable_code_coverage := @enable_code_coverage@ enable_prof := @enable_prof@
enable_experimental := @enable_experimental@
enable_zone_allocator := @enable_zone_allocator@ enable_zone_allocator := @enable_zone_allocator@
MALLOC_CONF := @JEMALLOC_CPREFIX@MALLOC_CONF
link_whole_archive := @link_whole_archive@
DSO_LDFLAGS = @DSO_LDFLAGS@ DSO_LDFLAGS = @DSO_LDFLAGS@
SOREV = @SOREV@ SOREV = @SOREV@
PIC_CFLAGS = @PIC_CFLAGS@ PIC_CFLAGS = @PIC_CFLAGS@
CTARGET = @CTARGET@ CTARGET = @CTARGET@
LDTARGET = @LDTARGET@ LDTARGET = @LDTARGET@
TEST_LD_MODE = @TEST_LD_MODE@
MKLIB = @MKLIB@ MKLIB = @MKLIB@
AR = @AR@ AR = @AR@
ARFLAGS = @ARFLAGS@ ARFLAGS = @ARFLAGS@
DUMP_SYMS = @DUMP_SYMS@
AWK := @AWK@
CC_MM = @CC_MM@ CC_MM = @CC_MM@
LM := @LM@
INSTALL = @INSTALL@
ifeq (macho, $(ABI)) ifeq (macho, $(ABI))
TEST_LIBRARY_PATH := DYLD_FALLBACK_LIBRARY_PATH="$(objroot)lib" TEST_LIBRARY_PATH := DYLD_FALLBACK_LIBRARY_PATH="$(objroot)lib"
...@@ -73,16 +87,38 @@ endif ...@@ -73,16 +87,38 @@ endif
LIBJEMALLOC := $(LIBPREFIX)jemalloc$(install_suffix) LIBJEMALLOC := $(LIBPREFIX)jemalloc$(install_suffix)
# Lists of files. # Lists of files.
BINS := $(srcroot)bin/pprof $(objroot)bin/jemalloc.sh BINS := $(objroot)bin/jemalloc-config $(objroot)bin/jemalloc.sh $(objroot)bin/jeprof
C_HDRS := $(objroot)include/jemalloc/jemalloc$(install_suffix).h C_HDRS := $(objroot)include/jemalloc/jemalloc$(install_suffix).h
C_SRCS := $(srcroot)src/jemalloc.c $(srcroot)src/arena.c \ C_SRCS := $(srcroot)src/jemalloc.c \
$(srcroot)src/atomic.c $(srcroot)src/base.c $(srcroot)src/bitmap.c \ $(srcroot)src/arena.c \
$(srcroot)src/chunk.c $(srcroot)src/chunk_dss.c \ $(srcroot)src/background_thread.c \
$(srcroot)src/chunk_mmap.c $(srcroot)src/ckh.c $(srcroot)src/ctl.c \ $(srcroot)src/base.c \
$(srcroot)src/extent.c $(srcroot)src/hash.c $(srcroot)src/huge.c \ $(srcroot)src/bin.c \
$(srcroot)src/mb.c $(srcroot)src/mutex.c $(srcroot)src/prof.c \ $(srcroot)src/bitmap.c \
$(srcroot)src/quarantine.c $(srcroot)src/rtree.c $(srcroot)src/stats.c \ $(srcroot)src/ckh.c \
$(srcroot)src/tcache.c $(srcroot)src/util.c $(srcroot)src/tsd.c $(srcroot)src/ctl.c \
$(srcroot)src/div.c \
$(srcroot)src/extent.c \
$(srcroot)src/extent_dss.c \
$(srcroot)src/extent_mmap.c \
$(srcroot)src/hash.c \
$(srcroot)src/hooks.c \
$(srcroot)src/large.c \
$(srcroot)src/log.c \
$(srcroot)src/malloc_io.c \
$(srcroot)src/mutex.c \
$(srcroot)src/mutex_pool.c \
$(srcroot)src/nstime.c \
$(srcroot)src/pages.c \
$(srcroot)src/prng.c \
$(srcroot)src/prof.c \
$(srcroot)src/rtree.c \
$(srcroot)src/stats.c \
$(srcroot)src/sz.c \
$(srcroot)src/tcache.c \
$(srcroot)src/ticker.c \
$(srcroot)src/tsd.c \
$(srcroot)src/witness.c
ifeq ($(enable_zone_allocator), 1) ifeq ($(enable_zone_allocator), 1)
C_SRCS += $(srcroot)src/zone.c C_SRCS += $(srcroot)src/zone.c
endif endif
...@@ -98,57 +134,119 @@ DSOS := $(objroot)lib/$(LIBJEMALLOC).$(SOREV) ...@@ -98,57 +134,119 @@ DSOS := $(objroot)lib/$(LIBJEMALLOC).$(SOREV)
ifneq ($(SOREV),$(SO)) ifneq ($(SOREV),$(SO))
DSOS += $(objroot)lib/$(LIBJEMALLOC).$(SO) DSOS += $(objroot)lib/$(LIBJEMALLOC).$(SO)
endif endif
ifeq (1, $(link_whole_archive))
LJEMALLOC := -Wl,--whole-archive -L$(objroot)lib -l$(LIBJEMALLOC) -Wl,--no-whole-archive
else
LJEMALLOC := $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB)
endif
PC := $(objroot)jemalloc.pc
MAN3 := $(objroot)doc/jemalloc$(install_suffix).3 MAN3 := $(objroot)doc/jemalloc$(install_suffix).3
DOCS_XML := $(objroot)doc/jemalloc$(install_suffix).xml DOCS_XML := $(objroot)doc/jemalloc$(install_suffix).xml
DOCS_HTML := $(DOCS_XML:$(objroot)%.xml=$(srcroot)%.html) DOCS_HTML := $(DOCS_XML:$(objroot)%.xml=$(objroot)%.html)
DOCS_MAN3 := $(DOCS_XML:$(objroot)%.xml=$(srcroot)%.3) DOCS_MAN3 := $(DOCS_XML:$(objroot)%.xml=$(objroot)%.3)
DOCS := $(DOCS_HTML) $(DOCS_MAN3) DOCS := $(DOCS_HTML) $(DOCS_MAN3)
C_TESTLIB_SRCS := $(srcroot)test/src/math.c $(srcroot)test/src/mtx.c \ C_TESTLIB_SRCS := $(srcroot)test/src/btalloc.c $(srcroot)test/src/btalloc_0.c \
$(srcroot)test/src/btalloc_1.c $(srcroot)test/src/math.c \
$(srcroot)test/src/mtx.c $(srcroot)test/src/mq.c \
$(srcroot)test/src/SFMT.c $(srcroot)test/src/test.c \ $(srcroot)test/src/SFMT.c $(srcroot)test/src/test.c \
$(srcroot)test/src/thd.c $(srcroot)test/src/thd.c $(srcroot)test/src/timer.c
C_UTIL_INTEGRATION_SRCS := $(srcroot)src/util.c ifeq (1, $(link_whole_archive))
TESTS_UNIT := $(srcroot)test/unit/bitmap.c \ C_UTIL_INTEGRATION_SRCS :=
C_UTIL_CPP_SRCS :=
else
C_UTIL_INTEGRATION_SRCS := $(srcroot)src/nstime.c $(srcroot)src/malloc_io.c
C_UTIL_CPP_SRCS := $(srcroot)src/nstime.c $(srcroot)src/malloc_io.c
endif
TESTS_UNIT := \
$(srcroot)test/unit/a0.c \
$(srcroot)test/unit/arena_reset.c \
$(srcroot)test/unit/atomic.c \
$(srcroot)test/unit/background_thread.c \
$(srcroot)test/unit/background_thread_enable.c \
$(srcroot)test/unit/base.c \
$(srcroot)test/unit/bitmap.c \
$(srcroot)test/unit/ckh.c \ $(srcroot)test/unit/ckh.c \
$(srcroot)test/unit/decay.c \
$(srcroot)test/unit/div.c \
$(srcroot)test/unit/emitter.c \
$(srcroot)test/unit/extent_quantize.c \
$(srcroot)test/unit/fork.c \
$(srcroot)test/unit/hash.c \ $(srcroot)test/unit/hash.c \
$(srcroot)test/unit/hooks.c \
$(srcroot)test/unit/junk.c \ $(srcroot)test/unit/junk.c \
$(srcroot)test/unit/junk_alloc.c \
$(srcroot)test/unit/junk_free.c \
$(srcroot)test/unit/log.c \
$(srcroot)test/unit/mallctl.c \ $(srcroot)test/unit/mallctl.c \
$(srcroot)test/unit/malloc_io.c \
$(srcroot)test/unit/math.c \ $(srcroot)test/unit/math.c \
$(srcroot)test/unit/mq.c \ $(srcroot)test/unit/mq.c \
$(srcroot)test/unit/mtx.c \ $(srcroot)test/unit/mtx.c \
$(srcroot)test/unit/pack.c \
$(srcroot)test/unit/pages.c \
$(srcroot)test/unit/ph.c \
$(srcroot)test/unit/prng.c \
$(srcroot)test/unit/prof_accum.c \ $(srcroot)test/unit/prof_accum.c \
$(srcroot)test/unit/prof_active.c \
$(srcroot)test/unit/prof_gdump.c \ $(srcroot)test/unit/prof_gdump.c \
$(srcroot)test/unit/prof_idump.c \ $(srcroot)test/unit/prof_idump.c \
$(srcroot)test/unit/prof_reset.c \
$(srcroot)test/unit/prof_tctx.c \
$(srcroot)test/unit/prof_thread_name.c \
$(srcroot)test/unit/ql.c \ $(srcroot)test/unit/ql.c \
$(srcroot)test/unit/qr.c \ $(srcroot)test/unit/qr.c \
$(srcroot)test/unit/quarantine.c \
$(srcroot)test/unit/rb.c \ $(srcroot)test/unit/rb.c \
$(srcroot)test/unit/retained.c \
$(srcroot)test/unit/rtree.c \ $(srcroot)test/unit/rtree.c \
$(srcroot)test/unit/SFMT.c \ $(srcroot)test/unit/SFMT.c \
$(srcroot)test/unit/size_classes.c \
$(srcroot)test/unit/slab.c \
$(srcroot)test/unit/smoothstep.c \
$(srcroot)test/unit/spin.c \
$(srcroot)test/unit/stats.c \ $(srcroot)test/unit/stats.c \
$(srcroot)test/unit/stats_print.c \
$(srcroot)test/unit/ticker.c \
$(srcroot)test/unit/nstime.c \
$(srcroot)test/unit/tsd.c \ $(srcroot)test/unit/tsd.c \
$(srcroot)test/unit/util.c \ $(srcroot)test/unit/witness.c \
$(srcroot)test/unit/zero.c $(srcroot)test/unit/zero.c
TESTS_UNIT_AUX := $(srcroot)test/unit/prof_accum_a.c \ ifeq (@enable_prof@, 1)
$(srcroot)test/unit/prof_accum_b.c TESTS_UNIT += \
$(srcroot)test/unit/arena_reset_prof.c
endif
TESTS_INTEGRATION := $(srcroot)test/integration/aligned_alloc.c \ TESTS_INTEGRATION := $(srcroot)test/integration/aligned_alloc.c \
$(srcroot)test/integration/allocated.c \ $(srcroot)test/integration/allocated.c \
$(srcroot)test/integration/extent.c \
$(srcroot)test/integration/mallocx.c \ $(srcroot)test/integration/mallocx.c \
$(srcroot)test/integration/mremap.c \ $(srcroot)test/integration/MALLOCX_ARENA.c \
$(srcroot)test/integration/overflow.c \
$(srcroot)test/integration/posix_memalign.c \ $(srcroot)test/integration/posix_memalign.c \
$(srcroot)test/integration/rallocx.c \ $(srcroot)test/integration/rallocx.c \
$(srcroot)test/integration/sdallocx.c \
$(srcroot)test/integration/thread_arena.c \ $(srcroot)test/integration/thread_arena.c \
$(srcroot)test/integration/thread_tcache_enabled.c \ $(srcroot)test/integration/thread_tcache_enabled.c \
$(srcroot)test/integration/xallocx.c $(srcroot)test/integration/xallocx.c
ifeq ($(enable_experimental), 1) ifeq (@enable_cxx@, 1)
TESTS_INTEGRATION += $(srcroot)test/integration/allocm.c \ CPP_SRCS := $(srcroot)src/jemalloc_cpp.cpp
$(srcroot)test/integration/MALLOCX_ARENA.c \ TESTS_INTEGRATION_CPP := $(srcroot)test/integration/cpp/basic.cpp
$(srcroot)test/integration/rallocm.c else
CPP_SRCS :=
TESTS_INTEGRATION_CPP :=
endif endif
TESTS_STRESS := TESTS_STRESS := $(srcroot)test/stress/microbench.c
TESTS := $(TESTS_UNIT) $(TESTS_INTEGRATION) $(TESTS_STRESS)
TESTS := $(TESTS_UNIT) $(TESTS_INTEGRATION) $(TESTS_INTEGRATION_CPP) $(TESTS_STRESS)
PRIVATE_NAMESPACE_HDRS := $(objroot)include/jemalloc/internal/private_namespace.h $(objroot)include/jemalloc/internal/private_namespace_jet.h
PRIVATE_NAMESPACE_GEN_HDRS := $(PRIVATE_NAMESPACE_HDRS:%.h=%.gen.h)
C_SYM_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.sym.$(O))
C_SYMS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.sym)
C_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.$(O)) C_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.$(O))
CPP_OBJS := $(CPP_SRCS:$(srcroot)%.cpp=$(objroot)%.$(O))
C_PIC_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.pic.$(O)) C_PIC_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.pic.$(O))
CPP_PIC_OBJS := $(CPP_SRCS:$(srcroot)%.cpp=$(objroot)%.pic.$(O))
C_JET_SYM_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.jet.sym.$(O))
C_JET_SYMS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.jet.sym)
C_JET_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.jet.$(O)) C_JET_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.jet.$(O))
C_TESTLIB_UNIT_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.unit.$(O)) C_TESTLIB_UNIT_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.unit.$(O))
C_TESTLIB_INTEGRATION_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.integration.$(O)) C_TESTLIB_INTEGRATION_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.integration.$(O))
...@@ -157,27 +255,28 @@ C_TESTLIB_STRESS_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.stress.$(O)) ...@@ -157,27 +255,28 @@ C_TESTLIB_STRESS_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.stress.$(O))
C_TESTLIB_OBJS := $(C_TESTLIB_UNIT_OBJS) $(C_TESTLIB_INTEGRATION_OBJS) $(C_UTIL_INTEGRATION_OBJS) $(C_TESTLIB_STRESS_OBJS) C_TESTLIB_OBJS := $(C_TESTLIB_UNIT_OBJS) $(C_TESTLIB_INTEGRATION_OBJS) $(C_UTIL_INTEGRATION_OBJS) $(C_TESTLIB_STRESS_OBJS)
TESTS_UNIT_OBJS := $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%.$(O)) TESTS_UNIT_OBJS := $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%.$(O))
TESTS_UNIT_AUX_OBJS := $(TESTS_UNIT_AUX:$(srcroot)%.c=$(objroot)%.$(O))
TESTS_INTEGRATION_OBJS := $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%.$(O)) TESTS_INTEGRATION_OBJS := $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%.$(O))
TESTS_INTEGRATION_CPP_OBJS := $(TESTS_INTEGRATION_CPP:$(srcroot)%.cpp=$(objroot)%.$(O))
TESTS_STRESS_OBJS := $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%.$(O)) TESTS_STRESS_OBJS := $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%.$(O))
TESTS_OBJS := $(TESTS_UNIT_OBJS) $(TESTS_UNIT_AUX_OBJS) $(TESTS_INTEGRATION_OBJS) $(TESTS_STRESS_OBJS) TESTS_OBJS := $(TESTS_UNIT_OBJS) $(TESTS_INTEGRATION_OBJS) $(TESTS_STRESS_OBJS)
TESTS_CPP_OBJS := $(TESTS_INTEGRATION_CPP_OBJS)
.PHONY: all dist build_doc_html build_doc_man build_doc .PHONY: all dist build_doc_html build_doc_man build_doc
.PHONY: install_bin install_include install_lib .PHONY: install_bin install_include install_lib
.PHONY: install_doc_html install_doc_man install_doc install .PHONY: install_doc_html install_doc_man install_doc install
.PHONY: tests check clean distclean relclean .PHONY: tests check clean distclean relclean
.SECONDARY : $(TESTS_OBJS) .SECONDARY : $(PRIVATE_NAMESPACE_GEN_HDRS) $(TESTS_OBJS) $(TESTS_CPP_OBJS)
# Default target. # Default target.
all: build_lib all: build_lib
dist: build_doc dist: build_doc
$(srcroot)doc/%.html : $(objroot)doc/%.xml $(srcroot)doc/stylesheet.xsl $(objroot)doc/html.xsl $(objroot)doc/%.html : $(objroot)doc/%.xml $(srcroot)doc/stylesheet.xsl $(objroot)doc/html.xsl
$(XSLTPROC) -o $@ $(objroot)doc/html.xsl $< $(XSLTPROC) -o $@ $(objroot)doc/html.xsl $<
$(srcroot)doc/%.3 : $(objroot)doc/%.xml $(srcroot)doc/stylesheet.xsl $(objroot)doc/manpages.xsl $(objroot)doc/%.3 : $(objroot)doc/%.xml $(srcroot)doc/stylesheet.xsl $(objroot)doc/manpages.xsl
$(XSLTPROC) -o $@ $(objroot)doc/manpages.xsl $< $(XSLTPROC) -o $@ $(objroot)doc/manpages.xsl $<
build_doc_html: $(DOCS_HTML) build_doc_html: $(DOCS_HTML)
...@@ -188,18 +287,32 @@ build_doc: $(DOCS) ...@@ -188,18 +287,32 @@ build_doc: $(DOCS)
# Include generated dependency files. # Include generated dependency files.
# #
ifdef CC_MM ifdef CC_MM
-include $(C_SYM_OBJS:%.$(O)=%.d)
-include $(C_OBJS:%.$(O)=%.d) -include $(C_OBJS:%.$(O)=%.d)
-include $(CPP_OBJS:%.$(O)=%.d)
-include $(C_PIC_OBJS:%.$(O)=%.d) -include $(C_PIC_OBJS:%.$(O)=%.d)
-include $(CPP_PIC_OBJS:%.$(O)=%.d)
-include $(C_JET_SYM_OBJS:%.$(O)=%.d)
-include $(C_JET_OBJS:%.$(O)=%.d) -include $(C_JET_OBJS:%.$(O)=%.d)
-include $(C_TESTLIB_OBJS:%.$(O)=%.d) -include $(C_TESTLIB_OBJS:%.$(O)=%.d)
-include $(TESTS_OBJS:%.$(O)=%.d) -include $(TESTS_OBJS:%.$(O)=%.d)
-include $(TESTS_CPP_OBJS:%.$(O)=%.d)
endif endif
$(C_SYM_OBJS): $(objroot)src/%.sym.$(O): $(srcroot)src/%.c
$(C_SYM_OBJS): CPPFLAGS += -DJEMALLOC_NO_PRIVATE_NAMESPACE
$(C_SYMS): $(objroot)src/%.sym: $(objroot)src/%.sym.$(O)
$(C_OBJS): $(objroot)src/%.$(O): $(srcroot)src/%.c $(C_OBJS): $(objroot)src/%.$(O): $(srcroot)src/%.c
$(CPP_OBJS): $(objroot)src/%.$(O): $(srcroot)src/%.cpp
$(C_PIC_OBJS): $(objroot)src/%.pic.$(O): $(srcroot)src/%.c $(C_PIC_OBJS): $(objroot)src/%.pic.$(O): $(srcroot)src/%.c
$(C_PIC_OBJS): CFLAGS += $(PIC_CFLAGS) $(C_PIC_OBJS): CFLAGS += $(PIC_CFLAGS)
$(CPP_PIC_OBJS): $(objroot)src/%.pic.$(O): $(srcroot)src/%.cpp
$(CPP_PIC_OBJS): CXXFLAGS += $(PIC_CFLAGS)
$(C_JET_SYM_OBJS): $(objroot)src/%.jet.sym.$(O): $(srcroot)src/%.c
$(C_JET_SYM_OBJS): CPPFLAGS += -DJEMALLOC_JET -DJEMALLOC_NO_PRIVATE_NAMESPACE
$(C_JET_SYMS): $(objroot)src/%.jet.sym: $(objroot)src/%.jet.sym.$(O)
$(C_JET_OBJS): $(objroot)src/%.jet.$(O): $(srcroot)src/%.c $(C_JET_OBJS): $(objroot)src/%.jet.$(O): $(srcroot)src/%.c
$(C_JET_OBJS): CFLAGS += -DJEMALLOC_JET $(C_JET_OBJS): CPPFLAGS += -DJEMALLOC_JET
$(C_TESTLIB_UNIT_OBJS): $(objroot)test/src/%.unit.$(O): $(srcroot)test/src/%.c $(C_TESTLIB_UNIT_OBJS): $(objroot)test/src/%.unit.$(O): $(srcroot)test/src/%.c
$(C_TESTLIB_UNIT_OBJS): CPPFLAGS += -DJEMALLOC_UNIT_TEST $(C_TESTLIB_UNIT_OBJS): CPPFLAGS += -DJEMALLOC_UNIT_TEST
$(C_TESTLIB_INTEGRATION_OBJS): $(objroot)test/src/%.integration.$(O): $(srcroot)test/src/%.c $(C_TESTLIB_INTEGRATION_OBJS): $(objroot)test/src/%.integration.$(O): $(srcroot)test/src/%.c
...@@ -209,112 +322,147 @@ $(C_TESTLIB_STRESS_OBJS): $(objroot)test/src/%.stress.$(O): $(srcroot)test/src/% ...@@ -209,112 +322,147 @@ $(C_TESTLIB_STRESS_OBJS): $(objroot)test/src/%.stress.$(O): $(srcroot)test/src/%
$(C_TESTLIB_STRESS_OBJS): CPPFLAGS += -DJEMALLOC_STRESS_TEST -DJEMALLOC_STRESS_TESTLIB $(C_TESTLIB_STRESS_OBJS): CPPFLAGS += -DJEMALLOC_STRESS_TEST -DJEMALLOC_STRESS_TESTLIB
$(C_TESTLIB_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include $(C_TESTLIB_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include
$(TESTS_UNIT_OBJS): CPPFLAGS += -DJEMALLOC_UNIT_TEST $(TESTS_UNIT_OBJS): CPPFLAGS += -DJEMALLOC_UNIT_TEST
$(TESTS_UNIT_AUX_OBJS): CPPFLAGS += -DJEMALLOC_UNIT_TEST
define make-unit-link-dep
$(1): TESTS_UNIT_LINK_OBJS += $(2)
$(1): $(2)
endef
$(foreach test, $(TESTS_UNIT:$(srcroot)test/unit/%.c=$(objroot)test/unit/%$(EXE)), $(eval $(call make-unit-link-dep,$(test),$(filter $(test:%=%_a.$(O)) $(test:%=%_b.$(O)),$(TESTS_UNIT_AUX_OBJS)))))
$(TESTS_INTEGRATION_OBJS): CPPFLAGS += -DJEMALLOC_INTEGRATION_TEST $(TESTS_INTEGRATION_OBJS): CPPFLAGS += -DJEMALLOC_INTEGRATION_TEST
$(TESTS_INTEGRATION_CPP_OBJS): CPPFLAGS += -DJEMALLOC_INTEGRATION_CPP_TEST
$(TESTS_STRESS_OBJS): CPPFLAGS += -DJEMALLOC_STRESS_TEST $(TESTS_STRESS_OBJS): CPPFLAGS += -DJEMALLOC_STRESS_TEST
$(TESTS_OBJS): $(objroot)test/%.$(O): $(srcroot)test/%.c $(TESTS_OBJS): $(objroot)test/%.$(O): $(srcroot)test/%.c
$(TESTS_CPP_OBJS): $(objroot)test/%.$(O): $(srcroot)test/%.cpp
$(TESTS_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include $(TESTS_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include
$(TESTS_CPP_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include
ifneq ($(IMPORTLIB),$(SO)) ifneq ($(IMPORTLIB),$(SO))
$(C_OBJS): CPPFLAGS += -DDLLEXPORT $(CPP_OBJS) $(C_SYM_OBJS) $(C_OBJS) $(C_JET_SYM_OBJS) $(C_JET_OBJS): CPPFLAGS += -DDLLEXPORT
endif endif
ifndef CC_MM
# Dependencies. # Dependencies.
ifndef CC_MM
HEADER_DIRS = $(srcroot)include/jemalloc/internal \ HEADER_DIRS = $(srcroot)include/jemalloc/internal \
$(objroot)include/jemalloc $(objroot)include/jemalloc/internal $(objroot)include/jemalloc $(objroot)include/jemalloc/internal
HEADERS = $(wildcard $(foreach dir,$(HEADER_DIRS),$(dir)/*.h)) HEADERS = $(filter-out $(PRIVATE_NAMESPACE_HDRS),$(wildcard $(foreach dir,$(HEADER_DIRS),$(dir)/*.h)))
$(C_OBJS) $(C_PIC_OBJS) $(C_JET_OBJS) $(C_TESTLIB_OBJS) $(TESTS_OBJS): $(HEADERS) $(C_SYM_OBJS) $(C_OBJS) $(CPP_OBJS) $(C_PIC_OBJS) $(CPP_PIC_OBJS) $(C_JET_SYM_OBJS) $(C_JET_OBJS) $(C_TESTLIB_OBJS) $(TESTS_OBJS) $(TESTS_CPP_OBJS): $(HEADERS)
$(TESTS_OBJS): $(objroot)test/unit/jemalloc_test.h $(TESTS_OBJS) $(TESTS_CPP_OBJS): $(objroot)test/include/test/jemalloc_test.h
endif endif
$(C_OBJS) $(C_PIC_OBJS) $(C_JET_OBJS) $(C_TESTLIB_OBJS) $(TESTS_OBJS): %.$(O): $(C_OBJS) $(CPP_OBJS) $(C_PIC_OBJS) $(CPP_PIC_OBJS) $(C_TESTLIB_INTEGRATION_OBJS) $(C_UTIL_INTEGRATION_OBJS) $(TESTS_INTEGRATION_OBJS) $(TESTS_INTEGRATION_CPP_OBJS): $(objroot)include/jemalloc/internal/private_namespace.h
$(C_JET_OBJS) $(C_TESTLIB_UNIT_OBJS) $(C_TESTLIB_STRESS_OBJS) $(TESTS_UNIT_OBJS) $(TESTS_STRESS_OBJS): $(objroot)include/jemalloc/internal/private_namespace_jet.h
$(C_SYM_OBJS) $(C_OBJS) $(C_PIC_OBJS) $(C_JET_SYM_OBJS) $(C_JET_OBJS) $(C_TESTLIB_OBJS) $(TESTS_OBJS): %.$(O):
@mkdir -p $(@D) @mkdir -p $(@D)
$(CC) $(CFLAGS) -c $(CPPFLAGS) $(CTARGET) $< $(CC) $(CFLAGS) -c $(CPPFLAGS) $(CTARGET) $<
ifdef CC_MM ifdef CC_MM
@$(CC) -MM $(CPPFLAGS) -MT $@ -o $(@:%.$(O)=%.d) $< @$(CC) -MM $(CPPFLAGS) -MT $@ -o $(@:%.$(O)=%.d) $<
endif endif
$(C_SYMS): %.sym:
@mkdir -p $(@D)
$(DUMP_SYMS) $< | $(AWK) -f $(objroot)include/jemalloc/internal/private_symbols.awk > $@
$(C_JET_SYMS): %.sym:
@mkdir -p $(@D)
$(DUMP_SYMS) $< | $(AWK) -f $(objroot)include/jemalloc/internal/private_symbols_jet.awk > $@
$(objroot)include/jemalloc/internal/private_namespace.gen.h: $(C_SYMS)
$(SHELL) $(srcroot)include/jemalloc/internal/private_namespace.sh $^ > $@
$(objroot)include/jemalloc/internal/private_namespace_jet.gen.h: $(C_JET_SYMS)
$(SHELL) $(srcroot)include/jemalloc/internal/private_namespace.sh $^ > $@
%.h: %.gen.h
@if ! `cmp -s $< $@` ; then echo "cp $< $<"; cp $< $@ ; fi
$(CPP_OBJS) $(CPP_PIC_OBJS) $(TESTS_CPP_OBJS): %.$(O):
@mkdir -p $(@D)
$(CXX) $(CXXFLAGS) -c $(CPPFLAGS) $(CTARGET) $<
ifdef CC_MM
@$(CXX) -MM $(CPPFLAGS) -MT $@ -o $(@:%.$(O)=%.d) $<
endif
ifneq ($(SOREV),$(SO)) ifneq ($(SOREV),$(SO))
%.$(SO) : %.$(SOREV) %.$(SO) : %.$(SOREV)
@mkdir -p $(@D) @mkdir -p $(@D)
ln -sf $(<F) $@ ln -sf $(<F) $@
endif endif
$(objroot)lib/$(LIBJEMALLOC).$(SOREV) : $(if $(PIC_CFLAGS),$(C_PIC_OBJS),$(C_OBJS)) $(objroot)lib/$(LIBJEMALLOC).$(SOREV) : $(if $(PIC_CFLAGS),$(C_PIC_OBJS),$(C_OBJS)) $(if $(PIC_CFLAGS),$(CPP_PIC_OBJS),$(CPP_OBJS))
@mkdir -p $(@D) @mkdir -p $(@D)
$(CC) $(DSO_LDFLAGS) $(call RPATH,$(RPATH_EXTRA)) $(LDTARGET) $+ $(LDFLAGS) $(LIBS) $(EXTRA_LDFLAGS) $(CC) $(DSO_LDFLAGS) $(call RPATH,$(RPATH_EXTRA)) $(LDTARGET) $+ $(LDFLAGS) $(LIBS) $(EXTRA_LDFLAGS)
$(objroot)lib/$(LIBJEMALLOC)_pic.$(A) : $(C_PIC_OBJS) $(objroot)lib/$(LIBJEMALLOC)_pic.$(A) : $(C_PIC_OBJS) $(CPP_PIC_OBJS)
$(objroot)lib/$(LIBJEMALLOC).$(A) : $(C_OBJS) $(objroot)lib/$(LIBJEMALLOC).$(A) : $(C_OBJS) $(CPP_OBJS)
$(objroot)lib/$(LIBJEMALLOC)_s.$(A) : $(C_OBJS) $(objroot)lib/$(LIBJEMALLOC)_s.$(A) : $(C_OBJS) $(CPP_OBJS)
$(STATIC_LIBS): $(STATIC_LIBS):
@mkdir -p $(@D) @mkdir -p $(@D)
$(AR) $(ARFLAGS)@AROUT@ $+ $(AR) $(ARFLAGS)@AROUT@ $+
$(objroot)test/unit/%$(EXE): $(objroot)test/unit/%.$(O) $(TESTS_UNIT_LINK_OBJS) $(C_JET_OBJS) $(C_TESTLIB_UNIT_OBJS) $(objroot)test/unit/%$(EXE): $(objroot)test/unit/%.$(O) $(C_JET_OBJS) $(C_TESTLIB_UNIT_OBJS)
@mkdir -p $(@D) @mkdir -p $(@D)
$(CC) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(LDFLAGS) $(filter-out -lm,$(LIBS)) -lm $(EXTRA_LDFLAGS) $(CC) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(LDFLAGS) $(filter-out -lm,$(LIBS)) $(LM) $(EXTRA_LDFLAGS)
$(objroot)test/integration/%$(EXE): $(objroot)test/integration/%.$(O) $(C_TESTLIB_INTEGRATION_OBJS) $(C_UTIL_INTEGRATION_OBJS) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB) $(objroot)test/integration/%$(EXE): $(objroot)test/integration/%.$(O) $(C_TESTLIB_INTEGRATION_OBJS) $(C_UTIL_INTEGRATION_OBJS) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB)
@mkdir -p $(@D) @mkdir -p $(@D)
$(CC) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB) $(LDFLAGS) $(filter-out -lm,$(filter -lpthread,$(LIBS))) -lm $(EXTRA_LDFLAGS) $(CC) $(TEST_LD_MODE) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(LJEMALLOC) $(LDFLAGS) $(filter-out -lm,$(filter -lrt -lpthread -lstdc++,$(LIBS))) $(LM) $(EXTRA_LDFLAGS)
$(objroot)test/integration/cpp/%$(EXE): $(objroot)test/integration/cpp/%.$(O) $(C_TESTLIB_INTEGRATION_OBJS) $(C_UTIL_INTEGRATION_OBJS) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB)
@mkdir -p $(@D)
$(CXX) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB) $(LDFLAGS) $(filter-out -lm,$(LIBS)) -lm $(EXTRA_LDFLAGS)
$(objroot)test/stress/%$(EXE): $(objroot)test/stress/%.$(O) $(C_JET_OBJS) $(C_TESTLIB_STRESS_OBJS) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB) $(objroot)test/stress/%$(EXE): $(objroot)test/stress/%.$(O) $(C_JET_OBJS) $(C_TESTLIB_STRESS_OBJS) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB)
@mkdir -p $(@D) @mkdir -p $(@D)
$(CC) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB) $(LDFLAGS) $(filter-out -lm,$(LIBS)) -lm $(EXTRA_LDFLAGS) $(CC) $(TEST_LD_MODE) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB) $(LDFLAGS) $(filter-out -lm,$(LIBS)) $(LM) $(EXTRA_LDFLAGS)
build_lib_shared: $(DSOS) build_lib_shared: $(DSOS)
build_lib_static: $(STATIC_LIBS) build_lib_static: $(STATIC_LIBS)
build_lib: build_lib_shared build_lib_static build_lib: build_lib_shared build_lib_static
install_bin: install_bin:
install -d $(BINDIR) $(INSTALL) -d $(BINDIR)
@for b in $(BINS); do \ @for b in $(BINS); do \
echo "install -m 755 $$b $(BINDIR)"; \ echo "$(INSTALL) -m 755 $$b $(BINDIR)"; \
install -m 755 $$b $(BINDIR); \ $(INSTALL) -m 755 $$b $(BINDIR); \
done done
install_include: install_include:
install -d $(INCLUDEDIR)/jemalloc $(INSTALL) -d $(INCLUDEDIR)/jemalloc
@for h in $(C_HDRS); do \ @for h in $(C_HDRS); do \
echo "install -m 644 $$h $(INCLUDEDIR)/jemalloc"; \ echo "$(INSTALL) -m 644 $$h $(INCLUDEDIR)/jemalloc"; \
install -m 644 $$h $(INCLUDEDIR)/jemalloc; \ $(INSTALL) -m 644 $$h $(INCLUDEDIR)/jemalloc; \
done done
install_lib_shared: $(DSOS) install_lib_shared: $(DSOS)
install -d $(LIBDIR) $(INSTALL) -d $(LIBDIR)
install -m 755 $(objroot)lib/$(LIBJEMALLOC).$(SOREV) $(LIBDIR) $(INSTALL) -m 755 $(objroot)lib/$(LIBJEMALLOC).$(SOREV) $(LIBDIR)
ifneq ($(SOREV),$(SO)) ifneq ($(SOREV),$(SO))
ln -sf $(LIBJEMALLOC).$(SOREV) $(LIBDIR)/$(LIBJEMALLOC).$(SO) ln -sf $(LIBJEMALLOC).$(SOREV) $(LIBDIR)/$(LIBJEMALLOC).$(SO)
endif endif
install_lib_static: $(STATIC_LIBS) install_lib_static: $(STATIC_LIBS)
install -d $(LIBDIR) $(INSTALL) -d $(LIBDIR)
@for l in $(STATIC_LIBS); do \ @for l in $(STATIC_LIBS); do \
echo "install -m 755 $$l $(LIBDIR)"; \ echo "$(INSTALL) -m 755 $$l $(LIBDIR)"; \
install -m 755 $$l $(LIBDIR); \ $(INSTALL) -m 755 $$l $(LIBDIR); \
done done
install_lib: install_lib_shared install_lib_static install_lib_pc: $(PC)
$(INSTALL) -d $(LIBDIR)/pkgconfig
@for l in $(PC); do \
echo "$(INSTALL) -m 644 $$l $(LIBDIR)/pkgconfig"; \
$(INSTALL) -m 644 $$l $(LIBDIR)/pkgconfig; \
done
install_lib: install_lib_shared install_lib_static install_lib_pc
install_doc_html: install_doc_html:
install -d $(DATADIR)/doc/jemalloc$(install_suffix) $(INSTALL) -d $(DATADIR)/doc/jemalloc$(install_suffix)
@for d in $(DOCS_HTML); do \ @for d in $(DOCS_HTML); do \
echo "install -m 644 $$d $(DATADIR)/doc/jemalloc$(install_suffix)"; \ echo "$(INSTALL) -m 644 $$d $(DATADIR)/doc/jemalloc$(install_suffix)"; \
install -m 644 $$d $(DATADIR)/doc/jemalloc$(install_suffix); \ $(INSTALL) -m 644 $$d $(DATADIR)/doc/jemalloc$(install_suffix); \
done done
install_doc_man: install_doc_man:
install -d $(MANDIR)/man3 $(INSTALL) -d $(MANDIR)/man3
@for d in $(DOCS_MAN3); do \ @for d in $(DOCS_MAN3); do \
echo "install -m 644 $$d $(MANDIR)/man3"; \ echo "$(INSTALL) -m 644 $$d $(MANDIR)/man3"; \
install -m 644 $$d $(MANDIR)/man3; \ $(INSTALL) -m 644 $$d $(MANDIR)/man3; \
done done
install_doc: install_doc_html install_doc_man install_doc: install_doc_html install_doc_man
...@@ -322,7 +470,7 @@ install_doc: install_doc_html install_doc_man ...@@ -322,7 +470,7 @@ install_doc: install_doc_html install_doc_man
install: install_bin install_include install_lib install_doc install: install_bin install_include install_lib install_doc
tests_unit: $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%$(EXE)) tests_unit: $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%$(EXE))
tests_integration: $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%$(EXE)) tests_integration: $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%$(EXE)) $(TESTS_INTEGRATION_CPP:$(srcroot)%.cpp=$(objroot)%$(EXE))
tests_stress: $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%$(EXE)) tests_stress: $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%$(EXE))
tests: tests_unit tests_integration tests_stress tests: tests_unit tests_integration tests_stress
...@@ -330,78 +478,61 @@ check_unit_dir: ...@@ -330,78 +478,61 @@ check_unit_dir:
@mkdir -p $(objroot)test/unit @mkdir -p $(objroot)test/unit
check_integration_dir: check_integration_dir:
@mkdir -p $(objroot)test/integration @mkdir -p $(objroot)test/integration
check_stress_dir: stress_dir:
@mkdir -p $(objroot)test/stress @mkdir -p $(objroot)test/stress
check_dir: check_unit_dir check_integration_dir check_stress_dir check_dir: check_unit_dir check_integration_dir
check_unit: tests_unit check_unit_dir check_unit: tests_unit check_unit_dir
$(SHELL) $(objroot)test/test.sh $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%) $(SHELL) $(objroot)test/test.sh $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%)
check_integration_prof: tests_integration check_integration_dir
ifeq ($(enable_prof), 1)
$(MALLOC_CONF)="prof:true" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%) $(TESTS_INTEGRATION_CPP:$(srcroot)%.cpp=$(objroot)%)
$(MALLOC_CONF)="prof:true,prof_active:false" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%) $(TESTS_INTEGRATION_CPP:$(srcroot)%.cpp=$(objroot)%)
endif
check_integration_decay: tests_integration check_integration_dir
$(MALLOC_CONF)="dirty_decay_ms:-1,muzzy_decay_ms:-1" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%) $(TESTS_INTEGRATION_CPP:$(srcroot)%.cpp=$(objroot)%)
$(MALLOC_CONF)="dirty_decay_ms:0,muzzy_decay_ms:0" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%) $(TESTS_INTEGRATION_CPP:$(srcroot)%.cpp=$(objroot)%)
check_integration: tests_integration check_integration_dir check_integration: tests_integration check_integration_dir
$(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%) $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%) $(TESTS_INTEGRATION_CPP:$(srcroot)%.cpp=$(objroot)%)
check_stress: tests_stress check_stress_dir stress: tests_stress stress_dir
$(SHELL) $(objroot)test/test.sh $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%) $(SHELL) $(objroot)test/test.sh $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%)
check: tests check_dir check: check_unit check_integration check_integration_decay check_integration_prof
$(SHELL) $(objroot)test/test.sh $(TESTS:$(srcroot)%.c=$(objroot)%)
ifeq ($(enable_code_coverage), 1)
coverage_unit: check_unit
$(SHELL) $(srcroot)coverage.sh $(srcroot)src jet $(C_JET_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src unit $(C_TESTLIB_UNIT_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/unit unit $(TESTS_UNIT_OBJS)
coverage_integration: check_integration
$(SHELL) $(srcroot)coverage.sh $(srcroot)src pic $(C_PIC_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)src integration $(C_UTIL_INTEGRATION_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src integration $(C_TESTLIB_INTEGRATION_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/integration integration $(TESTS_INTEGRATION_OBJS)
coverage_stress: check_stress
$(SHELL) $(srcroot)coverage.sh $(srcroot)src pic $(C_PIC_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)src jet $(C_JET_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src stress $(C_TESTLIB_STRESS_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/stress stress $(TESTS_STRESS_OBJS)
coverage: check
$(SHELL) $(srcroot)coverage.sh $(srcroot)src pic $(C_PIC_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)src jet $(C_JET_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)src integration $(C_UTIL_INTEGRATION_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src unit $(C_TESTLIB_UNIT_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src integration $(C_TESTLIB_INTEGRATION_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src stress $(C_TESTLIB_STRESS_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/unit unit $(TESTS_UNIT_OBJS) $(TESTS_UNIT_AUX_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/integration integration $(TESTS_INTEGRATION_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/stress integration $(TESTS_STRESS_OBJS)
endif
clean: clean:
rm -f $(PRIVATE_NAMESPACE_HDRS)
rm -f $(PRIVATE_NAMESPACE_GEN_HDRS)
rm -f $(C_SYM_OBJS)
rm -f $(C_SYMS)
rm -f $(C_OBJS) rm -f $(C_OBJS)
rm -f $(CPP_OBJS)
rm -f $(C_PIC_OBJS) rm -f $(C_PIC_OBJS)
rm -f $(CPP_PIC_OBJS)
rm -f $(C_JET_SYM_OBJS)
rm -f $(C_JET_SYMS)
rm -f $(C_JET_OBJS) rm -f $(C_JET_OBJS)
rm -f $(C_TESTLIB_OBJS) rm -f $(C_TESTLIB_OBJS)
rm -f $(C_SYM_OBJS:%.$(O)=%.d)
rm -f $(C_OBJS:%.$(O)=%.d) rm -f $(C_OBJS:%.$(O)=%.d)
rm -f $(C_OBJS:%.$(O)=%.gcda) rm -f $(CPP_OBJS:%.$(O)=%.d)
rm -f $(C_OBJS:%.$(O)=%.gcno)
rm -f $(C_PIC_OBJS:%.$(O)=%.d) rm -f $(C_PIC_OBJS:%.$(O)=%.d)
rm -f $(C_PIC_OBJS:%.$(O)=%.gcda) rm -f $(CPP_PIC_OBJS:%.$(O)=%.d)
rm -f $(C_PIC_OBJS:%.$(O)=%.gcno) rm -f $(C_JET_SYM_OBJS:%.$(O)=%.d)
rm -f $(C_JET_OBJS:%.$(O)=%.d) rm -f $(C_JET_OBJS:%.$(O)=%.d)
rm -f $(C_JET_OBJS:%.$(O)=%.gcda)
rm -f $(C_JET_OBJS:%.$(O)=%.gcno)
rm -f $(C_TESTLIB_OBJS:%.$(O)=%.d) rm -f $(C_TESTLIB_OBJS:%.$(O)=%.d)
rm -f $(C_TESTLIB_OBJS:%.$(O)=%.gcda)
rm -f $(C_TESTLIB_OBJS:%.$(O)=%.gcno)
rm -f $(TESTS_OBJS:%.$(O)=%$(EXE)) rm -f $(TESTS_OBJS:%.$(O)=%$(EXE))
rm -f $(TESTS_OBJS) rm -f $(TESTS_OBJS)
rm -f $(TESTS_OBJS:%.$(O)=%.d) rm -f $(TESTS_OBJS:%.$(O)=%.d)
rm -f $(TESTS_OBJS:%.$(O)=%.gcda)
rm -f $(TESTS_OBJS:%.$(O)=%.gcno)
rm -f $(TESTS_OBJS:%.$(O)=%.out) rm -f $(TESTS_OBJS:%.$(O)=%.out)
rm -f $(TESTS_CPP_OBJS:%.$(O)=%$(EXE))
rm -f $(TESTS_CPP_OBJS)
rm -f $(TESTS_CPP_OBJS:%.$(O)=%.d)
rm -f $(TESTS_CPP_OBJS:%.$(O)=%.out)
rm -f $(DSOS) $(STATIC_LIBS) rm -f $(DSOS) $(STATIC_LIBS)
rm -f $(objroot)*.gcov.*
distclean: clean distclean: clean
rm -rf $(objroot)autom4te.cache rm -f $(objroot)bin/jemalloc-config
rm -f $(objroot)bin/jemalloc.sh rm -f $(objroot)bin/jemalloc.sh
rm -f $(objroot)bin/jeprof
rm -f $(objroot)config.log rm -f $(objroot)config.log
rm -f $(objroot)config.status rm -f $(objroot)config.status
rm -f $(objroot)config.stamp rm -f $(objroot)config.stamp
...@@ -410,7 +541,7 @@ distclean: clean ...@@ -410,7 +541,7 @@ distclean: clean
relclean: distclean relclean: distclean
rm -f $(objroot)configure rm -f $(objroot)configure
rm -f $(srcroot)VERSION rm -f $(objroot)VERSION
rm -f $(DOCS_HTML) rm -f $(DOCS_HTML)
rm -f $(DOCS_MAN3) rm -f $(DOCS_MAN3)
......
...@@ -3,12 +3,12 @@ fragmentation avoidance and scalable concurrency support. jemalloc first came ...@@ -3,12 +3,12 @@ fragmentation avoidance and scalable concurrency support. jemalloc first came
into use as the FreeBSD libc allocator in 2005, and since then it has found its into use as the FreeBSD libc allocator in 2005, and since then it has found its
way into numerous applications that rely on its predictable behavior. In 2010 way into numerous applications that rely on its predictable behavior. In 2010
jemalloc development efforts broadened to include developer support features jemalloc development efforts broadened to include developer support features
such as heap profiling, Valgrind integration, and extensive monitoring/tuning such as heap profiling and extensive monitoring/tuning hooks. Modern jemalloc
hooks. Modern jemalloc releases continue to be integrated back into FreeBSD, releases continue to be integrated back into FreeBSD, and therefore versatility
and therefore versatility remains critical. Ongoing development efforts trend remains critical. Ongoing development efforts trend toward making jemalloc
toward making jemalloc among the best allocators for a broad range of demanding among the best allocators for a broad range of demanding applications, and
applications, and eliminating/mitigating weaknesses that have practical eliminating/mitigating weaknesses that have practical repercussions for real
repercussions for real world applications. world applications.
The COPYING file contains copyright and licensing information. The COPYING file contains copyright and licensing information.
...@@ -17,4 +17,4 @@ jemalloc. ...@@ -17,4 +17,4 @@ jemalloc.
The ChangeLog file contains a brief summary of changes for each release. The ChangeLog file contains a brief summary of changes for each release.
URL: http://www.canonware.com/jemalloc/ URL: http://jemalloc.net/
This document summarizes the common approaches for performance fine tuning with
jemalloc (as of 5.1.0). The default configuration of jemalloc tends to work
reasonably well in practice, and most applications should not have to tune any
options. However, in order to cover a wide range of applications and avoid
pathological cases, the default setting is sometimes kept conservative and
suboptimal, even for many common workloads. When jemalloc is properly tuned for
a specific application / workload, it is common to improve system level metrics
by a few percent, or make favorable trade-offs.
## Notable runtime options for performance tuning
Runtime options can be set via
[malloc_conf](http://jemalloc.net/jemalloc.3.html#tuning).
* [background_thread](http://jemalloc.net/jemalloc.3.html#background_thread)
Enabling jemalloc background threads generally improves the tail latency for
application threads, since unused memory purging is shifted to the dedicated
background threads. In addition, unintended purging delay caused by
application inactivity is avoided with background threads.
Suggested: `background_thread:true` when jemalloc managed threads can be
allowed.
* [metadata_thp](http://jemalloc.net/jemalloc.3.html#opt.metadata_thp)
Allowing jemalloc to utilize transparent huge pages for its internal
metadata usually reduces TLB misses significantly, especially for programs
with large memory footprint and frequent allocation / deallocation
activities. Metadata memory usage may increase due to the use of huge
pages.
Suggested for allocation intensive programs: `metadata_thp:auto` or
`metadata_thp:always`, which is expected to improve CPU utilization at a
small memory cost.
* [dirty_decay_ms](http://jemalloc.net/jemalloc.3.html#opt.dirty_decay_ms) and
[muzzy_decay_ms](http://jemalloc.net/jemalloc.3.html#opt.muzzy_decay_ms)
Decay time determines how fast jemalloc returns unused pages back to the
operating system, and therefore provides a fairly straightforward trade-off
between CPU and memory usage. Shorter decay time purges unused pages faster
to reduces memory usage (usually at the cost of more CPU cycles spent on
purging), and vice versa.
Suggested: tune the values based on the desired trade-offs.
* [narenas](http://jemalloc.net/jemalloc.3.html#opt.narenas)
By default jemalloc uses multiple arenas to reduce internal lock contention.
However high arena count may also increase overall memory fragmentation,
since arenas manage memory independently. When high degree of parallelism
is not expected at the allocator level, lower number of arenas often
improves memory usage.
Suggested: if low parallelism is expected, try lower arena count while
monitoring CPU and memory usage.
* [percpu_arena](http://jemalloc.net/jemalloc.3.html#opt.percpu_arena)
Enable dynamic thread to arena association based on running CPU. This has
the potential to improve locality, e.g. when thread to CPU affinity is
present.
Suggested: try `percpu_arena:percpu` or `percpu_arena:phycpu` if
thread migration between processors is expected to be infrequent.
Examples:
* High resource consumption application, prioritizing CPU utilization:
`background_thread:true,metadata_thp:auto` combined with relaxed decay time
(increased `dirty_decay_ms` and / or `muzzy_decay_ms`,
e.g. `dirty_decay_ms:30000,muzzy_decay_ms:30000`).
* High resource consumption application, prioritizing memory usage:
`background_thread:true` combined with shorter decay time (decreased
`dirty_decay_ms` and / or `muzzy_decay_ms`,
e.g. `dirty_decay_ms:5000,muzzy_decay_ms:5000`), and lower arena count
(e.g. number of CPUs).
* Low resource consumption application:
`narenas:1,lg_tcache_max:13` combined with shorter decay time (decreased
`dirty_decay_ms` and / or `muzzy_decay_ms`,e.g.
`dirty_decay_ms:1000,muzzy_decay_ms:0`).
* Extremely conservative -- minimize memory usage at all costs, only suitable when
allocation activity is very rare:
`narenas:1,tcache:false,dirty_decay_ms:0,muzzy_decay_ms:0`
Note that it is recommended to combine the options with `abort_conf:true` which
aborts immediately on illegal options.
## Beyond runtime options
In addition to the runtime options, there are a number of programmatic ways to
improve application performance with jemalloc.
* [Explicit arenas](http://jemalloc.net/jemalloc.3.html#arenas.create)
Manually created arenas can help performance in various ways, e.g. by
managing locality and contention for specific usages. For example,
applications can explicitly allocate frequently accessed objects from a
dedicated arena with
[mallocx()](http://jemalloc.net/jemalloc.3.html#MALLOCX_ARENA) to improve
locality. In addition, explicit arenas often benefit from individually
tuned options, e.g. relaxed [decay
time](http://jemalloc.net/jemalloc.3.html#arena.i.dirty_decay_ms) if
frequent reuse is expected.
* [Extent hooks](http://jemalloc.net/jemalloc.3.html#arena.i.extent_hooks)
Extent hooks allow customization for managing underlying memory. One use
case for performance purpose is to utilize huge pages -- for example,
[HHVM](https://github.com/facebook/hhvm/blob/master/hphp/util/alloc.cpp)
uses explicit arenas with customized extent hooks to manage 1GB huge pages
for frequently accessed data, which reduces TLB misses significantly.
* [Explicit thread-to-arena
binding](http://jemalloc.net/jemalloc.3.html#thread.arena)
It is common for some threads in an application to have different memory
access / allocation patterns. Threads with heavy workloads often benefit
from explicit binding, e.g. binding very active threads to dedicated arenas
may reduce contention at the allocator level.
3.6.0-0-g46c0af68bd248b04df75e4f92d5fb804c3d75340 5.1.0-0-g0
#!/bin/sh
usage() {
cat <<EOF
Usage:
@BINDIR@/jemalloc-config <option>
Options:
--help | -h : Print usage.
--version : Print jemalloc version.
--revision : Print shared library revision number.
--config : Print configure options used to build jemalloc.
--prefix : Print installation directory prefix.
--bindir : Print binary installation directory.
--datadir : Print data installation directory.
--includedir : Print include installation directory.
--libdir : Print library installation directory.
--mandir : Print manual page installation directory.
--cc : Print compiler used to build jemalloc.
--cflags : Print compiler flags used to build jemalloc.
--cppflags : Print preprocessor flags used to build jemalloc.
--cxxflags : Print C++ compiler flags used to build jemalloc.
--ldflags : Print library flags used to build jemalloc.
--libs : Print libraries jemalloc was linked against.
EOF
}
prefix="@prefix@"
exec_prefix="@exec_prefix@"
case "$1" in
--help | -h)
usage
exit 0
;;
--version)
echo "@jemalloc_version@"
;;
--revision)
echo "@rev@"
;;
--config)
echo "@CONFIG@"
;;
--prefix)
echo "@PREFIX@"
;;
--bindir)
echo "@BINDIR@"
;;
--datadir)
echo "@DATADIR@"
;;
--includedir)
echo "@INCLUDEDIR@"
;;
--libdir)
echo "@LIBDIR@"
;;
--mandir)
echo "@MANDIR@"
;;
--cc)
echo "@CC@"
;;
--cflags)
echo "@CFLAGS@"
;;
--cppflags)
echo "@CPPFLAGS@"
;;
--cxxflags)
echo "@CXXFLAGS@"
;;
--ldflags)
echo "@LDFLAGS@ @EXTRA_LDFLAGS@"
;;
--libs)
echo "@LIBS@"
;;
*)
usage
exit 1
esac
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
# Copyright (c) 1998-2007, Google Inc. # Copyright (c) 1998-2007, Google Inc.
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are # modification, are permitted provided that the following conditions are
# met: # met:
# #
# * Redistributions of source code must retain the above copyright # * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer. # notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above # * Redistributions in binary form must reproduce the above
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# * Neither the name of Google Inc. nor the names of its # * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from # contributors may be used to endorse or promote products derived from
# this software without specific prior written permission. # this software without specific prior written permission.
# #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -40,28 +40,28 @@ ...@@ -40,28 +40,28 @@
# #
# Examples: # Examples:
# #
# % tools/pprof "program" "profile" # % tools/jeprof "program" "profile"
# Enters "interactive" mode # Enters "interactive" mode
# #
# % tools/pprof --text "program" "profile" # % tools/jeprof --text "program" "profile"
# Generates one line per procedure # Generates one line per procedure
# #
# % tools/pprof --gv "program" "profile" # % tools/jeprof --gv "program" "profile"
# Generates annotated call-graph and displays via "gv" # Generates annotated call-graph and displays via "gv"
# #
# % tools/pprof --gv --focus=Mutex "program" "profile" # % tools/jeprof --gv --focus=Mutex "program" "profile"
# Restrict to code paths that involve an entry that matches "Mutex" # Restrict to code paths that involve an entry that matches "Mutex"
# #
# % tools/pprof --gv --focus=Mutex --ignore=string "program" "profile" # % tools/jeprof --gv --focus=Mutex --ignore=string "program" "profile"
# Restrict to code paths that involve an entry that matches "Mutex" # Restrict to code paths that involve an entry that matches "Mutex"
# and does not match "string" # and does not match "string"
# #
# % tools/pprof --list=IBF_CheckDocid "program" "profile" # % tools/jeprof --list=IBF_CheckDocid "program" "profile"
# Generates disassembly listing of all routines with at least one # Generates disassembly listing of all routines with at least one
# sample that match the --list=<regexp> pattern. The listing is # sample that match the --list=<regexp> pattern. The listing is
# annotated with the flat and cumulative sample counts at each line. # annotated with the flat and cumulative sample counts at each line.
# #
# % tools/pprof --disasm=IBF_CheckDocid "program" "profile" # % tools/jeprof --disasm=IBF_CheckDocid "program" "profile"
# Generates disassembly listing of all routines with at least one # Generates disassembly listing of all routines with at least one
# sample that match the --disasm=<regexp> pattern. The listing is # sample that match the --disasm=<regexp> pattern. The listing is
# annotated with the flat and cumulative sample counts at each PC value. # annotated with the flat and cumulative sample counts at each PC value.
...@@ -71,11 +71,13 @@ ...@@ -71,11 +71,13 @@
use strict; use strict;
use warnings; use warnings;
use Getopt::Long; use Getopt::Long;
use Cwd;
my $JEPROF_VERSION = "@jemalloc_version@";
my $PPROF_VERSION = "2.0"; my $PPROF_VERSION = "2.0";
# These are the object tools we use which can come from a # These are the object tools we use which can come from a
# user-specified location using --tools, from the PPROF_TOOLS # user-specified location using --tools, from the JEPROF_TOOLS
# environment variable, or from the environment. # environment variable, or from the environment.
my %obj_tool_map = ( my %obj_tool_map = (
"objdump" => "objdump", "objdump" => "objdump",
...@@ -94,7 +96,7 @@ my @EVINCE = ("evince"); # could also be xpdf or perhaps acroread ...@@ -94,7 +96,7 @@ my @EVINCE = ("evince"); # could also be xpdf or perhaps acroread
my @KCACHEGRIND = ("kcachegrind"); my @KCACHEGRIND = ("kcachegrind");
my @PS2PDF = ("ps2pdf"); my @PS2PDF = ("ps2pdf");
# These are used for dynamic profiles # These are used for dynamic profiles
my @URL_FETCHER = ("curl", "-s"); my @URL_FETCHER = ("curl", "-s", "--fail");
# These are the web pages that servers need to support for dynamic profiles # These are the web pages that servers need to support for dynamic profiles
my $HEAP_PAGE = "/pprof/heap"; my $HEAP_PAGE = "/pprof/heap";
...@@ -144,13 +146,13 @@ my $sep_address = undef; ...@@ -144,13 +146,13 @@ my $sep_address = undef;
sub usage_string { sub usage_string {
return <<EOF; return <<EOF;
Usage: Usage:
pprof [options] <program> <profiles> jeprof [options] <program> <profiles>
<profiles> is a space separated list of profile names. <profiles> is a space separated list of profile names.
pprof [options] <symbolized-profiles> jeprof [options] <symbolized-profiles>
<symbolized-profiles> is a list of profile files where each file contains <symbolized-profiles> is a list of profile files where each file contains
the necessary symbol mappings as well as profile data (likely generated the necessary symbol mappings as well as profile data (likely generated
with --raw). with --raw).
pprof [options] <profile> jeprof [options] <profile>
<profile> is a remote form. Symbols are obtained from host:port$SYMBOL_PAGE <profile> is a remote form. Symbols are obtained from host:port$SYMBOL_PAGE
Each name can be: Each name can be:
...@@ -161,9 +163,9 @@ pprof [options] <profile> ...@@ -161,9 +163,9 @@ pprof [options] <profile>
$GROWTH_PAGE, $CONTENTION_PAGE, /pprof/wall, $GROWTH_PAGE, $CONTENTION_PAGE, /pprof/wall,
$CENSUSPROFILE_PAGE, or /pprof/filteredprofile. $CENSUSPROFILE_PAGE, or /pprof/filteredprofile.
For instance: For instance:
pprof http://myserver.com:80$HEAP_PAGE jeprof http://myserver.com:80$HEAP_PAGE
If /<service> is omitted, the service defaults to $PROFILE_PAGE (cpu profiling). If /<service> is omitted, the service defaults to $PROFILE_PAGE (cpu profiling).
pprof --symbols <program> jeprof --symbols <program>
Maps addresses to symbol names. In this mode, stdin should be a Maps addresses to symbol names. In this mode, stdin should be a
list of library mappings, in the same format as is found in the heap- list of library mappings, in the same format as is found in the heap-
and cpu-profile files (this loosely matches that of /proc/self/maps and cpu-profile files (this loosely matches that of /proc/self/maps
...@@ -202,7 +204,7 @@ Output type: ...@@ -202,7 +204,7 @@ Output type:
--pdf Generate PDF to stdout --pdf Generate PDF to stdout
--svg Generate SVG to stdout --svg Generate SVG to stdout
--gif Generate GIF to stdout --gif Generate GIF to stdout
--raw Generate symbolized pprof data (useful with remote fetch) --raw Generate symbolized jeprof data (useful with remote fetch)
Heap-Profile Options: Heap-Profile Options:
--inuse_space Display in-use (mega)bytes [default] --inuse_space Display in-use (mega)bytes [default]
...@@ -222,11 +224,14 @@ Call-graph Options: ...@@ -222,11 +224,14 @@ Call-graph Options:
--nodefraction=<f> Hide nodes below <f>*total [default=.005] --nodefraction=<f> Hide nodes below <f>*total [default=.005]
--edgefraction=<f> Hide edges below <f>*total [default=.001] --edgefraction=<f> Hide edges below <f>*total [default=.001]
--maxdegree=<n> Max incoming/outgoing edges per node [default=8] --maxdegree=<n> Max incoming/outgoing edges per node [default=8]
--focus=<regexp> Focus on nodes matching <regexp> --focus=<regexp> Focus on backtraces with nodes matching <regexp>
--ignore=<regexp> Ignore nodes matching <regexp> --thread=<n> Show profile for thread <n>
--ignore=<regexp> Ignore backtraces with nodes matching <regexp>
--scale=<n> Set GV scaling [default=0] --scale=<n> Set GV scaling [default=0]
--heapcheck Make nodes with non-0 object counts --heapcheck Make nodes with non-0 object counts
(i.e. direct leak generators) more visible (i.e. direct leak generators) more visible
--retain=<regexp> Retain only nodes that match <regexp>
--exclude=<regexp> Exclude all nodes that match <regexp>
Miscellaneous: Miscellaneous:
--tools=<prefix or binary:fullpath>[,...] \$PATH for object tool pathnames --tools=<prefix or binary:fullpath>[,...] \$PATH for object tool pathnames
...@@ -235,34 +240,34 @@ Miscellaneous: ...@@ -235,34 +240,34 @@ Miscellaneous:
--version Version information --version Version information
Environment Variables: Environment Variables:
PPROF_TMPDIR Profiles directory. Defaults to \$HOME/pprof JEPROF_TMPDIR Profiles directory. Defaults to \$HOME/jeprof
PPROF_TOOLS Prefix for object tools pathnames JEPROF_TOOLS Prefix for object tools pathnames
Examples: Examples:
pprof /bin/ls ls.prof jeprof /bin/ls ls.prof
Enters "interactive" mode Enters "interactive" mode
pprof --text /bin/ls ls.prof jeprof --text /bin/ls ls.prof
Outputs one line per procedure Outputs one line per procedure
pprof --web /bin/ls ls.prof jeprof --web /bin/ls ls.prof
Displays annotated call-graph in web browser Displays annotated call-graph in web browser
pprof --gv /bin/ls ls.prof jeprof --gv /bin/ls ls.prof
Displays annotated call-graph via 'gv' Displays annotated call-graph via 'gv'
pprof --gv --focus=Mutex /bin/ls ls.prof jeprof --gv --focus=Mutex /bin/ls ls.prof
Restricts to code paths including a .*Mutex.* entry Restricts to code paths including a .*Mutex.* entry
pprof --gv --focus=Mutex --ignore=string /bin/ls ls.prof jeprof --gv --focus=Mutex --ignore=string /bin/ls ls.prof
Code paths including Mutex but not string Code paths including Mutex but not string
pprof --list=getdir /bin/ls ls.prof jeprof --list=getdir /bin/ls ls.prof
(Per-line) annotated source listing for getdir() (Per-line) annotated source listing for getdir()
pprof --disasm=getdir /bin/ls ls.prof jeprof --disasm=getdir /bin/ls ls.prof
(Per-PC) annotated disassembly for getdir() (Per-PC) annotated disassembly for getdir()
pprof http://localhost:1234/ jeprof http://localhost:1234/
Enters "interactive" mode Enters "interactive" mode
pprof --text localhost:1234 jeprof --text localhost:1234
Outputs one line per procedure for localhost:1234 Outputs one line per procedure for localhost:1234
pprof --raw localhost:1234 > ./local.raw jeprof --raw localhost:1234 > ./local.raw
pprof --text ./local.raw jeprof --text ./local.raw
Fetches a remote profile for later analysis and then Fetches a remote profile for later analysis and then
analyzes it in text mode. analyzes it in text mode.
EOF EOF
...@@ -270,7 +275,8 @@ EOF ...@@ -270,7 +275,8 @@ EOF
sub version_string { sub version_string {
return <<EOF return <<EOF
pprof (part of gperftools $PPROF_VERSION) jeprof (part of jemalloc $JEPROF_VERSION)
based on pprof (part of gperftools $PPROF_VERSION)
Copyright 1998-2007 Google Inc. Copyright 1998-2007 Google Inc.
...@@ -293,8 +299,8 @@ sub Init() { ...@@ -293,8 +299,8 @@ sub Init() {
# Setup tmp-file name and handler to clean it up. # Setup tmp-file name and handler to clean it up.
# We do this in the very beginning so that we can use # We do this in the very beginning so that we can use
# error() and cleanup() function anytime here after. # error() and cleanup() function anytime here after.
$main::tmpfile_sym = "/tmp/pprof$$.sym"; $main::tmpfile_sym = "/tmp/jeprof$$.sym";
$main::tmpfile_ps = "/tmp/pprof$$"; $main::tmpfile_ps = "/tmp/jeprof$$";
$main::next_tmpfile = 0; $main::next_tmpfile = 0;
$SIG{'INT'} = \&sighandler; $SIG{'INT'} = \&sighandler;
...@@ -332,9 +338,12 @@ sub Init() { ...@@ -332,9 +338,12 @@ sub Init() {
$main::opt_edgefraction = 0.001; $main::opt_edgefraction = 0.001;
$main::opt_maxdegree = 8; $main::opt_maxdegree = 8;
$main::opt_focus = ''; $main::opt_focus = '';
$main::opt_thread = undef;
$main::opt_ignore = ''; $main::opt_ignore = '';
$main::opt_scale = 0; $main::opt_scale = 0;
$main::opt_heapcheck = 0; $main::opt_heapcheck = 0;
$main::opt_retain = '';
$main::opt_exclude = '';
$main::opt_seconds = 30; $main::opt_seconds = 30;
$main::opt_lib = ""; $main::opt_lib = "";
...@@ -402,9 +411,12 @@ sub Init() { ...@@ -402,9 +411,12 @@ sub Init() {
"edgefraction=f" => \$main::opt_edgefraction, "edgefraction=f" => \$main::opt_edgefraction,
"maxdegree=i" => \$main::opt_maxdegree, "maxdegree=i" => \$main::opt_maxdegree,
"focus=s" => \$main::opt_focus, "focus=s" => \$main::opt_focus,
"thread=s" => \$main::opt_thread,
"ignore=s" => \$main::opt_ignore, "ignore=s" => \$main::opt_ignore,
"scale=i" => \$main::opt_scale, "scale=i" => \$main::opt_scale,
"heapcheck" => \$main::opt_heapcheck, "heapcheck" => \$main::opt_heapcheck,
"retain=s" => \$main::opt_retain,
"exclude=s" => \$main::opt_exclude,
"inuse_space!" => \$main::opt_inuse_space, "inuse_space!" => \$main::opt_inuse_space,
"inuse_objects!" => \$main::opt_inuse_objects, "inuse_objects!" => \$main::opt_inuse_objects,
"alloc_space!" => \$main::opt_alloc_space, "alloc_space!" => \$main::opt_alloc_space,
...@@ -562,66 +574,12 @@ sub Init() { ...@@ -562,66 +574,12 @@ sub Init() {
} }
} }
sub Main() { sub FilterAndPrint {
Init(); my ($profile, $symbols, $libs, $thread) = @_;
$main::collected_profile = undef;
@main::profile_files = ();
$main::op_time = time();
# Printing symbols is special and requires a lot less info that most.
if ($main::opt_symbols) {
PrintSymbols(*STDIN); # Get /proc/maps and symbols output from stdin
return;
}
# Fetch all profile data
FetchDynamicProfiles();
# this will hold symbols that we read from the profile files
my $symbol_map = {};
# Read one profile, pick the last item on the list
my $data = ReadProfile($main::prog, pop(@main::profile_files));
my $profile = $data->{profile};
my $pcs = $data->{pcs};
my $libs = $data->{libs}; # Info about main program and shared libraries
$symbol_map = MergeSymbols($symbol_map, $data->{symbols});
# Add additional profiles, if available.
if (scalar(@main::profile_files) > 0) {
foreach my $pname (@main::profile_files) {
my $data2 = ReadProfile($main::prog, $pname);
$profile = AddProfile($profile, $data2->{profile});
$pcs = AddPcs($pcs, $data2->{pcs});
$symbol_map = MergeSymbols($symbol_map, $data2->{symbols});
}
}
# Subtract base from profile, if specified
if ($main::opt_base ne '') {
my $base = ReadProfile($main::prog, $main::opt_base);
$profile = SubtractProfile($profile, $base->{profile});
$pcs = AddPcs($pcs, $base->{pcs});
$symbol_map = MergeSymbols($symbol_map, $base->{symbols});
}
# Get total data in profile # Get total data in profile
my $total = TotalProfile($profile); my $total = TotalProfile($profile);
# Collect symbols
my $symbols;
if ($main::use_symbolized_profile) {
$symbols = FetchSymbols($pcs, $symbol_map);
} elsif ($main::use_symbol_page) {
$symbols = FetchSymbols($pcs);
} else {
# TODO(csilvers): $libs uses the /proc/self/maps data from profile1,
# which may differ from the data from subsequent profiles, especially
# if they were run on different machines. Use appropriate libs for
# each pc somehow.
$symbols = ExtractSymbols($libs, $pcs);
}
# Remove uniniteresting stack items # Remove uniniteresting stack items
$profile = RemoveUninterestingFrames($symbols, $profile); $profile = RemoveUninterestingFrames($symbols, $profile);
...@@ -656,7 +614,9 @@ sub Main() { ...@@ -656,7 +614,9 @@ sub Main() {
# (only matters when --heapcheck is given but we must be # (only matters when --heapcheck is given but we must be
# compatible with old branches that did not pass --heapcheck always): # compatible with old branches that did not pass --heapcheck always):
if ($total != 0) { if ($total != 0) {
printf("Total: %s %s\n", Unparse($total), Units()); printf("Total%s: %s %s\n",
(defined($thread) ? " (t$thread)" : ""),
Unparse($total), Units());
} }
PrintText($symbols, $flat, $cumulative, -1); PrintText($symbols, $flat, $cumulative, -1);
} elsif ($main::opt_raw) { } elsif ($main::opt_raw) {
...@@ -692,6 +652,77 @@ sub Main() { ...@@ -692,6 +652,77 @@ sub Main() {
} else { } else {
InteractiveMode($profile, $symbols, $libs, $total); InteractiveMode($profile, $symbols, $libs, $total);
} }
}
sub Main() {
Init();
$main::collected_profile = undef;
@main::profile_files = ();
$main::op_time = time();
# Printing symbols is special and requires a lot less info that most.
if ($main::opt_symbols) {
PrintSymbols(*STDIN); # Get /proc/maps and symbols output from stdin
return;
}
# Fetch all profile data
FetchDynamicProfiles();
# this will hold symbols that we read from the profile files
my $symbol_map = {};
# Read one profile, pick the last item on the list
my $data = ReadProfile($main::prog, pop(@main::profile_files));
my $profile = $data->{profile};
my $pcs = $data->{pcs};
my $libs = $data->{libs}; # Info about main program and shared libraries
$symbol_map = MergeSymbols($symbol_map, $data->{symbols});
# Add additional profiles, if available.
if (scalar(@main::profile_files) > 0) {
foreach my $pname (@main::profile_files) {
my $data2 = ReadProfile($main::prog, $pname);
$profile = AddProfile($profile, $data2->{profile});
$pcs = AddPcs($pcs, $data2->{pcs});
$symbol_map = MergeSymbols($symbol_map, $data2->{symbols});
}
}
# Subtract base from profile, if specified
if ($main::opt_base ne '') {
my $base = ReadProfile($main::prog, $main::opt_base);
$profile = SubtractProfile($profile, $base->{profile});
$pcs = AddPcs($pcs, $base->{pcs});
$symbol_map = MergeSymbols($symbol_map, $base->{symbols});
}
# Collect symbols
my $symbols;
if ($main::use_symbolized_profile) {
$symbols = FetchSymbols($pcs, $symbol_map);
} elsif ($main::use_symbol_page) {
$symbols = FetchSymbols($pcs);
} else {
# TODO(csilvers): $libs uses the /proc/self/maps data from profile1,
# which may differ from the data from subsequent profiles, especially
# if they were run on different machines. Use appropriate libs for
# each pc somehow.
$symbols = ExtractSymbols($libs, $pcs);
}
if (!defined($main::opt_thread)) {
FilterAndPrint($profile, $symbols, $libs);
}
if (defined($data->{threads})) {
foreach my $thread (sort { $a <=> $b } keys(%{$data->{threads}})) {
if (defined($main::opt_thread) &&
($main::opt_thread eq '*' || $main::opt_thread == $thread)) {
my $thread_profile = $data->{threads}{$thread};
FilterAndPrint($thread_profile, $symbols, $libs, $thread);
}
}
}
cleanup(); cleanup();
exit(0); exit(0);
...@@ -780,14 +811,14 @@ sub InteractiveMode { ...@@ -780,14 +811,14 @@ sub InteractiveMode {
$| = 1; # Make output unbuffered for interactive mode $| = 1; # Make output unbuffered for interactive mode
my ($orig_profile, $symbols, $libs, $total) = @_; my ($orig_profile, $symbols, $libs, $total) = @_;
print STDERR "Welcome to pprof! For help, type 'help'.\n"; print STDERR "Welcome to jeprof! For help, type 'help'.\n";
# Use ReadLine if it's installed and input comes from a console. # Use ReadLine if it's installed and input comes from a console.
if ( -t STDIN && if ( -t STDIN &&
!ReadlineMightFail() && !ReadlineMightFail() &&
defined(eval {require Term::ReadLine}) ) { defined(eval {require Term::ReadLine}) ) {
my $term = new Term::ReadLine 'pprof'; my $term = new Term::ReadLine 'jeprof';
while ( defined ($_ = $term->readline('(pprof) '))) { while ( defined ($_ = $term->readline('(jeprof) '))) {
$term->addhistory($_) if /\S/; $term->addhistory($_) if /\S/;
if (!InteractiveCommand($orig_profile, $symbols, $libs, $total, $_)) { if (!InteractiveCommand($orig_profile, $symbols, $libs, $total, $_)) {
last; # exit when we get an interactive command to quit last; # exit when we get an interactive command to quit
...@@ -795,7 +826,7 @@ sub InteractiveMode { ...@@ -795,7 +826,7 @@ sub InteractiveMode {
} }
} else { # don't have readline } else { # don't have readline
while (1) { while (1) {
print STDERR "(pprof) "; print STDERR "(jeprof) ";
$_ = <STDIN>; $_ = <STDIN>;
last if ! defined $_ ; last if ! defined $_ ;
s/\r//g; # turn windows-looking lines into unix-looking lines s/\r//g; # turn windows-looking lines into unix-looking lines
...@@ -988,7 +1019,7 @@ sub ProcessProfile { ...@@ -988,7 +1019,7 @@ sub ProcessProfile {
sub InteractiveHelpMessage { sub InteractiveHelpMessage {
print STDERR <<ENDOFHELP; print STDERR <<ENDOFHELP;
Interactive pprof mode Interactive jeprof mode
Commands: Commands:
gv gv
...@@ -1031,7 +1062,7 @@ Commands: ...@@ -1031,7 +1062,7 @@ Commands:
Generates callgrind file. If no filename is given, kcachegrind is called. Generates callgrind file. If no filename is given, kcachegrind is called.
help - This listing help - This listing
quit or ^D - End pprof quit or ^D - End jeprof
For commands that accept optional -ignore tags, samples where any routine in For commands that accept optional -ignore tags, samples where any routine in
the stack trace matches the regular expression in any of the -ignore the stack trace matches the regular expression in any of the -ignore
...@@ -1136,8 +1167,21 @@ sub PrintSymbolizedProfile { ...@@ -1136,8 +1167,21 @@ sub PrintSymbolizedProfile {
} }
print '---', "\n"; print '---', "\n";
$PROFILE_PAGE =~ m,[^/]+$,; # matches everything after the last slash my $profile_marker;
my $profile_marker = $&; if ($main::profile_type eq 'heap') {
$HEAP_PAGE =~ m,[^/]+$,; # matches everything after the last slash
$profile_marker = $&;
} elsif ($main::profile_type eq 'growth') {
$GROWTH_PAGE =~ m,[^/]+$,; # matches everything after the last slash
$profile_marker = $&;
} elsif ($main::profile_type eq 'contention') {
$CONTENTION_PAGE =~ m,[^/]+$,; # matches everything after the last slash
$profile_marker = $&;
} else { # elsif ($main::profile_type eq 'cpu')
$PROFILE_PAGE =~ m,[^/]+$,; # matches everything after the last slash
$profile_marker = $&;
}
print '--- ', $profile_marker, "\n"; print '--- ', $profile_marker, "\n";
if (defined($main::collected_profile)) { if (defined($main::collected_profile)) {
# if used with remote fetch, simply dump the collected profile to output. # if used with remote fetch, simply dump the collected profile to output.
...@@ -1147,6 +1191,12 @@ sub PrintSymbolizedProfile { ...@@ -1147,6 +1191,12 @@ sub PrintSymbolizedProfile {
} }
close(SRC); close(SRC);
} else { } else {
# --raw/http: For everything to work correctly for non-remote profiles, we
# would need to extend PrintProfileData() to handle all possible profile
# types, re-enable the code that is currently disabled in ReadCPUProfile()
# and FixCallerAddresses(), and remove the remote profile dumping code in
# the block above.
die "--raw/http: jeprof can only dump remote profiles for --raw\n";
# dump a cpu-format profile to standard out # dump a cpu-format profile to standard out
PrintProfileData($profile); PrintProfileData($profile);
} }
...@@ -1476,7 +1526,7 @@ h1 { ...@@ -1476,7 +1526,7 @@ h1 {
} }
</style> </style>
<script type="text/javascript"> <script type="text/javascript">
function pprof_toggle_asm(e) { function jeprof_toggle_asm(e) {
var target; var target;
if (!e) e = window.event; if (!e) e = window.event;
if (e.target) target = e.target; if (e.target) target = e.target;
...@@ -1683,23 +1733,23 @@ sub PrintSource { ...@@ -1683,23 +1733,23 @@ sub PrintSource {
HtmlPrintNumber($c2), HtmlPrintNumber($c2),
UnparseAddress($offset, $e->[0]), UnparseAddress($offset, $e->[0]),
CleanDisassembly($e->[3])); CleanDisassembly($e->[3]));
# Append the most specific source line associated with this instruction # Append the most specific source line associated with this instruction
if (length($dis) < 80) { $dis .= (' ' x (80 - length($dis))) }; if (length($dis) < 80) { $dis .= (' ' x (80 - length($dis))) };
$dis = HtmlEscape($dis); $dis = HtmlEscape($dis);
my $f = $e->[5]; my $f = $e->[5];
my $l = $e->[6]; my $l = $e->[6];
if ($f ne $last_dis_filename) { if ($f ne $last_dis_filename) {
$dis .= sprintf("<span class=disasmloc>%s:%d</span>", $dis .= sprintf("<span class=disasmloc>%s:%d</span>",
HtmlEscape(CleanFileName($f)), $l); HtmlEscape(CleanFileName($f)), $l);
} elsif ($l ne $last_dis_linenum) { } elsif ($l ne $last_dis_linenum) {
# De-emphasize the unchanged file name portion # De-emphasize the unchanged file name portion
$dis .= sprintf("<span class=unimportant>%s</span>" . $dis .= sprintf("<span class=unimportant>%s</span>" .
"<span class=disasmloc>:%d</span>", "<span class=disasmloc>:%d</span>",
HtmlEscape(CleanFileName($f)), $l); HtmlEscape(CleanFileName($f)), $l);
} else { } else {
# De-emphasize the entire location # De-emphasize the entire location
$dis .= sprintf("<span class=unimportant>%s:%d</span>", $dis .= sprintf("<span class=unimportant>%s:%d</span>",
HtmlEscape(CleanFileName($f)), $l); HtmlEscape(CleanFileName($f)), $l);
} }
$last_dis_filename = $f; $last_dis_filename = $f;
...@@ -1745,7 +1795,7 @@ sub PrintSource { ...@@ -1745,7 +1795,7 @@ sub PrintSource {
if ($html) { if ($html) {
printf $output ( printf $output (
"<h1>%s</h1>%s\n<pre onClick=\"pprof_toggle_asm()\">\n" . "<h1>%s</h1>%s\n<pre onClick=\"jeprof_toggle_asm()\">\n" .
"Total:%6s %6s (flat / cumulative %s)\n", "Total:%6s %6s (flat / cumulative %s)\n",
HtmlEscape(ShortFunctionName($routine)), HtmlEscape(ShortFunctionName($routine)),
HtmlEscape(CleanFileName($filename)), HtmlEscape(CleanFileName($filename)),
...@@ -1788,8 +1838,8 @@ sub PrintSource { ...@@ -1788,8 +1838,8 @@ sub PrintSource {
if (defined($dis) && $dis ne '') { if (defined($dis) && $dis ne '') {
$asm = "<span class=\"asm\">" . $dis . "</span>"; $asm = "<span class=\"asm\">" . $dis . "</span>";
} }
my $source_class = (($n1 + $n2 > 0) my $source_class = (($n1 + $n2 > 0)
? "livesrc" ? "livesrc"
: (($asm ne "") ? "deadsrc" : "nop")); : (($asm ne "") ? "deadsrc" : "nop"));
printf $output ( printf $output (
"<span class=\"line\">%5d</span> " . "<span class=\"line\">%5d</span> " .
...@@ -2797,6 +2847,43 @@ sub ExtractCalls { ...@@ -2797,6 +2847,43 @@ sub ExtractCalls {
return $calls; return $calls;
} }
sub FilterFrames {
my $symbols = shift;
my $profile = shift;
if ($main::opt_retain eq '' && $main::opt_exclude eq '') {
return $profile;
}
my $result = {};
foreach my $k (keys(%{$profile})) {
my $count = $profile->{$k};
my @addrs = split(/\n/, $k);
my @path = ();
foreach my $a (@addrs) {
my $sym;
if (exists($symbols->{$a})) {
$sym = $symbols->{$a}->[0];
} else {
$sym = $a;
}
if ($main::opt_retain ne '' && $sym !~ m/$main::opt_retain/) {
next;
}
if ($main::opt_exclude ne '' && $sym =~ m/$main::opt_exclude/) {
next;
}
push(@path, $a);
}
if (scalar(@path) > 0) {
my $reduced_path = join("\n", @path);
AddEntry($result, $reduced_path, $count);
}
}
return $result;
}
sub RemoveUninterestingFrames { sub RemoveUninterestingFrames {
my $symbols = shift; my $symbols = shift;
my $profile = shift; my $profile = shift;
...@@ -2805,15 +2892,23 @@ sub RemoveUninterestingFrames { ...@@ -2805,15 +2892,23 @@ sub RemoveUninterestingFrames {
my %skip = (); my %skip = ();
my $skip_regexp = 'NOMATCH'; my $skip_regexp = 'NOMATCH';
if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') { if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
foreach my $name ('calloc', foreach my $name ('@JEMALLOC_PREFIX@calloc',
'cfree', 'cfree',
'malloc', '@JEMALLOC_PREFIX@malloc',
'free', 'newImpl',
'memalign', 'void* newImpl',
'posix_memalign', '@JEMALLOC_PREFIX@free',
'@JEMALLOC_PREFIX@memalign',
'@JEMALLOC_PREFIX@posix_memalign',
'@JEMALLOC_PREFIX@aligned_alloc',
'pvalloc', 'pvalloc',
'valloc', '@JEMALLOC_PREFIX@valloc',
'realloc', '@JEMALLOC_PREFIX@realloc',
'@JEMALLOC_PREFIX@mallocx',
'@JEMALLOC_PREFIX@rallocx',
'@JEMALLOC_PREFIX@xallocx',
'@JEMALLOC_PREFIX@dallocx',
'@JEMALLOC_PREFIX@sdallocx',
'tc_calloc', 'tc_calloc',
'tc_cfree', 'tc_cfree',
'tc_malloc', 'tc_malloc',
...@@ -2923,6 +3018,10 @@ sub RemoveUninterestingFrames { ...@@ -2923,6 +3018,10 @@ sub RemoveUninterestingFrames {
if (exists($symbols->{$a})) { if (exists($symbols->{$a})) {
my $func = $symbols->{$a}->[0]; my $func = $symbols->{$a}->[0];
if ($skip{$func} || ($func =~ m/$skip_regexp/)) { if ($skip{$func} || ($func =~ m/$skip_regexp/)) {
# Throw away the portion of the backtrace seen so far, under the
# assumption that previous frames were for functions internal to the
# allocator.
@path = ();
next; next;
} }
} }
...@@ -2931,6 +3030,9 @@ sub RemoveUninterestingFrames { ...@@ -2931,6 +3030,9 @@ sub RemoveUninterestingFrames {
my $reduced_path = join("\n", @path); my $reduced_path = join("\n", @path);
AddEntry($result, $reduced_path, $count); AddEntry($result, $reduced_path, $count);
} }
$result = FilterFrames($symbols, $result);
return $result; return $result;
} }
...@@ -3240,7 +3342,7 @@ sub ResolveRedirectionForCurl { ...@@ -3240,7 +3342,7 @@ sub ResolveRedirectionForCurl {
# Add a timeout flat to URL_FETCHER. Returns a new list. # Add a timeout flat to URL_FETCHER. Returns a new list.
sub AddFetchTimeout { sub AddFetchTimeout {
my $timeout = shift; my $timeout = shift;
my @fetcher = shift; my @fetcher = @_;
if (defined($timeout)) { if (defined($timeout)) {
if (join(" ", @fetcher) =~ m/\bcurl -s/) { if (join(" ", @fetcher) =~ m/\bcurl -s/) {
push(@fetcher, "--max-time", sprintf("%d", $timeout)); push(@fetcher, "--max-time", sprintf("%d", $timeout));
...@@ -3286,6 +3388,27 @@ sub ReadSymbols { ...@@ -3286,6 +3388,27 @@ sub ReadSymbols {
return $map; return $map;
} }
sub URLEncode {
my $str = shift;
$str =~ s/([^A-Za-z0-9\-_.!~*'()])/ sprintf "%%%02x", ord $1 /eg;
return $str;
}
sub AppendSymbolFilterParams {
my $url = shift;
my @params = ();
if ($main::opt_retain ne '') {
push(@params, sprintf("retain=%s", URLEncode($main::opt_retain)));
}
if ($main::opt_exclude ne '') {
push(@params, sprintf("exclude=%s", URLEncode($main::opt_exclude)));
}
if (scalar @params > 0) {
$url = sprintf("%s?%s", $url, join("&", @params));
}
return $url;
}
# Fetches and processes symbols to prepare them for use in the profile output # Fetches and processes symbols to prepare them for use in the profile output
# code. If the optional 'symbol_map' arg is not given, fetches symbols from # code. If the optional 'symbol_map' arg is not given, fetches symbols from
# $SYMBOL_PAGE for all PC values found in profile. Otherwise, the raw symbols # $SYMBOL_PAGE for all PC values found in profile. Otherwise, the raw symbols
...@@ -3310,9 +3433,11 @@ sub FetchSymbols { ...@@ -3310,9 +3433,11 @@ sub FetchSymbols {
my $command_line; my $command_line;
if (join(" ", @URL_FETCHER) =~ m/\bcurl -s/) { if (join(" ", @URL_FETCHER) =~ m/\bcurl -s/) {
$url = ResolveRedirectionForCurl($url); $url = ResolveRedirectionForCurl($url);
$url = AppendSymbolFilterParams($url);
$command_line = ShellEscape(@URL_FETCHER, "-d", "\@$main::tmpfile_sym", $command_line = ShellEscape(@URL_FETCHER, "-d", "\@$main::tmpfile_sym",
$url); $url);
} else { } else {
$url = AppendSymbolFilterParams($url);
$command_line = (ShellEscape(@URL_FETCHER, "--post", $url) $command_line = (ShellEscape(@URL_FETCHER, "--post", $url)
. " < " . ShellEscape($main::tmpfile_sym)); . " < " . ShellEscape($main::tmpfile_sym));
} }
...@@ -3393,15 +3518,25 @@ sub FetchDynamicProfile { ...@@ -3393,15 +3518,25 @@ sub FetchDynamicProfile {
} }
$url .= sprintf("seconds=%d", $main::opt_seconds); $url .= sprintf("seconds=%d", $main::opt_seconds);
$fetch_timeout = $main::opt_seconds * 1.01 + 60; $fetch_timeout = $main::opt_seconds * 1.01 + 60;
# Set $profile_type for consumption by PrintSymbolizedProfile.
$main::profile_type = 'cpu';
} else { } else {
# For non-CPU profiles, we add a type-extension to # For non-CPU profiles, we add a type-extension to
# the target profile file name. # the target profile file name.
my $suffix = $path; my $suffix = $path;
$suffix =~ s,/,.,g; $suffix =~ s,/,.,g;
$profile_file .= $suffix; $profile_file .= $suffix;
# Set $profile_type for consumption by PrintSymbolizedProfile.
if ($path =~ m/$HEAP_PAGE/) {
$main::profile_type = 'heap';
} elsif ($path =~ m/$GROWTH_PAGE/) {
$main::profile_type = 'growth';
} elsif ($path =~ m/$CONTENTION_PAGE/) {
$main::profile_type = 'contention';
}
} }
my $profile_dir = $ENV{"PPROF_TMPDIR"} || ($ENV{HOME} . "/pprof"); my $profile_dir = $ENV{"JEPROF_TMPDIR"} || ($ENV{HOME} . "/jeprof");
if (! -d $profile_dir) { if (! -d $profile_dir) {
mkdir($profile_dir) mkdir($profile_dir)
|| die("Unable to create profile directory $profile_dir: $!\n"); || die("Unable to create profile directory $profile_dir: $!\n");
...@@ -3617,7 +3752,7 @@ BEGIN { ...@@ -3617,7 +3752,7 @@ BEGIN {
# Reads the top, 'header' section of a profile, and returns the last # Reads the top, 'header' section of a profile, and returns the last
# line of the header, commonly called a 'header line'. The header # line of the header, commonly called a 'header line'. The header
# section of a profile consists of zero or more 'command' lines that # section of a profile consists of zero or more 'command' lines that
# are instructions to pprof, which pprof executes when reading the # are instructions to jeprof, which jeprof executes when reading the
# header. All 'command' lines start with a %. After the command # header. All 'command' lines start with a %. After the command
# lines is the 'header line', which is a profile-specific line that # lines is the 'header line', which is a profile-specific line that
# indicates what type of profile it is, and perhaps other global # indicates what type of profile it is, and perhaps other global
...@@ -3680,6 +3815,7 @@ sub IsSymbolizedProfileFile { ...@@ -3680,6 +3815,7 @@ sub IsSymbolizedProfileFile {
# $result->{version} Version number of profile file # $result->{version} Version number of profile file
# $result->{period} Sampling period (in microseconds) # $result->{period} Sampling period (in microseconds)
# $result->{profile} Profile object # $result->{profile} Profile object
# $result->{threads} Map of thread IDs to profile objects
# $result->{map} Memory map info from profile # $result->{map} Memory map info from profile
# $result->{pcs} Hash of all PC values seen, key is hex address # $result->{pcs} Hash of all PC values seen, key is hex address
sub ReadProfile { sub ReadProfile {
...@@ -3695,6 +3831,8 @@ sub ReadProfile { ...@@ -3695,6 +3831,8 @@ sub ReadProfile {
my $symbol_marker = $&; my $symbol_marker = $&;
$PROFILE_PAGE =~ m,[^/]+$,; # matches everything after the last slash $PROFILE_PAGE =~ m,[^/]+$,; # matches everything after the last slash
my $profile_marker = $&; my $profile_marker = $&;
$HEAP_PAGE =~ m,[^/]+$,; # matches everything after the last slash
my $heap_marker = $&;
# Look at first line to see if it is a heap or a CPU profile. # Look at first line to see if it is a heap or a CPU profile.
# CPU profile may start with no header at all, and just binary data # CPU profile may start with no header at all, and just binary data
...@@ -3721,13 +3859,22 @@ sub ReadProfile { ...@@ -3721,13 +3859,22 @@ sub ReadProfile {
$header = ReadProfileHeader(*PROFILE) || ""; $header = ReadProfileHeader(*PROFILE) || "";
} }
if ($header =~ m/^--- *($heap_marker|$growth_marker)/o) {
# Skip "--- ..." line for profile types that have their own headers.
$header = ReadProfileHeader(*PROFILE) || "";
}
$main::profile_type = ''; $main::profile_type = '';
if ($header =~ m/^heap profile:.*$growth_marker/o) { if ($header =~ m/^heap profile:.*$growth_marker/o) {
$main::profile_type = 'growth'; $main::profile_type = 'growth';
$result = ReadHeapProfile($prog, *PROFILE, $header); $result = ReadHeapProfile($prog, *PROFILE, $header);
} elsif ($header =~ m/^heap profile:/) { } elsif ($header =~ m/^heap profile:/) {
$main::profile_type = 'heap'; $main::profile_type = 'heap';
$result = ReadHeapProfile($prog, *PROFILE, $header); $result = ReadHeapProfile($prog, *PROFILE, $header);
} elsif ($header =~ m/^heap/) {
$main::profile_type = 'heap';
$result = ReadThreadedHeapProfile($prog, $fname, $header);
} elsif ($header =~ m/^--- *$contention_marker/o) { } elsif ($header =~ m/^--- *$contention_marker/o) {
$main::profile_type = 'contention'; $main::profile_type = 'contention';
$result = ReadSynchProfile($prog, *PROFILE); $result = ReadSynchProfile($prog, *PROFILE);
...@@ -3770,9 +3917,9 @@ sub ReadProfile { ...@@ -3770,9 +3917,9 @@ sub ReadProfile {
# independent implementation. # independent implementation.
sub FixCallerAddresses { sub FixCallerAddresses {
my $stack = shift; my $stack = shift;
if ($main::use_symbolized_profile) { # --raw/http: Always subtract one from pc's, because PrintSymbolizedProfile()
return $stack; # dumps unadjusted profiles.
} else { {
$stack =~ /(\s)/; $stack =~ /(\s)/;
my $delimiter = $1; my $delimiter = $1;
my @addrs = split(' ', $stack); my @addrs = split(' ', $stack);
...@@ -3840,12 +3987,7 @@ sub ReadCPUProfile { ...@@ -3840,12 +3987,7 @@ sub ReadCPUProfile {
for (my $j = 0; $j < $d; $j++) { for (my $j = 0; $j < $d; $j++) {
my $pc = $slots->get($i+$j); my $pc = $slots->get($i+$j);
# Subtract one from caller pc so we map back to call instr. # Subtract one from caller pc so we map back to call instr.
# However, don't do this if we're reading a symbolized profile $pc--;
# file, in which case the subtract-one was done when the file
# was written.
if ($j > 0 && !$main::use_symbolized_profile) {
$pc--;
}
$pc = sprintf("%0*x", $address_length, $pc); $pc = sprintf("%0*x", $address_length, $pc);
$pcs->{$pc} = 1; $pcs->{$pc} = 1;
push @k, $pc; push @k, $pc;
...@@ -3870,11 +4012,7 @@ sub ReadCPUProfile { ...@@ -3870,11 +4012,7 @@ sub ReadCPUProfile {
return $r; return $r;
} }
sub ReadHeapProfile { sub HeapProfileIndex {
my $prog = shift;
local *PROFILE = shift;
my $header = shift;
my $index = 1; my $index = 1;
if ($main::opt_inuse_space) { if ($main::opt_inuse_space) {
$index = 1; $index = 1;
...@@ -3885,6 +4023,84 @@ sub ReadHeapProfile { ...@@ -3885,6 +4023,84 @@ sub ReadHeapProfile {
} elsif ($main::opt_alloc_objects) { } elsif ($main::opt_alloc_objects) {
$index = 2; $index = 2;
} }
return $index;
}
sub ReadMappedLibraries {
my $fh = shift;
my $map = "";
# Read the /proc/self/maps data
while (<$fh>) {
s/\r//g; # turn windows-looking lines into unix-looking lines
$map .= $_;
}
return $map;
}
sub ReadMemoryMap {
my $fh = shift;
my $map = "";
# Read /proc/self/maps data as formatted by DumpAddressMap()
my $buildvar = "";
while (<PROFILE>) {
s/\r//g; # turn windows-looking lines into unix-looking lines
# Parse "build=<dir>" specification if supplied
if (m/^\s*build=(.*)\n/) {
$buildvar = $1;
}
# Expand "$build" variable if available
$_ =~ s/\$build\b/$buildvar/g;
$map .= $_;
}
return $map;
}
sub AdjustSamples {
my ($sample_adjustment, $sampling_algorithm, $n1, $s1, $n2, $s2) = @_;
if ($sample_adjustment) {
if ($sampling_algorithm == 2) {
# Remote-heap version 2
# The sampling frequency is the rate of a Poisson process.
# This means that the probability of sampling an allocation of
# size X with sampling rate Y is 1 - exp(-X/Y)
if ($n1 != 0) {
my $ratio = (($s1*1.0)/$n1)/($sample_adjustment);
my $scale_factor = 1/(1 - exp(-$ratio));
$n1 *= $scale_factor;
$s1 *= $scale_factor;
}
if ($n2 != 0) {
my $ratio = (($s2*1.0)/$n2)/($sample_adjustment);
my $scale_factor = 1/(1 - exp(-$ratio));
$n2 *= $scale_factor;
$s2 *= $scale_factor;
}
} else {
# Remote-heap version 1
my $ratio;
$ratio = (($s1*1.0)/$n1)/($sample_adjustment);
if ($ratio < 1) {
$n1 /= $ratio;
$s1 /= $ratio;
}
$ratio = (($s2*1.0)/$n2)/($sample_adjustment);
if ($ratio < 1) {
$n2 /= $ratio;
$s2 /= $ratio;
}
}
}
return ($n1, $s1, $n2, $s2);
}
sub ReadHeapProfile {
my $prog = shift;
local *PROFILE = shift;
my $header = shift;
my $index = HeapProfileIndex();
# Find the type of this profile. The header line looks like: # Find the type of this profile. The header line looks like:
# heap profile: 1246: 8800744 [ 1246: 8800744] @ <heap-url>/266053 # heap profile: 1246: 8800744 [ 1246: 8800744] @ <heap-url>/266053
...@@ -3974,29 +4190,12 @@ sub ReadHeapProfile { ...@@ -3974,29 +4190,12 @@ sub ReadHeapProfile {
while (<PROFILE>) { while (<PROFILE>) {
s/\r//g; # turn windows-looking lines into unix-looking lines s/\r//g; # turn windows-looking lines into unix-looking lines
if (/^MAPPED_LIBRARIES:/) { if (/^MAPPED_LIBRARIES:/) {
# Read the /proc/self/maps data $map .= ReadMappedLibraries(*PROFILE);
while (<PROFILE>) {
s/\r//g; # turn windows-looking lines into unix-looking lines
$map .= $_;
}
last; last;
} }
if (/^--- Memory map:/) { if (/^--- Memory map:/) {
# Read /proc/self/maps data as formatted by DumpAddressMap() $map .= ReadMemoryMap(*PROFILE);
my $buildvar = "";
while (<PROFILE>) {
s/\r//g; # turn windows-looking lines into unix-looking lines
# Parse "build=<dir>" specification if supplied
if (m/^\s*build=(.*)\n/) {
$buildvar = $1;
}
# Expand "$build" variable if available
$_ =~ s/\$build\b/$buildvar/g;
$map .= $_;
}
last; last;
} }
...@@ -4007,43 +4206,85 @@ sub ReadHeapProfile { ...@@ -4007,43 +4206,85 @@ sub ReadHeapProfile {
if (m/^\s*(\d+):\s+(\d+)\s+\[\s*(\d+):\s+(\d+)\]\s+@\s+(.*)$/) { if (m/^\s*(\d+):\s+(\d+)\s+\[\s*(\d+):\s+(\d+)\]\s+@\s+(.*)$/) {
my $stack = $5; my $stack = $5;
my ($n1, $s1, $n2, $s2) = ($1, $2, $3, $4); my ($n1, $s1, $n2, $s2) = ($1, $2, $3, $4);
my @counts = AdjustSamples($sample_adjustment, $sampling_algorithm,
$n1, $s1, $n2, $s2);
AddEntries($profile, $pcs, FixCallerAddresses($stack), $counts[$index]);
}
}
if ($sample_adjustment) { my $r = {};
if ($sampling_algorithm == 2) { $r->{version} = "heap";
# Remote-heap version 2 $r->{period} = 1;
# The sampling frequency is the rate of a Poisson process. $r->{profile} = $profile;
# This means that the probability of sampling an allocation of $r->{libs} = ParseLibraries($prog, $map, $pcs);
# size X with sampling rate Y is 1 - exp(-X/Y) $r->{pcs} = $pcs;
if ($n1 != 0) { return $r;
my $ratio = (($s1*1.0)/$n1)/($sample_adjustment); }
my $scale_factor = 1/(1 - exp(-$ratio));
$n1 *= $scale_factor; sub ReadThreadedHeapProfile {
$s1 *= $scale_factor; my ($prog, $fname, $header) = @_;
}
if ($n2 != 0) { my $index = HeapProfileIndex();
my $ratio = (($s2*1.0)/$n2)/($sample_adjustment); my $sampling_algorithm = 0;
my $scale_factor = 1/(1 - exp(-$ratio)); my $sample_adjustment = 0;
$n2 *= $scale_factor; chomp($header);
$s2 *= $scale_factor; my $type = "unknown";
} # Assuming a very specific type of header for now.
} else { if ($header =~ m"^heap_v2/(\d+)") {
# Remote-heap version 1 $type = "_v2";
my $ratio; $sampling_algorithm = 2;
$ratio = (($s1*1.0)/$n1)/($sample_adjustment); $sample_adjustment = int($1);
if ($ratio < 1) { }
$n1 /= $ratio; if ($type ne "_v2" || !defined($sample_adjustment)) {
$s1 /= $ratio; die "Threaded heap profiles require v2 sampling with a sample rate\n";
} }
$ratio = (($s2*1.0)/$n2)/($sample_adjustment);
if ($ratio < 1) { my $profile = {};
$n2 /= $ratio; my $thread_profiles = {};
$s2 /= $ratio; my $pcs = {};
} my $map = "";
my $stack = "";
while (<PROFILE>) {
s/\r//g;
if (/^MAPPED_LIBRARIES:/) {
$map .= ReadMappedLibraries(*PROFILE);
last;
}
if (/^--- Memory map:/) {
$map .= ReadMemoryMap(*PROFILE);
last;
}
# Read entry of the form:
# @ a1 a2 ... an
# t*: <count1>: <bytes1> [<count2>: <bytes2>]
# t1: <count1>: <bytes1> [<count2>: <bytes2>]
# ...
# tn: <count1>: <bytes1> [<count2>: <bytes2>]
s/^\s*//;
s/\s*$//;
if (m/^@\s+(.*)$/) {
$stack = $1;
} elsif (m/^\s*(t(\*|\d+)):\s+(\d+):\s+(\d+)\s+\[\s*(\d+):\s+(\d+)\]$/) {
if ($stack eq "") {
# Still in the header, so this is just a per-thread summary.
next;
}
my $thread = $2;
my ($n1, $s1, $n2, $s2) = ($3, $4, $5, $6);
my @counts = AdjustSamples($sample_adjustment, $sampling_algorithm,
$n1, $s1, $n2, $s2);
if ($thread eq "*") {
AddEntries($profile, $pcs, FixCallerAddresses($stack), $counts[$index]);
} else {
if (!exists($thread_profiles->{$thread})) {
$thread_profiles->{$thread} = {};
} }
AddEntries($thread_profiles->{$thread}, $pcs,
FixCallerAddresses($stack), $counts[$index]);
} }
my @counts = ($n1, $s1, $n2, $s2);
AddEntries($profile, $pcs, FixCallerAddresses($stack), $counts[$index]);
} }
} }
...@@ -4051,6 +4292,7 @@ sub ReadHeapProfile { ...@@ -4051,6 +4292,7 @@ sub ReadHeapProfile {
$r->{version} = "heap"; $r->{version} = "heap";
$r->{period} = 1; $r->{period} = 1;
$r->{profile} = $profile; $r->{profile} = $profile;
$r->{threads} = $thread_profiles;
$r->{libs} = ParseLibraries($prog, $map, $pcs); $r->{libs} = ParseLibraries($prog, $map, $pcs);
$r->{pcs} = $pcs; $r->{pcs} = $pcs;
return $r; return $r;
...@@ -4120,10 +4362,10 @@ sub ReadSynchProfile { ...@@ -4120,10 +4362,10 @@ sub ReadSynchProfile {
} elsif ($variable eq "sampling period") { } elsif ($variable eq "sampling period") {
$sampling_period = $value; $sampling_period = $value;
} elsif ($variable eq "ms since reset") { } elsif ($variable eq "ms since reset") {
# Currently nothing is done with this value in pprof # Currently nothing is done with this value in jeprof
# So we just silently ignore it for now # So we just silently ignore it for now
} elsif ($variable eq "discarded samples") { } elsif ($variable eq "discarded samples") {
# Currently nothing is done with this value in pprof # Currently nothing is done with this value in jeprof
# So we just silently ignore it for now # So we just silently ignore it for now
} else { } else {
printf STDERR ("Ignoring unnknown variable in /contention output: " . printf STDERR ("Ignoring unnknown variable in /contention output: " .
...@@ -4331,7 +4573,7 @@ sub ParseTextSectionHeader { ...@@ -4331,7 +4573,7 @@ sub ParseTextSectionHeader {
# Split /proc/pid/maps dump into a list of libraries # Split /proc/pid/maps dump into a list of libraries
sub ParseLibraries { sub ParseLibraries {
return if $main::use_symbol_page; # We don't need libraries info. return if $main::use_symbol_page; # We don't need libraries info.
my $prog = shift; my $prog = Cwd::abs_path(shift);
my $map = shift; my $map = shift;
my $pcs = shift; my $pcs = shift;
...@@ -4364,6 +4606,16 @@ sub ParseLibraries { ...@@ -4364,6 +4606,16 @@ sub ParseLibraries {
$finish = HexExtend($2); $finish = HexExtend($2);
$offset = $zero_offset; $offset = $zero_offset;
$lib = $3; $lib = $3;
} elsif (($l =~ /^($h)-($h)\s+..x.\s+($h)\s+\S+:\S+\s+\d+\s+(\S+)$/i) && ($4 eq $prog)) {
# PIEs and address space randomization do not play well with our
# default assumption that main executable is at lowest
# addresses. So we're detecting main executable in
# /proc/self/maps as well.
$start = HexExtend($1);
$finish = HexExtend($2);
$offset = HexExtend($3);
$lib = $4;
$lib =~ s|\\|/|g; # turn windows-style paths into unix-style paths
} }
# FreeBSD 10.0 virtual memory map /proc/curproc/map as defined in # FreeBSD 10.0 virtual memory map /proc/curproc/map as defined in
# function procfs_doprocmap (sys/fs/procfs/procfs_map.c) # function procfs_doprocmap (sys/fs/procfs/procfs_map.c)
...@@ -4429,7 +4681,7 @@ sub ParseLibraries { ...@@ -4429,7 +4681,7 @@ sub ParseLibraries {
} }
# Add two hex addresses of length $address_length. # Add two hex addresses of length $address_length.
# Run pprof --test for unit test if this is changed. # Run jeprof --test for unit test if this is changed.
sub AddressAdd { sub AddressAdd {
my $addr1 = shift; my $addr1 = shift;
my $addr2 = shift; my $addr2 = shift;
...@@ -4483,7 +4735,7 @@ sub AddressAdd { ...@@ -4483,7 +4735,7 @@ sub AddressAdd {
# Subtract two hex addresses of length $address_length. # Subtract two hex addresses of length $address_length.
# Run pprof --test for unit test if this is changed. # Run jeprof --test for unit test if this is changed.
sub AddressSub { sub AddressSub {
my $addr1 = shift; my $addr1 = shift;
my $addr2 = shift; my $addr2 = shift;
...@@ -4535,7 +4787,7 @@ sub AddressSub { ...@@ -4535,7 +4787,7 @@ sub AddressSub {
} }
# Increment a hex addresses of length $address_length. # Increment a hex addresses of length $address_length.
# Run pprof --test for unit test if this is changed. # Run jeprof --test for unit test if this is changed.
sub AddressInc { sub AddressInc {
my $addr = shift; my $addr = shift;
my $sum; my $sum;
...@@ -4747,7 +4999,7 @@ sub MapToSymbols { ...@@ -4747,7 +4999,7 @@ sub MapToSymbols {
} }
} }
} }
# Prepend to accumulated symbols for pcstr # Prepend to accumulated symbols for pcstr
# (so that caller comes before callee) # (so that caller comes before callee)
my $sym = $symbols->{$pcstr}; my $sym = $symbols->{$pcstr};
...@@ -4853,7 +5105,7 @@ sub UnparseAddress { ...@@ -4853,7 +5105,7 @@ sub UnparseAddress {
# 32-bit or ELF 64-bit executable file. The location of the tools # 32-bit or ELF 64-bit executable file. The location of the tools
# is determined by considering the following options in this order: # is determined by considering the following options in this order:
# 1) --tools option, if set # 1) --tools option, if set
# 2) PPROF_TOOLS environment variable, if set # 2) JEPROF_TOOLS environment variable, if set
# 3) the environment # 3) the environment
sub ConfigureObjTools { sub ConfigureObjTools {
my $prog_file = shift; my $prog_file = shift;
...@@ -4886,7 +5138,7 @@ sub ConfigureObjTools { ...@@ -4886,7 +5138,7 @@ sub ConfigureObjTools {
# For windows, we provide a version of nm and addr2line as part of # For windows, we provide a version of nm and addr2line as part of
# the opensource release, which is capable of parsing # the opensource release, which is capable of parsing
# Windows-style PDB executables. It should live in the path, or # Windows-style PDB executables. It should live in the path, or
# in the same directory as pprof. # in the same directory as jeprof.
$obj_tool_map{"nm_pdb"} = "nm-pdb"; $obj_tool_map{"nm_pdb"} = "nm-pdb";
$obj_tool_map{"addr2line_pdb"} = "addr2line-pdb"; $obj_tool_map{"addr2line_pdb"} = "addr2line-pdb";
} }
...@@ -4905,20 +5157,20 @@ sub ConfigureObjTools { ...@@ -4905,20 +5157,20 @@ sub ConfigureObjTools {
} }
# Returns the path of a caller-specified object tool. If --tools or # Returns the path of a caller-specified object tool. If --tools or
# PPROF_TOOLS are specified, then returns the full path to the tool # JEPROF_TOOLS are specified, then returns the full path to the tool
# with that prefix. Otherwise, returns the path unmodified (which # with that prefix. Otherwise, returns the path unmodified (which
# means we will look for it on PATH). # means we will look for it on PATH).
sub ConfigureTool { sub ConfigureTool {
my $tool = shift; my $tool = shift;
my $path; my $path;
# --tools (or $PPROF_TOOLS) is a comma separated list, where each # --tools (or $JEPROF_TOOLS) is a comma separated list, where each
# item is either a) a pathname prefix, or b) a map of the form # item is either a) a pathname prefix, or b) a map of the form
# <tool>:<path>. First we look for an entry of type (b) for our # <tool>:<path>. First we look for an entry of type (b) for our
# tool. If one is found, we use it. Otherwise, we consider all the # tool. If one is found, we use it. Otherwise, we consider all the
# pathname prefixes in turn, until one yields an existing file. If # pathname prefixes in turn, until one yields an existing file. If
# none does, we use a default path. # none does, we use a default path.
my $tools = $main::opt_tools || $ENV{"PPROF_TOOLS"} || ""; my $tools = $main::opt_tools || $ENV{"JEPROF_TOOLS"} || "";
if ($tools =~ m/(,|^)\Q$tool\E:([^,]*)/) { if ($tools =~ m/(,|^)\Q$tool\E:([^,]*)/) {
$path = $2; $path = $2;
# TODO(csilvers): sanity-check that $path exists? Hard if it's relative. # TODO(csilvers): sanity-check that $path exists? Hard if it's relative.
...@@ -4932,16 +5184,16 @@ sub ConfigureTool { ...@@ -4932,16 +5184,16 @@ sub ConfigureTool {
} }
if (!$path) { if (!$path) {
error("No '$tool' found with prefix specified by " . error("No '$tool' found with prefix specified by " .
"--tools (or \$PPROF_TOOLS) '$tools'\n"); "--tools (or \$JEPROF_TOOLS) '$tools'\n");
} }
} else { } else {
# ... otherwise use the version that exists in the same directory as # ... otherwise use the version that exists in the same directory as
# pprof. If there's nothing there, use $PATH. # jeprof. If there's nothing there, use $PATH.
$0 =~ m,[^/]*$,; # this is everything after the last slash $0 =~ m,[^/]*$,; # this is everything after the last slash
my $dirname = $`; # this is everything up to and including the last slash my $dirname = $`; # this is everything up to and including the last slash
if (-x "$dirname$tool") { if (-x "$dirname$tool") {
$path = "$dirname$tool"; $path = "$dirname$tool";
} else { } else {
$path = $tool; $path = $tool;
} }
} }
...@@ -4966,7 +5218,7 @@ sub cleanup { ...@@ -4966,7 +5218,7 @@ sub cleanup {
unlink($main::tmpfile_sym); unlink($main::tmpfile_sym);
unlink(keys %main::tempnames); unlink(keys %main::tempnames);
# We leave any collected profiles in $HOME/pprof in case the user wants # We leave any collected profiles in $HOME/jeprof in case the user wants
# to look at them later. We print a message informing them of this. # to look at them later. We print a message informing them of this.
if ((scalar(@main::profile_files) > 0) && if ((scalar(@main::profile_files) > 0) &&
defined($main::collected_profile)) { defined($main::collected_profile)) {
...@@ -4975,7 +5227,7 @@ sub cleanup { ...@@ -4975,7 +5227,7 @@ sub cleanup {
} }
print STDERR "If you want to investigate this profile further, you can do:\n"; print STDERR "If you want to investigate this profile further, you can do:\n";
print STDERR "\n"; print STDERR "\n";
print STDERR " pprof \\\n"; print STDERR " jeprof \\\n";
print STDERR " $main::prog \\\n"; print STDERR " $main::prog \\\n";
print STDERR " $main::collected_profile\n"; print STDERR " $main::collected_profile\n";
print STDERR "\n"; print STDERR "\n";
...@@ -5160,7 +5412,7 @@ sub GetProcedureBoundaries { ...@@ -5160,7 +5412,7 @@ sub GetProcedureBoundaries {
# The test vectors for AddressAdd/Sub/Inc are 8-16-nibble hex strings. # The test vectors for AddressAdd/Sub/Inc are 8-16-nibble hex strings.
# To make them more readable, we add underscores at interesting places. # To make them more readable, we add underscores at interesting places.
# This routine removes the underscores, producing the canonical representation # This routine removes the underscores, producing the canonical representation
# used by pprof to represent addresses, particularly in the tested routines. # used by jeprof to represent addresses, particularly in the tested routines.
sub CanonicalHex { sub CanonicalHex {
my $arg = shift; my $arg = shift;
return join '', (split '_',$arg); return join '', (split '_',$arg);
......
#! /bin/sh #! /bin/sh
# Attempt to guess a canonical system name. # Attempt to guess a canonical system name.
# Copyright 1992-2013 Free Software Foundation, Inc. # Copyright 1992-2016 Free Software Foundation, Inc.
timestamp='2013-06-10' timestamp='2016-10-02'
# This file is free software; you can redistribute it and/or modify it # This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by # under the terms of the GNU General Public License as published by
...@@ -24,12 +24,12 @@ timestamp='2013-06-10' ...@@ -24,12 +24,12 @@ timestamp='2013-06-10'
# program. This Exception is an additional permission under section 7 # program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3"). # of the GNU General Public License, version 3 ("GPLv3").
# #
# Originally written by Per Bothner. # Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
# #
# You can get the latest version of this script from: # You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
# #
# Please send patches with a ChangeLog entry to config-patches@gnu.org. # Please send patches to <config-patches@gnu.org>.
me=`echo "$0" | sed -e 's,.*/,,'` me=`echo "$0" | sed -e 's,.*/,,'`
...@@ -50,7 +50,7 @@ version="\ ...@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp) GNU config.guess ($timestamp)
Originally written by Per Bothner. Originally written by Per Bothner.
Copyright 1992-2013 Free Software Foundation, Inc. Copyright 1992-2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
...@@ -149,7 +149,7 @@ Linux|GNU|GNU/*) ...@@ -149,7 +149,7 @@ Linux|GNU|GNU/*)
LIBC=gnu LIBC=gnu
#endif #endif
EOF EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
;; ;;
esac esac
...@@ -168,19 +168,29 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ...@@ -168,19 +168,29 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# Note: NetBSD doesn't particularly care about the vendor # Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown". # portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch" sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || echo unknown)` /sbin/$sysctl 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || \
echo unknown)`
case "${UNAME_MACHINE_ARCH}" in case "${UNAME_MACHINE_ARCH}" in
armeb) machine=armeb-unknown ;; armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;; arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;; sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;; sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;; sh5el) machine=sh5le-unknown ;;
earmv*)
arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
machine=${arch}${endian}-unknown
;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac esac
# The Operating System including object format, if it has switched # The Operating System including object format, if it has switched
# to ELF recently, or will in the future. # to ELF recently (or will in the future) and ABI.
case "${UNAME_MACHINE_ARCH}" in case "${UNAME_MACHINE_ARCH}" in
earm*)
os=netbsdelf
;;
arm*|i386|m68k|ns32k|sh3*|sparc|vax) arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
...@@ -197,6 +207,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ...@@ -197,6 +207,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
os=netbsd os=netbsd
;; ;;
esac esac
# Determine ABI tags.
case "${UNAME_MACHINE_ARCH}" in
earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
;;
esac
# The OS release # The OS release
# Debian GNU/NetBSD machines have a different userland, and # Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need # thus, need a distinct triplet. However, they do not need
...@@ -207,13 +224,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ...@@ -207,13 +224,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
release='-gnu' release='-gnu'
;; ;;
*) *)
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
;; ;;
esac esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form: # contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}" echo "${machine}-${os}${release}${abi}"
exit ;; exit ;;
*:Bitrig:*:*) *:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
...@@ -223,6 +240,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ...@@ -223,6 +240,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
exit ;; exit ;;
*:LibertyBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
exit ;;
*:ekkoBSD:*:*) *:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;; exit ;;
...@@ -235,6 +256,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ...@@ -235,6 +256,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:MirBSD:*:*) *:MirBSD:*:*)
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
exit ;; exit ;;
*:Sortix:*:*)
echo ${UNAME_MACHINE}-unknown-sortix
exit ;;
alpha:OSF1:*:*) alpha:OSF1:*:*)
case $UNAME_RELEASE in case $UNAME_RELEASE in
*4.0) *4.0)
...@@ -251,42 +275,42 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ...@@ -251,42 +275,42 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case "$ALPHA_CPU_TYPE" in case "$ALPHA_CPU_TYPE" in
"EV4 (21064)") "EV4 (21064)")
UNAME_MACHINE="alpha" ;; UNAME_MACHINE=alpha ;;
"EV4.5 (21064)") "EV4.5 (21064)")
UNAME_MACHINE="alpha" ;; UNAME_MACHINE=alpha ;;
"LCA4 (21066/21068)") "LCA4 (21066/21068)")
UNAME_MACHINE="alpha" ;; UNAME_MACHINE=alpha ;;
"EV5 (21164)") "EV5 (21164)")
UNAME_MACHINE="alphaev5" ;; UNAME_MACHINE=alphaev5 ;;
"EV5.6 (21164A)") "EV5.6 (21164A)")
UNAME_MACHINE="alphaev56" ;; UNAME_MACHINE=alphaev56 ;;
"EV5.6 (21164PC)") "EV5.6 (21164PC)")
UNAME_MACHINE="alphapca56" ;; UNAME_MACHINE=alphapca56 ;;
"EV5.7 (21164PC)") "EV5.7 (21164PC)")
UNAME_MACHINE="alphapca57" ;; UNAME_MACHINE=alphapca57 ;;
"EV6 (21264)") "EV6 (21264)")
UNAME_MACHINE="alphaev6" ;; UNAME_MACHINE=alphaev6 ;;
"EV6.7 (21264A)") "EV6.7 (21264A)")
UNAME_MACHINE="alphaev67" ;; UNAME_MACHINE=alphaev67 ;;
"EV6.8CB (21264C)") "EV6.8CB (21264C)")
UNAME_MACHINE="alphaev68" ;; UNAME_MACHINE=alphaev68 ;;
"EV6.8AL (21264B)") "EV6.8AL (21264B)")
UNAME_MACHINE="alphaev68" ;; UNAME_MACHINE=alphaev68 ;;
"EV6.8CX (21264D)") "EV6.8CX (21264D)")
UNAME_MACHINE="alphaev68" ;; UNAME_MACHINE=alphaev68 ;;
"EV6.9A (21264/EV69A)") "EV6.9A (21264/EV69A)")
UNAME_MACHINE="alphaev69" ;; UNAME_MACHINE=alphaev69 ;;
"EV7 (21364)") "EV7 (21364)")
UNAME_MACHINE="alphaev7" ;; UNAME_MACHINE=alphaev7 ;;
"EV7.9 (21364A)") "EV7.9 (21364A)")
UNAME_MACHINE="alphaev79" ;; UNAME_MACHINE=alphaev79 ;;
esac esac
# A Pn.n version is a patched version. # A Pn.n version is a patched version.
# A Vn.n version is a released version. # A Vn.n version is a released version.
# A Tn.n version is a released field test version. # A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel. # A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r. # 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
# Reset EXIT trap before exiting to avoid spurious non-zero exit code. # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$? exitcode=$?
trap '' 0 trap '' 0
...@@ -359,16 +383,16 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ...@@ -359,16 +383,16 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
exit ;; exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
eval $set_cc_for_build eval $set_cc_for_build
SUN_ARCH="i386" SUN_ARCH=i386
# If there is a compiler, see if it is configured for 64-bit objects. # If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers. # This test works for both compilers.
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null grep IS_64BIT_ARCH >/dev/null
then then
SUN_ARCH="x86_64" SUN_ARCH=x86_64
fi fi
fi fi
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
...@@ -393,7 +417,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ...@@ -393,7 +417,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
exit ;; exit ;;
sun*:*:4.2BSD:*) sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
case "`/bin/arch`" in case "`/bin/arch`" in
sun3) sun3)
echo m68k-sun-sunos${UNAME_RELEASE} echo m68k-sun-sunos${UNAME_RELEASE}
...@@ -579,8 +603,9 @@ EOF ...@@ -579,8 +603,9 @@ EOF
else else
IBM_ARCH=powerpc IBM_ARCH=powerpc
fi fi
if [ -x /usr/bin/oslevel ] ; then if [ -x /usr/bin/lslpp ] ; then
IBM_REV=`/usr/bin/oslevel` IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi fi
...@@ -617,13 +642,13 @@ EOF ...@@ -617,13 +642,13 @@ EOF
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0 532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;; 32) HP_ARCH=hppa2.0n ;;
64) HP_ARCH="hppa2.0w" ;; 64) HP_ARCH=hppa2.0w ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
esac ;; esac ;;
esac esac
fi fi
...@@ -662,11 +687,11 @@ EOF ...@@ -662,11 +687,11 @@ EOF
exit (0); exit (0);
} }
EOF EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;; fi ;;
esac esac
if [ ${HP_ARCH} = "hppa2.0w" ] if [ ${HP_ARCH} = hppa2.0w ]
then then
eval $set_cc_for_build eval $set_cc_for_build
...@@ -679,12 +704,12 @@ EOF ...@@ -679,12 +704,12 @@ EOF
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
# => hppa64-hp-hpux11.23 # => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
grep -q __LP64__ grep -q __LP64__
then then
HP_ARCH="hppa2.0w" HP_ARCH=hppa2.0w
else else
HP_ARCH="hppa64" HP_ARCH=hppa64
fi fi
fi fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV} echo ${HP_ARCH}-hp-hpux${HPUX_REV}
...@@ -789,14 +814,14 @@ EOF ...@@ -789,14 +814,14 @@ EOF
echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;; exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;; exit ;;
5000:UNIX_System_V:4.*:*) 5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;; exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
...@@ -826,7 +851,7 @@ EOF ...@@ -826,7 +851,7 @@ EOF
*:MINGW*:*) *:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32 echo ${UNAME_MACHINE}-pc-mingw32
exit ;; exit ;;
i*:MSYS*:*) *:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys echo ${UNAME_MACHINE}-pc-msys
exit ;; exit ;;
i*:windows32*:*) i*:windows32*:*)
...@@ -878,7 +903,7 @@ EOF ...@@ -878,7 +903,7 @@ EOF
exit ;; exit ;;
*:GNU/*:*:*) *:GNU/*:*:*)
# other systems with GNU libc and userland # other systems with GNU libc and userland
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;; exit ;;
i*86:Minix:*:*) i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix echo ${UNAME_MACHINE}-pc-minix
...@@ -901,7 +926,7 @@ EOF ...@@ -901,7 +926,7 @@ EOF
EV68*) UNAME_MACHINE=alphaev68 ;; EV68*) UNAME_MACHINE=alphaev68 ;;
esac esac
objdump --private-headers /bin/sh | grep -q ld.so.1 objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
echo ${UNAME_MACHINE}-unknown-linux-${LIBC} echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;; exit ;;
arc:Linux:*:* | arceb:Linux:*:*) arc:Linux:*:* | arceb:Linux:*:*)
...@@ -932,6 +957,9 @@ EOF ...@@ -932,6 +957,9 @@ EOF
crisv32:Linux:*:*) crisv32:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-${LIBC} echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;; exit ;;
e2k:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
frv:Linux:*:*) frv:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC} echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;; exit ;;
...@@ -944,6 +972,9 @@ EOF ...@@ -944,6 +972,9 @@ EOF
ia64:Linux:*:*) ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC} echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;; exit ;;
k1om:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*) m32r*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC} echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;; exit ;;
...@@ -969,10 +1000,13 @@ EOF ...@@ -969,10 +1000,13 @@ EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;; ;;
or1k:Linux:*:*) mips64el:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC} echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;; exit ;;
or32:Linux:*:*) openrisc*:Linux:*:*)
echo or1k-unknown-linux-${LIBC}
exit ;;
or32:Linux:*:* | or1k*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC} echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;; exit ;;
padre:Linux:*:*) padre:Linux:*:*)
...@@ -1001,6 +1035,9 @@ EOF ...@@ -1001,6 +1035,9 @@ EOF
ppcle:Linux:*:*) ppcle:Linux:*:*)
echo powerpcle-unknown-linux-${LIBC} echo powerpcle-unknown-linux-${LIBC}
exit ;; exit ;;
riscv32:Linux:*:* | riscv64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*) s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux-${LIBC} echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;; exit ;;
...@@ -1020,7 +1057,7 @@ EOF ...@@ -1020,7 +1057,7 @@ EOF
echo ${UNAME_MACHINE}-dec-linux-${LIBC} echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;; exit ;;
x86_64:Linux:*:*) x86_64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC} echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;; exit ;;
xtensa*:Linux:*:*) xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC} echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
...@@ -1099,7 +1136,7 @@ EOF ...@@ -1099,7 +1136,7 @@ EOF
# uname -m prints for DJGPP always 'pc', but it prints nothing about # uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586. # the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub # Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configury will decide that # prints for the "djgpp" host, or else GDB configure will decide that
# this is a cross-build. # this is a cross-build.
echo i586-pc-msdosdjgpp echo i586-pc-msdosdjgpp
exit ;; exit ;;
...@@ -1248,6 +1285,9 @@ EOF ...@@ -1248,6 +1285,9 @@ EOF
SX-8R:SUPER-UX:*:*) SX-8R:SUPER-UX:*:*)
echo sx8r-nec-superux${UNAME_RELEASE} echo sx8r-nec-superux${UNAME_RELEASE}
exit ;; exit ;;
SX-ACE:SUPER-UX:*:*)
echo sxace-nec-superux${UNAME_RELEASE}
exit ;;
Power*:Rhapsody:*:*) Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE} echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;; exit ;;
...@@ -1260,22 +1300,32 @@ EOF ...@@ -1260,22 +1300,32 @@ EOF
if test "$UNAME_PROCESSOR" = unknown ; then if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc UNAME_PROCESSOR=powerpc
fi fi
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
grep IS_64BIT_ARCH >/dev/null (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
then grep IS_64BIT_ARCH >/dev/null
case $UNAME_PROCESSOR in then
i386) UNAME_PROCESSOR=x86_64 ;; case $UNAME_PROCESSOR in
powerpc) UNAME_PROCESSOR=powerpc64 ;; i386) UNAME_PROCESSOR=x86_64 ;;
esac powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
fi fi
elif test "$UNAME_PROCESSOR" = i386 ; then
# Avoid executing cc on OS X 10.9, as it ships with a stub
# that puts up a graphical alert prompting to install
# developer tools. Any system running Mac OS X 10.7 or
# later (Darwin 11 and later) is required to have a 64-bit
# processor. This is not true of the ARM version of Darwin
# that Apple uses in portable devices.
UNAME_PROCESSOR=x86_64
fi fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;; exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*) *:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p` UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = "x86"; then if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386 UNAME_PROCESSOR=i386
UNAME_MACHINE=pc UNAME_MACHINE=pc
fi fi
...@@ -1306,7 +1356,7 @@ EOF ...@@ -1306,7 +1356,7 @@ EOF
# "uname -m" is not consistent, so use $cputype instead. 386 # "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86 # is converted to i386 for consistency with other x86
# operating systems. # operating systems.
if test "$cputype" = "386"; then if test "$cputype" = 386; then
UNAME_MACHINE=i386 UNAME_MACHINE=i386
else else
UNAME_MACHINE="$cputype" UNAME_MACHINE="$cputype"
...@@ -1348,7 +1398,7 @@ EOF ...@@ -1348,7 +1398,7 @@ EOF
echo i386-pc-xenix echo i386-pc-xenix
exit ;; exit ;;
i*86:skyos:*:*) i*86:skyos:*:*)
echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
exit ;; exit ;;
i*86:rdos:*:*) i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos echo ${UNAME_MACHINE}-pc-rdos
...@@ -1359,171 +1409,25 @@ EOF ...@@ -1359,171 +1409,25 @@ EOF
x86_64:VMkernel:*:*) x86_64:VMkernel:*:*)
echo ${UNAME_MACHINE}-unknown-esx echo ${UNAME_MACHINE}-unknown-esx
exit ;; exit ;;
esac amd64:Isilon\ OneFS:*:*)
echo x86_64-unknown-onefs
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
# include <sys/utsname.h>
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
printf ("arm-acorn-riscix\n"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
printf ("m68k-hp-bsd\n"); exit (0);
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
# if !defined (ultrix)
# include <sys/param.h>
# if defined (BSD)
# if BSD == 43
printf ("vax-dec-bsd4.3\n"); exit (0);
# else
# if BSD == 199006
printf ("vax-dec-bsd4.3reno\n"); exit (0);
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# endif
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# else
printf ("vax-dec-ultrix\n"); exit (0);
# endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
{ echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
# Convex versions that predate uname can use getsysinfo(1)
if [ -x /usr/convex/getsysinfo ]
then
case `getsysinfo -f cpu_type` in
c1*)
echo c1-convex-bsd
exit ;;
c2*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
c34*)
echo c34-convex-bsd
exit ;;
c38*)
echo c38-convex-bsd
exit ;;
c4*)
echo c4-convex-bsd
exit ;; exit ;;
esac esac
fi
cat >&2 <<EOF cat >&2 <<EOF
$0: unable to guess system type $0: unable to guess system type
This script, last modified $timestamp, has failed to recognize This script (version $timestamp), has failed to recognize the
the operating system you are using. It is advised that you operating system you are using. If your script is old, overwrite
download the most up to date version of the config scripts from config.guess and config.sub with the latest versions from:
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
and and
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
If the version you run ($0) is already up to date, please If $0 has already been updated, send the following data and any
send the following data and any information you think might be information you think might be pertinent to config-patches@gnu.org to
pertinent to <config-patches@gnu.org> in order to provide the needed provide the necessary information to handle your system.
information to handle your system.
config.guess timestamp = $timestamp config.guess timestamp = $timestamp
......
#! /bin/sh #! /bin/sh
# Configuration validation subroutine script. # Configuration validation subroutine script.
# Copyright 1992-2013 Free Software Foundation, Inc. # Copyright 1992-2016 Free Software Foundation, Inc.
timestamp='2013-10-01' timestamp='2016-11-04'
# This file is free software; you can redistribute it and/or modify it # This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by # under the terms of the GNU General Public License as published by
...@@ -25,7 +25,7 @@ timestamp='2013-10-01' ...@@ -25,7 +25,7 @@ timestamp='2013-10-01'
# of the GNU General Public License, version 3 ("GPLv3"). # of the GNU General Public License, version 3 ("GPLv3").
# Please send patches with a ChangeLog entry to config-patches@gnu.org. # Please send patches to <config-patches@gnu.org>.
# #
# Configuration subroutine to validate and canonicalize a configuration type. # Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument. # Supply the specified configuration type as an argument.
...@@ -33,7 +33,7 @@ timestamp='2013-10-01' ...@@ -33,7 +33,7 @@ timestamp='2013-10-01'
# Otherwise, we print the canonical config type on stdout and succeed. # Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from: # You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
# This file is supposed to be the same for all GNU packages # This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases # and recognize all the CPU types, system types and aliases
...@@ -53,8 +53,7 @@ timestamp='2013-10-01' ...@@ -53,8 +53,7 @@ timestamp='2013-10-01'
me=`echo "$0" | sed -e 's,.*/,,'` me=`echo "$0" | sed -e 's,.*/,,'`
usage="\ usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
$0 [OPTION] ALIAS
Canonicalize a configuration name. Canonicalize a configuration name.
...@@ -68,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>." ...@@ -68,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\ version="\
GNU config.sub ($timestamp) GNU config.sub ($timestamp)
Copyright 1992-2013 Free Software Foundation, Inc. Copyright 1992-2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
...@@ -117,8 +116,8 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` ...@@ -117,8 +116,8 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
kopensolaris*-gnu* | \ kopensolaris*-gnu* | cloudabi*-eabi* | \
storm-chaos* | os2-emx* | rtmk-nova*) storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
...@@ -255,12 +254,13 @@ case $basic_machine in ...@@ -255,12 +254,13 @@ case $basic_machine in
| arc | arceb \ | arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \ | avr | avr32 \
| ba \
| be32 | be64 \ | be32 | be64 \
| bfin \ | bfin \
| c4x | c8051 | clipper \ | c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \ | d10v | d30v | dlx | dsp16xx \
| epiphany \ | e2k | epiphany \
| fido | fr30 | frv \ | fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \ | hexagon \
| i370 | i860 | i960 | ia64 \ | i370 | i860 | i960 | ia64 \
...@@ -283,8 +283,10 @@ case $basic_machine in ...@@ -283,8 +283,10 @@ case $basic_machine in
| mips64vr5900 | mips64vr5900el \ | mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \ | mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \ | mipsisa32r2 | mipsisa32r2el \
| mipsisa32r6 | mipsisa32r6el \
| mipsisa64 | mipsisa64el \ | mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \ | mipsisa64r2 | mipsisa64r2el \
| mipsisa64r6 | mipsisa64r6el \
| mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \ | mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \ | mipsr5900 | mipsr5900el \
...@@ -296,14 +298,15 @@ case $basic_machine in ...@@ -296,14 +298,15 @@ case $basic_machine in
| nds32 | nds32le | nds32be \ | nds32 | nds32le | nds32be \
| nios | nios2 | nios2eb | nios2el \ | nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \ | ns16k | ns32k \
| open8 \ | open8 | or1k | or1knd | or32 \
| or1k | or32 \
| pdp10 | pdp11 | pj | pjl \ | pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \ | powerpc | powerpc64 | powerpc64le | powerpcle \
| pru \
| pyramid \ | pyramid \
| riscv32 | riscv64 \
| rl78 | rx \ | rl78 | rx \
| score \ | score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \ | sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
...@@ -311,6 +314,7 @@ case $basic_machine in ...@@ -311,6 +314,7 @@ case $basic_machine in
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \ | ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| visium \
| we32k \ | we32k \
| x86 | xc16x | xstormy16 | xtensa \ | x86 | xc16x | xstormy16 | xtensa \
| z8k | z80) | z8k | z80)
...@@ -325,6 +329,9 @@ case $basic_machine in ...@@ -325,6 +329,9 @@ case $basic_machine in
c6x) c6x)
basic_machine=tic6x-unknown basic_machine=tic6x-unknown
;; ;;
leon|leon[3-9])
basic_machine=sparc-$basic_machine
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown basic_machine=$basic_machine-unknown
os=-none os=-none
...@@ -370,12 +377,13 @@ case $basic_machine in ...@@ -370,12 +377,13 @@ case $basic_machine in
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \ | avr-* | avr32-* \
| ba-* \
| be32-* | be64-* \ | be32-* | be64-* \
| bfin-* | bs2000-* \ | bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \
| c8051-* | clipper-* | craynv-* | cydra-* \ | c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \ | d10v-* | d30v-* | dlx-* \
| elxsi-* \ | e2k-* | elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \ | h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
...@@ -402,8 +410,10 @@ case $basic_machine in ...@@ -402,8 +410,10 @@ case $basic_machine in
| mips64vr5900-* | mips64vr5900el-* \ | mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \ | mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa32r6-* | mipsisa32r6el-* \
| mipsisa64-* | mipsisa64el-* \ | mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64r6-* | mipsisa64r6el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \ | mipsr5900-* | mipsr5900el-* \
...@@ -415,16 +425,19 @@ case $basic_machine in ...@@ -415,16 +425,19 @@ case $basic_machine in
| nios-* | nios2-* | nios2eb-* | nios2el-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \ | none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \ | open8-* \
| or1k*-* \
| orion-* \ | orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pru-* \
| pyramid-* \ | pyramid-* \
| riscv32-* | riscv64-* \
| rl78-* | romp-* | rs6000-* | rx-* \ | rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \ | sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
| tahoe-* \ | tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \ | tile*-* \
...@@ -432,6 +445,7 @@ case $basic_machine in ...@@ -432,6 +445,7 @@ case $basic_machine in
| ubicom32-* \ | ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \ | vax-* \
| visium-* \
| we32k-* \ | we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \ | xstormy16-* | xtensa*-* \
...@@ -508,6 +522,9 @@ case $basic_machine in ...@@ -508,6 +522,9 @@ case $basic_machine in
basic_machine=i386-pc basic_machine=i386-pc
os=-aros os=-aros
;; ;;
asmjs)
basic_machine=asmjs-unknown
;;
aux) aux)
basic_machine=m68k-apple basic_machine=m68k-apple
os=-aux os=-aux
...@@ -628,6 +645,14 @@ case $basic_machine in ...@@ -628,6 +645,14 @@ case $basic_machine in
basic_machine=m68k-bull basic_machine=m68k-bull
os=-sysv3 os=-sysv3
;; ;;
e500v[12])
basic_machine=powerpc-unknown
os=$os"spe"
;;
e500v[12]-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
os=$os"spe"
;;
ebmon29k) ebmon29k)
basic_machine=a29k-amd basic_machine=a29k-amd
os=-ebmon os=-ebmon
...@@ -769,6 +794,9 @@ case $basic_machine in ...@@ -769,6 +794,9 @@ case $basic_machine in
basic_machine=m68k-isi basic_machine=m68k-isi
os=-sysv os=-sysv
;; ;;
leon-*|leon[3-9]-*)
basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
;;
m68knommu) m68knommu)
basic_machine=m68k-unknown basic_machine=m68k-unknown
os=-linux os=-linux
...@@ -824,6 +852,10 @@ case $basic_machine in ...@@ -824,6 +852,10 @@ case $basic_machine in
basic_machine=powerpc-unknown basic_machine=powerpc-unknown
os=-morphos os=-morphos
;; ;;
moxiebox)
basic_machine=moxie-unknown
os=-moxiebox
;;
msdos) msdos)
basic_machine=i386-pc basic_machine=i386-pc
os=-msdos os=-msdos
...@@ -1000,7 +1032,7 @@ case $basic_machine in ...@@ -1000,7 +1032,7 @@ case $basic_machine in
ppc-* | ppcbe-*) ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;; ;;
ppcle | powerpclittle | ppc-le | powerpc-little) ppcle | powerpclittle)
basic_machine=powerpcle-unknown basic_machine=powerpcle-unknown
;; ;;
ppcle-* | powerpclittle-*) ppcle-* | powerpclittle-*)
...@@ -1010,7 +1042,7 @@ case $basic_machine in ...@@ -1010,7 +1042,7 @@ case $basic_machine in
;; ;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;; ;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little) ppc64le | powerpc64little)
basic_machine=powerpc64le-unknown basic_machine=powerpc64le-unknown
;; ;;
ppc64le-* | powerpc64little-*) ppc64le-* | powerpc64little-*)
...@@ -1356,27 +1388,28 @@ case $os in ...@@ -1356,27 +1388,28 @@ case $os in
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \ | -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \ | -aos* | -aros* | -cloudabi* | -sortix* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -bitrig* | -openbsd* | -solidbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \ | -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
| -onefs* | -tirtos* | -phoenix* | -fuchsia*)
# Remember, each alternative MUST END IN *, to match a version number. # Remember, each alternative MUST END IN *, to match a version number.
;; ;;
-qnx*) -qnx*)
...@@ -1508,6 +1541,8 @@ case $os in ...@@ -1508,6 +1541,8 @@ case $os in
;; ;;
-nacl*) -nacl*)
;; ;;
-ios)
;;
-none) -none)
;; ;;
*) *)
...@@ -1594,9 +1629,6 @@ case $basic_machine in ...@@ -1594,9 +1629,6 @@ case $basic_machine in
mips*-*) mips*-*)
os=-elf os=-elf
;; ;;
or1k-*)
os=-elf
;;
or32-*) or32-*)
os=-coff os=-coff
;; ;;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.68)
AC_INIT([Makefile.in]) AC_INIT([Makefile.in])
AC_CONFIG_AUX_DIR([build-aux])
dnl ============================================================================ dnl ============================================================================
dnl Custom macro definitions. dnl Custom macro definitions.
dnl JE_CFLAGS_APPEND(cflag) dnl JE_CONCAT_VVV(r, a, b)
AC_DEFUN([JE_CFLAGS_APPEND], dnl
[ dnl Set $r to the concatenation of $a and $b, with a space separating them iff
AC_MSG_CHECKING([whether compiler supports $1]) dnl both $a and $b are non-empty.
TCFLAGS="${CFLAGS}" AC_DEFUN([JE_CONCAT_VVV],
if test "x${CFLAGS}" = "x" ; then if test "x[$]{$2}" = "x" -o "x[$]{$3}" = "x" ; then
CFLAGS="$1" $1="[$]{$2}[$]{$3}"
else else
CFLAGS="${CFLAGS} $1" $1="[$]{$2} [$]{$3}"
fi fi
)
dnl JE_APPEND_VS(a, b)
dnl
dnl Set $a to the concatenation of $a and b, with a space separating them iff
dnl both $a and b are non-empty.
AC_DEFUN([JE_APPEND_VS],
T_APPEND_V=$2
JE_CONCAT_VVV($1, $1, T_APPEND_V)
)
CONFIGURE_CFLAGS=
SPECIFIED_CFLAGS="${CFLAGS}"
dnl JE_CFLAGS_ADD(cflag)
dnl
dnl CFLAGS is the concatenation of CONFIGURE_CFLAGS and SPECIFIED_CFLAGS
dnl (ignoring EXTRA_CFLAGS, which does not impact configure tests. This macro
dnl appends to CONFIGURE_CFLAGS and regenerates CFLAGS.
AC_DEFUN([JE_CFLAGS_ADD],
[
AC_MSG_CHECKING([whether compiler supports $1])
T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}"
JE_APPEND_VS(CONFIGURE_CFLAGS, $1)
JE_CONCAT_VVV(CFLAGS, CONFIGURE_CFLAGS, SPECIFIED_CFLAGS)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
]], [[
return 0;
]])],
[je_cv_cflags_added=$1]
AC_MSG_RESULT([yes]),
[je_cv_cflags_added=]
AC_MSG_RESULT([no])
[CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}"]
)
JE_CONCAT_VVV(CFLAGS, CONFIGURE_CFLAGS, SPECIFIED_CFLAGS)
])
dnl JE_CFLAGS_SAVE()
dnl JE_CFLAGS_RESTORE()
dnl
dnl Save/restore CFLAGS. Nesting is not supported.
AC_DEFUN([JE_CFLAGS_SAVE],
SAVED_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}"
)
AC_DEFUN([JE_CFLAGS_RESTORE],
CONFIGURE_CFLAGS="${SAVED_CONFIGURE_CFLAGS}"
JE_CONCAT_VVV(CFLAGS, CONFIGURE_CFLAGS, SPECIFIED_CFLAGS)
)
CONFIGURE_CXXFLAGS=
SPECIFIED_CXXFLAGS="${CXXFLAGS}"
dnl JE_CXXFLAGS_ADD(cxxflag)
AC_DEFUN([JE_CXXFLAGS_ADD],
[
AC_MSG_CHECKING([whether compiler supports $1])
T_CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}"
JE_APPEND_VS(CONFIGURE_CXXFLAGS, $1)
JE_CONCAT_VVV(CXXFLAGS, CONFIGURE_CXXFLAGS, SPECIFIED_CXXFLAGS)
AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM( AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[ [[
]], [[ ]], [[
return 0; return 0;
]])], ]])],
[je_cv_cflags_appended=$1] [je_cv_cxxflags_added=$1]
AC_MSG_RESULT([yes]), AC_MSG_RESULT([yes]),
[je_cv_cflags_appended=] [je_cv_cxxflags_added=]
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
[CFLAGS="${TCFLAGS}"] [CONFIGURE_CXXFLAGS="${T_CONFIGURE_CXXFLAGS}"]
) )
AC_LANG_POP([C++])
JE_CONCAT_VVV(CXXFLAGS, CONFIGURE_CXXFLAGS, SPECIFIED_CXXFLAGS)
]) ])
dnl JE_COMPILABLE(label, hcode, mcode, rvar) dnl JE_COMPILABLE(label, hcode, mcode, rvar)
dnl dnl
dnl Use AC_LINK_IFELSE() rather than AC_COMPILE_IFELSE() so that linker errors dnl Use AC_LINK_IFELSE() rather than AC_COMPILE_IFELSE() so that linker errors
dnl cause failure. dnl cause failure.
AC_DEFUN([JE_COMPILABLE], AC_DEFUN([JE_COMPILABLE],
...@@ -43,8 +108,11 @@ AC_CACHE_CHECK([whether $1 is compilable], ...@@ -43,8 +108,11 @@ AC_CACHE_CHECK([whether $1 is compilable],
dnl ============================================================================ dnl ============================================================================
CONFIG=`echo ${ac_configure_args} | sed -e 's#'"'"'\([^ ]*\)'"'"'#\1#g'`
AC_SUBST([CONFIG])
dnl Library revision. dnl Library revision.
rev=1 rev=2
AC_SUBST([rev]) AC_SUBST([rev])
srcroot=$srcdir srcroot=$srcdir
...@@ -113,6 +181,7 @@ dnl If CFLAGS isn't defined, set CFLAGS to something reasonable. Otherwise, ...@@ -113,6 +181,7 @@ dnl If CFLAGS isn't defined, set CFLAGS to something reasonable. Otherwise,
dnl just prevent autoconf from molesting CFLAGS. dnl just prevent autoconf from molesting CFLAGS.
CFLAGS=$CFLAGS CFLAGS=$CFLAGS
AC_PROG_CC AC_PROG_CC
if test "x$GCC" != "xyes" ; then if test "x$GCC" != "xyes" ; then
AC_CACHE_CHECK([whether compiler is MSVC], AC_CACHE_CHECK([whether compiler is MSVC],
[je_cv_msvc], [je_cv_msvc],
...@@ -126,42 +195,144 @@ if test "x$GCC" != "xyes" ; then ...@@ -126,42 +195,144 @@ if test "x$GCC" != "xyes" ; then
[je_cv_msvc=no])]) [je_cv_msvc=no])])
fi fi
if test "x$CFLAGS" = "x" ; then dnl check if a cray prgenv wrapper compiler is being used
no_CFLAGS="yes" je_cv_cray_prgenv_wrapper=""
if test "x$GCC" = "xyes" ; then if test "x${PE_ENV}" != "x" ; then
JE_CFLAGS_APPEND([-std=gnu99]) case "${CC}" in
if test "x$je_cv_cflags_appended" = "x-std=gnu99" ; then CC|cc)
je_cv_cray_prgenv_wrapper="yes"
;;
*)
;;
esac
fi
AC_CACHE_CHECK([whether compiler is cray],
[je_cv_cray],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
[
#ifndef _CRAYC
int fail[-1];
#endif
])],
[je_cv_cray=yes],
[je_cv_cray=no])])
if test "x${je_cv_cray}" = "xyes" ; then
AC_CACHE_CHECK([whether cray compiler version is 8.4],
[je_cv_cray_84],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
[
#if !(_RELEASE_MAJOR == 8 && _RELEASE_MINOR == 4)
int fail[-1];
#endif
])],
[je_cv_cray_84=yes],
[je_cv_cray_84=no])])
fi
if test "x$GCC" = "xyes" ; then
JE_CFLAGS_ADD([-std=gnu11])
if test "x$je_cv_cflags_added" = "x-std=gnu11" ; then
AC_DEFINE_UNQUOTED([JEMALLOC_HAS_RESTRICT])
else
JE_CFLAGS_ADD([-std=gnu99])
if test "x$je_cv_cflags_added" = "x-std=gnu99" ; then
AC_DEFINE_UNQUOTED([JEMALLOC_HAS_RESTRICT]) AC_DEFINE_UNQUOTED([JEMALLOC_HAS_RESTRICT])
fi fi
JE_CFLAGS_APPEND([-Wall])
JE_CFLAGS_APPEND([-pipe])
JE_CFLAGS_APPEND([-g3])
elif test "x$je_cv_msvc" = "xyes" ; then
CC="$CC -nologo"
JE_CFLAGS_APPEND([-Zi])
JE_CFLAGS_APPEND([-MT])
JE_CFLAGS_APPEND([-W3])
CPPFLAGS="$CPPFLAGS -I${srcroot}/include/msvc_compat"
fi fi
JE_CFLAGS_ADD([-Wall])
JE_CFLAGS_ADD([-Wshorten-64-to-32])
JE_CFLAGS_ADD([-Wsign-compare])
JE_CFLAGS_ADD([-Wundef])
JE_CFLAGS_ADD([-Wno-format-zero-length])
JE_CFLAGS_ADD([-pipe])
JE_CFLAGS_ADD([-g3])
elif test "x$je_cv_msvc" = "xyes" ; then
CC="$CC -nologo"
JE_CFLAGS_ADD([-Zi])
JE_CFLAGS_ADD([-MT])
JE_CFLAGS_ADD([-W3])
JE_CFLAGS_ADD([-FS])
JE_APPEND_VS(CPPFLAGS, -I${srcdir}/include/msvc_compat)
fi
if test "x$je_cv_cray" = "xyes" ; then
dnl cray compiler 8.4 has an inlining bug
if test "x$je_cv_cray_84" = "xyes" ; then
JE_CFLAGS_ADD([-hipa2])
JE_CFLAGS_ADD([-hnognu])
fi
dnl ignore unreachable code warning
JE_CFLAGS_ADD([-hnomessage=128])
dnl ignore redefinition of "malloc", "free", etc warning
JE_CFLAGS_ADD([-hnomessage=1357])
fi
AC_SUBST([CONFIGURE_CFLAGS])
AC_SUBST([SPECIFIED_CFLAGS])
AC_SUBST([EXTRA_CFLAGS])
AC_PROG_CPP
AC_ARG_ENABLE([cxx],
[AS_HELP_STRING([--disable-cxx], [Disable C++ integration])],
if test "x$enable_cxx" = "xno" ; then
enable_cxx="0"
else
enable_cxx="1"
fi fi
dnl Append EXTRA_CFLAGS to CFLAGS, if defined. ,
if test "x$EXTRA_CFLAGS" != "x" ; then enable_cxx="1"
JE_CFLAGS_APPEND([$EXTRA_CFLAGS]) )
if test "x$enable_cxx" = "x1" ; then
dnl Require at least c++14, which is the first version to support sized
dnl deallocation. C++ support is not compiled otherwise.
m4_include([m4/ax_cxx_compile_stdcxx.m4])
AX_CXX_COMPILE_STDCXX([14], [noext], [optional])
if test "x${HAVE_CXX14}" = "x1" ; then
JE_CXXFLAGS_ADD([-Wall])
JE_CXXFLAGS_ADD([-g3])
SAVED_LIBS="${LIBS}"
JE_APPEND_VS(LIBS, -lstdc++)
JE_COMPILABLE([libstdc++ linkage], [
#include <stdlib.h>
], [[
int *arr = (int *)malloc(sizeof(int) * 42);
if (arr == NULL)
return 1;
]], [je_cv_libstdcxx])
if test "x${je_cv_libstdcxx}" = "xno" ; then
LIBS="${SAVED_LIBS}"
fi
else
enable_cxx="0"
fi
fi fi
AC_PROG_CPP AC_SUBST([enable_cxx])
AC_SUBST([CONFIGURE_CXXFLAGS])
AC_SUBST([SPECIFIED_CXXFLAGS])
AC_SUBST([EXTRA_CXXFLAGS])
AC_C_BIGENDIAN([ac_cv_big_endian=1], [ac_cv_big_endian=0]) AC_C_BIGENDIAN([ac_cv_big_endian=1], [ac_cv_big_endian=0])
if test "x${ac_cv_big_endian}" = "x1" ; then if test "x${ac_cv_big_endian}" = "x1" ; then
AC_DEFINE_UNQUOTED([JEMALLOC_BIG_ENDIAN], [ ]) AC_DEFINE_UNQUOTED([JEMALLOC_BIG_ENDIAN], [ ])
fi fi
AC_CHECK_SIZEOF([void *]) if test "x${je_cv_msvc}" = "xyes" -a "x${ac_cv_header_inttypes_h}" = "xno"; then
if test "x${ac_cv_sizeof_void_p}" = "x8" ; then JE_APPEND_VS(CPPFLAGS, -I${srcdir}/include/msvc_compat/C99)
LG_SIZEOF_PTR=3 fi
elif test "x${ac_cv_sizeof_void_p}" = "x4" ; then
LG_SIZEOF_PTR=2 if test "x${je_cv_msvc}" = "xyes" ; then
LG_SIZEOF_PTR=LG_SIZEOF_PTR_WIN
AC_MSG_RESULT([Using a predefined value for sizeof(void *): 4 for 32-bit, 8 for 64-bit])
else else
AC_MSG_ERROR([Unsupported pointer size: ${ac_cv_sizeof_void_p}]) AC_CHECK_SIZEOF([void *])
if test "x${ac_cv_sizeof_void_p}" = "x8" ; then
LG_SIZEOF_PTR=3
elif test "x${ac_cv_sizeof_void_p}" = "x4" ; then
LG_SIZEOF_PTR=2
else
AC_MSG_ERROR([Unsupported pointer size: ${ac_cv_sizeof_void_p}])
fi
fi fi
AC_DEFINE_UNQUOTED([LG_SIZEOF_PTR], [$LG_SIZEOF_PTR]) AC_DEFINE_UNQUOTED([LG_SIZEOF_PTR], [$LG_SIZEOF_PTR])
...@@ -185,6 +356,16 @@ else ...@@ -185,6 +356,16 @@ else
fi fi
AC_DEFINE_UNQUOTED([LG_SIZEOF_LONG], [$LG_SIZEOF_LONG]) AC_DEFINE_UNQUOTED([LG_SIZEOF_LONG], [$LG_SIZEOF_LONG])
AC_CHECK_SIZEOF([long long])
if test "x${ac_cv_sizeof_long_long}" = "x8" ; then
LG_SIZEOF_LONG_LONG=3
elif test "x${ac_cv_sizeof_long_long}" = "x4" ; then
LG_SIZEOF_LONG_LONG=2
else
AC_MSG_ERROR([Unsupported long long size: ${ac_cv_sizeof_long_long}])
fi
AC_DEFINE_UNQUOTED([LG_SIZEOF_LONG_LONG], [$LG_SIZEOF_LONG_LONG])
AC_CHECK_SIZEOF([intmax_t]) AC_CHECK_SIZEOF([intmax_t])
if test "x${ac_cv_sizeof_intmax_t}" = "x16" ; then if test "x${ac_cv_sizeof_intmax_t}" = "x16" ; then
LG_SIZEOF_INTMAX_T=4 LG_SIZEOF_INTMAX_T=4
...@@ -201,32 +382,120 @@ AC_CANONICAL_HOST ...@@ -201,32 +382,120 @@ AC_CANONICAL_HOST
dnl CPU-specific settings. dnl CPU-specific settings.
CPU_SPINWAIT="" CPU_SPINWAIT=""
case "${host_cpu}" in case "${host_cpu}" in
i[[345]]86)
;;
i686|x86_64) i686|x86_64)
JE_COMPILABLE([pause instruction], [], HAVE_CPU_SPINWAIT=1
[[__asm__ volatile("pause"); return 0;]], if test "x${je_cv_msvc}" = "xyes" ; then
[je_cv_pause]) AC_CACHE_VAL([je_cv_pause_msvc],
if test "x${je_cv_pause}" = "xyes" ; then [JE_COMPILABLE([pause instruction MSVC], [],
CPU_SPINWAIT='__asm__ volatile("pause")' [[_mm_pause(); return 0;]],
fi [je_cv_pause_msvc])])
dnl emmintrin.h fails to compile unless MMX, SSE, and SSE2 are if test "x${je_cv_pause_msvc}" = "xyes" ; then
dnl supported. CPU_SPINWAIT='_mm_pause()'
JE_COMPILABLE([SSE2 intrinsics], [ fi
#include <emmintrin.h> else
], [], [je_cv_sse2]) AC_CACHE_VAL([je_cv_pause],
if test "x${je_cv_sse2}" = "xyes" ; then [JE_COMPILABLE([pause instruction], [],
AC_DEFINE_UNQUOTED([HAVE_SSE2], [ ]) [[__asm__ volatile("pause"); return 0;]],
[je_cv_pause])])
if test "x${je_cv_pause}" = "xyes" ; then
CPU_SPINWAIT='__asm__ volatile("pause")'
fi
fi fi
;; ;;
powerpc)
AC_DEFINE_UNQUOTED([HAVE_ALTIVEC], [ ])
;;
*) *)
HAVE_CPU_SPINWAIT=0
;; ;;
esac esac
AC_DEFINE_UNQUOTED([HAVE_CPU_SPINWAIT], [$HAVE_CPU_SPINWAIT])
AC_DEFINE_UNQUOTED([CPU_SPINWAIT], [$CPU_SPINWAIT]) AC_DEFINE_UNQUOTED([CPU_SPINWAIT], [$CPU_SPINWAIT])
AC_ARG_WITH([lg_vaddr],
[AS_HELP_STRING([--with-lg-vaddr=<lg-vaddr>], [Number of significant virtual address bits])],
[LG_VADDR="$with_lg_vaddr"], [LG_VADDR="detect"])
case "${host_cpu}" in
aarch64)
if test "x$LG_VADDR" = "xdetect"; then
AC_MSG_CHECKING([number of significant virtual address bits])
if test "x${LG_SIZEOF_PTR}" = "x2" ; then
#aarch64 ILP32
LG_VADDR=32
else
#aarch64 LP64
LG_VADDR=48
fi
AC_MSG_RESULT([$LG_VADDR])
fi
;;
x86_64)
if test "x$LG_VADDR" = "xdetect"; then
AC_CACHE_CHECK([number of significant virtual address bits],
[je_cv_lg_vaddr],
AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[
#include <stdio.h>
#ifdef _WIN32
#include <limits.h>
#include <intrin.h>
typedef unsigned __int32 uint32_t;
#else
#include <stdint.h>
#endif
]], [[
uint32_t r[[4]];
uint32_t eax_in = 0x80000008U;
#ifdef _WIN32
__cpuid((int *)r, (int)eax_in);
#else
asm volatile ("cpuid"
: "=a" (r[[0]]), "=b" (r[[1]]), "=c" (r[[2]]), "=d" (r[[3]])
: "a" (eax_in), "c" (0)
);
#endif
uint32_t eax_out = r[[0]];
uint32_t vaddr = ((eax_out & 0x0000ff00U) >> 8);
FILE *f = fopen("conftest.out", "w");
if (f == NULL) {
return 1;
}
if (vaddr > (sizeof(void *) << 3)) {
vaddr = sizeof(void *) << 3;
}
fprintf(f, "%u", vaddr);
fclose(f);
return 0;
]])],
[je_cv_lg_vaddr=`cat conftest.out`],
[je_cv_lg_vaddr=error],
[je_cv_lg_vaddr=57]))
if test "x${je_cv_lg_vaddr}" != "x" ; then
LG_VADDR="${je_cv_lg_vaddr}"
fi
if test "x${LG_VADDR}" != "xerror" ; then
AC_DEFINE_UNQUOTED([LG_VADDR], [$LG_VADDR])
else
AC_MSG_ERROR([cannot determine number of significant virtual address bits])
fi
fi
;;
*)
if test "x$LG_VADDR" = "xdetect"; then
AC_MSG_CHECKING([number of significant virtual address bits])
if test "x${LG_SIZEOF_PTR}" = "x3" ; then
LG_VADDR=64
elif test "x${LG_SIZEOF_PTR}" = "x2" ; then
LG_VADDR=32
elif test "x${LG_SIZEOF_PTR}" = "xLG_SIZEOF_PTR_WIN" ; then
LG_VADDR="(1U << (LG_SIZEOF_PTR_WIN+3))"
else
AC_MSG_ERROR([Unsupported lg(pointer size): ${LG_SIZEOF_PTR}])
fi
AC_MSG_RESULT([$LG_VADDR])
fi
;;
esac
AC_DEFINE_UNQUOTED([LG_VADDR], [$LG_VADDR])
LD_PRELOAD_VAR="LD_PRELOAD" LD_PRELOAD_VAR="LD_PRELOAD"
so="so" so="so"
importlib="${so}" importlib="${so}"
...@@ -234,60 +503,113 @@ o="$ac_objext" ...@@ -234,60 +503,113 @@ o="$ac_objext"
a="a" a="a"
exe="$ac_exeext" exe="$ac_exeext"
libprefix="lib" libprefix="lib"
link_whole_archive="0"
DSO_LDFLAGS='-shared -Wl,-soname,$(@F)' DSO_LDFLAGS='-shared -Wl,-soname,$(@F)'
RPATH='-Wl,-rpath,$(1)' RPATH='-Wl,-rpath,$(1)'
SOREV="${so}.${rev}" SOREV="${so}.${rev}"
PIC_CFLAGS='-fPIC -DPIC' PIC_CFLAGS='-fPIC -DPIC'
CTARGET='-o $@' CTARGET='-o $@'
LDTARGET='-o $@' LDTARGET='-o $@'
TEST_LD_MODE=
EXTRA_LDFLAGS= EXTRA_LDFLAGS=
ARFLAGS='crus' ARFLAGS='crus'
AROUT=' $@' AROUT=' $@'
CC_MM=1 CC_MM=1
if test "x$je_cv_cray_prgenv_wrapper" = "xyes" ; then
TEST_LD_MODE='-dynamic'
fi
if test "x${je_cv_cray}" = "xyes" ; then
CC_MM=
fi
AN_MAKEVAR([AR], [AC_PROG_AR]) AN_MAKEVAR([AR], [AC_PROG_AR])
AN_PROGRAM([ar], [AC_PROG_AR]) AN_PROGRAM([ar], [AC_PROG_AR])
AC_DEFUN([AC_PROG_AR], [AC_CHECK_TOOL(AR, ar, :)]) AC_DEFUN([AC_PROG_AR], [AC_CHECK_TOOL(AR, ar, :)])
AC_PROG_AR AC_PROG_AR
AN_MAKEVAR([NM], [AC_PROG_NM])
AN_PROGRAM([nm], [AC_PROG_NM])
AC_DEFUN([AC_PROG_NM], [AC_CHECK_TOOL(NM, nm, :)])
AC_PROG_NM
AC_PROG_AWK
dnl Platform-specific settings. abi and RPATH can probably be determined dnl Platform-specific settings. abi and RPATH can probably be determined
dnl programmatically, but doing so is error-prone, which makes it generally dnl programmatically, but doing so is error-prone, which makes it generally
dnl not worth the trouble. dnl not worth the trouble.
dnl dnl
dnl Define cpp macros in CPPFLAGS, rather than doing AC_DEFINE(macro), since the dnl Define cpp macros in CPPFLAGS, rather than doing AC_DEFINE(macro), since the
dnl definitions need to be seen before any headers are included, which is a pain dnl definitions need to be seen before any headers are included, which is a pain
dnl to make happen otherwise. dnl to make happen otherwise.
default_munmap="1" default_retain="0"
JEMALLOC_USABLE_SIZE_CONST="const" maps_coalesce="1"
DUMP_SYMS="${NM} -a"
SYM_PREFIX=""
case "${host}" in case "${host}" in
*-*-darwin*) *-*-darwin* | *-*-ios*)
CFLAGS="$CFLAGS"
abi="macho" abi="macho"
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
RPATH="" RPATH=""
LD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES" LD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES"
so="dylib" so="dylib"
importlib="${so}" importlib="${so}"
force_tls="0" force_tls="0"
DSO_LDFLAGS='-shared -Wl,-dylib_install_name,$(@F)' DSO_LDFLAGS='-shared -Wl,-install_name,$(LIBDIR)/$(@F)'
SOREV="${rev}.${so}" SOREV="${rev}.${so}"
sbrk_deprecated="1" sbrk_deprecated="1"
SYM_PREFIX="_"
;; ;;
*-*-freebsd*) *-*-freebsd*)
CFLAGS="$CFLAGS"
abi="elf" abi="elf"
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ]) AC_DEFINE([JEMALLOC_SYSCTL_VM_OVERCOMMIT], [ ])
force_lazy_lock="1" force_lazy_lock="1"
;; ;;
*-*-dragonfly*)
abi="elf"
;;
*-*-openbsd*)
abi="elf"
force_tls="0"
;;
*-*-bitrig*)
abi="elf"
;;
*-*-linux-android)
dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE.
JE_APPEND_VS(CPPFLAGS, -D_GNU_SOURCE)
abi="elf"
AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS], [ ])
AC_DEFINE([JEMALLOC_HAS_ALLOCA_H])
AC_DEFINE([JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY], [ ])
AC_DEFINE([JEMALLOC_THREADED_INIT], [ ])
AC_DEFINE([JEMALLOC_C11_ATOMICS])
force_tls="0"
if test "${LG_SIZEOF_PTR}" = "3"; then
default_retain="1"
fi
;;
*-*-linux*) *-*-linux*)
CFLAGS="$CFLAGS" dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE.
CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" JE_APPEND_VS(CPPFLAGS, -D_GNU_SOURCE)
abi="elf" abi="elf"
AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS], [ ])
AC_DEFINE([JEMALLOC_HAS_ALLOCA_H]) AC_DEFINE([JEMALLOC_HAS_ALLOCA_H])
AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED], [ ]) AC_DEFINE([JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY], [ ])
AC_DEFINE([JEMALLOC_THREADED_INIT], [ ]) AC_DEFINE([JEMALLOC_THREADED_INIT], [ ])
JEMALLOC_USABLE_SIZE_CONST="" AC_DEFINE([JEMALLOC_USE_CXX_THROW], [ ])
default_munmap="0" if test "${LG_SIZEOF_PTR}" = "3"; then
default_retain="1"
fi
;;
*-*-kfreebsd*)
dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE.
JE_APPEND_VS(CPPFLAGS, -D_GNU_SOURCE)
abi="elf"
AC_DEFINE([JEMALLOC_HAS_ALLOCA_H])
AC_DEFINE([JEMALLOC_SYSCTL_VM_OVERCOMMIT], [ ])
AC_DEFINE([JEMALLOC_THREADED_INIT], [ ])
AC_DEFINE([JEMALLOC_USE_CXX_THROW], [ ])
;; ;;
*-*-netbsd*) *-*-netbsd*)
AC_MSG_CHECKING([ABI]) AC_MSG_CHECKING([ABI])
...@@ -298,22 +620,19 @@ case "${host}" in ...@@ -298,22 +620,19 @@ case "${host}" in
#error aout #error aout
#endif #endif
]])], ]])],
[CFLAGS="$CFLAGS"; abi="elf"], [abi="elf"],
[abi="aout"]) [abi="aout"])
AC_MSG_RESULT([$abi]) AC_MSG_RESULT([$abi])
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
;; ;;
*-*-solaris2*) *-*-solaris2*)
CFLAGS="$CFLAGS"
abi="elf" abi="elf"
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
RPATH='-Wl,-R,$(1)' RPATH='-Wl,-R,$(1)'
dnl Solaris needs this for sigwait(). dnl Solaris needs this for sigwait().
CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS" JE_APPEND_VS(CPPFLAGS, -D_POSIX_PTHREAD_SEMANTICS)
LIBS="$LIBS -lposix4 -lsocket -lnsl" JE_APPEND_VS(LIBS, -lposix4 -lsocket -lnsl)
;; ;;
*-ibm-aix*) *-ibm-aix*)
if "$LG_SIZEOF_PTR" = "8"; then if test "${LG_SIZEOF_PTR}" = "3"; then
dnl 64bit AIX dnl 64bit AIX
LD_PRELOAD_VAR="LDR_PRELOAD64" LD_PRELOAD_VAR="LDR_PRELOAD64"
else else
...@@ -322,9 +641,10 @@ case "${host}" in ...@@ -322,9 +641,10 @@ case "${host}" in
fi fi
abi="xcoff" abi="xcoff"
;; ;;
*-*-mingw*) *-*-mingw* | *-*-cygwin*)
abi="pecoff" abi="pecoff"
force_tls="0" force_tls="0"
maps_coalesce="0"
RPATH="" RPATH=""
so="dll" so="dll"
if test "x$je_cv_msvc" = "xyes" ; then if test "x$je_cv_msvc" = "xyes" ; then
...@@ -340,7 +660,15 @@ case "${host}" in ...@@ -340,7 +660,15 @@ case "${host}" in
else else
importlib="${so}" importlib="${so}"
DSO_LDFLAGS="-shared" DSO_LDFLAGS="-shared"
link_whole_archive="1"
fi fi
case "${host}" in
*-*-cygwin*)
DUMP_SYMS="dumpbin /SYMBOLS"
;;
*)
;;
esac
a="lib" a="lib"
libprefix="" libprefix=""
SOREV="${so}" SOREV="${so}"
...@@ -351,6 +679,22 @@ case "${host}" in ...@@ -351,6 +679,22 @@ case "${host}" in
abi="elf" abi="elf"
;; ;;
esac esac
JEMALLOC_USABLE_SIZE_CONST=const
AC_CHECK_HEADERS([malloc.h], [
AC_MSG_CHECKING([whether malloc_usable_size definition can use const argument])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[#include <malloc.h>
#include <stddef.h>
size_t malloc_usable_size(const void *ptr);
],
[])],[
AC_MSG_RESULT([yes])
],[
JEMALLOC_USABLE_SIZE_CONST=
AC_MSG_RESULT([no])
])
])
AC_DEFINE_UNQUOTED([JEMALLOC_USABLE_SIZE_CONST], [$JEMALLOC_USABLE_SIZE_CONST]) AC_DEFINE_UNQUOTED([JEMALLOC_USABLE_SIZE_CONST], [$JEMALLOC_USABLE_SIZE_CONST])
AC_SUBST([abi]) AC_SUBST([abi])
AC_SUBST([RPATH]) AC_SUBST([RPATH])
...@@ -361,17 +705,29 @@ AC_SUBST([o]) ...@@ -361,17 +705,29 @@ AC_SUBST([o])
AC_SUBST([a]) AC_SUBST([a])
AC_SUBST([exe]) AC_SUBST([exe])
AC_SUBST([libprefix]) AC_SUBST([libprefix])
AC_SUBST([link_whole_archive])
AC_SUBST([DSO_LDFLAGS]) AC_SUBST([DSO_LDFLAGS])
AC_SUBST([EXTRA_LDFLAGS]) AC_SUBST([EXTRA_LDFLAGS])
AC_SUBST([SOREV]) AC_SUBST([SOREV])
AC_SUBST([PIC_CFLAGS]) AC_SUBST([PIC_CFLAGS])
AC_SUBST([CTARGET]) AC_SUBST([CTARGET])
AC_SUBST([LDTARGET]) AC_SUBST([LDTARGET])
AC_SUBST([TEST_LD_MODE])
AC_SUBST([MKLIB]) AC_SUBST([MKLIB])
AC_SUBST([ARFLAGS]) AC_SUBST([ARFLAGS])
AC_SUBST([AROUT]) AC_SUBST([AROUT])
AC_SUBST([DUMP_SYMS])
AC_SUBST([CC_MM]) AC_SUBST([CC_MM])
dnl Determine whether libm must be linked to use e.g. log(3).
AC_SEARCH_LIBS([log], [m], , [AC_MSG_ERROR([Missing math functions])])
if test "x$ac_cv_search_log" != "xnone required" ; then
LM="$ac_cv_search_log"
else
LM=
fi
AC_SUBST(LM)
JE_COMPILABLE([__attribute__ syntax], JE_COMPILABLE([__attribute__ syntax],
[static __attribute__((unused)) void foo(void){}], [static __attribute__((unused)) void foo(void){}],
[], [],
...@@ -379,23 +735,55 @@ JE_COMPILABLE([__attribute__ syntax], ...@@ -379,23 +735,55 @@ JE_COMPILABLE([__attribute__ syntax],
if test "x${je_cv_attribute}" = "xyes" ; then if test "x${je_cv_attribute}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_ATTR], [ ]) AC_DEFINE([JEMALLOC_HAVE_ATTR], [ ])
if test "x${GCC}" = "xyes" -a "x${abi}" = "xelf"; then if test "x${GCC}" = "xyes" -a "x${abi}" = "xelf"; then
JE_CFLAGS_APPEND([-fvisibility=hidden]) JE_CFLAGS_ADD([-fvisibility=hidden])
JE_CXXFLAGS_ADD([-fvisibility=hidden])
fi fi
fi fi
dnl Check for tls_model attribute support (clang 3.0 still lacks support). dnl Check for tls_model attribute support (clang 3.0 still lacks support).
SAVED_CFLAGS="${CFLAGS}" JE_CFLAGS_SAVE()
JE_CFLAGS_APPEND([-Werror]) JE_CFLAGS_ADD([-Werror])
JE_CFLAGS_ADD([-herror_on_warning])
JE_COMPILABLE([tls_model attribute], [], JE_COMPILABLE([tls_model attribute], [],
[static __thread int [static __thread int
__attribute__((tls_model("initial-exec"))) foo; __attribute__((tls_model("initial-exec"), unused)) foo;
foo = 0;], foo = 0;],
[je_cv_tls_model]) [je_cv_tls_model])
CFLAGS="${SAVED_CFLAGS}" JE_CFLAGS_RESTORE()
if test "x${je_cv_tls_model}" = "xyes" ; then dnl (Setting of JEMALLOC_TLS_MODEL is done later, after we've checked for
AC_DEFINE([JEMALLOC_TLS_MODEL], dnl --disable-initial-exec-tls)
[__attribute__((tls_model("initial-exec")))])
else dnl Check for alloc_size attribute support.
AC_DEFINE([JEMALLOC_TLS_MODEL], [ ]) JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-Werror])
JE_CFLAGS_ADD([-herror_on_warning])
JE_COMPILABLE([alloc_size attribute], [#include <stdlib.h>],
[void *foo(size_t size) __attribute__((alloc_size(1)));],
[je_cv_alloc_size])
JE_CFLAGS_RESTORE()
if test "x${je_cv_alloc_size}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_ATTR_ALLOC_SIZE], [ ])
fi
dnl Check for format(gnu_printf, ...) attribute support.
JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-Werror])
JE_CFLAGS_ADD([-herror_on_warning])
JE_COMPILABLE([format(gnu_printf, ...) attribute], [#include <stdlib.h>],
[void *foo(const char *format, ...) __attribute__((format(gnu_printf, 1, 2)));],
[je_cv_format_gnu_printf])
JE_CFLAGS_RESTORE()
if test "x${je_cv_format_gnu_printf}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF], [ ])
fi
dnl Check for format(printf, ...) attribute support.
JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-Werror])
JE_CFLAGS_ADD([-herror_on_warning])
JE_COMPILABLE([format(printf, ...) attribute], [#include <stdlib.h>],
[void *foo(const char *format, ...) __attribute__((format(printf, 1, 2)));],
[je_cv_format_printf])
JE_CFLAGS_RESTORE()
if test "x${je_cv_format_printf}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_ATTR_FORMAT_PRINTF], [ ])
fi fi
dnl Support optional additions to rpath. dnl Support optional additions to rpath.
...@@ -428,59 +816,6 @@ AC_PROG_RANLIB ...@@ -428,59 +816,6 @@ AC_PROG_RANLIB
AC_PATH_PROG([LD], [ld], [false], [$PATH]) AC_PATH_PROG([LD], [ld], [false], [$PATH])
AC_PATH_PROG([AUTOCONF], [autoconf], [false], [$PATH]) AC_PATH_PROG([AUTOCONF], [autoconf], [false], [$PATH])
public_syms="malloc_conf malloc_message malloc calloc posix_memalign aligned_alloc realloc free mallocx rallocx xallocx sallocx dallocx nallocx mallctl mallctlnametomib mallctlbymib malloc_stats_print malloc_usable_size"
dnl Check for allocator-related functions that should be wrapped.
AC_CHECK_FUNC([memalign],
[AC_DEFINE([JEMALLOC_OVERRIDE_MEMALIGN], [ ])
public_syms="${public_syms} memalign"])
AC_CHECK_FUNC([valloc],
[AC_DEFINE([JEMALLOC_OVERRIDE_VALLOC], [ ])
public_syms="${public_syms} valloc"])
dnl Support the experimental API by default.
AC_ARG_ENABLE([experimental],
[AS_HELP_STRING([--disable-experimental],
[Disable support for the experimental API])],
[if test "x$enable_experimental" = "xno" ; then
enable_experimental="0"
else
enable_experimental="1"
fi
],
[enable_experimental="1"]
)
if test "x$enable_experimental" = "x1" ; then
AC_DEFINE([JEMALLOC_EXPERIMENTAL], [ ])
public_syms="${public_syms} allocm dallocm nallocm rallocm sallocm"
fi
AC_SUBST([enable_experimental])
dnl Do not compute test code coverage by default.
GCOV_FLAGS=
AC_ARG_ENABLE([code-coverage],
[AS_HELP_STRING([--enable-code-coverage],
[Enable code coverage])],
[if test "x$enable_code_coverage" = "xno" ; then
enable_code_coverage="0"
else
enable_code_coverage="1"
fi
],
[enable_code_coverage="0"]
)
if test "x$enable_code_coverage" = "x1" ; then
deoptimize="no"
echo "$CFLAGS $EXTRA_CFLAGS" | grep '\-O' >/dev/null || deoptimize="yes"
if test "x${deoptimize}" = "xyes" ; then
JE_CFLAGS_APPEND([-O0])
fi
JE_CFLAGS_APPEND([-fprofile-arcs -ftest-coverage])
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -fprofile-arcs -ftest-coverage"
AC_DEFINE([JEMALLOC_CODE_COVERAGE], [ ])
fi
AC_SUBST([enable_code_coverage])
dnl Perform no name mangling by default. dnl Perform no name mangling by default.
AC_ARG_WITH([mangling], AC_ARG_WITH([mangling],
[AS_HELP_STRING([--with-mangling=<map>], [Mangle symbols in <map>])], [AS_HELP_STRING([--with-mangling=<map>], [Mangle symbols in <map>])],
...@@ -496,11 +831,15 @@ else ...@@ -496,11 +831,15 @@ else
JEMALLOC_PREFIX="je_" JEMALLOC_PREFIX="je_"
fi] fi]
) )
if test "x$JEMALLOC_PREFIX" != "x" ; then if test "x$JEMALLOC_PREFIX" = "x" ; then
AC_DEFINE([JEMALLOC_IS_MALLOC])
else
JEMALLOC_CPREFIX=`echo ${JEMALLOC_PREFIX} | tr "a-z" "A-Z"` JEMALLOC_CPREFIX=`echo ${JEMALLOC_PREFIX} | tr "a-z" "A-Z"`
AC_DEFINE_UNQUOTED([JEMALLOC_PREFIX], ["$JEMALLOC_PREFIX"]) AC_DEFINE_UNQUOTED([JEMALLOC_PREFIX], ["$JEMALLOC_PREFIX"])
AC_DEFINE_UNQUOTED([JEMALLOC_CPREFIX], ["$JEMALLOC_CPREFIX"]) AC_DEFINE_UNQUOTED([JEMALLOC_CPREFIX], ["$JEMALLOC_CPREFIX"])
fi fi
AC_SUBST([JEMALLOC_PREFIX])
AC_SUBST([JEMALLOC_CPREFIX])
AC_ARG_WITH([export], AC_ARG_WITH([export],
[AS_HELP_STRING([--without-export], [disable exporting jemalloc public APIs])], [AS_HELP_STRING([--without-export], [disable exporting jemalloc public APIs])],
...@@ -509,6 +848,49 @@ AC_ARG_WITH([export], ...@@ -509,6 +848,49 @@ AC_ARG_WITH([export],
fi] fi]
) )
public_syms="aligned_alloc calloc dallocx free mallctl mallctlbymib mallctlnametomib malloc malloc_conf malloc_message malloc_stats_print malloc_usable_size mallocx nallocx posix_memalign rallocx realloc sallocx sdallocx xallocx"
dnl Check for additional platform-specific public API functions.
AC_CHECK_FUNC([memalign],
[AC_DEFINE([JEMALLOC_OVERRIDE_MEMALIGN], [ ])
public_syms="${public_syms} memalign"])
AC_CHECK_FUNC([valloc],
[AC_DEFINE([JEMALLOC_OVERRIDE_VALLOC], [ ])
public_syms="${public_syms} valloc"])
dnl Check for allocator-related functions that should be wrapped.
wrap_syms=
if test "x${JEMALLOC_PREFIX}" = "x" ; then
AC_CHECK_FUNC([__libc_calloc],
[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_CALLOC], [ ])
wrap_syms="${wrap_syms} __libc_calloc"])
AC_CHECK_FUNC([__libc_free],
[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_FREE], [ ])
wrap_syms="${wrap_syms} __libc_free"])
AC_CHECK_FUNC([__libc_malloc],
[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_MALLOC], [ ])
wrap_syms="${wrap_syms} __libc_malloc"])
AC_CHECK_FUNC([__libc_memalign],
[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_MEMALIGN], [ ])
wrap_syms="${wrap_syms} __libc_memalign"])
AC_CHECK_FUNC([__libc_realloc],
[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_REALLOC], [ ])
wrap_syms="${wrap_syms} __libc_realloc"])
AC_CHECK_FUNC([__libc_valloc],
[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_VALLOC], [ ])
wrap_syms="${wrap_syms} __libc_valloc"])
AC_CHECK_FUNC([__posix_memalign],
[AC_DEFINE([JEMALLOC_OVERRIDE___POSIX_MEMALIGN], [ ])
wrap_syms="${wrap_syms} __posix_memalign"])
fi
case "${host}" in
*-*-mingw* | *-*-cygwin*)
wrap_syms="${wrap_syms} tls_callback"
;;
*)
;;
esac
dnl Mangle library-private APIs. dnl Mangle library-private APIs.
AC_ARG_WITH([private_namespace], AC_ARG_WITH([private_namespace],
[AS_HELP_STRING([--with-private-namespace=<prefix>], [Prefix to prepend to all library-private APIs])], [AS_HELP_STRING([--with-private-namespace=<prefix>], [Prefix to prepend to all library-private APIs])],
...@@ -528,58 +910,72 @@ AC_ARG_WITH([install_suffix], ...@@ -528,58 +910,72 @@ AC_ARG_WITH([install_suffix],
install_suffix="$INSTALL_SUFFIX" install_suffix="$INSTALL_SUFFIX"
AC_SUBST([install_suffix]) AC_SUBST([install_suffix])
dnl Specify default malloc_conf.
AC_ARG_WITH([malloc_conf],
[AS_HELP_STRING([--with-malloc-conf=<malloc_conf>], [config.malloc_conf options string])],
[JEMALLOC_CONFIG_MALLOC_CONF="$with_malloc_conf"],
[JEMALLOC_CONFIG_MALLOC_CONF=""]
)
config_malloc_conf="$JEMALLOC_CONFIG_MALLOC_CONF"
AC_DEFINE_UNQUOTED([JEMALLOC_CONFIG_MALLOC_CONF], ["$config_malloc_conf"])
dnl Substitute @je_@ in jemalloc_protos.h.in, primarily to make generation of dnl Substitute @je_@ in jemalloc_protos.h.in, primarily to make generation of
dnl jemalloc_protos_jet.h easy. dnl jemalloc_protos_jet.h easy.
je_="je_" je_="je_"
AC_SUBST([je_]) AC_SUBST([je_])
cfgoutputs_in="${srcroot}Makefile.in" cfgoutputs_in="Makefile.in"
cfgoutputs_in="${cfgoutputs_in} ${srcroot}doc/html.xsl.in" cfgoutputs_in="${cfgoutputs_in} jemalloc.pc.in"
cfgoutputs_in="${cfgoutputs_in} ${srcroot}doc/manpages.xsl.in" cfgoutputs_in="${cfgoutputs_in} doc/html.xsl.in"
cfgoutputs_in="${cfgoutputs_in} ${srcroot}doc/jemalloc.xml.in" cfgoutputs_in="${cfgoutputs_in} doc/manpages.xsl.in"
cfgoutputs_in="${cfgoutputs_in} ${srcroot}include/jemalloc/jemalloc_macros.h.in" cfgoutputs_in="${cfgoutputs_in} doc/jemalloc.xml.in"
cfgoutputs_in="${cfgoutputs_in} ${srcroot}include/jemalloc/jemalloc_protos.h.in" cfgoutputs_in="${cfgoutputs_in} include/jemalloc/jemalloc_macros.h.in"
cfgoutputs_in="${cfgoutputs_in} ${srcroot}include/jemalloc/internal/jemalloc_internal.h.in" cfgoutputs_in="${cfgoutputs_in} include/jemalloc/jemalloc_protos.h.in"
cfgoutputs_in="${cfgoutputs_in} ${srcroot}test/test.sh.in" cfgoutputs_in="${cfgoutputs_in} include/jemalloc/jemalloc_typedefs.h.in"
cfgoutputs_in="${cfgoutputs_in} ${srcroot}test/include/test/jemalloc_test.h.in" cfgoutputs_in="${cfgoutputs_in} include/jemalloc/internal/jemalloc_preamble.h.in"
cfgoutputs_in="${cfgoutputs_in} test/test.sh.in"
cfgoutputs_in="${cfgoutputs_in} test/include/test/jemalloc_test.h.in"
cfgoutputs_out="Makefile" cfgoutputs_out="Makefile"
cfgoutputs_out="${cfgoutputs_out} jemalloc.pc"
cfgoutputs_out="${cfgoutputs_out} doc/html.xsl" cfgoutputs_out="${cfgoutputs_out} doc/html.xsl"
cfgoutputs_out="${cfgoutputs_out} doc/manpages.xsl" cfgoutputs_out="${cfgoutputs_out} doc/manpages.xsl"
cfgoutputs_out="${cfgoutputs_out} doc/jemalloc.xml" cfgoutputs_out="${cfgoutputs_out} doc/jemalloc.xml"
cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_macros.h" cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_macros.h"
cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_protos.h" cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_protos.h"
cfgoutputs_out="${cfgoutputs_out} include/jemalloc/internal/jemalloc_internal.h" cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_typedefs.h"
cfgoutputs_out="${cfgoutputs_out} include/jemalloc/internal/jemalloc_preamble.h"
cfgoutputs_out="${cfgoutputs_out} test/test.sh" cfgoutputs_out="${cfgoutputs_out} test/test.sh"
cfgoutputs_out="${cfgoutputs_out} test/include/test/jemalloc_test.h" cfgoutputs_out="${cfgoutputs_out} test/include/test/jemalloc_test.h"
cfgoutputs_tup="Makefile" cfgoutputs_tup="Makefile"
cfgoutputs_tup="${cfgoutputs_tup} jemalloc.pc:jemalloc.pc.in"
cfgoutputs_tup="${cfgoutputs_tup} doc/html.xsl:doc/html.xsl.in" cfgoutputs_tup="${cfgoutputs_tup} doc/html.xsl:doc/html.xsl.in"
cfgoutputs_tup="${cfgoutputs_tup} doc/manpages.xsl:doc/manpages.xsl.in" cfgoutputs_tup="${cfgoutputs_tup} doc/manpages.xsl:doc/manpages.xsl.in"
cfgoutputs_tup="${cfgoutputs_tup} doc/jemalloc.xml:doc/jemalloc.xml.in" cfgoutputs_tup="${cfgoutputs_tup} doc/jemalloc.xml:doc/jemalloc.xml.in"
cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_macros.h:include/jemalloc/jemalloc_macros.h.in" cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_macros.h:include/jemalloc/jemalloc_macros.h.in"
cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_protos.h:include/jemalloc/jemalloc_protos.h.in" cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_protos.h:include/jemalloc/jemalloc_protos.h.in"
cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/internal/jemalloc_internal.h" cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_typedefs.h:include/jemalloc/jemalloc_typedefs.h.in"
cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/internal/jemalloc_preamble.h"
cfgoutputs_tup="${cfgoutputs_tup} test/test.sh:test/test.sh.in" cfgoutputs_tup="${cfgoutputs_tup} test/test.sh:test/test.sh.in"
cfgoutputs_tup="${cfgoutputs_tup} test/include/test/jemalloc_test.h:test/include/test/jemalloc_test.h.in" cfgoutputs_tup="${cfgoutputs_tup} test/include/test/jemalloc_test.h:test/include/test/jemalloc_test.h.in"
cfghdrs_in="${srcroot}include/jemalloc/jemalloc_defs.h.in" cfghdrs_in="include/jemalloc/jemalloc_defs.h.in"
cfghdrs_in="${cfghdrs_in} ${srcroot}include/jemalloc/internal/jemalloc_internal_defs.h.in" cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/jemalloc_internal_defs.h.in"
cfghdrs_in="${cfghdrs_in} ${srcroot}include/jemalloc/internal/private_namespace.sh" cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/private_symbols.sh"
cfghdrs_in="${cfghdrs_in} ${srcroot}include/jemalloc/internal/private_unnamespace.sh" cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/private_namespace.sh"
cfghdrs_in="${cfghdrs_in} ${srcroot}include/jemalloc/internal/private_symbols.txt" cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/public_namespace.sh"
cfghdrs_in="${cfghdrs_in} ${srcroot}include/jemalloc/internal/public_namespace.sh" cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/public_unnamespace.sh"
cfghdrs_in="${cfghdrs_in} ${srcroot}include/jemalloc/internal/public_unnamespace.sh" cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/size_classes.sh"
cfghdrs_in="${cfghdrs_in} ${srcroot}include/jemalloc/internal/size_classes.sh" cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc_rename.sh"
cfghdrs_in="${cfghdrs_in} ${srcroot}include/jemalloc/jemalloc_rename.sh" cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc_mangle.sh"
cfghdrs_in="${cfghdrs_in} ${srcroot}include/jemalloc/jemalloc_mangle.sh" cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc.sh"
cfghdrs_in="${cfghdrs_in} ${srcroot}include/jemalloc/jemalloc.sh" cfghdrs_in="${cfghdrs_in} test/include/test/jemalloc_test_defs.h.in"
cfghdrs_in="${cfghdrs_in} ${srcroot}test/include/test/jemalloc_test_defs.h.in"
cfghdrs_out="include/jemalloc/jemalloc_defs.h" cfghdrs_out="include/jemalloc/jemalloc_defs.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc${install_suffix}.h" cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc${install_suffix}.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/private_namespace.h" cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/private_symbols.awk"
cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/private_unnamespace.h" cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/private_symbols_jet.awk"
cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_symbols.txt" cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_symbols.txt"
cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_namespace.h" cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_namespace.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_unnamespace.h" cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_unnamespace.h"
...@@ -592,29 +988,13 @@ cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/jemalloc_internal_defs.h" ...@@ -592,29 +988,13 @@ cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/jemalloc_internal_defs.h"
cfghdrs_out="${cfghdrs_out} test/include/test/jemalloc_test_defs.h" cfghdrs_out="${cfghdrs_out} test/include/test/jemalloc_test_defs.h"
cfghdrs_tup="include/jemalloc/jemalloc_defs.h:include/jemalloc/jemalloc_defs.h.in" cfghdrs_tup="include/jemalloc/jemalloc_defs.h:include/jemalloc/jemalloc_defs.h.in"
cfghdrs_tup="${cfghdrs_tup} include/jemalloc/internal/jemalloc_internal_defs.h:${srcroot}include/jemalloc/internal/jemalloc_internal_defs.h.in" cfghdrs_tup="${cfghdrs_tup} include/jemalloc/internal/jemalloc_internal_defs.h:include/jemalloc/internal/jemalloc_internal_defs.h.in"
cfghdrs_tup="${cfghdrs_tup} test/include/test/jemalloc_test_defs.h:${srcroot}test/include/test/jemalloc_test_defs.h.in" cfghdrs_tup="${cfghdrs_tup} test/include/test/jemalloc_test_defs.h:test/include/test/jemalloc_test_defs.h.in"
dnl Do not silence irrelevant compiler warnings by default, since enabling this
dnl option incurs a performance penalty.
AC_ARG_ENABLE([cc-silence],
[AS_HELP_STRING([--enable-cc-silence],
[Silence irrelevant compiler warnings])],
[if test "x$enable_cc_silence" = "xno" ; then
enable_cc_silence="0"
else
enable_cc_silence="1"
fi
],
[enable_cc_silence="0"]
)
if test "x$enable_cc_silence" = "x1" ; then
AC_DEFINE([JEMALLOC_CC_SILENCE], [ ])
fi
dnl Do not compile with debugging by default. dnl Do not compile with debugging by default.
AC_ARG_ENABLE([debug], AC_ARG_ENABLE([debug],
[AS_HELP_STRING([--enable-debug], [Build debugging code (implies --enable-ivsalloc)])], [AS_HELP_STRING([--enable-debug],
[Build debugging code])],
[if test "x$enable_debug" = "xno" ; then [if test "x$enable_debug" = "xno" ; then
enable_debug="0" enable_debug="0"
else else
...@@ -625,39 +1005,24 @@ fi ...@@ -625,39 +1005,24 @@ fi
) )
if test "x$enable_debug" = "x1" ; then if test "x$enable_debug" = "x1" ; then
AC_DEFINE([JEMALLOC_DEBUG], [ ]) AC_DEFINE([JEMALLOC_DEBUG], [ ])
enable_ivsalloc="1"
fi fi
AC_SUBST([enable_debug]) if test "x$enable_debug" = "x1" ; then
AC_DEFINE([JEMALLOC_DEBUG], [ ])
dnl Do not validate pointers by default.
AC_ARG_ENABLE([ivsalloc],
[AS_HELP_STRING([--enable-ivsalloc], [Validate pointers passed through the public API])],
[if test "x$enable_ivsalloc" = "xno" ; then
enable_ivsalloc="0"
else
enable_ivsalloc="1"
fi
],
[enable_ivsalloc="0"]
)
if test "x$enable_ivsalloc" = "x1" ; then
AC_DEFINE([JEMALLOC_IVSALLOC], [ ])
fi fi
AC_SUBST([enable_debug])
dnl Only optimize if not debugging. dnl Only optimize if not debugging.
if test "x$enable_debug" = "x0" -a "x$no_CFLAGS" = "xyes" ; then if test "x$enable_debug" = "x0" ; then
dnl Make sure that an optimization flag was not specified in EXTRA_CFLAGS. if test "x$GCC" = "xyes" ; then
optimize="no" JE_CFLAGS_ADD([-O3])
echo "$CFLAGS $EXTRA_CFLAGS" | grep '\-O' >/dev/null || optimize="yes" JE_CXXFLAGS_ADD([-O3])
if test "x${optimize}" = "xyes" ; then JE_CFLAGS_ADD([-funroll-loops])
if test "x$GCC" = "xyes" ; then elif test "x$je_cv_msvc" = "xyes" ; then
JE_CFLAGS_APPEND([-O3]) JE_CFLAGS_ADD([-O2])
JE_CFLAGS_APPEND([-funroll-loops]) JE_CXXFLAGS_ADD([-O2])
elif test "x$je_cv_msvc" = "xyes" ; then else
JE_CFLAGS_APPEND([-O2]) JE_CFLAGS_ADD([-O])
else JE_CXXFLAGS_ADD([-O])
JE_CFLAGS_APPEND([-O])
fi
fi fi
fi fi
...@@ -721,10 +1086,10 @@ fi, ...@@ -721,10 +1086,10 @@ fi,
if test "x$backtrace_method" = "x" -a "x$enable_prof_libunwind" = "x1" ; then if test "x$backtrace_method" = "x" -a "x$enable_prof_libunwind" = "x1" ; then
AC_CHECK_HEADERS([libunwind.h], , [enable_prof_libunwind="0"]) AC_CHECK_HEADERS([libunwind.h], , [enable_prof_libunwind="0"])
if test "x$LUNWIND" = "x-lunwind" ; then if test "x$LUNWIND" = "x-lunwind" ; then
AC_CHECK_LIB([unwind], [backtrace], [LIBS="$LIBS $LUNWIND"], AC_CHECK_LIB([unwind], [unw_backtrace], [JE_APPEND_VS(LIBS, $LUNWIND)],
[enable_prof_libunwind="0"]) [enable_prof_libunwind="0"])
else else
LIBS="$LIBS $LUNWIND" JE_APPEND_VS(LIBS, $LUNWIND)
fi fi
if test "x${enable_prof_libunwind}" = "x1" ; then if test "x${enable_prof_libunwind}" = "x1" ; then
backtrace_method="libunwind" backtrace_method="libunwind"
...@@ -746,7 +1111,9 @@ fi ...@@ -746,7 +1111,9 @@ fi
if test "x$backtrace_method" = "x" -a "x$enable_prof_libgcc" = "x1" \ if test "x$backtrace_method" = "x" -a "x$enable_prof_libgcc" = "x1" \
-a "x$GCC" = "xyes" ; then -a "x$GCC" = "xyes" ; then
AC_CHECK_HEADERS([unwind.h], , [enable_prof_libgcc="0"]) AC_CHECK_HEADERS([unwind.h], , [enable_prof_libgcc="0"])
AC_CHECK_LIB([gcc], [_Unwind_Backtrace], [LIBS="$LIBS -lgcc"], [enable_prof_libgcc="0"]) if test "x${enable_prof_libgcc}" = "x1" ; then
AC_CHECK_LIB([gcc], [_Unwind_Backtrace], [JE_APPEND_VS(LIBS, -lgcc)], [enable_prof_libgcc="0"])
fi
if test "x${enable_prof_libgcc}" = "x1" ; then if test "x${enable_prof_libgcc}" = "x1" ; then
backtrace_method="libgcc" backtrace_method="libgcc"
AC_DEFINE([JEMALLOC_PROF_LIBGCC], [ ]) AC_DEFINE([JEMALLOC_PROF_LIBGCC], [ ])
...@@ -768,7 +1135,7 @@ fi ...@@ -768,7 +1135,7 @@ fi
) )
if test "x$backtrace_method" = "x" -a "x$enable_prof_gcc" = "x1" \ if test "x$backtrace_method" = "x" -a "x$enable_prof_gcc" = "x1" \
-a "x$GCC" = "xyes" ; then -a "x$GCC" = "xyes" ; then
JE_CFLAGS_APPEND([-fno-omit-frame-pointer]) JE_CFLAGS_ADD([-fno-omit-frame-pointer])
backtrace_method="gcc intrinsics" backtrace_method="gcc intrinsics"
AC_DEFINE([JEMALLOC_PROF_GCC], [ ]) AC_DEFINE([JEMALLOC_PROF_GCC], [ ])
else else
...@@ -782,112 +1149,44 @@ fi ...@@ -782,112 +1149,44 @@ fi
AC_MSG_CHECKING([configured backtracing method]) AC_MSG_CHECKING([configured backtracing method])
AC_MSG_RESULT([$backtrace_method]) AC_MSG_RESULT([$backtrace_method])
if test "x$enable_prof" = "x1" ; then if test "x$enable_prof" = "x1" ; then
if test "x${force_tls}" = "x0" ; then dnl Heap profiling uses the log(3) function.
AC_MSG_ERROR([Heap profiling requires TLS]); JE_APPEND_VS(LIBS, $LM)
fi
force_tls="1"
if test "x$abi" != "xpecoff"; then
dnl Heap profiling uses the log(3) function.
LIBS="$LIBS -lm"
fi
AC_DEFINE([JEMALLOC_PROF], [ ]) AC_DEFINE([JEMALLOC_PROF], [ ])
fi fi
AC_SUBST([enable_prof]) AC_SUBST([enable_prof])
dnl Enable thread-specific caching by default. dnl Indicate whether adjacent virtual memory mappings automatically coalesce
AC_ARG_ENABLE([tcache], dnl (and fragment on demand).
[AS_HELP_STRING([--disable-tcache], [Disable per thread caches])], if test "x${maps_coalesce}" = "x1" ; then
[if test "x$enable_tcache" = "xno" ; then AC_DEFINE([JEMALLOC_MAPS_COALESCE], [ ])
enable_tcache="0"
else
enable_tcache="1"
fi
],
[enable_tcache="1"]
)
if test "x$enable_tcache" = "x1" ; then
AC_DEFINE([JEMALLOC_TCACHE], [ ])
fi fi
AC_SUBST([enable_tcache])
dnl Disable mremap() for huge realloc() by default. dnl Indicate whether to retain memory (rather than using munmap()) by default.
AC_ARG_ENABLE([mremap], if test "x$default_retain" = "x1" ; then
[AS_HELP_STRING([--enable-mremap], [Enable mremap(2) for huge realloc()])], AC_DEFINE([JEMALLOC_RETAIN], [ ])
[if test "x$enable_mremap" = "xno" ; then
enable_mremap="0"
else
enable_mremap="1"
fi
],
[enable_mremap="0"]
)
if test "x$enable_mremap" = "x1" ; then
JE_COMPILABLE([mremap(...MREMAP_FIXED...)], [
#define _GNU_SOURCE
#include <sys/mman.h>
], [
void *p = mremap((void *)0, 0, 0, MREMAP_MAYMOVE|MREMAP_FIXED, (void *)0);
], [je_cv_mremap_fixed])
if test "x${je_cv_mremap_fixed}" = "xno" ; then
enable_mremap="0"
fi
fi
if test "x$enable_mremap" = "x1" ; then
AC_DEFINE([JEMALLOC_MREMAP], [ ])
fi fi
AC_SUBST([enable_mremap])
dnl Enable VM deallocation via munmap() by default. dnl Enable allocation from DSS if supported by the OS.
AC_ARG_ENABLE([munmap], have_dss="1"
[AS_HELP_STRING([--disable-munmap], [Disable VM deallocation via munmap(2)])],
[if test "x$enable_munmap" = "xno" ; then
enable_munmap="0"
else
enable_munmap="1"
fi
],
[enable_munmap="${default_munmap}"]
)
if test "x$enable_munmap" = "x1" ; then
AC_DEFINE([JEMALLOC_MUNMAP], [ ])
fi
AC_SUBST([enable_munmap])
dnl Do not enable allocation from DSS by default.
AC_ARG_ENABLE([dss],
[AS_HELP_STRING([--enable-dss], [Enable allocation from DSS])],
[if test "x$enable_dss" = "xno" ; then
enable_dss="0"
else
enable_dss="1"
fi
],
[enable_dss="0"]
)
dnl Check whether the BSD/SUSv1 sbrk() exists. If not, disable DSS support. dnl Check whether the BSD/SUSv1 sbrk() exists. If not, disable DSS support.
AC_CHECK_FUNC([sbrk], [have_sbrk="1"], [have_sbrk="0"]) AC_CHECK_FUNC([sbrk], [have_sbrk="1"], [have_sbrk="0"])
if test "x$have_sbrk" = "x1" ; then if test "x$have_sbrk" = "x1" ; then
if test "x$sbrk_deprecated" == "x1" ; then if test "x$sbrk_deprecated" = "x1" ; then
AC_MSG_RESULT([Disabling dss allocation because sbrk is deprecated]) AC_MSG_RESULT([Disabling dss allocation because sbrk is deprecated])
enable_dss="0" have_dss="0"
else
AC_DEFINE([JEMALLOC_HAVE_SBRK], [ ])
fi fi
else else
enable_dss="0" have_dss="0"
fi fi
if test "x$enable_dss" = "x1" ; then if test "x$have_dss" = "x1" ; then
AC_DEFINE([JEMALLOC_DSS], [ ]) AC_DEFINE([JEMALLOC_DSS], [ ])
fi fi
AC_SUBST([enable_dss])
dnl Support the junk/zero filling option by default. dnl Support the junk/zero filling option by default.
AC_ARG_ENABLE([fill], AC_ARG_ENABLE([fill],
[AS_HELP_STRING([--disable-fill], [AS_HELP_STRING([--disable-fill], [Disable support for junk/zero filling])],
[Disable support for junk/zero filling, quarantine, and redzones])],
[if test "x$enable_fill" = "xno" ; then [if test "x$enable_fill" = "xno" ; then
enable_fill="0" enable_fill="0"
else else
...@@ -929,35 +1228,6 @@ if test "x$enable_utrace" = "x1" ; then ...@@ -929,35 +1228,6 @@ if test "x$enable_utrace" = "x1" ; then
fi fi
AC_SUBST([enable_utrace]) AC_SUBST([enable_utrace])
dnl Support Valgrind by default.
AC_ARG_ENABLE([valgrind],
[AS_HELP_STRING([--disable-valgrind], [Disable support for Valgrind])],
[if test "x$enable_valgrind" = "xno" ; then
enable_valgrind="0"
else
enable_valgrind="1"
fi
],
[enable_valgrind="1"]
)
if test "x$enable_valgrind" = "x1" ; then
JE_COMPILABLE([valgrind], [
#include <valgrind/valgrind.h>
#include <valgrind/memcheck.h>
#if !defined(VALGRIND_RESIZEINPLACE_BLOCK)
# error "Incompatible Valgrind version"
#endif
], [], [je_cv_valgrind])
if test "x${je_cv_valgrind}" = "xno" ; then
enable_valgrind="0"
fi
if test "x$enable_valgrind" = "x1" ; then
AC_DEFINE([JEMALLOC_VALGRIND], [ ])
fi
fi
AC_SUBST([enable_valgrind])
dnl Do not support the xmalloc option by default. dnl Do not support the xmalloc option by default.
AC_ARG_ENABLE([xmalloc], AC_ARG_ENABLE([xmalloc],
[AS_HELP_STRING([--enable-xmalloc], [Support xmalloc option])], [AS_HELP_STRING([--enable-xmalloc], [Support xmalloc option])],
...@@ -974,8 +1244,110 @@ if test "x$enable_xmalloc" = "x1" ; then ...@@ -974,8 +1244,110 @@ if test "x$enable_xmalloc" = "x1" ; then
fi fi
AC_SUBST([enable_xmalloc]) AC_SUBST([enable_xmalloc])
AC_CACHE_CHECK([STATIC_PAGE_SHIFT], dnl Support cache-oblivious allocation alignment by default.
[je_cv_static_page_shift], AC_ARG_ENABLE([cache-oblivious],
[AS_HELP_STRING([--disable-cache-oblivious],
[Disable support for cache-oblivious allocation alignment])],
[if test "x$enable_cache_oblivious" = "xno" ; then
enable_cache_oblivious="0"
else
enable_cache_oblivious="1"
fi
],
[enable_cache_oblivious="1"]
)
if test "x$enable_cache_oblivious" = "x1" ; then
AC_DEFINE([JEMALLOC_CACHE_OBLIVIOUS], [ ])
fi
AC_SUBST([enable_cache_oblivious])
dnl Do not log by default.
AC_ARG_ENABLE([log],
[AS_HELP_STRING([--enable-log], [Support debug logging])],
[if test "x$enable_log" = "xno" ; then
enable_log="0"
else
enable_log="1"
fi
],
[enable_log="0"]
)
if test "x$enable_log" = "x1" ; then
AC_DEFINE([JEMALLOC_LOG], [ ])
fi
AC_SUBST([enable_log])
JE_COMPILABLE([a program using __builtin_unreachable], [
void foo (void) {
__builtin_unreachable();
}
], [
{
foo();
}
], [je_cv_gcc_builtin_unreachable])
if test "x${je_cv_gcc_builtin_unreachable}" = "xyes" ; then
AC_DEFINE([JEMALLOC_INTERNAL_UNREACHABLE], [__builtin_unreachable])
else
AC_DEFINE([JEMALLOC_INTERNAL_UNREACHABLE], [abort])
fi
dnl ============================================================================
dnl Check for __builtin_ffsl(), then ffsl(3), and fail if neither are found.
dnl One of those two functions should (theoretically) exist on all platforms
dnl that jemalloc currently has a chance of functioning on without modification.
dnl We additionally assume ffs[ll]() or __builtin_ffs[ll]() are defined if
dnl ffsl() or __builtin_ffsl() are defined, respectively.
JE_COMPILABLE([a program using __builtin_ffsl], [
#include <stdio.h>
#include <strings.h>
#include <string.h>
], [
{
int rv = __builtin_ffsl(0x08);
printf("%d\n", rv);
}
], [je_cv_gcc_builtin_ffsl])
if test "x${je_cv_gcc_builtin_ffsl}" = "xyes" ; then
AC_DEFINE([JEMALLOC_INTERNAL_FFSLL], [__builtin_ffsll])
AC_DEFINE([JEMALLOC_INTERNAL_FFSL], [__builtin_ffsl])
AC_DEFINE([JEMALLOC_INTERNAL_FFS], [__builtin_ffs])
else
JE_COMPILABLE([a program using ffsl], [
#include <stdio.h>
#include <strings.h>
#include <string.h>
], [
{
int rv = ffsl(0x08);
printf("%d\n", rv);
}
], [je_cv_function_ffsl])
if test "x${je_cv_function_ffsl}" = "xyes" ; then
AC_DEFINE([JEMALLOC_INTERNAL_FFSLL], [ffsll])
AC_DEFINE([JEMALLOC_INTERNAL_FFSL], [ffsl])
AC_DEFINE([JEMALLOC_INTERNAL_FFS], [ffs])
else
AC_MSG_ERROR([Cannot build without ffsl(3) or __builtin_ffsl()])
fi
fi
AC_ARG_WITH([lg_quantum],
[AS_HELP_STRING([--with-lg-quantum=<lg-quantum>],
[Base 2 log of minimum allocation alignment])],
[LG_QUANTA="$with_lg_quantum"],
[LG_QUANTA="3 4"])
if test "x$with_lg_quantum" != "x" ; then
AC_DEFINE_UNQUOTED([LG_QUANTUM], [$with_lg_quantum])
fi
AC_ARG_WITH([lg_page],
[AS_HELP_STRING([--with-lg-page=<lg-page>], [Base 2 log of system page size])],
[LG_PAGE="$with_lg_page"], [LG_PAGE="detect"])
if test "x$LG_PAGE" = "xdetect"; then
AC_CACHE_CHECK([LG_PAGE],
[je_cv_lg_page],
AC_RUN_IFELSE([AC_LANG_PROGRAM( AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[ [[
#include <strings.h> #include <strings.h>
...@@ -1000,35 +1372,117 @@ AC_CACHE_CHECK([STATIC_PAGE_SHIFT], ...@@ -1000,35 +1372,117 @@ AC_CACHE_CHECK([STATIC_PAGE_SHIFT],
if (result == -1) { if (result == -1) {
return 1; return 1;
} }
result = ffsl(result) - 1; result = JEMALLOC_INTERNAL_FFSL(result) - 1;
f = fopen("conftest.out", "w"); f = fopen("conftest.out", "w");
if (f == NULL) { if (f == NULL) {
return 1; return 1;
} }
fprintf(f, "%d\n", result); fprintf(f, "%d", result);
fclose(f); fclose(f);
return 0; return 0;
]])], ]])],
[je_cv_static_page_shift=`cat conftest.out`], [je_cv_lg_page=`cat conftest.out`],
[je_cv_static_page_shift=undefined])) [je_cv_lg_page=undefined],
[je_cv_lg_page=12]))
if test "x$je_cv_static_page_shift" != "xundefined"; then fi
AC_DEFINE_UNQUOTED([STATIC_PAGE_SHIFT], [$je_cv_static_page_shift]) if test "x${je_cv_lg_page}" != "x" ; then
LG_PAGE="${je_cv_lg_page}"
fi
if test "x${LG_PAGE}" != "xundefined" ; then
AC_DEFINE_UNQUOTED([LG_PAGE], [$LG_PAGE])
else else
AC_MSG_ERROR([cannot determine value for STATIC_PAGE_SHIFT]) AC_MSG_ERROR([cannot determine value for LG_PAGE])
fi
AC_ARG_WITH([lg_hugepage],
[AS_HELP_STRING([--with-lg-hugepage=<lg-hugepage>],
[Base 2 log of system huge page size])],
[je_cv_lg_hugepage="${with_lg_hugepage}"],
[je_cv_lg_hugepage=""])
if test "x${je_cv_lg_hugepage}" = "x" ; then
dnl Look in /proc/meminfo (Linux-specific) for information on the default huge
dnl page size, if any. The relevant line looks like:
dnl
dnl Hugepagesize: 2048 kB
if test -e "/proc/meminfo" ; then
hpsk=[`cat /proc/meminfo 2>/dev/null | \
grep -e '^Hugepagesize:[[:space:]]\+[0-9]\+[[:space:]]kB$' | \
awk '{print $2}'`]
if test "x${hpsk}" != "x" ; then
je_cv_lg_hugepage=10
while test "${hpsk}" -gt 1 ; do
hpsk="$((hpsk / 2))"
je_cv_lg_hugepage="$((je_cv_lg_hugepage + 1))"
done
fi
fi
dnl Set default if unable to automatically configure.
if test "x${je_cv_lg_hugepage}" = "x" ; then
je_cv_lg_hugepage=21
fi
fi
if test "x${LG_PAGE}" != "xundefined" -a \
"${je_cv_lg_hugepage}" -lt "${LG_PAGE}" ; then
AC_MSG_ERROR([Huge page size (2^${je_cv_lg_hugepage}) must be at least page size (2^${LG_PAGE})])
fi fi
AC_DEFINE_UNQUOTED([LG_HUGEPAGE], [${je_cv_lg_hugepage}])
AC_ARG_WITH([lg_page_sizes],
[AS_HELP_STRING([--with-lg-page-sizes=<lg-page-sizes>],
[Base 2 logs of system page sizes to support])],
[LG_PAGE_SIZES="$with_lg_page_sizes"], [LG_PAGE_SIZES="$LG_PAGE"])
dnl ============================================================================ dnl ============================================================================
dnl jemalloc configuration. dnl jemalloc configuration.
dnl dnl
dnl Set VERSION if source directory has an embedded git repository. AC_ARG_WITH([version],
if test -d "${srcroot}.git" ; then [AS_HELP_STRING([--with-version=<major>.<minor>.<bugfix>-<nrev>-g<gid>],
git describe --long --abbrev=40 > ${srcroot}VERSION [Version string])],
[
echo "${with_version}" | grep ['^[0-9]\+\.[0-9]\+\.[0-9]\+-[0-9]\+-g[0-9a-f]\+$'] 2>&1 1>/dev/null
if test $? -eq 0 ; then
echo "$with_version" > "${objroot}VERSION"
else
echo "${with_version}" | grep ['^VERSION$'] 2>&1 1>/dev/null
if test $? -ne 0 ; then
AC_MSG_ERROR([${with_version} does not match <major>.<minor>.<bugfix>-<nrev>-g<gid> or VERSION])
fi
fi
], [
dnl Set VERSION if source directory is inside a git repository.
if test "x`test ! \"${srcroot}\" && cd \"${srcroot}\"; git rev-parse --is-inside-work-tree 2>/dev/null`" = "xtrue" ; then
dnl Pattern globs aren't powerful enough to match both single- and
dnl double-digit version numbers, so iterate over patterns to support up
dnl to version 99.99.99 without any accidental matches.
for pattern in ['[0-9].[0-9].[0-9]' '[0-9].[0-9].[0-9][0-9]' \
'[0-9].[0-9][0-9].[0-9]' '[0-9].[0-9][0-9].[0-9][0-9]' \
'[0-9][0-9].[0-9].[0-9]' '[0-9][0-9].[0-9].[0-9][0-9]' \
'[0-9][0-9].[0-9][0-9].[0-9]' \
'[0-9][0-9].[0-9][0-9].[0-9][0-9]']; do
(test ! "${srcroot}" && cd "${srcroot}"; git describe --long --abbrev=40 --match="${pattern}") > "${objroot}VERSION.tmp" 2>/dev/null
if test $? -eq 0 ; then
mv "${objroot}VERSION.tmp" "${objroot}VERSION"
break
fi
done
fi
rm -f "${objroot}VERSION.tmp"
])
if test ! -e "${objroot}VERSION" ; then
if test ! -e "${srcroot}VERSION" ; then
AC_MSG_RESULT(
[Missing VERSION file, and unable to generate it; creating bogus VERSION])
echo "0.0.0-0-g0000000000000000000000000000000000000000" > "${objroot}VERSION"
else
cp ${srcroot}VERSION ${objroot}VERSION
fi
fi fi
jemalloc_version=`cat ${srcroot}VERSION` jemalloc_version=`cat "${objroot}VERSION"`
jemalloc_version_major=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]1}'` jemalloc_version_major=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]1}'`
jemalloc_version_minor=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]2}'` jemalloc_version_minor=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]2}'`
jemalloc_version_bugfix=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]3}'` jemalloc_version_bugfix=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]3}'`
...@@ -1045,15 +1499,164 @@ dnl ============================================================================ ...@@ -1045,15 +1499,164 @@ dnl ============================================================================
dnl Configure pthreads. dnl Configure pthreads.
if test "x$abi" != "xpecoff" ; then if test "x$abi" != "xpecoff" ; then
AC_DEFINE([JEMALLOC_HAVE_PTHREAD], [ ])
AC_CHECK_HEADERS([pthread.h], , [AC_MSG_ERROR([pthread.h is missing])]) AC_CHECK_HEADERS([pthread.h], , [AC_MSG_ERROR([pthread.h is missing])])
dnl Some systems may embed pthreads functionality in libc; check for libpthread dnl Some systems may embed pthreads functionality in libc; check for libpthread
dnl first, but try libc too before failing. dnl first, but try libc too before failing.
AC_CHECK_LIB([pthread], [pthread_create], [LIBS="$LIBS -lpthread"], AC_CHECK_LIB([pthread], [pthread_create], [JE_APPEND_VS(LIBS, -lpthread)],
[AC_SEARCH_LIBS([pthread_create], , , [AC_SEARCH_LIBS([pthread_create], , ,
AC_MSG_ERROR([libpthread is missing]))]) AC_MSG_ERROR([libpthread is missing]))])
wrap_syms="${wrap_syms} pthread_create"
have_pthread="1"
dnl Check if we have dlsym support.
have_dlsym="1"
AC_CHECK_HEADERS([dlfcn.h],
AC_CHECK_FUNC([dlsym], [],
[AC_CHECK_LIB([dl], [dlsym], [LIBS="$LIBS -ldl"], [have_dlsym="0"])]),
[have_dlsym="0"])
if test "x$have_dlsym" = "x1" ; then
AC_DEFINE([JEMALLOC_HAVE_DLSYM], [ ])
fi
JE_COMPILABLE([pthread_atfork(3)], [
#include <pthread.h>
], [
pthread_atfork((void *)0, (void *)0, (void *)0);
], [je_cv_pthread_atfork])
if test "x${je_cv_pthread_atfork}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_PTHREAD_ATFORK], [ ])
fi
dnl Check if pthread_setname_np is available with the expected API.
JE_COMPILABLE([pthread_setname_np(3)], [
#include <pthread.h>
], [
pthread_setname_np(pthread_self(), "setname_test");
], [je_cv_pthread_setname_np])
if test "x${je_cv_pthread_setname_np}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_PTHREAD_SETNAME_NP], [ ])
fi
fi
JE_APPEND_VS(CPPFLAGS, -D_REENTRANT)
dnl Check whether clock_gettime(2) is in libc or librt.
AC_SEARCH_LIBS([clock_gettime], [rt])
dnl Cray wrapper compiler often adds `-lrt` when using `-static`. Check with
dnl `-dynamic` as well in case a user tries to dynamically link in jemalloc
if test "x$je_cv_cray_prgenv_wrapper" = "xyes" ; then
if test "$ac_cv_search_clock_gettime" != "-lrt"; then
JE_CFLAGS_SAVE()
unset ac_cv_search_clock_gettime
JE_CFLAGS_ADD([-dynamic])
AC_SEARCH_LIBS([clock_gettime], [rt])
JE_CFLAGS_RESTORE()
fi
fi fi
CPPFLAGS="$CPPFLAGS -D_REENTRANT" dnl check for CLOCK_MONOTONIC_COARSE (Linux-specific).
JE_COMPILABLE([clock_gettime(CLOCK_MONOTONIC_COARSE, ...)], [
#include <time.h>
], [
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
], [je_cv_clock_monotonic_coarse])
if test "x${je_cv_clock_monotonic_coarse}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE])
fi
dnl check for CLOCK_MONOTONIC.
JE_COMPILABLE([clock_gettime(CLOCK_MONOTONIC, ...)], [
#include <unistd.h>
#include <time.h>
], [
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
#if !defined(_POSIX_MONOTONIC_CLOCK) || _POSIX_MONOTONIC_CLOCK < 0
# error _POSIX_MONOTONIC_CLOCK missing/invalid
#endif
], [je_cv_clock_monotonic])
if test "x${je_cv_clock_monotonic}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_CLOCK_MONOTONIC])
fi
dnl Check for mach_absolute_time().
JE_COMPILABLE([mach_absolute_time()], [
#include <mach/mach_time.h>
], [
mach_absolute_time();
], [je_cv_mach_absolute_time])
if test "x${je_cv_mach_absolute_time}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_MACH_ABSOLUTE_TIME])
fi
dnl Use syscall(2) (if available) by default.
AC_ARG_ENABLE([syscall],
[AS_HELP_STRING([--disable-syscall], [Disable use of syscall(2)])],
[if test "x$enable_syscall" = "xno" ; then
enable_syscall="0"
else
enable_syscall="1"
fi
],
[enable_syscall="1"]
)
if test "x$enable_syscall" = "x1" ; then
dnl Check if syscall(2) is usable. Treat warnings as errors, so that e.g. OS
dnl X 10.12's deprecation warning prevents use.
JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-Werror])
JE_COMPILABLE([syscall(2)], [
#include <sys/syscall.h>
#include <unistd.h>
], [
syscall(SYS_write, 2, "hello", 5);
],
[je_cv_syscall])
JE_CFLAGS_RESTORE()
if test "x$je_cv_syscall" = "xyes" ; then
AC_DEFINE([JEMALLOC_USE_SYSCALL], [ ])
fi
fi
dnl Check if the GNU-specific secure_getenv function exists.
AC_CHECK_FUNC([secure_getenv],
[have_secure_getenv="1"],
[have_secure_getenv="0"]
)
if test "x$have_secure_getenv" = "x1" ; then
AC_DEFINE([JEMALLOC_HAVE_SECURE_GETENV], [ ])
fi
dnl Check if the GNU-specific sched_getcpu function exists.
AC_CHECK_FUNC([sched_getcpu],
[have_sched_getcpu="1"],
[have_sched_getcpu="0"]
)
if test "x$have_sched_getcpu" = "x1" ; then
AC_DEFINE([JEMALLOC_HAVE_SCHED_GETCPU], [ ])
fi
dnl Check if the GNU-specific sched_setaffinity function exists.
AC_CHECK_FUNC([sched_setaffinity],
[have_sched_setaffinity="1"],
[have_sched_setaffinity="0"]
)
if test "x$have_sched_setaffinity" = "x1" ; then
AC_DEFINE([JEMALLOC_HAVE_SCHED_SETAFFINITY], [ ])
fi
dnl Check if the Solaris/BSD issetugid function exists.
AC_CHECK_FUNC([issetugid],
[have_issetugid="1"],
[have_issetugid="0"]
)
if test "x$have_issetugid" = "x1" ; then
AC_DEFINE([JEMALLOC_HAVE_ISSETUGID], [ ])
fi
dnl Check whether the BSD-specific _malloc_thread_cleanup() exists. If so, use dnl Check whether the BSD-specific _malloc_thread_cleanup() exists. If so, use
dnl it rather than pthreads TSD cleanup functions to support cleanup during dnl it rather than pthreads TSD cleanup functions to support cleanup during
...@@ -1065,6 +1668,7 @@ AC_CHECK_FUNC([_malloc_thread_cleanup], ...@@ -1065,6 +1668,7 @@ AC_CHECK_FUNC([_malloc_thread_cleanup],
) )
if test "x$have__malloc_thread_cleanup" = "x1" ; then if test "x$have__malloc_thread_cleanup" = "x1" ; then
AC_DEFINE([JEMALLOC_MALLOC_THREAD_CLEANUP], [ ]) AC_DEFINE([JEMALLOC_MALLOC_THREAD_CLEANUP], [ ])
wrap_syms="${wrap_syms} _malloc_thread_cleanup"
force_tls="1" force_tls="1"
fi fi
...@@ -1077,6 +1681,7 @@ AC_CHECK_FUNC([_pthread_mutex_init_calloc_cb], ...@@ -1077,6 +1681,7 @@ AC_CHECK_FUNC([_pthread_mutex_init_calloc_cb],
) )
if test "x$have__pthread_mutex_init_calloc_cb" = "x1" ; then if test "x$have__pthread_mutex_init_calloc_cb" = "x1" ; then
AC_DEFINE([JEMALLOC_MUTEX_INIT_CB]) AC_DEFINE([JEMALLOC_MUTEX_INIT_CB])
wrap_syms="${wrap_syms} _malloc_prefork _malloc_postfork"
fi fi
dnl Disable lazy locking by default. dnl Disable lazy locking by default.
...@@ -1089,42 +1694,37 @@ else ...@@ -1089,42 +1694,37 @@ else
enable_lazy_lock="1" enable_lazy_lock="1"
fi fi
], ],
[enable_lazy_lock="0"] [enable_lazy_lock=""]
) )
if test "x$enable_lazy_lock" = "x0" -a "x${force_lazy_lock}" = "x1" ; then if test "x${enable_lazy_lock}" = "x" ; then
AC_MSG_RESULT([Forcing lazy-lock to avoid allocator/threading bootstrap issues]) if test "x${force_lazy_lock}" = "x1" ; then
enable_lazy_lock="1" AC_MSG_RESULT([Forcing lazy-lock to avoid allocator/threading bootstrap issues])
enable_lazy_lock="1"
else
enable_lazy_lock="0"
fi
fi
if test "x${enable_lazy_lock}" = "x1" -a "x${abi}" = "xpecoff" ; then
AC_MSG_RESULT([Forcing no lazy-lock because thread creation monitoring is unimplemented])
enable_lazy_lock="0"
fi fi
if test "x$enable_lazy_lock" = "x1" ; then if test "x$enable_lazy_lock" = "x1" ; then
if test "x$abi" != "xpecoff" ; then if test "x$have_dlsym" = "x1" ; then
AC_CHECK_HEADERS([dlfcn.h], , [AC_MSG_ERROR([dlfcn.h is missing])]) AC_DEFINE([JEMALLOC_LAZY_LOCK], [ ])
AC_CHECK_FUNC([dlsym], [], else
[AC_CHECK_LIB([dl], [dlsym], [LIBS="$LIBS -ldl"], AC_MSG_ERROR([Missing dlsym support: lazy-lock cannot be enabled.])
[AC_MSG_ERROR([libdl is missing])])
])
fi fi
AC_DEFINE([JEMALLOC_LAZY_LOCK], [ ])
fi fi
AC_SUBST([enable_lazy_lock]) AC_SUBST([enable_lazy_lock])
AC_ARG_ENABLE([tls], dnl Automatically configure TLS.
[AS_HELP_STRING([--disable-tls], [Disable thread-local storage (__thread keyword)])], if test "x${force_tls}" = "x1" ; then
if test "x$enable_tls" = "xno" ; then enable_tls="1"
elif test "x${force_tls}" = "x0" ; then
enable_tls="0" enable_tls="0"
else else
enable_tls="1" enable_tls="1"
fi fi
,
enable_tls="1"
)
if test "x${enable_tls}" = "x0" -a "x${force_tls}" = "x1" ; then
AC_MSG_RESULT([Forcing TLS to avoid allocator/threading bootstrap issues])
enable_tls="1"
fi
if test "x${enable_tls}" = "x1" -a "x${force_tls}" = "x0" ; then
AC_MSG_RESULT([Forcing no TLS to avoid allocator/threading bootstrap issues])
enable_tls="0"
fi
if test "x${enable_tls}" = "x1" ; then if test "x${enable_tls}" = "x1" ; then
AC_MSG_CHECKING([for TLS]) AC_MSG_CHECKING([for TLS])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM( AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
...@@ -1138,57 +1738,68 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM( ...@@ -1138,57 +1738,68 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
AC_MSG_RESULT([yes]), AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
enable_tls="0") enable_tls="0")
else
enable_tls="0"
fi fi
AC_SUBST([enable_tls]) AC_SUBST([enable_tls])
if test "x${enable_tls}" = "x1" ; then if test "x${enable_tls}" = "x1" ; then
AC_DEFINE_UNQUOTED([JEMALLOC_TLS], [ ]) AC_DEFINE_UNQUOTED([JEMALLOC_TLS], [ ])
elif test "x${force_tls}" = "x1" ; then
AC_MSG_ERROR([Failed to configure TLS, which is mandatory for correct function])
fi fi
dnl ============================================================================ dnl ============================================================================
dnl Check for ffsl(3), and fail if not found. This function exists on all dnl Check for C11 atomics.
dnl platforms that jemalloc currently has a chance of functioning on without
dnl modification. JE_COMPILABLE([C11 atomics], [
JE_COMPILABLE([a program using ffsl], [ #include <stdint.h>
#include <stdio.h> #if (__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__)
#include <strings.h> #include <stdatomic.h>
#include <string.h> #else
#error Atomics not available
#endif
], [ ], [
{ uint64_t *p = (uint64_t *)0;
int rv = ffsl(0x08); uint64_t x = 1;
printf("%d\n", rv); volatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p;
} uint64_t r = atomic_fetch_add(a, x) + x;
], [je_cv_function_ffsl]) return r == 0;
if test "x${je_cv_function_ffsl}" != "xyes" ; then ], [je_cv_c11_atomics])
AC_MSG_ERROR([Cannot build without ffsl(3)]) if test "x${je_cv_c11_atomics}" = "xyes" ; then
AC_DEFINE([JEMALLOC_C11_ATOMICS])
fi fi
dnl ============================================================================ dnl ============================================================================
dnl Check for atomic(9) operations as provided on FreeBSD. dnl Check for GCC-style __atomic atomics.
JE_COMPILABLE([atomic(9)], [ JE_COMPILABLE([GCC __atomic atomics], [
#include <sys/types.h>
#include <machine/atomic.h>
#include <inttypes.h>
], [ ], [
{ int x = 0;
uint32_t x32 = 0; int val = 1;
volatile uint32_t *x32p = &x32; int y = __atomic_fetch_add(&x, val, __ATOMIC_RELAXED);
atomic_fetchadd_32(x32p, 1); int after_add = x;
} return after_add == 1;
{ ], [je_cv_gcc_atomic_atomics])
unsigned long xlong = 0; if test "x${je_cv_gcc_atomic_atomics}" = "xyes" ; then
volatile unsigned long *xlongp = &xlong; AC_DEFINE([JEMALLOC_GCC_ATOMIC_ATOMICS])
atomic_fetchadd_long(xlongp, 1); fi
}
], [je_cv_atomic9]) dnl ============================================================================
if test "x${je_cv_atomic9}" = "xyes" ; then dnl Check for GCC-style __sync atomics.
AC_DEFINE([JEMALLOC_ATOMIC9])
JE_COMPILABLE([GCC __sync atomics], [
], [
int x = 0;
int before_add = __sync_fetch_and_add(&x, 1);
int after_add = x;
return (before_add == 0) && (after_add == 1);
], [je_cv_gcc_sync_atomics])
if test "x${je_cv_gcc_sync_atomics}" = "xyes" ; then
AC_DEFINE([JEMALLOC_GCC_SYNC_ATOMICS])
fi fi
dnl ============================================================================ dnl ============================================================================
dnl Check for atomic(3) operations as provided on Darwin. dnl Check for atomic(3) operations as provided on Darwin.
dnl We need this not for the atomic operations (which are provided above), but
dnl rather for the OSSpinLock type it exposes.
JE_COMPILABLE([Darwin OSAtomic*()], [ JE_COMPILABLE([Darwin OSAtomic*()], [
#include <libkern/OSAtomic.h> #include <libkern/OSAtomic.h>
...@@ -1209,6 +1820,75 @@ if test "x${je_cv_osatomic}" = "xyes" ; then ...@@ -1209,6 +1820,75 @@ if test "x${je_cv_osatomic}" = "xyes" ; then
AC_DEFINE([JEMALLOC_OSATOMIC], [ ]) AC_DEFINE([JEMALLOC_OSATOMIC], [ ])
fi fi
dnl ============================================================================
dnl Check for madvise(2).
JE_COMPILABLE([madvise(2)], [
#include <sys/mman.h>
], [
madvise((void *)0, 0, 0);
], [je_cv_madvise])
if test "x${je_cv_madvise}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_MADVISE], [ ])
dnl Check for madvise(..., MADV_FREE).
JE_COMPILABLE([madvise(..., MADV_FREE)], [
#include <sys/mman.h>
], [
madvise((void *)0, 0, MADV_FREE);
], [je_cv_madv_free])
if test "x${je_cv_madv_free}" = "xyes" ; then
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
elif test "x${je_cv_madvise}" = "xyes" ; then
case "${host_cpu}" in i686|x86_64)
case "${host}" in *-*-linux*)
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
AC_DEFINE([JEMALLOC_DEFINE_MADVISE_FREE], [ ])
;;
esac
;;
esac
fi
dnl Check for madvise(..., MADV_DONTNEED).
JE_COMPILABLE([madvise(..., MADV_DONTNEED)], [
#include <sys/mman.h>
], [
madvise((void *)0, 0, MADV_DONTNEED);
], [je_cv_madv_dontneed])
if test "x${je_cv_madv_dontneed}" = "xyes" ; then
AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED], [ ])
fi
dnl Check for madvise(..., MADV_DO[NT]DUMP).
JE_COMPILABLE([madvise(..., MADV_DO[[NT]]DUMP)], [
#include <sys/mman.h>
], [
madvise((void *)0, 0, MADV_DONTDUMP);
madvise((void *)0, 0, MADV_DODUMP);
], [je_cv_madv_dontdump])
if test "x${je_cv_madv_dontdump}" = "xyes" ; then
AC_DEFINE([JEMALLOC_MADVISE_DONTDUMP], [ ])
fi
dnl Check for madvise(..., MADV_[NO]HUGEPAGE).
JE_COMPILABLE([madvise(..., MADV_[[NO]]HUGEPAGE)], [
#include <sys/mman.h>
], [
madvise((void *)0, 0, MADV_HUGEPAGE);
madvise((void *)0, 0, MADV_NOHUGEPAGE);
], [je_cv_thp])
case "${host_cpu}" in
arm*)
;;
*)
if test "x${je_cv_thp}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_MADVISE_HUGE], [ ])
fi
;;
esac
fi
dnl ============================================================================ dnl ============================================================================
dnl Check whether __sync_{add,sub}_and_fetch() are available despite dnl Check whether __sync_{add,sub}_and_fetch() are available despite
dnl __GCC_HAVE_SYNC_COMPARE_AND_SWAP_n macros being undefined. dnl __GCC_HAVE_SYNC_COMPARE_AND_SWAP_n macros being undefined.
...@@ -1243,6 +1923,48 @@ if test "x${je_cv_atomic9}" != "xyes" -a "x${je_cv_osatomic}" != "xyes" ; then ...@@ -1243,6 +1923,48 @@ if test "x${je_cv_atomic9}" != "xyes" -a "x${je_cv_osatomic}" != "xyes" ; then
JE_SYNC_COMPARE_AND_SWAP_CHECK(64, 8) JE_SYNC_COMPARE_AND_SWAP_CHECK(64, 8)
fi fi
dnl ============================================================================
dnl Check for __builtin_clz() and __builtin_clzl().
AC_CACHE_CHECK([for __builtin_clz],
[je_cv_builtin_clz],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
[
{
unsigned x = 0;
int y = __builtin_clz(x);
}
{
unsigned long x = 0;
int y = __builtin_clzl(x);
}
])],
[je_cv_builtin_clz=yes],
[je_cv_builtin_clz=no])])
if test "x${je_cv_builtin_clz}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_BUILTIN_CLZ], [ ])
fi
dnl ============================================================================
dnl Check for os_unfair_lock operations as provided on Darwin.
JE_COMPILABLE([Darwin os_unfair_lock_*()], [
#include <os/lock.h>
#include <AvailabilityMacros.h>
], [
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101200
#error "os_unfair_lock is not supported"
#else
os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
os_unfair_lock_lock(&lock);
os_unfair_lock_unlock(&lock);
#endif
], [je_cv_os_unfair_lock])
if test "x${je_cv_os_unfair_lock}" = "xyes" ; then
AC_DEFINE([JEMALLOC_OS_UNFAIR_LOCK], [ ])
fi
dnl ============================================================================ dnl ============================================================================
dnl Check for spinlock(3) operations as provided on Darwin. dnl Check for spinlock(3) operations as provided on Darwin.
...@@ -1281,39 +2003,107 @@ if test "x${enable_zone_allocator}" = "x1" ; then ...@@ -1281,39 +2003,107 @@ if test "x${enable_zone_allocator}" = "x1" ; then
if test "x${abi}" != "xmacho"; then if test "x${abi}" != "xmacho"; then
AC_MSG_ERROR([--enable-zone-allocator is only supported on Darwin]) AC_MSG_ERROR([--enable-zone-allocator is only supported on Darwin])
fi fi
AC_DEFINE([JEMALLOC_IVSALLOC], [ ])
AC_DEFINE([JEMALLOC_ZONE], [ ]) AC_DEFINE([JEMALLOC_ZONE], [ ])
fi
dnl The szone version jumped from 3 to 6 between the OS X 10.5.x and 10.6 dnl ============================================================================
dnl releases. malloc_zone_t and malloc_introspection_t have new fields in dnl Use initial-exec TLS by default.
dnl 10.6, which is the only source-level indication of the change. AC_ARG_ENABLE([initial-exec-tls],
AC_MSG_CHECKING([malloc zone version]) [AS_HELP_STRING([--disable-initial-exec-tls],
AC_DEFUN([JE_ZONE_PROGRAM], [Disable the initial-exec tls model])],
[AC_LANG_PROGRAM( [if test "x$enable_initial_exec_tls" = "xno" ; then
[#include <malloc/malloc.h>], enable_initial_exec_tls="0"
[static foo[[sizeof($1) $2 sizeof(void *) * $3 ? 1 : -1]]] else
)]) enable_initial_exec_tls="1"
fi
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,14)],[JEMALLOC_ZONE_VERSION=3],[ ],
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,15)],[JEMALLOC_ZONE_VERSION=5],[ [enable_initial_exec_tls="1"]
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,16)],[ )
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_introspection_t,==,9)],[JEMALLOC_ZONE_VERSION=6],[ AC_SUBST([enable_initial_exec_tls])
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_introspection_t,==,13)],[JEMALLOC_ZONE_VERSION=7],[JEMALLOC_ZONE_VERSION=]
)])],[ if test "x${je_cv_tls_model}" = "xyes" -a \
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,17)],[JEMALLOC_ZONE_VERSION=8],[ "x${enable_initial_exec_tls}" = "x1" ; then
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,>,17)],[JEMALLOC_ZONE_VERSION=9],[JEMALLOC_ZONE_VERSION=] AC_DEFINE([JEMALLOC_TLS_MODEL],
)])])])]) [__attribute__((tls_model("initial-exec")))])
if test "x${JEMALLOC_ZONE_VERSION}" = "x"; then else
AC_MSG_RESULT([unsupported]) AC_DEFINE([JEMALLOC_TLS_MODEL], [ ])
AC_MSG_ERROR([Unsupported malloc zone version]) fi
dnl ============================================================================
dnl Enable background threads if possible.
if test "x${have_pthread}" = "x1" -a "x${have_dlsym}" = "x1" \
-a "x${je_cv_os_unfair_lock}" != "xyes" \
-a "x${je_cv_osspin}" != "xyes" ; then
AC_DEFINE([JEMALLOC_BACKGROUND_THREAD])
fi
dnl ============================================================================
dnl Check for glibc malloc hooks
JE_COMPILABLE([glibc malloc hook], [
#include <stddef.h>
extern void (* __free_hook)(void *ptr);
extern void *(* __malloc_hook)(size_t size);
extern void *(* __realloc_hook)(void *ptr, size_t size);
], [
void *ptr = 0L;
if (__malloc_hook) ptr = __malloc_hook(1);
if (__realloc_hook) ptr = __realloc_hook(ptr, 2);
if (__free_hook && ptr) __free_hook(ptr);
], [je_cv_glibc_malloc_hook])
if test "x${je_cv_glibc_malloc_hook}" = "xyes" ; then
if test "x${JEMALLOC_PREFIX}" = "x" ; then
AC_DEFINE([JEMALLOC_GLIBC_MALLOC_HOOK], [ ])
wrap_syms="${wrap_syms} __free_hook __malloc_hook __realloc_hook"
fi fi
if test "${JEMALLOC_ZONE_VERSION}" = 9; then fi
JEMALLOC_ZONE_VERSION=8
AC_MSG_RESULT([> 8]) JE_COMPILABLE([glibc memalign hook], [
else #include <stddef.h>
AC_MSG_RESULT([$JEMALLOC_ZONE_VERSION])
extern void *(* __memalign_hook)(size_t alignment, size_t size);
], [
void *ptr = 0L;
if (__memalign_hook) ptr = __memalign_hook(16, 7);
], [je_cv_glibc_memalign_hook])
if test "x${je_cv_glibc_memalign_hook}" = "xyes" ; then
if test "x${JEMALLOC_PREFIX}" = "x" ; then
AC_DEFINE([JEMALLOC_GLIBC_MEMALIGN_HOOK], [ ])
wrap_syms="${wrap_syms} __memalign_hook"
fi fi
AC_DEFINE_UNQUOTED(JEMALLOC_ZONE_VERSION, [$JEMALLOC_ZONE_VERSION]) fi
JE_COMPILABLE([pthreads adaptive mutexes], [
#include <pthread.h>
], [
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
pthread_mutexattr_destroy(&attr);
], [je_cv_pthread_mutex_adaptive_np])
if test "x${je_cv_pthread_mutex_adaptive_np}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP], [ ])
fi
JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-D_GNU_SOURCE])
JE_CFLAGS_ADD([-Werror])
JE_CFLAGS_ADD([-herror_on_warning])
JE_COMPILABLE([strerror_r returns char with gnu source], [
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
], [
char *buffer = (char *) malloc(100);
char *error = strerror_r(EINVAL, buffer, 100);
printf("%s\n", error);
], [je_cv_strerror_r_returns_char_with_gnu_source])
JE_CFLAGS_RESTORE()
if test "x${je_cv_strerror_r_returns_char_with_gnu_source}" = "xyes" ; then
AC_DEFINE([JEMALLOC_STRERROR_R_RETURNS_CHAR_WITH_GNU_SOURCE], [ ])
fi fi
dnl ============================================================================ dnl ============================================================================
...@@ -1323,20 +2113,6 @@ AC_HEADER_STDBOOL ...@@ -1323,20 +2113,6 @@ AC_HEADER_STDBOOL
dnl ============================================================================ dnl ============================================================================
dnl Define commands that generate output files. dnl Define commands that generate output files.
AC_CONFIG_COMMANDS([include/jemalloc/internal/private_namespace.h], [
mkdir -p "${objroot}include/jemalloc/internal"
"${srcdir}/include/jemalloc/internal/private_namespace.sh" "${srcdir}/include/jemalloc/internal/private_symbols.txt" > "${objroot}include/jemalloc/internal/private_namespace.h"
], [
srcdir="${srcdir}"
objroot="${objroot}"
])
AC_CONFIG_COMMANDS([include/jemalloc/internal/private_unnamespace.h], [
mkdir -p "${objroot}include/jemalloc/internal"
"${srcdir}/include/jemalloc/internal/private_unnamespace.sh" "${srcdir}/include/jemalloc/internal/private_symbols.txt" > "${objroot}include/jemalloc/internal/private_unnamespace.h"
], [
srcdir="${srcdir}"
objroot="${objroot}"
])
AC_CONFIG_COMMANDS([include/jemalloc/internal/public_symbols.txt], [ AC_CONFIG_COMMANDS([include/jemalloc/internal/public_symbols.txt], [
f="${objroot}include/jemalloc/internal/public_symbols.txt" f="${objroot}include/jemalloc/internal/public_symbols.txt"
mkdir -p "${objroot}include/jemalloc/internal" mkdir -p "${objroot}include/jemalloc/internal"
...@@ -1360,6 +2136,31 @@ AC_CONFIG_COMMANDS([include/jemalloc/internal/public_symbols.txt], [ ...@@ -1360,6 +2136,31 @@ AC_CONFIG_COMMANDS([include/jemalloc/internal/public_symbols.txt], [
public_syms="${public_syms}" public_syms="${public_syms}"
JEMALLOC_PREFIX="${JEMALLOC_PREFIX}" JEMALLOC_PREFIX="${JEMALLOC_PREFIX}"
]) ])
AC_CONFIG_COMMANDS([include/jemalloc/internal/private_symbols.awk], [
f="${objroot}include/jemalloc/internal/private_symbols.awk"
mkdir -p "${objroot}include/jemalloc/internal"
export_syms=`for sym in ${public_syms}; do echo "${JEMALLOC_PREFIX}${sym}"; done; for sym in ${wrap_syms}; do echo "${sym}"; done;`
"${srcdir}/include/jemalloc/internal/private_symbols.sh" "${SYM_PREFIX}" ${export_syms} > "${objroot}include/jemalloc/internal/private_symbols.awk"
], [
srcdir="${srcdir}"
objroot="${objroot}"
public_syms="${public_syms}"
wrap_syms="${wrap_syms}"
SYM_PREFIX="${SYM_PREFIX}"
JEMALLOC_PREFIX="${JEMALLOC_PREFIX}"
])
AC_CONFIG_COMMANDS([include/jemalloc/internal/private_symbols_jet.awk], [
f="${objroot}include/jemalloc/internal/private_symbols_jet.awk"
mkdir -p "${objroot}include/jemalloc/internal"
export_syms=`for sym in ${public_syms}; do echo "jet_${sym}"; done; for sym in ${wrap_syms}; do echo "${sym}"; done;`
"${srcdir}/include/jemalloc/internal/private_symbols.sh" "${SYM_PREFIX}" ${export_syms} > "${objroot}include/jemalloc/internal/private_symbols_jet.awk"
], [
srcdir="${srcdir}"
objroot="${objroot}"
public_syms="${public_syms}"
wrap_syms="${wrap_syms}"
SYM_PREFIX="${SYM_PREFIX}"
])
AC_CONFIG_COMMANDS([include/jemalloc/internal/public_namespace.h], [ AC_CONFIG_COMMANDS([include/jemalloc/internal/public_namespace.h], [
mkdir -p "${objroot}include/jemalloc/internal" mkdir -p "${objroot}include/jemalloc/internal"
"${srcdir}/include/jemalloc/internal/public_namespace.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" > "${objroot}include/jemalloc/internal/public_namespace.h" "${srcdir}/include/jemalloc/internal/public_namespace.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" > "${objroot}include/jemalloc/internal/public_namespace.h"
...@@ -1376,10 +2177,13 @@ AC_CONFIG_COMMANDS([include/jemalloc/internal/public_unnamespace.h], [ ...@@ -1376,10 +2177,13 @@ AC_CONFIG_COMMANDS([include/jemalloc/internal/public_unnamespace.h], [
]) ])
AC_CONFIG_COMMANDS([include/jemalloc/internal/size_classes.h], [ AC_CONFIG_COMMANDS([include/jemalloc/internal/size_classes.h], [
mkdir -p "${objroot}include/jemalloc/internal" mkdir -p "${objroot}include/jemalloc/internal"
"${srcdir}/include/jemalloc/internal/size_classes.sh" > "${objroot}include/jemalloc/internal/size_classes.h" "${SHELL}" "${srcdir}/include/jemalloc/internal/size_classes.sh" "${LG_QUANTA}" 3 "${LG_PAGE_SIZES}" 2 > "${objroot}include/jemalloc/internal/size_classes.h"
], [ ], [
SHELL="${SHELL}"
srcdir="${srcdir}" srcdir="${srcdir}"
objroot="${objroot}" objroot="${objroot}"
LG_QUANTA="${LG_QUANTA}"
LG_PAGE_SIZES="${LG_PAGE_SIZES}"
]) ])
AC_CONFIG_COMMANDS([include/jemalloc/jemalloc_protos_jet.h], [ AC_CONFIG_COMMANDS([include/jemalloc/jemalloc_protos_jet.h], [
mkdir -p "${objroot}include/jemalloc" mkdir -p "${objroot}include/jemalloc"
...@@ -1426,7 +2230,7 @@ AC_CONFIG_HEADERS([$cfghdrs_tup]) ...@@ -1426,7 +2230,7 @@ AC_CONFIG_HEADERS([$cfghdrs_tup])
dnl ============================================================================ dnl ============================================================================
dnl Generate outputs. dnl Generate outputs.
AC_CONFIG_FILES([$cfgoutputs_tup config.stamp bin/jemalloc.sh]) AC_CONFIG_FILES([$cfgoutputs_tup config.stamp bin/jemalloc-config bin/jemalloc.sh bin/jeprof])
AC_SUBST([cfgoutputs_in]) AC_SUBST([cfgoutputs_in])
AC_SUBST([cfgoutputs_out]) AC_SUBST([cfgoutputs_out])
AC_OUTPUT AC_OUTPUT
...@@ -1437,11 +2241,19 @@ AC_MSG_RESULT([================================================================= ...@@ -1437,11 +2241,19 @@ AC_MSG_RESULT([=================================================================
AC_MSG_RESULT([jemalloc version : ${jemalloc_version}]) AC_MSG_RESULT([jemalloc version : ${jemalloc_version}])
AC_MSG_RESULT([library revision : ${rev}]) AC_MSG_RESULT([library revision : ${rev}])
AC_MSG_RESULT([]) AC_MSG_RESULT([])
AC_MSG_RESULT([CONFIG : ${CONFIG}])
AC_MSG_RESULT([CC : ${CC}]) AC_MSG_RESULT([CC : ${CC}])
AC_MSG_RESULT([CONFIGURE_CFLAGS : ${CONFIGURE_CFLAGS}])
AC_MSG_RESULT([SPECIFIED_CFLAGS : ${SPECIFIED_CFLAGS}])
AC_MSG_RESULT([EXTRA_CFLAGS : ${EXTRA_CFLAGS}])
AC_MSG_RESULT([CPPFLAGS : ${CPPFLAGS}]) AC_MSG_RESULT([CPPFLAGS : ${CPPFLAGS}])
AC_MSG_RESULT([CFLAGS : ${CFLAGS}]) AC_MSG_RESULT([CXX : ${CXX}])
AC_MSG_RESULT([CONFIGURE_CXXFLAGS : ${CONFIGURE_CXXFLAGS}])
AC_MSG_RESULT([SPECIFIED_CXXFLAGS : ${SPECIFIED_CXXFLAGS}])
AC_MSG_RESULT([EXTRA_CXXFLAGS : ${EXTRA_CXXFLAGS}])
AC_MSG_RESULT([LDFLAGS : ${LDFLAGS}]) AC_MSG_RESULT([LDFLAGS : ${LDFLAGS}])
AC_MSG_RESULT([EXTRA_LDFLAGS : ${EXTRA_LDFLAGS}]) AC_MSG_RESULT([EXTRA_LDFLAGS : ${EXTRA_LDFLAGS}])
AC_MSG_RESULT([DSO_LDFLAGS : ${DSO_LDFLAGS}])
AC_MSG_RESULT([LIBS : ${LIBS}]) AC_MSG_RESULT([LIBS : ${LIBS}])
AC_MSG_RESULT([RPATH_EXTRA : ${RPATH_EXTRA}]) AC_MSG_RESULT([RPATH_EXTRA : ${RPATH_EXTRA}])
AC_MSG_RESULT([]) AC_MSG_RESULT([])
...@@ -1450,9 +2262,9 @@ AC_MSG_RESULT([XSLROOT : ${XSLROOT}]) ...@@ -1450,9 +2262,9 @@ AC_MSG_RESULT([XSLROOT : ${XSLROOT}])
AC_MSG_RESULT([]) AC_MSG_RESULT([])
AC_MSG_RESULT([PREFIX : ${PREFIX}]) AC_MSG_RESULT([PREFIX : ${PREFIX}])
AC_MSG_RESULT([BINDIR : ${BINDIR}]) AC_MSG_RESULT([BINDIR : ${BINDIR}])
AC_MSG_RESULT([DATADIR : ${DATADIR}])
AC_MSG_RESULT([INCLUDEDIR : ${INCLUDEDIR}]) AC_MSG_RESULT([INCLUDEDIR : ${INCLUDEDIR}])
AC_MSG_RESULT([LIBDIR : ${LIBDIR}]) AC_MSG_RESULT([LIBDIR : ${LIBDIR}])
AC_MSG_RESULT([DATADIR : ${DATADIR}])
AC_MSG_RESULT([MANDIR : ${MANDIR}]) AC_MSG_RESULT([MANDIR : ${MANDIR}])
AC_MSG_RESULT([]) AC_MSG_RESULT([])
AC_MSG_RESULT([srcroot : ${srcroot}]) AC_MSG_RESULT([srcroot : ${srcroot}])
...@@ -1464,24 +2276,19 @@ AC_MSG_RESULT([JEMALLOC_PREFIX : ${JEMALLOC_PREFIX}]) ...@@ -1464,24 +2276,19 @@ AC_MSG_RESULT([JEMALLOC_PREFIX : ${JEMALLOC_PREFIX}])
AC_MSG_RESULT([JEMALLOC_PRIVATE_NAMESPACE]) AC_MSG_RESULT([JEMALLOC_PRIVATE_NAMESPACE])
AC_MSG_RESULT([ : ${JEMALLOC_PRIVATE_NAMESPACE}]) AC_MSG_RESULT([ : ${JEMALLOC_PRIVATE_NAMESPACE}])
AC_MSG_RESULT([install_suffix : ${install_suffix}]) AC_MSG_RESULT([install_suffix : ${install_suffix}])
AC_MSG_RESULT([malloc_conf : ${config_malloc_conf}])
AC_MSG_RESULT([autogen : ${enable_autogen}]) AC_MSG_RESULT([autogen : ${enable_autogen}])
AC_MSG_RESULT([experimental : ${enable_experimental}])
AC_MSG_RESULT([cc-silence : ${enable_cc_silence}])
AC_MSG_RESULT([debug : ${enable_debug}]) AC_MSG_RESULT([debug : ${enable_debug}])
AC_MSG_RESULT([code-coverage : ${enable_code_coverage}])
AC_MSG_RESULT([stats : ${enable_stats}]) AC_MSG_RESULT([stats : ${enable_stats}])
AC_MSG_RESULT([prof : ${enable_prof}]) AC_MSG_RESULT([prof : ${enable_prof}])
AC_MSG_RESULT([prof-libunwind : ${enable_prof_libunwind}]) AC_MSG_RESULT([prof-libunwind : ${enable_prof_libunwind}])
AC_MSG_RESULT([prof-libgcc : ${enable_prof_libgcc}]) AC_MSG_RESULT([prof-libgcc : ${enable_prof_libgcc}])
AC_MSG_RESULT([prof-gcc : ${enable_prof_gcc}]) AC_MSG_RESULT([prof-gcc : ${enable_prof_gcc}])
AC_MSG_RESULT([tcache : ${enable_tcache}])
AC_MSG_RESULT([fill : ${enable_fill}]) AC_MSG_RESULT([fill : ${enable_fill}])
AC_MSG_RESULT([utrace : ${enable_utrace}]) AC_MSG_RESULT([utrace : ${enable_utrace}])
AC_MSG_RESULT([valgrind : ${enable_valgrind}])
AC_MSG_RESULT([xmalloc : ${enable_xmalloc}]) AC_MSG_RESULT([xmalloc : ${enable_xmalloc}])
AC_MSG_RESULT([mremap : ${enable_mremap}]) AC_MSG_RESULT([log : ${enable_log}])
AC_MSG_RESULT([munmap : ${enable_munmap}])
AC_MSG_RESULT([dss : ${enable_dss}])
AC_MSG_RESULT([lazy_lock : ${enable_lazy_lock}]) AC_MSG_RESULT([lazy_lock : ${enable_lazy_lock}])
AC_MSG_RESULT([tls : ${enable_tls}]) AC_MSG_RESULT([cache-oblivious : ${enable_cache_oblivious}])
AC_MSG_RESULT([cxx : ${enable_cxx}])
AC_MSG_RESULT([===============================================================================]) AC_MSG_RESULT([===============================================================================])
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment