Squashed 'third_party/gperftools/' changes from 54505f1d50..c25941200e

c25941200e fix cmake gperftools_enable_libunwind invalid
43504ab709 tcmalloc page fences: add TCMALLOC_PAGE_FENCE_READABLE option
d57a9ea8bc README: replace "golang" moniker with "Go"
f7c6fb6c8e bump version to 2.9.1
c2f60400a8 prefer backtrace() on OSX
a015377a54 Set tcmalloc heap limit prior to testing oom
c939dd5531 correctly check sized delete hint when asserts are on
47b5b59ca9 bump version to 2.9
d7cbc8c2ff unbreak cmake build
be0bbdb340 amputate various unused bits from elfcore.h
42bab59f25 liberate profile handler from linux_syscall_support
4629511e99 liberate spinlock futex waits from linux_syscall_support includes
2e7094a862 liberate malloc_hook_mmap_linux.h from linux_syscall_support
35301e2e59 add missing noopt wrappings around more operator new calls
fa412adfe3 Fix thread-safety (annotalysis) annotations
cc496aecb8 tcmalloc: Switch thread-safety annotations to support clang
96ba58e19b bump version to 2.9rc
9ce32aefa9 upgrade test bot to xenial (ubuntu 16.04 LTS)
91ff311449 don't default to generic_fp without frame pointers
4cf7dd0a75 enable emergency_malloc on all architectures with mmap
37087ec536 prefer libunwind on x86-64 even with -fno-omit-frame-pointer
f4aa2a435e implement generic frame pointer backtracer
17bab484ae always respect --enable-frame-pointers
22c0eceddc add emacs mode line annotations to remaining files
b12139ddba delete-trailing-whitespace on all files
419c85814d amputate unused dynamic annotations support
73a72cdb61 don't check for snprintf
95b52b0504 don't check for unused uname symbol
01c2697fac amputate unused SleepForMilliseconds from sysinfo.{h,cc}
ac68c97187 don't check for useless __builtin_stack_pointer
7271bb72be unbreak cmake check for TLS support
7c106ca241 don't bother checking for stl namespace and use std
0d6f32b9ce use standard way to print size_t-sized ints
0c11d35f4a amputate checking for __int64
92718aaaeb amputate checking for conflict-signal.h
9bb2937261 amputate checking for inline keyword support
d9c4c3b481 profile-handler: use documented sigev_notify_thread_id in sigevent
43459feb33 configure.ac: check for features.h once
290b123c01 atomicops: Remove Acquire_Store / Release_Load
3b1c60cc4e Add support for Elbrus 2000 (e2k)
c5747615da syscall: Mark x8 as clobbered
d8eb315fb1 bump version to 2.8.1
6ed61f8e91 add note that cmake build is preliminary
6bbf2ed150 Update cmake
913d3eb7d7 Fix a few macros for Apple
64a73b1cb8 Work on fixing linking errors in stacktrace
b788d51eb4 Fix conditional definitions
495229b625 Make internal tcmalloc libs
cca7f6f669 More unit tests and libraries
11dc65c3c4 Fix config headers, add more unit tests
6078fe40d9 Finish configure.ac conversion to CMake, start on Makefile.am
515fb22196 Generate config header
4adb5ff74d Add architecture checks
fa9bedc82c Add most of CMake build
9e4f72fd1f Define options, start system checks
a6ce98174b Add CMakeLists.txt
3134955875 Additional porting for riscv64.
f0e289bdbb Enable build on riscv64.
6c715b4fa1 docs: fix simple typo, defininitions -> definitions
02d5264018 Revert "drop page heap lock when returning memory back to kernel"
151cbf5146 Add OS X arm64 program counter
140e3481d0 Merge pull request #1231 from PatriosTheGreat/master
0fc5cabdfc Fix implicit-int-float-conversion warning.
bda3c82e11 Increase kMaxStackDepth to 254
1d9b8bb59d don't test sbrk hook if we're on linux and don't have __sbrk
180bfa10d7 bumped version to 2.8
c1bcc412ba Don't try to mark esp as clobbered in linux syscall support.
50f89afaed liberate gperftools tests from relying on -fno-builtin-XXX flags
98ccd0f102 prevent inlining in heap-checker unittest
e521472f1a fix linking of page_heap_test on windows
e5f77d6485 chmod -x Makefile.am gperftools.sln
6b92e00cec don't assume HAVE_MMAP on mingw builds
4cddede399 New ProfilerGetStackTrace()
db7aa547ab bumped version to 2.8rc
be3da70298 drop page heap lock when returning memory back to kernel
87acc2782f amputate span events history
e40c7f231a Fix mmap syscall on s390
b7607ee7d4 tcmalloc: ability to disable fallback allocator in memfs
1bfcb5bc3a tcmalloc: fragmentation overhead instrumentation
36bf1309de Fix a clang-tidy readability warning for static member access
2b2a962c2b Remove executable flag for c++ files
8f308afbfe Increase kClassSizesMax to 128 to allow for page size of 4K
d3fefdb694 Allow configuring page size to 4K, 8K, 16K, 32K, 64K, 128K and 256K
cf2df3b000 Fix the removed std::allocator::pointer member type removed in C++20
31024506c5 Add mips64* support
fe62a0baab Update config.h in Windows
8272631b5a Fix a long time typo
c1d546d7b2 never test and always default HAVE_MMAP to on
fba6ce0e7a Fix build on FreeBSD
98ac4ee9bc Fix typos
9e5b162873 don't try to mark rsp as clobbered in linux syscall support
1e36ed7055 Use initial exec TLS model for all thread local variables from thread_cache.cc
8f9a873fce Fix accessing PC on FreeBSD/powerpc and powerpc64
fc00474ddc Include asm/ptrace.h when accessing ucontext_t
5574c87e39 Compile time aggressive decommit option
e9ab4c5304 undef mmap64 function
5eec9d0ae3 Drop not very portable and not very useful unwind benchmark.
1561f0946f check for __sbrk
1de76671d4 Fix mmap region iteration while no regions are recorded.
acdcacc28f Use off64_t instead of __off64_t
0177a2420a Return early in WriteProfile to reduce indentation
b85652bf26 Add generic.total_physical_bytes property to MallocExtension
90df23c81f Make some tcmalloc constants truly const
49dbe4362b Add comment about gperftools 2.8 not deduplicating heapz samples.
63a12a5ed3 Drop de-duplication of heap sample (aka heapz) entries.
954f9dc0e3 Add flag to disable installing unmaintained & deprecated pprof.
893bff51bc Avoid static initialization of pprof path for symbolization.
69867c523b Clean up MSVC projects
f2bca77aed Fix page_heap_test flakiness
c41688bf20 Use standard-conforming alignof in debugallocation.cc
71c8cedaca Fix incompatible aliasing warnings
8dd3040358 Format and fix out of bound access in CpuProfilerSwitch
467502e70a provide constexpr constructor for Sampler
1fb543cc70 Patch _free_dbg to make Debug mode in MSVC works
267f431d80 Use indirect system calls in the linux spinlock implementation
73ee9b1544 Use indirect system calls in the mmap malloc hooks.
3af509d4f9 benchmark: use angle brackets to include ucontext.h
0cdda6d7cc use utf-8 for special symbols
c7a0cfda88 Fix potential missing nul character on resolved symbol names
e42bfc8c06 tcmalloc: use relative addresses with the windows addr2line wrapper
d8f8d1cced tcmalloc: add long form flag '--exe' to specify the binary
25c53aca12 tcmalloc: fixes for the windows addr2line wrapper
f02e28f348 Replace builtin_expect configure test with a direct GCC compiler check
62c4eca6e7 Under x64, the PE loader looks for callbacks in constant sections
0b588e7490 Fix uninitialized memory use in sampler_test
51a5613f21 Upgrade MSVC projects to MSVC2015
44da4ce539 build with c++11 or later
f47a52ce85 Make _recalloc adhere to MS's definition
fe87ffb7ea Disable large allocation report by default
9608fa3bcf bumped version to 2.7
db890ccfad Clean up src/windows/config.h
497ea33165 Fix WIN32_OVERRIDE_ALLOCATORS for VS2017
ebc85cca90 Enable aligned new/delete declarations on Windows when applicable
a3badd6d21 Really fix CheckAddressBits compilation warning
7c718fe176 Add tests for sized deallocation
30e5e614a8 Fix build without static libraries
836c4f29a5 Update documentation for heap_checker.html
e47d0d1c51 powerpc: Re-enable VDSO support
0a66dd3a6a linux: add aarch64_ilp32 support.
05dff09663 Fix signature of sbrk.
33ae0ed2ae unbreak compilation on GNU/Linux i386
977e0d4500 Remove not needed header in vdso_support.cc.
36bfa9a404 Enable tcmalloc VDSO support only on x86 to reduce static initializers
1cb5de6db9 Explicitly prevent int overflow
8f63f2bb98 Correctly detect presence of various functions in tcmalloc.h
736648887b Don't test OOM handling of debugallocator
c4a8e00da4 Fix warning about one of CheckAddressBits functions unused
47c99cf492 unbreak printing large span stats
34f78a2dcd bumped version to 2.7rc
db98aac55a Add a central free list for kMaxPages-sized spans
d7be938560 implement more robust detection of sized delete support
f1d3fe4a21 refactored handling of reverse span set iterator for correctness
59c77be0fa Update docs for central page heap to reflect tree
06c9414ec4 Implemented O(log n) searching among large spans
a42e44738a typo in docs/tcmalloc.html
71bf09aabe bumped version to 2.6.3
0bccb5e658 fix malloc fast path for patched windows functions
8b1d13c631 configure.ac: use link check for std::align_val_t
36ab068baa configure.ac: better test for -faligned-new
6a4b079997 bumped version to 2.6.2
2291714518 implement fast-path for memalign/aligned_alloc/tc_new_aligned
8b9728b023 add memalign benchmark to malloc_bench
79c91a9810 always define empty PERFTOOLS_NOTHROW
03da6afff5 unbreak throw declarations on operators new/delete
89fe59c831 Fix OOM handling in fast-path
a29a0cf348 delete-trailing-whitespace on thread_cache.*
e6cd69bdec reintroduce aliasing for aligned delete
fb30c3d435 fully disable aligned new on windows for now
7efb3ecf37 Add support for C++17 operator new/delete for overaligned types.
7a6e25f3b1 Add new statistics for the PageHeap
6e3a702fb9 Fix data race setting size_left_ in ThreadCache::SetMaxSize
235471f965 fix memory leak in Symbolize function
47efdd60f5 Added mising va_end() in TracePrintf function
497b60ef0f Implemented GetProgramInvocationName on FreeBSD
ac072a3fc7 Revert "Ignore current_instance heap allocation when leak sanitizer is enabled"
fb5987d579 Revert "Ensure that lsan flags are appended on all necessary targets"
5815f02105 Use safe getenv for setting up backtrace capturing method
aab4277311 Fixed LTO warning about the mismatch between return values for ProfilingIsEnabledForAllThreads()
d406f22853 implement support for C11 aligned_alloc
92a27e41a1 Fix build on macOS.
e033431e5a include fcntl.h for loff_t definition
e41bc41404 Use ucontext_t instead of struct ucontext
bf840dec04 bumped version to 2.6.1
2d220c7e26 Replace "throw()" by "PERFTOOLS_NOTHROW"
c4de73c0e6 Add PERFTOOLS_THROW where necessary (as detected by GCC).
e5fbd0e24e Rename PERFTOOLS_THROW into PERFTOOLS_NOTHROW.
eeb7b84c20 Register tcmalloc atfork handler as early as possible
208c26caef Add initial syscall support for mips64 32-bit ABI
a3bf61ca81 Ensure that lsan flags are appended on all necessary targets
97646a1932 Add missing NEWS entry for recent 2.6 release
4be05e43a1 bumped version up to 2.6
70a35422b5 Ignore current_instance heap allocation when leak sanitizer is enabled
6eca6c64fa Revert "issue-654: [pprof] handle split text segments"
a495969cb6 update the prev_class_size in each loop, or the min_object_size of tcmalloc.thread will always be 1 when calling GetFreeListSizes
163224d8af Document HEAPPROFILESIGNAL environment variable
5ac82ec5b9 added stacktrace capturing benchmark
c571ae2fc9 2.6rc4
f2bae51e7e Revert "Revert "disable dynamic sized delete support by default""
6426c0cc80 2.6rc3
0c0e2fe43b enable 48-bit page map on msvc as well
83d6818295 speed up 3-level page map access
f7ff175b92 add configure-time warning on unsupported backtrace capturing
cef582350c align fast-path functions only if compiler supports that
bddf862b18 actually support very early freeing of NULL
07a124d8c1 don't use arg-ful constructor attribute for early nallocx test
5346b8a4de don't depend on SIZE_MAX definition in sampler.cc
50125d8f70 2.6rc2
a5e8e42a47 don't link-in libunwind if libunwind.h is missing
e92acdf98d Fix compilation error for powerpc32
b48403a4b0 2.6rc
53f15325d9 fix compilation of tcmalloc_unittest.cc on older llvm-gcc
b1d88662cb change size class to be represented by 32 bit int
991f47a159 change default transfer batch back to 32
7bc34ad1f6 support different number of size classes at runtime
4585b78c8d massage allocation and deallocation fast-path for performance
5964a1d9c9 always inline a number of hot functions
e419b7b9a6 introduce ATTRIBUTE_ALWAYS_INLINE
7d588da7ec synchronized Sampler implementation with Google-internal version
27da4ade70 reduce size of class_to_size_ array
335f09d4e4 use static location for pageheap
6ff332fb51 move size classes map earlier in SizeMap
121b1cb32e slightly faster size class cache
b57c0bad41 init tcmalloc prior to replacing system alloc
71fa9f8730 use 2-level page map for 48-bit addresses
bad70249dd use 48-bit addresses on 64-bit arms too
5f12147c6d use hidden visibility for some key global variables
dfd53da578 set ENOMEM in handle_oom
14fd551072 avoid O(N²) in thread cache creation code
507a105e84 pass original size to DoSampledAllocation
bb77979dea don't declare throw() on malloc funtions since it is faster
89c74cb79c handle duplicate google_malloc frames in malloc hook stack trace
0feb1109ac fix stack trace capturing in debug malloc
0506e965ee replace LIKELY/UNLIKELY with PREDICT_{TRUE,FALSE}
59a4987054 prevent inlining ATTRIBUTE_SECTION functions
ebb575b8a0 Revert "enabled aggressive decommit by default"
b82d89cb7c Revert "disable dynamic sized delete support by default"
fac0bb44d5 Do not depend on memchr in commandlineflags::StringToBool
7d49f015a0 Make GetenvBeforeMain work inside ifunc handler
a2550b6309 turn bench_fastpath_throughput into actual throughput benchmark
b762b1a492 added sized free benchmarks to malloc_bench
71ffc1cd6b added free lists randomization step to malloc_bench
732dfeb83d Run StartStopNoOptionsEmpty profiledata unittest
cbb312fbe8 aggressive decommit: only free necessary regions and fix O(N²)
6d98223a90 don't build with -fno-exceptions
d6a1931cce fixed warning in casting heap of checker's main_thread_counter
5c778701d9 added tcmalloc minimal unittest with ASSERTs checked
a9167617ab drop unused g_load_map variable in patch_functionc.cc
d52e56dcb5 don't compare integer to NULL
bae00c0341 add fake_stacktrace_scope to few msvc projects
79aab4fed4 correctly dllexport nallocx on windows
b010895a08 don't undef PERFTOOLS_DLL_DECL
491b1aca7e don't try to use pthread_atfork on windows
691045b957 suppress warnings from legacy headers while building legacy headers test
22f7ceb97a use unsigned for few flags in mini_disassembler_types.h
9b17a8a5ba remove superfluous size_t value >= 0 check
86ce69d77f Update binary_trees.cc
cd8586ed6c Fix path names in README
98753aa737 test that sized deallocation really works before enabling it
5618ef7850 Don't assume memalign exists in memalign vs nallocx test
bf640cd740 rename sys allocator's sys_alloc symbol to tcmalloc_sys_alloc
069e3b1655 build malloc_bench_shared_full only when full tcmalloc is built
b8f9d0d44f ported nallocx support from Google-internal tcmalloc
b0abefd938 Fix a typo in the page fence flag declaration
855b380006 replace docs by doc
664210ead8 doc -> docs, with symlink
75dc9a6e14 Fix Post(s)cript tyos
dde32f8bbc Fix unaligned memory accesses in debug allocator
02eeed29df Fix redefinition of mmap on aarch64.
c07a15cff4 [windows] patch _free_base as well
acac6af26b Fix finding default zone on macOS sierra
7822b5b0b9 Stop using glibc malloc hooks
c92f0ed089 Remove references to __malloc_initialize_hook
9709eef361 Merge pull request #821 from jtmcdole/patch-1
44f276e132 Rename TCMALLOC_DEBUG to PERFTOOLS_VERBOSE
eb474c995e Summary: support gcc atomic ops on clang too
7f86eab1f3 Recognize .node files as shared libraries
bf8eacce69 Add support for 31-bit s390; merge linux_syscall_support.h changes from upstream.
c54218069b Update README
06f4ce65c2 Small performance tweak: avoid calling time() if we don't need it
db8d483609 Autogenerate ChangeLog from git on make dist
4a13598319 renamed ChangeLog to ChangeLog.old
7852eeb75b Use initial-exec tls for libunwind's recursion flag
a07f9fe75a gerftools -> gperftools in readme
9fd6d26879 added define to enable MADV_FREE usage on Linux
6f7a14f45e Don't use MADV_FREE on Linux
55cf6e6281 Fix symbol resolution on OSX
8e85843622 added simple .travis.yml config
05e40d29c0 Recognize modern Linux ARM
632de2975e bumped version up to 2.5
6682016092 Unbreak profiling with CPUPROFILE_FREQUENCY=1
6ff86ff6a7 bumped version to 2.4.91 for 2.5rc2
782165fa7f build sized delete aliases even when sized-delete is disabled
06811b3ae4 disable dynamic sized delete support by default
d4d99eb608 unbreak compilation with visual studio
126d4582c1 Call function pointers with the right type
e0fa28ef7d Don't shift a type by more than its width
a1c764d263 Initialize counters in test
22123a37c2 Don't overflow a signed integer
66e1e94f38 added minimal "header section" to README
2804b7cfee bumped version to 2.5rc
f47fefbfc1 updated NEWS for 2.5rc
cef6036174 alias same malloc/free variants to their canonical versions
ea8d242061 Re-enable MultipleIdleNonIdlePhases test
c9962f698b added maybe_emergency_malloc.h to Makefile.am
7dd4af6536 don't round up sizes for large allocation when sampling
4f3410e759 enable emergency malloc by default on arm when using libunwind
7f12051dbe implemented emergency malloc
3ee2360250 replaced invalid uses of __THROW
013b82abcf unbreak <malloc.h> inclusion in gperftools/tcmalloc.h
19903e6f15 drop detection of sys/malloc.h and malloc/malloc.h
cdff090ebd Fix several harmless clang warnings
9095ed0840 implemented stacktrace capturing via libgcc's C++ ABI function
728cbe1021 force profiler_unittest to do 'real' work
fff6b4fb88 Extend low-level allocator to support custom pages allocator
32d9926795 added malloc_bench_shared_full
00d8fa1ef8 always use real throw() on operators new/delete
08e034ad59 Detect working ifunc before enabling dynamic sized delete support
a788f354a0 include unistd.h for getpid in thread_lister.c
644a6bdbdb Add support for Linux s390x
bab7753aad Fix typo in heap-checker-death_unittest.sh
17182e1d3c Fix include of malloc_hook_c.h in malloc_hook.h
c69721b2b2 Add support for obtaining cache size of the current thread and softer idling
5ce42e535d Don't always arm the profiling timer.
7f801ea091 Make sure the alias is not removed by link-time optimization when it can prove that it isn't used by the program, as it might still be needed to override the corresponding symbol in shared libraries (or inline assembler for that matter). For example, suppose the program uses malloc and free but not calloc and is statically linked against tcmalloc (built with -flto) and LTO is done.  Then before this patch the calloc alias would be deleted by LTO due to not being used, but the malloc/free aliases would be kept because they are used by the program.  Suppose the program is dynamically linked with a shared library that allocates memory using calloc and later frees it by calling free.  Then calloc will use the libc memory allocator, because the calloc alias was deleted, but free will call into tcmalloc, resulting in a crash.
6b3e6ef5e0 don't retain compatibility with old docdir behavior
ccffcbd9e9 support use of configure --docdir argument
050f2d28be use alias attribute only for elf platforms
07b0b21ddd fix compilation error in spinlock
e14450366a Added better description for GetStats API
64892ae730 lower default transfer batch size down to 512
6fdfc5a7f4 implemented enabling sized-delete support at runtime
c2a79d063c use x86 pause in spin loop
0fb6dd8aa3 added binary_trees benchmark
a8852489e5 drop unsupported allocation sampling code in tcmalloc_minimal
a9db0ae516 implemented (disabled by default) sized delete support
88686972b9 pass -fsized-deallocation to gcc 5
0a18fab3af implemented sized free support via tc_free_sized
464688ab6d speedup free code path by dropping "fast path allowed check"
10f7e20716 added SizeMap::MaybeSizeClass
436e1dea43 slightly faster GetCacheIfPresent
04df911915 tell compiler that non-empty hooks are unlikely
8cc75acd1f correctly test for -Wno-unused-result support
7753d8239b fixed clang warning about shifting negative values
ae09ebb383 Fix tmpdir usage in heap-profiler_unittest.sh
df34e71b57 use $0 when referring to pprof
7773ea64ee Alignment fix to static variables for system allocators
c46eb1f3d2 Fixed printf misuse in pprof - printed string was passed as format. Better use print instead
9bbed8b1a8 Fixed assembler argument passing inside _syscall6 on MIPS - it was causing 'Expression too complex' compilation errors in spinlock
962aa53c55 added more fastpath microbenchmarks
347a830689 Ensure that PPROF_PATH is set for debugallocation_test
a9059b7c30 prevent clang from inlining Mallocer in heap checker unittest
6627f9217d drop cycleclock
f985abc296 amputate unportable and unused stuff from sysinfo
16408eb4d7 amputated wait_cycles accounting in spinlocks
fedceef40c drop cycleclock reference in ThreadCache
d7fdc3fc9d dropped unused and unsupported synchronization profiling facility
3a054d37c1 dropped unused SpinLockWait function
5b62d38329 avoid checking for dup. entries on empty backtrace
7b9ded722e fixed compiler warning in memory_region_map.cc
4194e485cb Don't link libtcmalloc_minimal.so to libpthread.so
121038308d Check if _MSC_VER is defined to avoid warnings
7367322995 Make default config.h work with VS2015
ae0a444db0 Ensure ThreadCache objects are CACHELINE_ALIGNED.
ea0b1d3154 unbreak TestErrno again
e53aef24ad don't try to test memalign on windows
7707582448 Merge pull request #717 from myrsloik/master
9eb63bddfb Use correct mangled new and delete symbols on windows x64
5078abdb33 Don't discard curl options if timeout is not defined.

