aboutsummaryrefslogtreecommitdiff
path: root/build/toolchain/concurrent_links.gni
blob: c3275b42faf668ceec2dad35cc3fe5345bcf1fb0 (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
# Copyright 2016 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This file should only be imported from files that define toolchains.
# There's no way to enforce this exactly, but all toolchains are processed
# in the context of the default_toolchain, so we can at least check for that.
assert(current_toolchain == default_toolchain)

import("//build/config/android/config.gni")
import("//build/config/apple/symbols.gni")
import("//build/config/chromeos/ui_mode.gni")
import("//build/config/compiler/compiler.gni")
import("//build/config/coverage/coverage.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//build/toolchain/toolchain.gni")

declare_args() {
  # Limit the number of concurrent links; we often want to run fewer
  # links at once than we do compiles, because linking is memory-intensive.
  # The default to use varies by platform and by the amount of memory
  # available, so we call out to a script to get the right value.
  concurrent_links = -1
}

if (concurrent_links == -1) {
  if (use_thin_lto) {
    _args = [ "--reserve_mem_gb=10" ]
    if (use_goma_thin_lto) {
      _args += [ "--thin-lto=goma" ]
    } else {
      _args += [ "--thin-lto=local" ]
    }
    if (is_win) {
      # Based on measurements of linking chrome.dll and chrome_child.dll, plus
      # a little padding to account for future growth.
      _args += [ "--mem_per_link_gb=45" ]
    } else {
      _args += [ "--mem_per_link_gb=20" ]
    }
  } else if ((use_clang_coverage &&
              # When coverage_instrumentation_input_file is not empty it means
              # we're only instrumenting changed files and not using a lot of
              # memory. Likewise, when it's empty we're building everything with
              # coverage, which requires more memory.
              coverage_instrumentation_input_file == "") ||
             use_sanitizer_coverage || use_fuzzing_engine) {
    # Full sanitizer coverage instrumentation increases linker memory consumption
    # significantly.
    _args = [ "--mem_per_link_gb=16" ]
  } else if (is_win && symbol_level == 1 && !is_debug && is_component_build) {
    _args = [ "--mem_per_link_gb=3" ]
  } else if (is_win) {
    _args = [ "--mem_per_link_gb=6" ]
  } else if (is_mac) {
    if (enable_dsyms) {
      _args = [ "--mem_per_link_gb=12" ]
    } else {
      _args = [ "--mem_per_link_gb=4" ]
    }
  } else if (is_android && !is_component_build && symbol_level == 2) {
    # Full debug symbols require large memory for link.
    _args = [ "--mem_per_link_gb=25" ]
  } else if (is_android && !is_debug && !using_sanitizer && symbol_level < 2) {
    if (symbol_level == 1) {
      _args = [ "--mem_per_link_gb=6" ]
    } else {
      _args = [ "--mem_per_link_gb=4" ]
    }
  } else if ((is_linux || is_chromeos_lacros) && symbol_level == 0) {
    # Memory consumption on link without debug symbols is low on linux.
    _args = [ "--mem_per_link_gb=3" ]
  } else if (current_os == "zos") {
    _args = [ "--mem_per_link_gb=1" ]
  } else if (is_fuchsia) {
    # TODO(crbug.com/1347159): This was defaulting to 8GB. The number of
    #    linker instances to run in parallel is calculated by diviging
    #    the available memory by this value. On a 32GB machine with
    #    roughly 29GB of available memory, this would cause three instances
    #    to run. This started running out of memory and thrashing. This change
    #    addresses that issue to get the SDk rollers running again but
    #    could be optimized (maybe to 12GB or for different configs like
    #    component build).
    _args = [ "--mem_per_link_gb=16" ]
  } else if (is_chromeos && is_msan) {
    # crbug.com/1505350 - CrOS MSan builder consumes more memory and crushes.
    # Max 25.2GB, Avg: 9.4GB, Median: 7.9GB
    _args = [ "--mem_per_link_gb=12" ]
  } else if (is_chromeos && is_debug) {
    # b/315102033, b/312072730: Large links use 9GB-13.5GB.
    _args = [ "--mem_per_link_gb=10" ]
  } else {
    _args = []
  }

  # For Android builds, we also need to be wary of:
  # * ProGuard / R8
  # * Android Lint
  # These both have a peak usage of < 2GB, but that is still large enough for
  # them to need to use a pool since they both typically happen at the
  # same time as linking.
  if (is_android) {
    _args += [ "--secondary_mem_per_link=2" ]
  }

  # TODO(crbug.com/617429) Pass more build configuration info to the script
  # so that we can compute better values.
  _command_dict = exec_script("get_concurrent_links.py", _args, "scope")

  concurrent_links = _command_dict.primary_pool_size
  concurrent_links_logs = _command_dict.explanation

  if (_command_dict.secondary_pool_size >= concurrent_links) {
    # Have R8 / Lint share the link pool unless we would safely get more
    # concurrency out of using a separate one.
    # On low-RAM machines, this allows an apk's native library to link at the
    # same time as its java is optimized with R8.
    java_cmd_pool_size = _command_dict.secondary_pool_size
  }
} else {
  assert(!use_thin_lto, "can't explicitly set concurrent_links with thinlto")
  concurrent_links_logs =
      [ "concurrent_links set by GN arg (value=$concurrent_links)" ]
}