summaryrefslogtreecommitdiff
path: root/src/third_party/gperftools/SConscript
blob: 5e41c8c1be6047ef1eb5676a10146e1822dde2e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# -*- mode: python -*-

Import("env")
Import("has_option")
Import("use_libunwind")
Import("debugBuild")
Import("selected_experimental_optimizations")

env = env.Clone(
    # Building with hidden visibility interferes with intercepting the
    # libc allocation functions.
    DISALLOW_VISHIDDEN=True, )

# If we don't have a frame pointer, we need to tell tcmalloc so that
# it doesn't try to select a frame pointer based unwinder like
# generic_fp. For debugBuilds, we also don't want the generic_fp or
# libunwind based unwinders because they are currently too slow. We
# will still fall back to libunwind if it is present and no better
# option is available. Note that defining
# TCMALLOC_DONT_PREFER_LIBUNWIND has real effects even if libunwind
# isn't in play. Specifically, it enables the architecture specific
# implementations for x86 and ppc.
#
# Please see the following gperftools issues for ongoing discussion:
#
# https://github.com/gperftools/gperftools/issues/1276
# https://github.com/gperftools/gperftools/issues/1277
# https://github.com/gperftools/gperftools/issues/1278
#

fp = 'nofp' not in selected_experimental_optimizations
if not fp or debugBuild:
    env.Append(
        CPPDEFINES=[
            'NO_FRAME_POINTER',
            'TCMALLOC_DONT_PREFER_LIBUNWIND' if debugBuild else None,
        ], )

if use_libunwind:
    env.Append(CPPDEFINES=[
        ("HAVE_LIBUNWIND_H", "1"),
        'HAVE_UCONTEXT_H',
    ], )
    env.InjectThirdParty(libraries=['unwind'])

files = [
    'src/base/dynamic_annotations.c',
    'src/base/elf_mem_image.cc',
    'src/base/logging.cc',
    'src/base/spinlock.cc',
    'src/base/spinlock_internal.cc',
    'src/base/sysinfo.cc',
    'src/base/vdso_support.cc',
    'src/central_freelist.cc',
    'src/common.cc',
    'src/internal_logging.cc',
    'src/malloc_extension.cc',
    'src/malloc_hook.cc',
    'src/memfs_malloc.cc',
    'src/page_heap.cc',
    'src/sampler.cc',
    'src/span.cc',
    'src/stack_trace_table.cc',
    'src/stacktrace.cc',
    'src/static_vars.cc',
    'src/symbolize.cc',
    'src/thread_cache.cc',
]

if env.TargetOSIs('windows'):
    files += [
        'src/tcmalloc.cc',
        'src/windows/port.cc',
        'src/windows/system-alloc.cc',
        'src/fake_stacktrace_scope.cc',
    ]

    # warning C4141: 'inline': used more than once
    # warning C4305: 'argument': truncation from 'ssize_t' to 'double'
    # warning C4003: not enough arguments for function-like macro invocation
    env.Append(CXXFLAGS=["/wd4141", "/wd4305", '/wd4003'])

else:
    files += [
        'src/emergency_malloc_for_stacktrace.cc',
        'src/maybe_threads.cc',
        'src/system-alloc.cc',
    ]

    if not debugBuild:
        files += ['src/tcmalloc.cc']
    else:
        files += ['src/debugallocation.cc']

    # gperftools has some sloppy write calls that emit warnings
    env.Append(CXXFLAGS=["-Wno-unused-result"])

env.Append(CPPDEFINES=["NO_HEAP_CHECK"], )

# The build system doesn't define NDEBUG globally for historical reasons, however, TCMalloc
# expects that NDEBUG is used to select between preferring the mmap or the sbrk allocator. For
# non-debug builds, we want to prefer the sbrk allocator since this is TCMallocs preferred
# production deployment configuration. See the use of NDEBUG and kDebugMode in
# src/system-alloc.cc for more details.
if not debugBuild:
    env.Append(CPPDEFINES=["NDEBUG"])

# For debug builds we want to capture stacks during (de)allocations,
# but we don't want to pay that cost for release builds. For non-debug
# builds we use NO_TCMALLOC_SAMPLES to disable the stack trace
# collection. For debug builds we enable stack capture, but only on
# intel targets, since tcmalloc's unwinder is very slow on other
# platforms (see SERVER-28502).
if (not debugBuild) or (not env['TARGET_ARCH'] in ['x86_64', 'i386']):
    env.Append(CPPDEFINES=["NO_TCMALLOC_SAMPLES"])

gperftools_root = env.Dir("#/src/third_party/gperftools")
gperftools_platform = gperftools_root.Dir("platform/${TARGET_OS}_${TARGET_ARCH}")

env.Append(CPPPATH=[
    gperftools_platform.Dir("internal/src"),
    gperftools_root.Dir("dist/src"),
])

# propagates to consumers that Inject (depend on) gperftools.
env.RegisterConsumerModifications(CPPPATH=[gperftools_platform.Dir("include")])


def removeIfPresent(lst, item):
    try:
        lst.remove(item)
    except ValueError:
        pass


env['CCFLAGS_WERROR'] = []
env['CXXFLAGS_WERROR'] = []
for to_remove in ["-Wsign-compare", "-Wall"]:
    removeIfPresent(env['CCFLAGS'], to_remove)

if not env.TargetOSIs('windows'):
    env.Append(CXXFLAGS=['-Wno-unused-result'])
    if env.ToolchainIs('GCC'):
        env.Append(CXXFLAGS=['-Wno-attribute-alias'])

# GCC on PowerPC under C++11 mode does not define __linux which gperftools depends on
if env['TARGET_ARCH'] == 'ppc64le':
    env.Append(CPPDEFINES=["__linux"])

env.Library(
    target='tcmalloc_minimal',
    source=[env.Dir('dist').File(f) for f in files],
    LIBDEPS_PRIVATE=[
        '$BUILD_DIR/third_party/shim_unwind' if use_libunwind else [],
    ],
)