Change-Id: If80121a97ff4c18289c6ebff7ccea1d1b355ec89
git-subtree-dir: third_party/gperftools
git-subtree-split: c25941200ef4ce39d0774c1332ff7abfbeab7035
Signed-off-by: Brian Silverman <bsilver16834@gmail.com>
diff --git a/src/tests/addressmap_unittest.cc b/src/tests/addressmap_unittest.cc
index a847dd6..45781f3 100644
--- a/src/tests/addressmap_unittest.cc
+++ b/src/tests/addressmap_unittest.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2005, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +34,7 @@
 #include <stdlib.h>   // for rand()
 #include <vector>
 #include <set>
+#include <random>
 #include <algorithm>
 #include <utility>
 #include "addressmap-inl.h"
@@ -47,7 +48,7 @@
 using std::make_pair;
 using std::vector;
 using std::set;
-using std::random_shuffle;
+using std::shuffle;
 
 struct UniformRandomNumberGenerator {
   size_t Uniform(size_t max_size) {
@@ -91,7 +92,9 @@
     RAW_LOG(INFO, "Iteration %d/%d...\n", x, FLAGS_iters);
 
     // Permute pointers to get rid of allocation order issues
-    random_shuffle(ptrs_and_sizes.begin(), ptrs_and_sizes.end());
+    std::random_device rd;
+    std::mt19937 g(rd());
+    shuffle(ptrs_and_sizes.begin(), ptrs_and_sizes.end(), g);
 
     AddressMap<ValueT> map(malloc, free);
     const ValueT* result;
diff --git a/src/tests/atomicops_unittest.cc b/src/tests/atomicops_unittest.cc
index aa82a6b..22be839 100644
--- a/src/tests/atomicops_unittest.cc
+++ b/src/tests/atomicops_unittest.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 /* Copyright (c) 2006, Google Inc.
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
- * 
+ *
  *     * Redistributions of source code must retain the above copyright
  * notice, this list of conditions and the following disclaimer.
  *     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
  *     * Neither the name of Google Inc. nor the names of its
  * contributors may be used to endorse or promote products derived from
  * this software without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -104,11 +104,6 @@
   base::subtle::NoBarrier_Store(&value, kVal2);
   ASSERT_EQ(kVal2, value);
 
-  base::subtle::Acquire_Store(&value, kVal1);
-  ASSERT_EQ(kVal1, value);
-  base::subtle::Acquire_Store(&value, kVal2);
-  ASSERT_EQ(kVal2, value);
-
   base::subtle::Release_Store(&value, kVal1);
   ASSERT_EQ(kVal1, value);
   base::subtle::Release_Store(&value, kVal2);
@@ -133,11 +128,6 @@
   ASSERT_EQ(kVal1, base::subtle::Acquire_Load(&value));
   value = kVal2;
   ASSERT_EQ(kVal2, base::subtle::Acquire_Load(&value));
-
-  value = kVal1;
-  ASSERT_EQ(kVal1, base::subtle::Release_Load(&value));
-  value = kVal2;
-  ASSERT_EQ(kVal2, base::subtle::Release_Load(&value));
 }
 
 template <class AtomicType>
diff --git a/src/tests/current_allocated_bytes_test.cc b/src/tests/current_allocated_bytes_test.cc
index eaa6a7b..49b7dc3 100644
--- a/src/tests/current_allocated_bytes_test.cc
+++ b/src/tests/current_allocated_bytes_test.cc
@@ -46,12 +46,12 @@
 #include <gperftools/malloc_extension.h>
 #include "base/logging.h"
 
-const char kCurrent[] = "generic.current_allocated_bytes";
-
 int main() {
   // We don't do accounting right when using debugallocation.cc, so
   // turn off the test then.  TODO(csilvers): get this working too.
 #ifdef NDEBUG
+  static const char kCurrent[] = "generic.current_allocated_bytes";
+
   size_t before_bytes, after_bytes;
   MallocExtension::instance()->GetNumericProperty(kCurrent, &before_bytes);
   free(malloc(200));
diff --git a/src/tests/debugallocation_test.cc b/src/tests/debugallocation_test.cc
index d935dbb..1e45db6 100644
--- a/src/tests/debugallocation_test.cc
+++ b/src/tests/debugallocation_test.cc
@@ -38,6 +38,7 @@
 #include "gperftools/malloc_extension.h"
 #include "gperftools/tcmalloc.h"
 #include "base/logging.h"
+#include "tests/testutil.h"
 
 using std::vector;
 
@@ -91,7 +92,7 @@
 
   // Allocate with malloc.
   {
-    int* x = static_cast<int*>(malloc(sizeof(*x)));
+    int* x = static_cast<int*>(noopt(malloc(sizeof(*x))));
     IF_DEBUG_EXPECT_DEATH(delete x, "mismatch.*being dealloc.*delete");
     IF_DEBUG_EXPECT_DEATH(delete [] x, "mismatch.*being dealloc.*delete *[[]");
     // Should work fine.
@@ -100,8 +101,8 @@
 
   // Allocate with new.
   {
-    int* x = new int;
-    int* y = new int;
+    int* x = noopt(new int);
+    int* y = noopt(new int);
     IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free");
     IF_DEBUG_EXPECT_DEATH(delete [] x, "mismatch.*being dealloc.*delete *[[]");
     delete x;
@@ -110,8 +111,8 @@
 
   // Allocate with new[].
   {
-    int* x = new int[1];
-    int* y = new int[1];
+    int* x = noopt(new int[1]);
+    int* y = noopt(new int[1]);
     IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free");
     IF_DEBUG_EXPECT_DEATH(delete x, "mismatch.*being dealloc.*delete");
     delete [] x;
@@ -120,8 +121,8 @@
 
   // Allocate with new(nothrow).
   {
-    int* x = new(std::nothrow) int;
-    int* y = new(std::nothrow) int;
+    int* x = noopt(new (std::nothrow) int);
+    int* y = noopt(new (std::nothrow) int);
     IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free");
     IF_DEBUG_EXPECT_DEATH(delete [] x, "mismatch.*being dealloc.*delete *[[]");
     delete x;
@@ -130,8 +131,8 @@
 
   // Allocate with new(nothrow)[].
   {
-    int* x = new(std::nothrow) int[1];
-    int* y = new(std::nothrow) int[1];
+    int* x = noopt(new (std::nothrow) int[1]);
+    int* y = noopt(new (std::nothrow) int[1]);
     IF_DEBUG_EXPECT_DEATH(free(x), "mismatch.*being dealloc.*free");
     IF_DEBUG_EXPECT_DEATH(delete x, "mismatch.*being dealloc.*delete");
     delete [] x;
@@ -141,13 +142,13 @@
 #endif  // #ifdef OS_MACOSX
 
 TEST(DebugAllocationTest, DoubleFree) {
-  int* pint = new int;
+  int* pint = noopt(new int);
   delete pint;
   IF_DEBUG_EXPECT_DEATH(delete pint, "has been already deallocated");
 }
 
 TEST(DebugAllocationTest, StompBefore) {
-  int* pint = new int;
+  int* pint = noopt(new int);
 #ifndef NDEBUG   // don't stomp memory if we're not in a position to detect it
   pint[-1] = 5;
   IF_DEBUG_EXPECT_DEATH(delete pint, "a word before object");
@@ -155,7 +156,7 @@
 }
 
 TEST(DebugAllocationTest, StompAfter) {
-  int* pint = new int;
+  int* pint = noopt(new int);
 #ifndef NDEBUG   // don't stomp memory if we're not in a position to detect it
   pint[1] = 5;
   IF_DEBUG_EXPECT_DEATH(delete pint, "a word after object");
@@ -164,10 +165,10 @@
 
 TEST(DebugAllocationTest, FreeQueueTest) {
   // Verify that the allocator doesn't return blocks that were recently freed.
-  int* x = new int;
+  int* x = noopt(new int);
   int* old_x = x;
   delete x;
-  x = new int;
+  x = noopt(new int);
   #if 1
     // This check should not be read as a universal guarantee of behavior.  If
     // other threads are executing, it would be theoretically possible for this
@@ -191,12 +192,12 @@
   // safe.  When debugging, we expect the (trashed) deleted block to be on the
   // list of recently-freed blocks, so the following 'new' will be safe.
 #if 1
-  int* x = new int;
+  int* x = noopt(new int);
   delete x;
   int poisoned_x_value = *x;
   *x = 1;  // a dangling write.
 
-  char* s = new char[FLAGS_max_free_queue_size];
+  char* s = noopt(new char[FLAGS_max_free_queue_size]);
   // When we delete s, we push the storage that was previously allocated to x
   // off the end of the free queue.  At that point, the write to that memory
   // will be detected.
@@ -210,7 +211,7 @@
 }
 
 TEST(DebugAllocationTest, DanglingWriteAtExitTest) {
-  int *x = new int;
+  int *x = noopt(new int);
   delete x;
   int old_x_value = *x;
   *x = 1;
@@ -221,7 +222,7 @@
 }
 
 TEST(DebugAllocationTest, StackTraceWithDanglingWriteAtExitTest) {
-  int *x = new int;
+  int *x = noopt(new int);
   delete x;
   int old_x_value = *x;
   *x = 1;
@@ -244,13 +245,13 @@
   FLAGS_max_free_queue_size = 0;
   // Force a round-trip through the queue management code so that the
   // new size is seen and the queue of recently-freed blocks is flushed.
-  free(malloc(1));
+  free(noopt(malloc(1)));
   FLAGS_max_free_queue_size = 1048576;
 #endif
 
   // Free something and check that it disappears from allocated bytes
   // immediately.
-  char* p = new char[1000];
+  char* p = noopt(new char[1000]);
   size_t after_malloc = CurrentlyAllocatedBytes();
   delete[] p;
   size_t after_free = CurrentlyAllocatedBytes();
@@ -263,12 +264,12 @@
   // exactly requested size, since debug_allocation doesn't allow users
   // to write more than that.
   for (int i = 0; i < 10; ++i) {
-    void *p = malloc(i);
+    void *p = noopt(malloc(i));
     EXPECT_EQ(i, MallocExtension::instance()->GetAllocatedSize(p));
     free(p);
   }
 #endif
-  void* a = malloc(1000);
+  void* a = noopt(malloc(1000));
   EXPECT_GE(MallocExtension::instance()->GetAllocatedSize(a), 1000);
   // This is just a sanity check.  If we allocated too much, alloc is broken
   EXPECT_LE(MallocExtension::instance()->GetAllocatedSize(a), 5000);
@@ -285,7 +286,7 @@
 
 #ifndef NDEBUG
 
-  a = malloc(kTooBig);
+  a = noopt(malloc(noopt(kTooBig)));
   EXPECT_EQ(NULL, a);
 
   // kAlsoTooBig is small enough not to get caught by debugallocation's check,
@@ -293,7 +294,7 @@
   // a non-const variable. See kTooBig for more details.
   size_t kAlsoTooBig = kTooBig - 1024;
 
-  a = malloc(kAlsoTooBig);
+  a = noopt(malloc(noopt(kAlsoTooBig)));
   EXPECT_EQ(NULL, a);
 #endif
 }
@@ -307,7 +308,7 @@
   EXPECT_NE(p, NULL);
   memcpy(stuff, p, sizeof(stuff));
 
-  p = realloc(p, sizeof(stuff) + 10);
+  p = noopt(realloc(p, sizeof(stuff) + 10));
   EXPECT_NE(p, NULL);
 
   int rv = memcmp(stuff, p, sizeof(stuff));
diff --git a/src/tests/debugallocation_test.sh b/src/tests/debugallocation_test.sh
index faa6c79..0f94ad0 100755
--- a/src/tests/debugallocation_test.sh
+++ b/src/tests/debugallocation_test.sh
@@ -33,6 +33,9 @@
 # Author: Craig Silverstein
 
 BINDIR="${BINDIR:-.}"
+# We expect PPROF_PATH to be set in the environment.
+# If not, we set it to some reasonable value
+export PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
 
 if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
   echo "USAGE: $0 [unittest dir]"
diff --git a/src/tests/frag_unittest.cc b/src/tests/frag_unittest.cc
index c4016f9..6d2619f 100644
--- a/src/tests/frag_unittest.cc
+++ b/src/tests/frag_unittest.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2003, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
diff --git a/src/tests/heap-checker-death_unittest.sh b/src/tests/heap-checker-death_unittest.sh
index 752a7ad..69db0c9 100755
--- a/src/tests/heap-checker-death_unittest.sh
+++ b/src/tests/heap-checker-death_unittest.sh
@@ -157,7 +157,7 @@
 
 # Test that we produce a reasonable textual leak report.
 Test 60 1 "MakeALeak" "" \
-          HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECK_TEST_NO_THREADS=1 \
+          HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \
   || exit 10
 
 # Test that very early log messages are present and controllable:
diff --git a/src/tests/heap-checker_unittest.cc b/src/tests/heap-checker_unittest.cc
index 8c8f865..b4bcb52 100644
--- a/src/tests/heap-checker_unittest.cc
+++ b/src/tests/heap-checker_unittest.cc
@@ -787,9 +787,9 @@
 static void DirectTestSTLAlloc(Alloc allocator, const char* name) {
   HeapLeakChecker check((string("direct_stl-") + name).c_str());
   static const int kSize = 1000;
-  typename Alloc::pointer ptrs[kSize];
+  typename Alloc::value_type* ptrs[kSize];
   for (int i = 0; i < kSize; ++i) {
-    typename Alloc::pointer p = allocator.allocate(i*3+1);
+    typename Alloc::value_type* p = allocator.allocate(i*3+1);
     HeapLeakChecker::IgnoreObject(p);
     // This will crash if p is not known to heap profiler:
     // (i.e. STL's "allocator" does not have a direct hook to heap profiler)
@@ -1298,7 +1298,7 @@
 #endif
 
 // to trick complier into preventing inlining
-static void* (*mmapper_addr)(uintptr_t* addr) = &Mmapper;
+static void* (* volatile mmapper_addr)(uintptr_t* addr) = &Mmapper;
 
 // TODO(maxim): copy/move this to memory_region_map_unittest
 // TODO(maxim): expand this test to include mmap64, mremap and sbrk calls.
@@ -1338,8 +1338,8 @@
   return r;
 }
 
-// to trick complier into preventing inlining
-static void* (*mallocer_addr)(uintptr_t* addr) = &Mallocer;
+// to trick compiler into preventing inlining
+static void* (* volatile mallocer_addr)(uintptr_t* addr) = &Mallocer;
 
 // non-static for friendship with HeapProfiler
 // TODO(maxim): expand this test to include
diff --git a/src/tests/heap-profiler_unittest.cc b/src/tests/heap-profiler_unittest.cc
index 3317813..addb5f1 100644
--- a/src/tests/heap-profiler_unittest.cc
+++ b/src/tests/heap-profiler_unittest.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2005, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
diff --git a/src/tests/heap-profiler_unittest.sh b/src/tests/heap-profiler_unittest.sh
index b4c2e9f..91af04f 100755
--- a/src/tests/heap-profiler_unittest.sh
+++ b/src/tests/heap-profiler_unittest.sh
@@ -54,14 +54,11 @@
 
 HEAP_PROFILER="${1:-$BINDIR/heap-profiler_unittest}"
 PPROF="${2:-$PPROF_PATH}"
-TEST_TMPDIR=/tmp/heap_profile_info
+TEST_TMPDIR=`mktemp -d /tmp/heap-profiler_unittest.XXXXXX`
 
 # It's meaningful to the profiler, so make sure we know its state
 unset HEAPPROFILE
 
-rm -rf "$TEST_TMPDIR"
-mkdir "$TEST_TMPDIR" || exit 2
-
 num_failures=0
 
 # Given one profile (to check the contents of that profile) or two
@@ -140,7 +137,7 @@
 # testing of the HeapProfileStart/Stop functionality.
 $HEAP_PROFILER >"$TEST_TMPDIR/output2" 2>&1
 
-rm -rf $TMPDIR      # clean up
+rm -rf $TEST_TMPDIR      # clean up
 
 if [ $num_failures = 0 ]; then
   echo "PASS"
diff --git a/src/tests/low_level_alloc_unittest.cc b/src/tests/low_level_alloc_unittest.cc
index e3cb555..0474441 100644
--- a/src/tests/low_level_alloc_unittest.cc
+++ b/src/tests/low_level_alloc_unittest.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 /* Copyright (c) 2006, Google Inc.
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
- * 
+ *
  *     * Redistributions of source code must retain the above copyright
  * notice, this list of conditions and the following disclaimer.
  *     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
  *     * Neither the name of Google Inc. nor the names of its
  * contributors may be used to endorse or promote products derived from
  * this software without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
diff --git a/src/tests/malloc_extension_c_test.c b/src/tests/malloc_extension_c_test.c
index 278fdb7..2868b9c 100644
--- a/src/tests/malloc_extension_c_test.c
+++ b/src/tests/malloc_extension_c_test.c
@@ -1,11 +1,11 @@
 /* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */
 /* Copyright (c) 2009, Google Inc.
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
- * 
+ *
  *     * Redistributions of source code must retain the above copyright
  * notice, this list of conditions and the following disclaimer.
  *     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
  *     * Neither the name of Google Inc. nor the names of its
  * contributors may be used to endorse or promote products derived from
  * this software without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
diff --git a/src/tests/malloc_extension_test.cc b/src/tests/malloc_extension_test.cc
index 31c4968..6570772 100644
--- a/src/tests/malloc_extension_test.cc
+++ b/src/tests/malloc_extension_test.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2008, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
diff --git a/src/tests/markidle_unittest.cc b/src/tests/markidle_unittest.cc
index 827609f..829c503 100644
--- a/src/tests/markidle_unittest.cc
+++ b/src/tests/markidle_unittest.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2003, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -93,9 +93,26 @@
   CHECK_LE(post_idle, original);
 
   // Log after testing because logging can allocate heap memory.
-  VLOG(0, "Original usage: %" PRIuS "\n", original);
-  VLOG(0, "Post allocation: %" PRIuS "\n", post_allocation);
-  VLOG(0, "Post idle: %" PRIuS "\n", post_idle);
+  VLOG(0, "Original usage: %zu\n", original);
+  VLOG(0, "Post allocation: %zu\n", post_allocation);
+  VLOG(0, "Post idle: %zu\n", post_idle);
+}
+
+static void TestTemporarilyIdleUsage() {
+  const size_t original = MallocExtension::instance()->GetThreadCacheSize();
+
+  TestAllocation();
+  const size_t post_allocation = MallocExtension::instance()->GetThreadCacheSize();
+  CHECK_GT(post_allocation, original);
+
+  MallocExtension::instance()->MarkThreadIdle();
+  const size_t post_idle = MallocExtension::instance()->GetThreadCacheSize();
+  CHECK_EQ(post_idle, 0);
+
+  // Log after testing because logging can allocate heap memory.
+  VLOG(0, "Original usage: %zu\n", original);
+  VLOG(0, "Post allocation: %zu\n", post_allocation);
+  VLOG(0, "Post idle: %zu\n", post_idle);
 }
 
 int main(int argc, char** argv) {
@@ -103,6 +120,7 @@
   RunThread(&TestAllocation);
   RunThread(&MultipleIdleCalls);
   RunThread(&MultipleIdleNonIdlePhases);
+  RunThread(&TestTemporarilyIdleUsage);
 
   printf("PASS\n");
   return 0;
diff --git a/src/tests/memalign_unittest.cc b/src/tests/memalign_unittest.cc
index 309a3df..035f709 100644
--- a/src/tests/memalign_unittest.cc
+++ b/src/tests/memalign_unittest.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2004, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
diff --git a/src/tests/packed-cache_test.cc b/src/tests/packed-cache_test.cc
index befbd77..3984594 100644
--- a/src/tests/packed-cache_test.cc
+++ b/src/tests/packed-cache_test.cc
@@ -35,24 +35,43 @@
 #include "base/logging.h"
 #include "packed-cache-inl.h"
 
-static const int kHashbits = PackedCache<64, uint64>::kHashbits;
+static const int kHashbits = PackedCache<20>::kHashbits;
+
+template <int kKeybits>
+static size_t MustGet(const PackedCache<kKeybits>& cache, uintptr_t key) {
+  uint32 rv;
+  CHECK(cache.TryGet(key, &rv));
+  return rv;
+}
+
+template <int kKeybits>
+static size_t Has(const PackedCache<kKeybits>& cache, uintptr_t key) {
+  uint32 dummy;
+  return cache.TryGet(key, &dummy);
+}
 
 // A basic sanity test.
 void PackedCacheTest_basic() {
-  PackedCache<32, uint32> cache(0);
-  CHECK_EQ(cache.GetOrDefault(0, 1), 0);
+  PackedCache<20> cache;
+
+  CHECK(!Has(cache, 0));
   cache.Put(0, 17);
-  CHECK(cache.Has(0));
-  CHECK_EQ(cache.GetOrDefault(0, 1), 17);
+  CHECK(Has(cache, 0));
+  CHECK_EQ(MustGet(cache, 0), 17);
+
   cache.Put(19, 99);
-  CHECK(cache.Has(0) && cache.Has(19));
-  CHECK_EQ(cache.GetOrDefault(0, 1), 17);
-  CHECK_EQ(cache.GetOrDefault(19, 1), 99);
+  CHECK_EQ(MustGet(cache, 0), 17);
+  CHECK_EQ(MustGet(cache, 19), 99);
+
   // Knock <0, 17> out by using a conflicting key.
   cache.Put(1 << kHashbits, 22);
-  CHECK(!cache.Has(0));
-  CHECK_EQ(cache.GetOrDefault(0, 1), 1);
-  CHECK_EQ(cache.GetOrDefault(1 << kHashbits, 1), 22);
+  CHECK(!Has(cache, 0));
+  CHECK_EQ(MustGet(cache, 1 << kHashbits), 22);
+
+  cache.Invalidate(19);
+  CHECK(!Has(cache, 19));
+  CHECK(!Has(cache, 0));
+  CHECK(Has(cache, 1 << kHashbits));
 }
 
 int main(int argc, char **argv) {
diff --git a/src/tests/page_heap_test.cc b/src/tests/page_heap_test.cc
index e82a1da..3caacc0 100644
--- a/src/tests/page_heap_test.cc
+++ b/src/tests/page_heap_test.cc
@@ -6,9 +6,13 @@
 // be found in the LICENSE file.
 
 #include "config_for_unittests.h"
+
+#include <stdio.h>
+
+#include <memory>
+
 #include "page_heap.h"
 #include "system-alloc.h"
-#include <stdio.h>
 #include "base/logging.h"
 #include "common.h"
 
@@ -39,33 +43,63 @@
 }
 
 static void TestPageHeap_Stats() {
-  tcmalloc::PageHeap* ph = new tcmalloc::PageHeap();
+  std::unique_ptr<tcmalloc::PageHeap> ph(new tcmalloc::PageHeap());
 
   // Empty page heap
-  CheckStats(ph, 0, 0, 0);
+  CheckStats(ph.get(), 0, 0, 0);
 
   // Allocate a span 's1'
   tcmalloc::Span* s1 = ph->New(256);
-  CheckStats(ph, 256, 0, 0);
+  CheckStats(ph.get(), 256, 0, 0);
 
   // Split span 's1' into 's1', 's2'.  Delete 's2'
   tcmalloc::Span* s2 = ph->Split(s1, 128);
   ph->Delete(s2);
-  CheckStats(ph, 256, 128, 0);
+  CheckStats(ph.get(), 256, 128, 0);
 
   // Unmap deleted span 's2'
   ph->ReleaseAtLeastNPages(1);
-  CheckStats(ph, 256, 0, 128);
+  CheckStats(ph.get(), 256, 0, 128);
 
   // Delete span 's1'
   ph->Delete(s1);
-  CheckStats(ph, 256, 128, 128);
+  CheckStats(ph.get(), 256, 128, 128);
+}
 
-  delete ph;
+// The number of kMaxPages-sized Spans we will allocate and free during the
+// tests.
+// We will also do twice this many kMaxPages/2-sized ones.
+static constexpr int kNumberMaxPagesSpans = 10;
+
+// Allocates all the last-level page tables we will need. Doing this before
+// calculating the base heap usage is necessary, because otherwise if any of
+// these are allocated during the main test it will throw the heap usage
+// calculations off and cause the test to fail.
+static void AllocateAllPageTables() {
+  // Make a separate PageHeap from the main test so the test can start without
+  // any pages in the lists.
+  std::unique_ptr<tcmalloc::PageHeap> ph(new tcmalloc::PageHeap());
+  tcmalloc::Span *spans[kNumberMaxPagesSpans * 2];
+  for (int i = 0; i < kNumberMaxPagesSpans; ++i) {
+    spans[i] = ph->New(kMaxPages);
+    EXPECT_NE(spans[i], NULL);
+  }
+  for (int i = 0; i < kNumberMaxPagesSpans; ++i) {
+    ph->Delete(spans[i]);
+  }
+  for (int i = 0; i < kNumberMaxPagesSpans * 2; ++i) {
+    spans[i] = ph->New(kMaxPages >> 1);
+    EXPECT_NE(spans[i], NULL);
+  }
+  for (int i = 0; i < kNumberMaxPagesSpans * 2; ++i) {
+    ph->Delete(spans[i]);
+  }
 }
 
 static void TestPageHeap_Limit() {
-  tcmalloc::PageHeap* ph = new tcmalloc::PageHeap();
+  AllocateAllPageTables();
+
+  std::unique_ptr<tcmalloc::PageHeap> ph(new tcmalloc::PageHeap());
 
   CHECK_EQ(kMaxPages, 1 << (20 - kPageShift));
 
@@ -77,25 +111,26 @@
     while((s = ph->New(kMaxPages)) == NULL) {
       FLAGS_tcmalloc_heap_limit_mb++;
     }
-    FLAGS_tcmalloc_heap_limit_mb += 9;
+    FLAGS_tcmalloc_heap_limit_mb += kNumberMaxPagesSpans - 1;
     ph->Delete(s);
     // We are [10, 11) mb from the limit now.
   }
 
   // Test AllocLarge and GrowHeap first:
   {
-    tcmalloc::Span * spans[10];
-    for (int i=0; i<10; ++i) {
+    tcmalloc::Span * spans[kNumberMaxPagesSpans];
+    for (int i=0; i<kNumberMaxPagesSpans; ++i) {
       spans[i] = ph->New(kMaxPages);
       EXPECT_NE(spans[i], NULL);
     }
     EXPECT_EQ(ph->New(kMaxPages), NULL);
 
-    for (int i=0; i<10; i += 2) {
+    for (int i=0; i<kNumberMaxPagesSpans; i += 2) {
       ph->Delete(spans[i]);
     }
 
-    tcmalloc::Span *defragmented = ph->New(5 * kMaxPages);
+    tcmalloc::Span *defragmented =
+        ph->New(kNumberMaxPagesSpans / 2 * kMaxPages);
 
     if (HaveSystemRelease) {
       // EnsureLimit should release deleted normal spans
@@ -109,15 +144,15 @@
       EXPECT_TRUE(ph->CheckExpensive());
     }
 
-    for (int i=1; i<10; i += 2) {
+    for (int i=1; i<kNumberMaxPagesSpans; i += 2) {
       ph->Delete(spans[i]);
     }
   }
 
   // Once again, testing small lists this time (twice smaller spans):
   {
-    tcmalloc::Span * spans[20];
-    for (int i=0; i<20; ++i) {
+    tcmalloc::Span * spans[kNumberMaxPagesSpans * 2];
+    for (int i=0; i<kNumberMaxPagesSpans * 2; ++i) {
       spans[i] = ph->New(kMaxPages >> 1);
       EXPECT_NE(spans[i], NULL);
     }
@@ -125,12 +160,12 @@
     tcmalloc::Span * lastHalf = ph->New(kMaxPages >> 1);
     EXPECT_EQ(ph->New(kMaxPages >> 1), NULL);
 
-    for (int i=0; i<20; i += 2) {
+    for (int i=0; i<kNumberMaxPagesSpans * 2; i += 2) {
       ph->Delete(spans[i]);
     }
 
-    for(Length len = kMaxPages >> 2; len < 5 * kMaxPages; len = len << 1)
-    {
+    for (Length len = kMaxPages >> 2;
+         len < kNumberMaxPagesSpans / 2 * kMaxPages; len = len << 1) {
       if(len <= kMaxPages >> 1 || HaveSystemRelease) {
         tcmalloc::Span *s = ph->New(len);
         EXPECT_NE(s, NULL);
@@ -140,7 +175,7 @@
 
     EXPECT_TRUE(ph->CheckExpensive());
 
-    for (int i=1; i<20; i += 2) {
+    for (int i=1; i<kNumberMaxPagesSpans * 2; i += 2) {
       ph->Delete(spans[i]);
     }
 
@@ -148,8 +183,6 @@
       ph->Delete(lastHalf);
     }
   }
-
-  delete ph;
 }
 
 }  // namespace
diff --git a/src/tests/pagemap_unittest.cc b/src/tests/pagemap_unittest.cc
index 88d46e7..71a94dc 100644
--- a/src/tests/pagemap_unittest.cc
+++ b/src/tests/pagemap_unittest.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2003, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
diff --git a/src/tests/profile-handler_unittest.cc b/src/tests/profile-handler_unittest.cc
index 2984d0d..a8afbca 100644
--- a/src/tests/profile-handler_unittest.cc
+++ b/src/tests/profile-handler_unittest.cc
@@ -8,13 +8,6 @@
 //
 //
 // This file contains the unit tests for profile-handler.h interface.
-//
-// It is linked into three separate unit tests:
-//     profile-handler_unittest tests basic functionality
-//     profile-handler_disable_test tests that the profiler
-//         is disabled with --install_signal_handlers=false
-//     profile-handler_conflict_test tests that the profiler
-//         is disabled when a SIGPROF handler is registered before InitGoogle.
 
 #include "config.h"
 #include "profile-handler.h"
@@ -33,12 +26,6 @@
 DEFINE_bool(test_profiler_enabled, true,
             "expect profiler to be enabled during tests");
 
-// Should we look at the kernel signal handler settings during the test?
-// Not if we're in conflict_test, because we can't distinguish its nop
-// handler from the real one.
-DEFINE_bool(test_profiler_signal_handler, true,
-            "check profiler signal handler during tests");
-
 namespace {
 
 // TODO(csilvers): error-checking on the pthreads routines
@@ -81,11 +68,8 @@
 // reset.
 int kTimerResetInterval = 5000000;
 
-// Whether each thread has separate timers.
 static bool linux_per_thread_timers_mode_ = false;
-static bool timer_separate_ = false;
 static int timer_type_ = ITIMER_PROF;
-static int signal_number_ = SIGPROF;
 
 // Delays processing by the specified number of nano seconds. 'delay_ns'
 // must be less than the number of nano seconds in a second (1000000000).
@@ -110,51 +94,6 @@
           current_timer.it_value.tv_usec != 0);
 }
 
-class VirtualTimerGetterThread : public Thread {
- public:
-  VirtualTimerGetterThread() {
-    memset(&virtual_timer_, 0, sizeof virtual_timer_);
-  }
-  struct itimerval virtual_timer_;
-
- private:
-  void Run() {
-    CHECK_EQ(0, getitimer(ITIMER_VIRTUAL, &virtual_timer_));
-  }
-};
-
-// This function checks whether the timers are shared between thread. This
-// function spawns a thread, so use it carefully when testing thread-dependent
-// behaviour.
-static bool threads_have_separate_timers() {
-  struct itimerval new_timer_val;
-
-  // Enable the virtual timer in the current thread.
-  memset(&new_timer_val, 0, sizeof new_timer_val);
-  new_timer_val.it_value.tv_sec = 1000000;  // seconds
-  CHECK_EQ(0, setitimer(ITIMER_VIRTUAL, &new_timer_val, NULL));
-
-  // Spawn a thread, get the virtual timer's value there.
-  VirtualTimerGetterThread thread;
-  thread.SetJoinable(true);
-  thread.Start();
-  thread.Join();
-
-  // Disable timer here.
-  memset(&new_timer_val, 0, sizeof new_timer_val);
-  CHECK_EQ(0, setitimer(ITIMER_VIRTUAL, &new_timer_val, NULL));
-
-  bool target_timer_enabled = (thread.virtual_timer_.it_value.tv_sec != 0 ||
-                               thread.virtual_timer_.it_value.tv_usec != 0);
-  if (!target_timer_enabled) {
-    LOG(INFO, "threads have separate timers");
-    return true;
-  } else {
-    LOG(INFO, "threads have shared timers");
-    return false;
-  }
-}
-
 // Dummy worker thread to accumulate cpu time.
 class BusyThread : public Thread {
  public:
@@ -181,16 +120,12 @@
   void Run() {
     while (!stop_work()) {
     }
-    // If timers are separate, check that timer is enabled for this thread.
-    EXPECT_TRUE(linux_per_thread_timers_mode_ || !timer_separate_ || IsTimerEnabled());
   }
 };
 
 class NullThread : public Thread {
  private:
   void Run() {
-    // If timers are separate, check that timer is enabled for this thread.
-    EXPECT_TRUE(linux_per_thread_timers_mode_ || !timer_separate_ || IsTimerEnabled());
   }
 };
 
@@ -205,45 +140,34 @@
 class ProfileHandlerTest {
  protected:
 
-  // Determines whether threads have separate timers.
+  // Determines the timer type.
   static void SetUpTestCase() {
     timer_type_ = (getenv("CPUPROFILE_REALTIME") ? ITIMER_REAL : ITIMER_PROF);
-    signal_number_ = (getenv("CPUPROFILE_REALTIME") ? SIGALRM : SIGPROF);
 
-    timer_separate_ = threads_have_separate_timers();
 #if HAVE_LINUX_SIGEV_THREAD_ID
     linux_per_thread_timers_mode_ = (getenv("CPUPROFILE_PER_THREAD_TIMERS") != NULL);
     const char *signal_number = getenv("CPUPROFILE_TIMER_SIGNAL");
     if (signal_number) {
-      signal_number_ = strtol(signal_number, NULL, 0);
+      //signal_number_ = strtol(signal_number, NULL, 0);
       linux_per_thread_timers_mode_ = true;
+      Delay(kTimerResetInterval);
     }
 #endif
-    Delay(kTimerResetInterval);
   }
 
   // Sets up the profile timers and SIGPROF/SIGALRM handler in a known state.
   // It does the following:
-  // 1. Unregisters all the callbacks, stops the timer (if shared) and
-  //    clears out timer_sharing state in the ProfileHandler. This clears
-  //    out any state left behind by the previous test or during module
-  //    initialization when the test program was started.
-  // 2. Spawns two threads which will be registered with the ProfileHandler.
-  //    At this time ProfileHandler knows if the timers are shared.
+  // 1. Unregisters all the callbacks, stops the timer and clears out
+  //    timer_sharing state in the ProfileHandler. This clears out any state
+  //    left behind by the previous test or during module initialization when
+  //    the test program was started.
   // 3. Starts a busy worker thread to accumulate CPU usage.
   virtual void SetUp() {
     // Reset the state of ProfileHandler between each test. This unregisters
-    // all callbacks, stops timer (if shared) and clears timer sharing state.
+    // all callbacks and stops the timer.
     ProfileHandlerReset();
     EXPECT_EQ(0, GetCallbackCount());
     VerifyDisabled();
-    // ProfileHandler requires at least two threads to be registerd to determine
-    // whether timers are shared.
-    RegisterThread();
-    RegisterThread();
-    // Now that two threads are started, verify that the signal handler is
-    // disabled and the timers are correctly enabled/disabled.
-    VerifyDisabled();
     // Start worker to accumulate cpu usage.
     StartWorker();
   }
@@ -254,15 +178,6 @@
     StopWorker();
   }
 
-  // Starts a no-op thread that gets registered with the ProfileHandler. Waits
-  // for the thread to stop.
-  void RegisterThread() {
-    NullThread t;
-    t.SetJoinable(true);
-    t.Start();
-    t.Join();
-  }
-
   // Starts a busy worker thread to accumulate cpu time. There should be only
   // one busy worker running. This is required for the case where there are
   // separate timers for each thread.
@@ -282,14 +197,6 @@
     delete busy_worker_;
   }
 
-  // Checks whether SIGPROF/SIGALRM signal handler is enabled.
-  bool IsSignalEnabled() {
-    struct sigaction sa;
-    CHECK_EQ(sigaction(signal_number_, NULL, &sa), 0);
-    return ((sa.sa_handler == SIG_IGN) || (sa.sa_handler == SIG_DFL)) ?
-        false : true;
-  }
-
   // Gets the number of callbacks registered with the ProfileHandler.
   uint32 GetCallbackCount() {
     ProfileHandlerState state;
@@ -311,10 +218,6 @@
     EXPECT_GT(GetCallbackCount(), 0);
     // Check that the profile timer is enabled.
     EXPECT_EQ(FLAGS_test_profiler_enabled, linux_per_thread_timers_mode_ || IsTimerEnabled());
-    // Check that the signal handler is enabled.
-    if (FLAGS_test_profiler_signal_handler) {
-      EXPECT_EQ(FLAGS_test_profiler_enabled, IsSignalEnabled());
-    }
     uint64 interrupts_before = GetInterruptCount();
     // Sleep for a bit and check that tick counter is making progress.
     int old_tick_count = tick_counter;
@@ -337,38 +240,18 @@
     Delay(kSleepInterval);
     int new_tick_count = tick_counter;
     EXPECT_EQ(old_tick_count, new_tick_count);
-    // If no callbacks, signal handler and shared timer should be disabled.
+    // If no callbacks, timer should be disabled.
     if (GetCallbackCount() == 0) {
-      if (FLAGS_test_profiler_signal_handler) {
-        EXPECT_FALSE(IsSignalEnabled());
-      }
-      if (!linux_per_thread_timers_mode_) {
-        if (timer_separate_) {
-          EXPECT_TRUE(IsTimerEnabled());
-        } else {
-          EXPECT_FALSE(IsTimerEnabled());
-        }
-      }
+      EXPECT_FALSE(IsTimerEnabled());
     }
   }
 
-  // Verifies that the SIGPROF/SIGALRM interrupt handler is disabled and the
-  // timer, if shared, is disabled. Expects the worker to be running.
+  // Verifies that the timer is disabled. Expects the worker to be running.
   void VerifyDisabled() {
-    // Check that the signal handler is disabled.
-    if (FLAGS_test_profiler_signal_handler) {
-      EXPECT_FALSE(IsSignalEnabled());
-    }
     // Check that the callback count is 0.
     EXPECT_EQ(0, GetCallbackCount());
-    // Check that the timer is disabled if shared, enabled otherwise.
-    if (!linux_per_thread_timers_mode_) {
-      if (timer_separate_) {
-        EXPECT_TRUE(IsTimerEnabled());
-      } else {
-        EXPECT_FALSE(IsTimerEnabled());
-      }
-    }
+    // Check that the timer is disabled.
+    EXPECT_FALSE(IsTimerEnabled());
     // Verify that the ProfileHandler is not accumulating profile ticks.
     uint64 interrupts_before = GetInterruptCount();
     Delay(kSleepInterval);
@@ -435,14 +318,14 @@
 // Verifies that multiple callbacks can be registered.
 TEST_F(ProfileHandlerTest, MultipleCallbacks) {
   // Register first callback.
-  int first_tick_count;
+  int first_tick_count = 0;
   ProfileHandlerToken* token1 = RegisterCallback(&first_tick_count);
   // Check that callback was registered correctly.
   VerifyRegistration(first_tick_count);
   EXPECT_EQ(1, GetCallbackCount());
 
   // Register second callback.
-  int second_tick_count;
+  int second_tick_count = 0;
   ProfileHandlerToken* token2 = RegisterCallback(&second_tick_count);
   // Check that callback was registered correctly.
   VerifyRegistration(second_tick_count);
@@ -460,31 +343,31 @@
   VerifyUnregistration(second_tick_count);
   EXPECT_EQ(0, GetCallbackCount());
 
-  // Verify that the signal handler and timers are correctly disabled.
-  VerifyDisabled();
+  // Verify that the timers is correctly disabled.
+  if (!linux_per_thread_timers_mode_) VerifyDisabled();
 }
 
 // Verifies ProfileHandlerReset
 TEST_F(ProfileHandlerTest, Reset) {
   // Verify that the profile timer interrupt is disabled.
-  VerifyDisabled();
-  int first_tick_count;
+  if (!linux_per_thread_timers_mode_) VerifyDisabled();
+  int first_tick_count = 0;
   RegisterCallback(&first_tick_count);
   VerifyRegistration(first_tick_count);
   EXPECT_EQ(1, GetCallbackCount());
 
   // Register second callback.
-  int second_tick_count;
+  int second_tick_count = 0;
   RegisterCallback(&second_tick_count);
   VerifyRegistration(second_tick_count);
   EXPECT_EQ(2, GetCallbackCount());
 
   // Reset the profile handler and verify that callback were correctly
-  // unregistered and timer/signal are disabled.
+  // unregistered and the timer is disabled.
   ProfileHandlerReset();
   VerifyUnregistration(first_tick_count);
   VerifyUnregistration(second_tick_count);
-  VerifyDisabled();
+  if (!linux_per_thread_timers_mode_) VerifyDisabled();
 }
 
 // Verifies that ProfileHandler correctly handles a case where a callback was
@@ -492,30 +375,20 @@
 TEST_F(ProfileHandlerTest, RegisterCallbackBeforeThread) {
   // Stop the worker.
   StopWorker();
-  // Unregister all existing callbacks, stop the timer (if shared), disable
-  // the signal handler and reset the timer sharing state in the Profile
-  // Handler.
+  // Unregister all existing callbacks and stop the timer.
   ProfileHandlerReset();
   EXPECT_EQ(0, GetCallbackCount());
   VerifyDisabled();
 
-  // Start the worker. At this time ProfileHandler doesn't know if timers are
-  // shared as only one thread has registered so far.
+  // Start the worker.
   StartWorker();
-  // Register a callback and check that profile ticks are being delivered.
-  int tick_count;
+  // Register a callback and check that profile ticks are being delivered and
+  // the timer is enabled.
+  int tick_count = 0;
   RegisterCallback(&tick_count);
   EXPECT_EQ(1, GetCallbackCount());
   VerifyRegistration(tick_count);
-
-  // Register a second thread and verify that timer and signal handler are
-  // correctly enabled.
-  RegisterThread();
-  EXPECT_EQ(1, GetCallbackCount());
   EXPECT_EQ(FLAGS_test_profiler_enabled, linux_per_thread_timers_mode_ || IsTimerEnabled());
-  if (FLAGS_test_profiler_signal_handler) {
-    EXPECT_EQ(FLAGS_test_profiler_enabled, IsSignalEnabled());
-  }
 }
 
 }  // namespace
diff --git a/src/tests/profiledata_unittest.cc b/src/tests/profiledata_unittest.cc
index 972c1b0..3286b9c 100644
--- a/src/tests/profiledata_unittest.cc
+++ b/src/tests/profiledata_unittest.cc
@@ -366,6 +366,7 @@
     RUN(CollectTwoMatching);
     RUN(CollectTwoFlush);
     RUN(StartResetRestart);
+    RUN(StartStopNoOptionsEmpty);
     return 0;
   }
 };
diff --git a/src/tests/profiler_unittest.cc b/src/tests/profiler_unittest.cc
index 321f848..4c814c0 100644
--- a/src/tests/profiler_unittest.cc
+++ b/src/tests/profiler_unittest.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2005, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -46,7 +46,7 @@
 #include "base/simple_mutex.h"
 #include "tests/testutil.h"
 
-static int result = 0;
+static volatile int result = 0;
 static int g_iters = 0;   // argv[1]
 
 Mutex mutex(Mutex::LINKER_INITIALIZED);
diff --git a/src/tests/realloc_unittest.cc b/src/tests/realloc_unittest.cc
index e3d7b59..a4ea17c 100644
--- a/src/tests/realloc_unittest.cc
+++ b/src/tests/realloc_unittest.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2004, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
diff --git a/src/tests/sampler_test.cc b/src/tests/sampler_test.cc
old mode 100755
new mode 100644
index cd64b0f..4095d6a
--- a/src/tests/sampler_test.cc
+++ b/src/tests/sampler_test.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2008, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -48,7 +48,7 @@
 #include <algorithm>
 #include <vector>
 #include <string>
-#include <cmath>
+#include <math.h>
 #include "base/logging.h"
 #include "base/commandlineflags.h"
 #include "sampler.h"       // The Sampler class being tested
@@ -325,28 +325,6 @@
 }
 
 
-// Test for Fastlog2 code
-// We care about the percentage error because we're using this
-// for choosing step sizes, so "close" is relative to the size of
-// the step we would get if we used the built-in log function
-TEST(Sampler, FastLog2) {
-  tcmalloc::Sampler sampler;
-  sampler.Init(1);
-  double max_ratio_error = 0;
-  for (double d = -1021.9; d < 1; d+= 0.13124235) {
-    double e = pow(2.0, d);
-    double truelog = log(e) / log(2.0);  // log_2(e)
-    double fastlog = sampler.FastLog2(e);
-    max_ratio_error = max(max_ratio_error,
-                          max(truelog/fastlog-1, fastlog/truelog-1));
-    CHECK_LE(max_ratio_error, 0.01);
-        //        << StringPrintf("d = %f, e=%f, truelog = %f, fastlog= %f\n",
-        //                        d, e, truelog, fastlog);
-  }
-  LOG(INFO) << StringPrintf("Fastlog2: max_ratio_error = %f\n",
-                            max_ratio_error);
-}
-
 // Futher tests
 
 bool CheckMean(size_t mean, int num_samples) {
@@ -392,11 +370,11 @@
   int num_iters = 128*4*8;
   // Allocate in mixed chunks
   for (int i = 0; i < num_iters; i++) {
-    if (sampler.SampleAllocation(size_big)) {
+    if (!sampler.RecordAllocation(size_big)) {
       counter_big += 1;
     }
     for (int i = 0; i < 129; i++) {
-      if (sampler.SampleAllocation(size_small)) {
+      if (!sampler.RecordAllocation(size_small)) {
         counter_small += 1;
       }
     }
@@ -540,12 +518,9 @@
     uint64_t largest_prng_value = (static_cast<uint64_t>(1)<<48) - 1;
     double q = (largest_prng_value >> (prng_mod_power - 26)) + 1.0;
     LOG(INFO) << StringPrintf("q = %f\n", q);
-    LOG(INFO) << StringPrintf("FastLog2(q) = %f\n", sampler.FastLog2(q));
     LOG(INFO) << StringPrintf("log2(q) = %f\n", log(q)/log(2.0));
-    // Replace min(sampler.FastLog2(q) - 26, 0.0) with
-    // (sampler.FastLog2(q) - 26.000705) when using that optimization
     uint64_t smallest_sample_step
-        = static_cast<uint64_t>(min(sampler.FastLog2(q) - 26, 0.0)
+        = static_cast<uint64_t>(min(log2(q) - 26, 0.0)
                                 * sample_scaling + 1);
     LOG(INFO) << "Smallest sample step is " << smallest_sample_step;
     uint64_t cutoff = static_cast<uint64_t>(10)
@@ -558,10 +533,8 @@
     uint64_t smallest_prng_value = 0;
     q = (smallest_prng_value >> (prng_mod_power - 26)) + 1.0;
     LOG(INFO) << StringPrintf("q = %f\n", q);
-    // Replace min(sampler.FastLog2(q) - 26, 0.0) with
-    // (sampler.FastLog2(q) - 26.000705) when using that optimization
     uint64_t largest_sample_step
-        = static_cast<uint64_t>(min(sampler.FastLog2(q) - 26, 0.0)
+        = static_cast<uint64_t>(min(log2(q) - 26, 0.0)
                                 * sample_scaling + 1);
     LOG(INFO) << "Largest sample step is " << largest_sample_step;
     CHECK_LE(largest_sample_step, one<<63);
@@ -604,7 +577,7 @@
     CHECK_GE(q, 0); // << rnd << "  " << prng_mod_power;
   }
   // Test some potentially out of bounds value for rnd
-  for (int i = 1; i <= 66; i++) {
+  for (int i = 1; i <= 63; i++) {
     rnd = one << i;
     double q = (rnd >> (prng_mod_power - 26)) + 1.0;
     LOG(INFO) << "rnd = " << rnd << " i=" << i << " q=" << q;
diff --git a/src/tests/simple_compat_test.cc b/src/tests/simple_compat_test.cc
index 5dbfd7a..24583a0 100644
--- a/src/tests/simple_compat_test.cc
+++ b/src/tests/simple_compat_test.cc
@@ -38,6 +38,9 @@
 
 #include <stddef.h>
 #include <stdio.h>
+
+#define GPERFTOOLS_SUPPRESS_LEGACY_WARNING
+
 #include <google/heap-checker.h>
 #include <google/heap-profiler.h>
 #include <google/malloc_extension.h>
diff --git a/src/tests/stack_trace_table_test.cc b/src/tests/stack_trace_table_test.cc
index 3cacd2d..393ebbe 100644
--- a/src/tests/stack_trace_table_test.cc
+++ b/src/tests/stack_trace_table_test.cc
@@ -70,18 +70,10 @@
   AddTrace(&table, t2);
   CHECK_EQ(table.depth_total(), 4);
   CHECK_EQ(table.bucket_total(), 2);
-  static const uintptr_t k3[] = {1, 1024, 2, 1, 2, 1,  512, 2, 2, 1, 0};
+  static const uintptr_t k3[] = {1, 512, 2, 2, 1, 1, 1024, 2, 1, 2, 0};
   CheckTracesAndReset(&table, k3, ARRAYSIZE(k3));
 
-  // Table w/ 2 x t1, 1 x t2
-  AddTrace(&table, t1);
-  AddTrace(&table, t2);
-  AddTrace(&table, t1);
-  CHECK_EQ(table.depth_total(), 4);
-  CHECK_EQ(table.bucket_total(), 2);
-  static const uintptr_t k4[] = {2, 2048, 2, 1, 2, 1,  512, 2, 2, 1, 0};
-  CheckTracesAndReset(&table, k4, ARRAYSIZE(k4));
-
+  // Table w/ t1, t3
   // Same stack as t1, but w/ different size
   tcmalloc::StackTrace t3;
   t3.size = static_cast<uintptr_t>(2);
@@ -89,12 +81,11 @@
   t3.stack[0] = reinterpret_cast<void*>(1);
   t3.stack[1] = reinterpret_cast<void*>(2);
 
-  // Table w/ t1, t3
   AddTrace(&table, t1);
   AddTrace(&table, t3);
-  CHECK_EQ(table.depth_total(), 2);
-  CHECK_EQ(table.bucket_total(), 1);
-  static const uintptr_t k5[] = {2, 1026, 2, 1, 2, 0};
+  CHECK_EQ(table.depth_total(), 4);
+  CHECK_EQ(table.bucket_total(), 2);
+  static const uintptr_t k5[] = {1, 2, 2, 1, 2, 1, 1024, 2, 1, 2, 0};
   CheckTracesAndReset(&table, k5, ARRAYSIZE(k5));
 
   puts("PASS");
diff --git a/src/tests/stacktrace_unittest.cc b/src/tests/stacktrace_unittest.cc
index 3c9f735..e55a632 100644
--- a/src/tests/stacktrace_unittest.cc
+++ b/src/tests/stacktrace_unittest.cc
@@ -1,10 +1,11 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2005, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -14,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -33,9 +34,18 @@
 #endif
 #include <stdio.h>
 #include <stdlib.h>
+
+// On those architectures we can and should test if backtracing with
+// ucontext and from signal handler works
+#if __GNUC__ && __linux__ && (__x86_64__ || __aarch64__ || __riscv)
+#include <signal.h>
+#define TEST_UCONTEXT_BITS 1
+#endif
+
 #include "base/commandlineflags.h"
 #include "base/logging.h"
 #include <gperftools/stacktrace.h>
+#include "tests/testutil.h"
 
 namespace {
 
@@ -96,6 +106,7 @@
 #define ADJUST_ADDRESS_RANGE_FROM_RA(prange) do { } while (0)
 #endif  // __GNUC__
 
+
 //-----------------------------------------------------------------------//
 
 void CheckRetAddrIsInFunction(void *ret_addr, const AddressRange &range)
@@ -106,24 +117,105 @@
 
 //-----------------------------------------------------------------------//
 
+#if TEST_UCONTEXT_BITS
+
+struct get_stack_trace_args {
+	int *size_ptr;
+	void **result;
+	int max_depth;
+	uintptr_t where;
+} gst_args;
+
+static
+void SignalHandler(int dummy, siginfo_t *si, void* ucv) {
+	auto uc = static_cast<ucontext_t*>(ucv);
+
+#ifdef __riscv
+	uc->uc_mcontext.__gregs[REG_PC] = gst_args.where;
+#elif __aarch64__
+	uc->uc_mcontext.pc = gst_args.where;
+#else
+	uc->uc_mcontext.gregs[REG_RIP] = gst_args.where;
+#endif
+
+	*gst_args.size_ptr = GetStackTraceWithContext(
+		gst_args.result,
+		gst_args.max_depth,
+		2,
+		uc);
+}
+
+int ATTRIBUTE_NOINLINE CaptureLeafUContext(void **stack, int stack_len) {
+  INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]);
+  DECLARE_ADDRESS_LABEL(start);
+
+  int size;
+
+  printf("Capturing stack trace from signal's ucontext\n");
+  struct sigaction sa;
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_sigaction = SignalHandler;
+  sa.sa_flags = SA_SIGINFO | SA_RESETHAND;
+  int rv = sigaction(SIGSEGV, &sa, nullptr);
+  CHECK(rv == 0);
+
+  gst_args.size_ptr = &size;
+  gst_args.result = stack;
+  gst_args.max_depth = stack_len;
+  gst_args.where = reinterpret_cast<uintptr_t>(noopt(&&after));
+
+  // now, "write" to null pointer and trigger sigsegv to run signal
+  // handler. It'll then change PC to after, as if we jumped one line
+  // below.
+  *noopt(reinterpret_cast<void**>(0)) = 0;
+  // this is not reached, but gcc gets really odd if we don't actually
+  // use computed goto.
+  static void* jump_target = &&after;
+  goto *noopt(&jump_target);
+
+after:
+  printf("Obtained %d stack frames.\n", size);
+  CHECK_GE(size, 1);
+  CHECK_LE(size, stack_len);
+
+  DECLARE_ADDRESS_LABEL(end);
+
+  return size;
+}
+
+#endif  // TEST_UCONTEXT_BITS
+
+int ATTRIBUTE_NOINLINE CaptureLeafPlain(void **stack, int stack_len) {
+  INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]);
+  DECLARE_ADDRESS_LABEL(start);
+
+  int size = GetStackTrace(stack, stack_len, 0);
+
+  printf("Obtained %d stack frames.\n", size);
+  CHECK_GE(size, 1);
+  CHECK_LE(size, stack_len);
+
+  DECLARE_ADDRESS_LABEL(end);
+
+  return size;
+}
+
 void ATTRIBUTE_NOINLINE CheckStackTrace(int);
-void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) {
-  const int STACK_LEN = 10;
+
+int (*leaf_capture_fn)(void**, int) = CaptureLeafPlain;
+
+void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(int i) {
+  const int STACK_LEN = 20;
   void *stack[STACK_LEN];
   int size;
 
   ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[1]);
-  INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]);
-  DECLARE_ADDRESS_LABEL(start);
-  size = GetStackTrace(stack, STACK_LEN, 0);
-  printf("Obtained %d stack frames.\n", size);
-  CHECK_GE(size, 1);
-  CHECK_LE(size, STACK_LEN);
+
+  size = leaf_capture_fn(stack, STACK_LEN);
 
 #ifdef HAVE_EXECINFO_H
   {
     char **strings = backtrace_symbols(stack, size);
-    printf("Obtained %d stack frames.\n", size);
     for (int i = 0; i < size; i++)
       printf("%s %p\n", strings[i], stack[i]);
     printf("CheckStackTrace() addr: %p\n", &CheckStackTrace);
@@ -131,14 +223,18 @@
   }
 #endif
 
-  for (int i = 0; i < BACKTRACE_STEPS; i++) {
+  for (int i = 0, j = 0; i < BACKTRACE_STEPS; i++, j++) {
+    if (i == 1 && j == 1) {
+      // this is expected to be our function for which we don't
+      // establish bounds. So skip.
+      j++;
+    }
     printf("Backtrace %d: expected: %p..%p  actual: %p ... ",
-           i, expected_range[i].start, expected_range[i].end, stack[i]);
+           i, expected_range[i].start, expected_range[i].end, stack[j]);
     fflush(stdout);
-    CheckRetAddrIsInFunction(stack[i], expected_range[i]);
+    CheckRetAddrIsInFunction(stack[j], expected_range[i]);
     printf("OK\n");
   }
-  DECLARE_ADDRESS_LABEL(end);
 }
 
 //-----------------------------------------------------------------------//
@@ -149,7 +245,7 @@
   INIT_ADDRESS_RANGE(CheckStackTrace4, start, end, &expected_range[1]);
   DECLARE_ADDRESS_LABEL(start);
   for (int j = i; j >= 0; j--)
-    CheckStackTraceLeaf();
+    CheckStackTraceLeaf(j);
   DECLARE_ADDRESS_LABEL(end);
 }
 void ATTRIBUTE_NOINLINE CheckStackTrace3(int i) {
@@ -179,8 +275,9 @@
 void ATTRIBUTE_NOINLINE CheckStackTrace(int i) {
   INIT_ADDRESS_RANGE(CheckStackTrace, start, end, &expected_range[5]);
   DECLARE_ADDRESS_LABEL(start);
-  for (int j = i; j >= 0; j--)
+  for (int j = i; j >= 0; j--) {
     CheckStackTrace1(j);
+  }
   DECLARE_ADDRESS_LABEL(end);
 }
 
@@ -190,5 +287,12 @@
 int main(int argc, char ** argv) {
   CheckStackTrace(0);
   printf("PASS\n");
+
+#if TEST_UCONTEXT_BITS
+  leaf_capture_fn = CaptureLeafUContext;
+  CheckStackTrace(0);
+  printf("PASS\n");
+#endif  // TEST_UCONTEXT_BITS
+
   return 0;
 }
diff --git a/src/tests/system-alloc_unittest.cc b/src/tests/system-alloc_unittest.cc
index 4a5f7c0..fd199e2 100644
--- a/src/tests/system-alloc_unittest.cc
+++ b/src/tests/system-alloc_unittest.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2007, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,7 +32,9 @@
 // Author: Arun Sharma
 
 #include "config_for_unittests.h"
+
 #include "system-alloc.h"
+
 #include <stdio.h>
 #if defined HAVE_STDINT_H
 #include <stdint.h>             // to get uintptr_t
@@ -40,11 +42,15 @@
 #include <inttypes.h>           // another place uintptr_t might be defined
 #endif
 #include <sys/types.h>
+
 #include <algorithm>
 #include <limits>
-#include "base/logging.h"               // for Check_GEImpl, Check_LTImpl, etc
-#include <gperftools/malloc_extension.h>    // for MallocExtension::instance
-#include "common.h"                     // for kAddressBits
+
+#include "base/logging.h"                // for Check_GEImpl, Check_LTImpl, etc
+#include "common.h"                      // for kAddressBits
+#include "gperftools/malloc_extension.h" // for MallocExtension::instance
+#include "gperftools/tcmalloc.h"
+#include "tests/testutil.h"
 
 class ArraySysAllocator : public SysAllocator {
 public:
@@ -101,7 +107,7 @@
 
   // An allocation size that is likely to trigger the system allocator.
   // XXX: this is implementation specific.
-  char *p = new char[1024 * 1024];
+  char *p =  noopt(new char[1024 * 1024]);
   delete [] p;
 
   // Make sure that our allocator was invoked.
@@ -136,12 +142,12 @@
   // disable this test.
   // The weird parens are to avoid macro-expansion of 'max' on windows.
   const size_t kHugeSize = (std::numeric_limits<size_t>::max)() / 2;
-  void* p1 = malloc(kHugeSize);
-  void* p2 = malloc(kHugeSize);
+  void* p1 = noopt(malloc(kHugeSize));
+  void* p2 = noopt(malloc(kHugeSize));
   CHECK(p2 == NULL);
   if (p1 != NULL) free(p1);
 
-  char* q = new char[1024];
+  char* q = noopt(new char[1024]);
   CHECK(q != NULL);
   delete [] q;
 }
diff --git a/src/tests/tcmalloc_large_unittest.cc b/src/tests/tcmalloc_large_unittest.cc
index ff22007..02b8569 100644
--- a/src/tests/tcmalloc_large_unittest.cc
+++ b/src/tests/tcmalloc_large_unittest.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2005, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -42,19 +42,21 @@
 #include <set>                          // for set, etc
 
 #include "base/logging.h"               // for operator<<, CHECK, etc
+#include "gperftools/tcmalloc.h"
+#include "tests/testutil.h"
 
 using std::set;
 
 // Alloc a size that should always fail.
 
 void TryAllocExpectFail(size_t size) {
-  void* p1 = malloc(size);
+  void* p1 = noopt(malloc(size));
   CHECK(p1 == NULL);
 
-  void* p2 = malloc(1);
+  void* p2 = noopt(malloc(1));
   CHECK(p2 != NULL);
 
-  void* p3 = realloc(p2, size);
+  void* p3 = noopt(realloc(p2, size));
   CHECK(p3 == NULL);
 
   free(p2);
@@ -64,24 +66,23 @@
 // If it does work, touch some pages.
 
 void TryAllocMightFail(size_t size) {
-  unsigned char* p = static_cast<unsigned char*>(malloc(size));
-  if ( p != NULL ) {
-    unsigned char volatile* vp = p;  // prevent optimizations
+  unsigned char* p = static_cast<unsigned char*>(noopt(malloc(size)));
+  if (p != NULL) {
     static const size_t kPoints = 1024;
 
     for ( size_t i = 0; i < kPoints; ++i ) {
-      vp[i * (size / kPoints)] = static_cast<unsigned char>(i);
+      p[i * (size / kPoints)] = static_cast<unsigned char>(i);
     }
 
     for ( size_t i = 0; i < kPoints; ++i ) {
-      CHECK(vp[i * (size / kPoints)] == static_cast<unsigned char>(i));
+      CHECK(p[i * (size / kPoints)] == static_cast<unsigned char>(i));
     }
 
-    vp[size-1] = 'M';
-    CHECK(vp[size-1] == 'M');
+    p[size-1] = 'M';
+    CHECK(p[size-1] == 'M');
   }
 
-  free(p);
+  free(noopt(p));
 }
 
 int main (int argc, char** argv) {
@@ -103,7 +104,7 @@
 
   // Grab some memory so that some later allocations are guaranteed to fail.
   printf("Test small malloc\n");
-  void* p_small = malloc(4*1048576);
+  void* p_small = noopt(malloc(4*1048576));
   CHECK(p_small != NULL);
 
   // Test sizes up near the maximum size_t.
diff --git a/src/tests/tcmalloc_unittest.cc b/src/tests/tcmalloc_unittest.cc
index 69698bc..658772f 100644
--- a/src/tests/tcmalloc_unittest.cc
+++ b/src/tests/tcmalloc_unittest.cc
@@ -69,7 +69,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
-#if defined HAVE_STDINT_H
+#ifdef HAVE_STDINT_H
 #include <stdint.h>        // for intptr_t
 #endif
 #include <sys/types.h>     // for size_t
@@ -91,6 +91,7 @@
 #include "base/simple_mutex.h"
 #include "gperftools/malloc_hook.h"
 #include "gperftools/malloc_extension.h"
+#include "gperftools/nallocx.h"
 #include "gperftools/tcmalloc.h"
 #include "thread_cache.h"
 #include "system-alloc.h"
@@ -135,14 +136,35 @@
 #else
 static bool kOSSupportsMemalign = true;
 static inline void* Memalign(size_t align, size_t size) {
-  return memalign(align, size);
+  return noopt(memalign(align, noopt(size)));
 }
 static inline int PosixMemalign(void** ptr, size_t align, size_t size) {
-  return posix_memalign(ptr, align, size);
+  return noopt(posix_memalign(ptr, align, noopt(size)));
 }
 
 #endif
 
+#if defined(ENABLE_ALIGNED_NEW_DELETE)
+
+#define OVERALIGNMENT 64
+
+struct overaligned_type
+{
+#if defined(__GNUC__)
+  __attribute__((__aligned__(OVERALIGNMENT)))
+#elif defined(_MSC_VER)
+  __declspec(align(OVERALIGNMENT))
+#else
+  alignas(OVERALIGNMENT)
+#endif
+  unsigned char data[OVERALIGNMENT * 2]; // make the object size different from
+                                         // alignment to make sure the correct
+                                         // values are passed to the new/delete
+                                         // implementation functions
+};
+
+#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
+
 // On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
 // form of the name instead.
 #ifndef MAP_ANONYMOUS
@@ -158,6 +180,37 @@
 DECLARE_int32(max_free_queue_size);     // in debugallocation.cc
 DECLARE_int64(tcmalloc_sample_parameter);
 
+struct OOMAbleSysAlloc : public SysAllocator {
+  SysAllocator *child;
+  int simulate_oom;
+
+  void* Alloc(size_t size, size_t* actual_size, size_t alignment) {
+    if (simulate_oom) {
+      return NULL;
+    }
+    return child->Alloc(size, actual_size, alignment);
+  }
+};
+
+static union {
+  char buf[sizeof(OOMAbleSysAlloc)];
+  void *ptr;
+} test_sys_alloc_space;
+
+static OOMAbleSysAlloc* get_test_sys_alloc() {
+  return reinterpret_cast<OOMAbleSysAlloc*>(&test_sys_alloc_space);
+}
+
+void setup_oomable_sys_alloc() {
+  SysAllocator *def = MallocExtension::instance()->GetSystemAllocator();
+
+  OOMAbleSysAlloc *alloc = get_test_sys_alloc();
+  new (alloc) OOMAbleSysAlloc;
+  alloc->child = def;
+
+  MallocExtension::instance()->SetSystemAllocator(alloc);
+}
+
 namespace testing {
 
 static const int FLAGS_numtests = 50000;
@@ -319,7 +372,7 @@
         }
       }
     }
-    return malloc(size);
+    return noopt(malloc(size));
   }
 
  private:
@@ -549,7 +602,7 @@
 }
 
 static void TryHugeAllocation(size_t s, AllocatorState* rnd) {
-  void* p = rnd->alloc(s);
+  void* p = rnd->alloc(noopt(s));
   CHECK(p == NULL);   // huge allocation s should fail!
 }
 
@@ -581,7 +634,7 @@
 static void TestCalloc(size_t n, size_t s, bool ok) {
   char* p = reinterpret_cast<char*>(calloc(n, s));
   if (FLAGS_verbose)
-    fprintf(LOGSTREAM, "calloc(%" PRIxS ", %" PRIxS "): %p\n", n, s, p);
+    fprintf(LOGSTREAM, "calloc(%zx, %zx): %p\n", n, s, p);
   if (!ok) {
     CHECK(p == NULL);  // calloc(n, s) should not succeed
   } else {
@@ -608,16 +661,16 @@
   int deltas[] = { 1, -2, 4, -8, 16, -32, 64, -128 };
 
   for (int s = 0; s < sizeof(start_sizes)/sizeof(*start_sizes); ++s) {
-    void* p = malloc(start_sizes[s]);
+    void* p = noopt(malloc(start_sizes[s]));
     CHECK(p);
     // The larger the start-size, the larger the non-reallocing delta.
     for (int d = 0; d < (s+1) * 2; ++d) {
-      void* new_p = realloc(p, start_sizes[s] + deltas[d]);
+      void* new_p = noopt(realloc(p, start_sizes[s] + deltas[d]));
       CHECK(p == new_p);  // realloc should not allocate new memory
     }
     // Test again, but this time reallocing smaller first.
     for (int d = 0; d < s*2; ++d) {
-      void* new_p = realloc(p, start_sizes[s] - deltas[d]);
+      void* new_p = noopt(realloc(p, start_sizes[s] - deltas[d]));
       CHECK(p == new_p);  // realloc should not allocate new memory
     }
     free(p);
@@ -626,12 +679,13 @@
 #endif
 }
 
-static void TestNewHandler() throw (std::bad_alloc) {
+static void TestNewHandler() {
   ++news_handled;
   throw std::bad_alloc();
 }
 
 static void TestOneNew(void* (*func)(size_t)) {
+  func = noopt(func);
   // success test
   try {
     void* ptr = (*func)(kNotTooBig);
@@ -676,6 +730,7 @@
 }
 
 static void TestOneNothrowNew(void* (*func)(size_t, const std::nothrow_t&)) {
+  func = noopt(func);
   // success test
   try {
     void* ptr = (*func)(kNotTooBig, std::nothrow);
@@ -725,9 +780,9 @@
 // that we used the tcmalloc version of the call, and not the libc.
 // Note the ... in the hook signature: we don't care what arguments
 // the hook takes.
-#define MAKE_HOOK_CALLBACK(hook_type)                                   \
+#define MAKE_HOOK_CALLBACK(hook_type, ...)                              \
   static volatile int g_##hook_type##_calls = 0;                                 \
-  static void IncrementCallsTo##hook_type(...) {                        \
+  static void IncrementCallsTo##hook_type(__VA_ARGS__) {                \
     g_##hook_type##_calls++;                                            \
   }                                                                     \
   static void Verify##hook_type##WasCalled() {                          \
@@ -744,12 +799,14 @@
   }
 
 // We do one for each hook typedef in malloc_hook.h
-MAKE_HOOK_CALLBACK(NewHook);
-MAKE_HOOK_CALLBACK(DeleteHook);
-MAKE_HOOK_CALLBACK(MmapHook);
-MAKE_HOOK_CALLBACK(MremapHook);
-MAKE_HOOK_CALLBACK(MunmapHook);
-MAKE_HOOK_CALLBACK(SbrkHook);
+MAKE_HOOK_CALLBACK(NewHook, const void*, size_t);
+MAKE_HOOK_CALLBACK(DeleteHook, const void*);
+MAKE_HOOK_CALLBACK(MmapHook, const void*, const void*, size_t, int, int, int,
+                   off_t);
+MAKE_HOOK_CALLBACK(MremapHook, const void*, const void*, size_t, size_t, int,
+                   const void*);
+MAKE_HOOK_CALLBACK(MunmapHook, const void *, size_t);
+MAKE_HOOK_CALLBACK(SbrkHook, const void *, ptrdiff_t);
 
 static void TestAlignmentForSize(int size) {
   fprintf(LOGSTREAM, "Testing alignment of malloc(%d)\n", size);
@@ -900,8 +957,8 @@
   AggressiveDecommitChanger disabler(0);
 
   static const int MB = 1048576;
-  void* a = malloc(MB);
-  void* b = malloc(MB);
+  void* a = noopt(malloc(MB));
+  void* b = noopt(malloc(MB));
   MallocExtension::instance()->ReleaseFreeMemory();
   size_t starting_bytes = GetUnmappedBytes();
 
@@ -937,7 +994,7 @@
   MallocExtension::instance()->ReleaseFreeMemory();
   EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
 
-  a = malloc(MB);
+  a = noopt(malloc(MB));
   free(a);
   EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
 
@@ -962,8 +1019,8 @@
   AggressiveDecommitChanger enabler(1);
 
   static const int MB = 1048576;
-  void* a = malloc(MB);
-  void* b = malloc(MB);
+  void* a = noopt(malloc(MB));
+  void* b = noopt(malloc(MB));
 
   size_t starting_bytes = GetUnmappedBytes();
 
@@ -984,7 +1041,7 @@
   MallocExtension::instance()->ReleaseFreeMemory();
   EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
 
-  a = malloc(MB);
+  a = noopt(malloc(MB));
   free(a);
 
   EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
@@ -1009,19 +1066,19 @@
 
   g_old_handler = std::set_new_handler(&OnNoMemory);
   g_no_memory = false;
-  void* ret = malloc(kTooBig);
+  void* ret = noopt(malloc(noopt(kTooBig)));
   EXPECT_EQ(NULL, ret);
   EXPECT_TRUE(g_no_memory);
 
   g_old_handler = std::set_new_handler(&OnNoMemory);
   g_no_memory = false;
-  ret = calloc(1, kTooBig);
+  ret = noopt(calloc(1, noopt(kTooBig)));
   EXPECT_EQ(NULL, ret);
   EXPECT_TRUE(g_no_memory);
 
   g_old_handler = std::set_new_handler(&OnNoMemory);
   g_no_memory = false;
-  ret = realloc(NULL, kTooBig);
+  ret = noopt(realloc(nullptr, noopt(kTooBig)));
   EXPECT_EQ(NULL, ret);
   EXPECT_TRUE(g_no_memory);
 
@@ -1048,13 +1105,16 @@
 }
 
 static void TestErrno(void) {
-  errno = 0;
-  void* ret = memalign(128, kTooBig);
-  EXPECT_EQ(NULL, ret);
-  EXPECT_EQ(ENOMEM, errno);
+  void* ret;
+  if (kOSSupportsMemalign) {
+    errno = 0;
+    ret = Memalign(128, kTooBig);
+    EXPECT_EQ(NULL, ret);
+    EXPECT_EQ(ENOMEM, errno);
+  }
 
   errno = 0;
-  ret = malloc(kTooBig);
+  ret = noopt(malloc(noopt(kTooBig)));
   EXPECT_EQ(NULL, ret);
   EXPECT_EQ(ENOMEM, errno);
 
@@ -1064,12 +1124,89 @@
   EXPECT_EQ(ENOMEM, errno);
 }
 
+
+#ifndef DEBUGALLOCATION
+// Ensure that nallocx works before main.
+struct GlobalNallocx {
+  GlobalNallocx() { CHECK_GT(nallocx(99, 0), 99); }
+} global_nallocx;
+
+#if defined(__GNUC__)
+
+static void check_global_nallocx() __attribute__((constructor));
+static void check_global_nallocx() { CHECK_GT(nallocx(99, 0), 99); }
+
+#endif // __GNUC__
+
+static void TestNAllocX() {
+  for (size_t size = 0; size <= (1 << 20); size += 7) {
+    size_t rounded = nallocx(size, 0);
+    ASSERT_GE(rounded, size);
+    void* ptr = malloc(size);
+    ASSERT_EQ(rounded, MallocExtension::instance()->GetAllocatedSize(ptr));
+    free(ptr);
+  }
+}
+
+static void TestNAllocXAlignment() {
+  for (size_t size = 0; size <= (1 << 20); size += 7) {
+    for (size_t align = 0; align < 10; align++) {
+      size_t rounded = nallocx(size, MALLOCX_LG_ALIGN(align));
+      ASSERT_GE(rounded, size);
+      ASSERT_EQ(rounded % (1 << align), 0);
+      void* ptr = tc_memalign(1 << align, size);
+      ASSERT_EQ(rounded, MallocExtension::instance()->GetAllocatedSize(ptr));
+      free(ptr);
+    }
+  }
+}
+
+static int saw_new_handler_runs;
+static void* volatile oom_test_last_ptr;
+
+static void test_new_handler() {
+  get_test_sys_alloc()->simulate_oom = false;
+  void *ptr = oom_test_last_ptr;
+  oom_test_last_ptr = NULL;
+  ::operator delete[](ptr);
+  saw_new_handler_runs++;
+}
+
+static ATTRIBUTE_NOINLINE void TestNewOOMHandling() {
+  // debug allocator does internal allocations and crashes when such
+  // internal allocation fails. So don't test it.
+  setup_oomable_sys_alloc();
+
+  std::new_handler old = std::set_new_handler(test_new_handler);
+  get_test_sys_alloc()->simulate_oom = true;
+
+  ASSERT_EQ(saw_new_handler_runs, 0);
+
+  for (int i = 0; i < 10240; i++) {
+    oom_test_last_ptr = noopt(new char [512]);
+    ASSERT_NE(oom_test_last_ptr, NULL);
+    if (saw_new_handler_runs) {
+      break;
+    }
+  }
+
+  ASSERT_GE(saw_new_handler_runs, 1);
+
+  get_test_sys_alloc()->simulate_oom = false;
+  std::set_new_handler(old);
+}
+#endif  // !DEBUGALLOCATION
+
 static int RunAllTests(int argc, char** argv) {
   // Optional argv[1] is the seed
   AllocatorState rnd(argc > 1 ? atoi(argv[1]) : 100);
 
   SetTestResourceLimit();
 
+#ifndef DEBUGALLOCATION
+  TestNewOOMHandling();
+#endif
+
   // TODO(odo):  This test has been disabled because it is only by luck that it
   // does not result in fragmentation.  When tcmalloc makes an allocation which
   // spans previously unused leaves of the pagemap it will allocate and fill in
@@ -1131,6 +1268,23 @@
     std::stable_sort(v.begin(), v.end());
   }
 
+#ifdef ENABLE_SIZED_DELETE
+  {
+    fprintf(LOGSTREAM, "Testing large sized delete is not crashing\n");
+    // Large sized delete
+    // case. https://github.com/gperftools/gperftools/issues/1254
+    std::vector<char*> addresses;
+    constexpr int kSizedDepth = 1024;
+    addresses.reserve(kSizedDepth);
+    for (int i = 0; i < kSizedDepth; i++) {
+      addresses.push_back(noopt(new char[12686]));
+    }
+    for (int i = 0; i < kSizedDepth; i++) {
+      ::operator delete[](addresses[i], 12686);
+    }
+  }
+#endif
+
   // Test each of the memory-allocation functions once, just as a sanity-check
   fprintf(LOGSTREAM, "Sanity-testing all the memory allocation functions\n");
   {
@@ -1191,59 +1345,136 @@
     VerifyDeleteHookWasCalled();
 #endif
 
-    p1 = valloc(60);
+    p1 = noopt(valloc(60));
     CHECK(p1 != NULL);
     VerifyNewHookWasCalled();
     free(p1);
     VerifyDeleteHookWasCalled();
 
-    p1 = pvalloc(70);
+    p1 = noopt(pvalloc(70));
     CHECK(p1 != NULL);
     VerifyNewHookWasCalled();
     free(p1);
     VerifyDeleteHookWasCalled();
 
-    char* p2 = new char;
+    char* p2 = noopt(new char);
     CHECK(p2 != NULL);
     VerifyNewHookWasCalled();
     delete p2;
     VerifyDeleteHookWasCalled();
 
-    p2 = new char[100];
+    p2 = noopt(new char[100]);
     CHECK(p2 != NULL);
     VerifyNewHookWasCalled();
     delete[] p2;
     VerifyDeleteHookWasCalled();
 
-    p2 = new(std::nothrow) char;
+    p2 = noopt(new (std::nothrow) char);
     CHECK(p2 != NULL);
     VerifyNewHookWasCalled();
     delete p2;
     VerifyDeleteHookWasCalled();
 
-    p2 = new(std::nothrow) char[100];
+    p2 = noopt(new (std::nothrow) char[100]);
     CHECK(p2 != NULL);
     VerifyNewHookWasCalled();
     delete[] p2;
     VerifyDeleteHookWasCalled();
 
     // Another way of calling operator new
-    p2 = static_cast<char*>(::operator new(100));
+    p2 = noopt(static_cast<char*>(::operator new(100)));
     CHECK(p2 != NULL);
     VerifyNewHookWasCalled();
     ::operator delete(p2);
     VerifyDeleteHookWasCalled();
 
     // Try to call nothrow's delete too.  Compilers use this.
-    p2 = static_cast<char*>(::operator new(100, std::nothrow));
+    p2 = noopt(static_cast<char*>(::operator new(100, std::nothrow)));
     CHECK(p2 != NULL);
     VerifyNewHookWasCalled();
     ::operator delete(p2, std::nothrow);
     VerifyDeleteHookWasCalled();
 
+#ifdef ENABLE_SIZED_DELETE
+    p2 = noopt(new char);
+    CHECK(p2 != NULL);
+    VerifyNewHookWasCalled();
+    ::operator delete(p2, sizeof(char));
+    VerifyDeleteHookWasCalled();
+
+    p2 = noopt(new char[100]);
+    CHECK(p2 != NULL);
+    VerifyNewHookWasCalled();
+    ::operator delete[](p2, sizeof(char) * 100);
+    VerifyDeleteHookWasCalled();
+#endif
+
+#if defined(ENABLE_ALIGNED_NEW_DELETE)
+
+    overaligned_type* poveraligned = noopt(new overaligned_type);
+    CHECK(poveraligned != NULL);
+    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
+    VerifyNewHookWasCalled();
+    delete poveraligned;
+    VerifyDeleteHookWasCalled();
+
+    poveraligned = noopt(new overaligned_type[10]);
+    CHECK(poveraligned != NULL);
+    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
+    VerifyNewHookWasCalled();
+    delete[] poveraligned;
+    VerifyDeleteHookWasCalled();
+
+    poveraligned = noopt(new(std::nothrow) overaligned_type);
+    CHECK(poveraligned != NULL);
+    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
+    VerifyNewHookWasCalled();
+    delete poveraligned;
+    VerifyDeleteHookWasCalled();
+
+    poveraligned = noopt(new(std::nothrow) overaligned_type[10]);
+    CHECK(poveraligned != NULL);
+    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
+    VerifyNewHookWasCalled();
+    delete[] poveraligned;
+    VerifyDeleteHookWasCalled();
+
+    // Another way of calling operator new
+    p2 = noopt(static_cast<char*>(::operator new(100, std::align_val_t(OVERALIGNMENT))));
+    CHECK(p2 != NULL);
+    CHECK((((size_t)p2) % OVERALIGNMENT) == 0u);
+    VerifyNewHookWasCalled();
+    ::operator delete(p2, std::align_val_t(OVERALIGNMENT));
+    VerifyDeleteHookWasCalled();
+
+    p2 = noopt(static_cast<char*>(::operator new(100, std::align_val_t(OVERALIGNMENT), std::nothrow)));
+    CHECK(p2 != NULL);
+    CHECK((((size_t)p2) % OVERALIGNMENT) == 0u);
+    VerifyNewHookWasCalled();
+    ::operator delete(p2, std::align_val_t(OVERALIGNMENT), std::nothrow);
+    VerifyDeleteHookWasCalled();
+
+#ifdef ENABLE_SIZED_DELETE
+    poveraligned = noopt(new overaligned_type);
+    CHECK(poveraligned != NULL);
+    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
+    VerifyNewHookWasCalled();
+    ::operator delete(poveraligned, sizeof(overaligned_type), std::align_val_t(OVERALIGNMENT));
+    VerifyDeleteHookWasCalled();
+
+    poveraligned = noopt(new overaligned_type[10]);
+    CHECK(poveraligned != NULL);
+    CHECK((((size_t)poveraligned) % OVERALIGNMENT) == 0u);
+    VerifyNewHookWasCalled();
+    ::operator delete[](poveraligned, sizeof(overaligned_type) * 10, std::align_val_t(OVERALIGNMENT));
+    VerifyDeleteHookWasCalled();
+#endif
+
+#endif // defined(ENABLE_ALIGNED_NEW_DELETE)
+
     // Try strdup(), which the system allocates but we must free.  If
     // all goes well, libc will use our malloc!
-    p2 = strdup("test");
+    p2 = noopt(strdup("in memory of James Golick"));
     CHECK(p2 != NULL);
     VerifyNewHookWasCalled();
     free(p2);
@@ -1279,9 +1510,9 @@
     VerifyMunmapHookWasCalled();
     close(fd);
 #else   // this is just to quiet the compiler: make sure all fns are called
-    IncrementCallsToMmapHook();
-    IncrementCallsToMunmapHook();
-    IncrementCallsToMremapHook();
+    IncrementCallsToMmapHook(NULL, NULL, 0, 0, 0, 0, 0);
+    IncrementCallsToMunmapHook(NULL, 0);
+    IncrementCallsToMremapHook(NULL, NULL, 0, 0, 0, NULL);
     VerifyMmapHookWasCalled();
     VerifyMremapHookWasCalled();
     VerifyMunmapHookWasCalled();
@@ -1289,7 +1520,7 @@
 
     // Test sbrk
     SetSbrkHook();
-#if defined(HAVE_SBRK) && defined(__linux) && \
+#if defined(HAVE___SBRK) && defined(__linux) && \
        (defined(__i386__) || defined(__x86_64__))
     p1 = sbrk(8192);
     CHECK(p1 != NULL);
@@ -1302,7 +1533,7 @@
     CHECK(p1 != NULL);
     CHECK_EQ(g_SbrkHook_calls, 0);
 #else   // this is just to quiet the compiler: make sure all fns are called
-    IncrementCallsToSbrkHook();
+    IncrementCallsToSbrkHook(NULL, 0);
     VerifySbrkHookWasCalled();
 #endif
 
@@ -1384,11 +1615,16 @@
   // Check that large allocations fail with NULL instead of crashing
 #ifndef DEBUGALLOCATION    // debug allocation takes forever for huge allocs
   fprintf(LOGSTREAM, "Testing out of memory\n");
+  size_t old_limit;
+  CHECK(MallocExtension::instance()->GetNumericProperty("tcmalloc.heap_limit_mb", &old_limit));
+  // Don't exercise more than 1 gig, no need to.
+  CHECK(MallocExtension::instance()->SetNumericProperty("tcmalloc.heap_limit_mb", 1 << 10));
   for (int s = 0; ; s += (10<<20)) {
     void* large_object = rnd.alloc(s);
     if (large_object == NULL) break;
     free(large_object);
   }
+  CHECK(MallocExtension::instance()->SetNumericProperty("tcmalloc.heap_limit_mb", old_limit));
 #endif
 
   TestHugeThreadCache();
@@ -1398,6 +1634,12 @@
   TestSetNewMode();
   TestErrno();
 
+// GetAllocatedSize under DEBUGALLOCATION returns the size that we asked for.
+#ifndef DEBUGALLOCATION
+  TestNAllocX();
+  TestNAllocXAlignment();
+#endif
+
   return 0;
 }
 
diff --git a/src/tests/tcmalloc_unittest.sh b/src/tests/tcmalloc_unittest.sh
index 755241e..0e7996a 100755
--- a/src/tests/tcmalloc_unittest.sh
+++ b/src/tests/tcmalloc_unittest.sh
@@ -69,12 +69,16 @@
 run_check_transfer_num_obj "40"
 run_check_transfer_num_obj "4096"
 
-echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_AGGRESSIVE_DECOMMIT=f ... "
+echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_AGGRESSIVE_DECOMMIT=t ... "
 
-TCMALLOC_AGGRESSIVE_DECOMMIT=f run_unittest
+TCMALLOC_AGGRESSIVE_DECOMMIT=t run_unittest
 
 echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_HEAP_LIMIT_MB=512 ... "
 
 TCMALLOC_HEAP_LIMIT_MB=512 run_unittest
 
+echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_ENABLE_SIZED_DELETE=t ..."
+
+TCMALLOC_ENABLE_SIZED_DELETE=t run_unittest
+
 echo "PASS"
diff --git a/src/tests/testutil.cc b/src/tests/testutil.cc
index c2c71cb..e5faa65 100644
--- a/src/tests/testutil.cc
+++ b/src/tests/testutil.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2007, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
diff --git a/src/tests/testutil.h b/src/tests/testutil.h
index 071a209..dc1db9b 100644
--- a/src/tests/testutil.h
+++ b/src/tests/testutil.h
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2007, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -59,4 +59,15 @@
 // out job limits.
 void SetTestResourceLimit();
 
+static void (* volatile noopt_helper)(void *) = +[] (void* dummy) {};
+
+// This function forces compiler to forget specific knowledge about
+// value of 'val'. This is useful to avoid compiler optimizing out
+// new/delete pairs for our unit tests.
+template <typename T>
+T noopt(T val) {
+  noopt_helper(&val);
+  return val;
+}
+
 #endif  // TCMALLOC_TOOLS_TESTUTIL_H_
diff --git a/src/tests/thread_dealloc_unittest.cc b/src/tests/thread_dealloc_unittest.cc
index 97615cd..770a760 100644
--- a/src/tests/thread_dealloc_unittest.cc
+++ b/src/tests/thread_dealloc_unittest.cc
@@ -1,11 +1,11 @@
 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
 // Copyright (c) 2004, Google Inc.
 // All rights reserved.
-// 
+//
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
-// 
+//
 //     * Redistributions of source code must retain the above copyright
 // notice, this list of conditions and the following disclaimer.
 //     * Redistributions in binary form must reproduce the above
@@ -15,7 +15,7 @@
 //     * Neither the name of Google Inc. nor the names of its
 // contributors may be used to endorse or promote products derived from
 // this software without specific prior written permission.
-// 
+//
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR