Skip to content

Commit

Permalink
Add support for including GNU Gold linker along with --section-orderi…
Browse files Browse the repository at this point in the history
…ng-file

GNU Gold linker will be auto-detected on Linux systems.
If available the pre-generated section ordering file will be used while
linking the node binary.
This will help improve performance through reduction of iTLB misses
as the most frequently used functions in the runtime will be packed
together.

Add documentation to generate the section reorderding file
Add an option to override this configure option if
LD environment variable is defined.
  • Loading branch information
sathvikl committed Jan 31, 2018
1 parent f79310b commit 1882886
Show file tree
Hide file tree
Showing 4 changed files with 4,799 additions and 1 deletion.
11 changes: 11 additions & 0 deletions common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
# Don't use ICU data file (icudtl.dat) from V8, we use our own.
'icu_use_data_file_flag%': 0,

# use exported value from the environment
'gold_section_ordering_file%': '',

'conditions': [
['GENERATOR=="ninja"', {
'OBJ_DIR': '<(PRODUCT_DIR)/obj',
Expand Down Expand Up @@ -431,6 +434,14 @@
'ldflags': [
'-Wl,--export-dynamic',
],
}],
['gold_section_ordering_file!=""', {
'cflags': [ '-fuse-ld=gold',
'-ffunction-sections'],
'ldflags': [
'-fuse-ld=gold',
'-Wl,--section-ordering-file=<(gold_section_ordering_file)',
],
}]
],
}
Expand Down
33 changes: 32 additions & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ import string
# If not run from node/, cd to node/.
os.chdir(os.path.dirname(__file__) or '.')

# Set by configure_node().
cross_compiling = False

# gcc and g++ as defaults matches what GYP's Makefile generator does,
# except on OS X.
CC = os.environ.get('CC', 'cc' if sys.platform == 'darwin' else 'gcc')
Expand Down Expand Up @@ -150,6 +153,12 @@ parser.add_option("--enable-vtune-profiling",
"JavaScript code executed in nodejs. This feature is only available "
"for x32, x86, and x64 architectures.")

parser.add_option("--enable-section-ordering",
action="store",
dest="section_ordering",
help="Use GNU Gold linker capability to reorder sections in a binary."
"This field will be passed to Gold linker's --section-ordering-file"
"Provide a section ordering file to override the default")

parser.add_option("--link-module",
action="append",
Expand Down Expand Up @@ -706,7 +715,6 @@ def check_compiler(o):
else:
o['variables']['gas_version'] = get_gas_version(CC)


def cc_macros(cc=None):
"""Checks predefined macros using the C compiler command."""

Expand Down Expand Up @@ -865,6 +873,7 @@ def configure_node(o):
o['variables']['target_arch'] = target_arch
o['variables']['node_byteorder'] = sys.byteorder

global cross_compiling
cross_compiling = (options.cross_compiling
if options.cross_compiling is not None
else target_arch != host_arch)
Expand Down Expand Up @@ -1099,6 +1108,25 @@ def configure_static(o):
o['libraries'] += ['-static-libasan']


def configure_gold(o):
try:
proc = subprocess.Popen(['ld.gold'] + ['-v'], stdin=subprocess.PIPE,
stderr=subprocess.PIPE, stdout=subprocess.PIPE)
except OSError:
return 0
match = re.match(r"(GNU gold) .* ([0-9]\.[0-9]+)",
proc.communicate()[0])
if match:
gold_version = match.group(2)
if gold_version > '1.1':
if options.section_ordering:
o['variables']['gold_section_ordering_file'] = options.section_ordering
else:
o['variables']['gold_section_ordering_file'] = \
os.path.realpath('tools/gold_linker_section_reordering.txt')
else:
return 0

def write(filename, data):
filename = filename
print('creating %s' % filename)
Expand Down Expand Up @@ -1425,6 +1453,7 @@ output = {
'libraries': [],
'defines': [],
'cflags': [],
'ldflags': [],
}

# Print a warning when the compiler is too old.
Expand All @@ -1450,6 +1479,8 @@ configure_v8(output)
configure_openssl(output)
configure_intl(output)
configure_static(output)
if not cross_compiling and not os.environ.get('LD'):
configure_gold(output)
configure_inspector(output)

# variables should be a root level element,
Expand Down
32 changes: 32 additions & 0 deletions tools/config_gold_section_ordering.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Once the workload, production server has reached a steady state/ post warm-up phase

- [] Collect the perf profile for the workload:
```
perf record -ag -e cycles:pp -o <perf_profile_cycles_pp> -- sleep 30
```
`:pp` offers a more precise dist of cycles accounting

- [] Use perf script command to decode the collected profile
```
perf script -i perf_profile_inst -f comm,ip -c node | gzip -c > perf_profile_decoded.pds.gz
```
- [] Use nm to dump the binary's symbol information
```
nm -S node > node.nm
```
- [] Run the hfsort program to determine the function ordering
for the node binary ideal for this workload.
https://github.com/facebook/hhvm/tree/master/hphp/tools/hfsort
```
Usage: hfsort [-p] [-e <EDGCNT_FILE>] <SYMBOL_FILE> <PERF_DATA_FILE>
-p, use pettis-hansen algorithm for code layout (optional)
-e <EDGCNT_FILE>, use edge profile result to build the call graph
hfsort -p node.nm perf_profile_decoded.pds.gz
```
This application will create 2 files hotfuncs.txt and result-hfsort.txt

hotfuncs.txt is what is used here. hfsort is one way to generate it.
hfsort generates the minimal working order set required to optimally run the program.
Loading

0 comments on commit 1882886

Please sign in to comment.