Commit 2eed63bc authored by Hans Wennborg's avatar Hans Wennborg Committed by Commit Bot

Remove support for using link order files on Windows

Since crrev.com/824529, we're using /call-graph-profile-sort instead,
which means the linker lays out the binary based on the PGO profile.

Bug: 1077279
Change-Id: I0f6a72902dd211fd0000deef4b9c76909db9782a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2550070
Commit-Queue: Hans Wennborg <hans@chromium.org>
Reviewed-by: default avatarSébastien Marchand <sebmarchand@chromium.org>
Reviewed-by: default avatarNico Weber <thakis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#829306}
parent 719003e5
......@@ -83,10 +83,6 @@ vs-chromium-project.txt
/chrome/android/profiles/local.txt
/chrome/angle_unittests_run.xml
/chrome/app/vector_icons/google_chrome/
/chrome/build/chrome.x64.orderfile
/chrome/build/chrome.x86.orderfile
/chrome/build/chrome_child.x64.orderfile
/chrome/build/chrome_child.x86.orderfile
/chrome/build/pgo_profiles/
/chrome/gl_tests_run.xml
/chrome/gles2_conform_test_run.xml
......
......@@ -4459,20 +4459,6 @@ hooks = [
'--bucket', 'chromium-webrtc-resources',
'-d', 'src/third_party/opus/tests/resources'],
},
# Pull order files for the win/clang build.
{
'name': 'orderfiles_win',
'pattern': '.',
'condition': 'checkout_win',
'action': [ 'python',
'src/third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'--num_threads=4',
'--bucket', 'chromium-browser-clang/orderfiles',
'-d', 'src/chrome/build',
],
},
{
'name': 'apache_mac',
'pattern': '\\.sha1',
......
......@@ -266,10 +266,6 @@ group("common_deps") {
public_deps += [ "//base/android/orderfile:orderfile_instrumentation" ]
}
if (is_win && generate_order_files && !is_nacl) {
public_deps += [ "//tools/cygprofile_win" ]
}
if (is_fuchsia) {
public_deps +=
[ "//third_party/fuchsia-sdk/sdk/build/config:runtime_library_group" ]
......
......@@ -361,11 +361,6 @@ if (is_android) {
[ "//build/config/android:default_orderfile_instrumentation" ]
}
if (is_win) {
default_compiler_configs +=
[ "//build/config/win:default_cygprofile_instrumentation" ]
}
if (is_clang && !is_nacl) {
default_compiler_configs += [
"//build/config/clang:find_bad_constructs",
......
......@@ -7,10 +7,6 @@ declare_args() {
# true means official Google Chrome branding (requires extra Google-internal
# resources).
is_chrome_branded = false
# Turn this on to generate order files. See
# https://chromium.googlesource.com/chromium/src/+/master/docs/win_order_files.md
generate_order_files = false
}
declare_args() {
......
......@@ -176,7 +176,7 @@ declare_args() {
current_cpu == "x64"))))
}
if (is_win || is_android || (is_chromeos && is_chromeos_device)) {
if (is_android || (is_chromeos && is_chromeos_device)) {
# Set the path to use orderfile for linking Chrome
# Note that this is for using only one orderfile for linking
# the Chrome binary/library.
......@@ -187,8 +187,6 @@ if (is_win || is_android || (is_chromeos && is_chromeos_device)) {
# Allow downstream tools to set orderfile path with
# another variable.
chrome_orderfile_path = default_chrome_orderfile
} else if (is_win && is_clang && is_official_build) {
chrome_orderfile_path = "//chrome/build/chrome.$target_cpu.orderfile"
} else if (is_chromeos && is_chromeos_device) {
chrome_orderfile_path = "//chromeos/profiles/chromeos.orderfile.txt"
}
......@@ -2470,29 +2468,19 @@ if (is_chromeos && is_chromeos_device) {
}
}
if (is_win || is_android || (is_chromeos && is_chromeos_device)) {
# Use orderfile for linking Chrome on win, android, and Chrome OS.
if (is_android || (is_chromeos && is_chromeos_device)) {
# Use orderfile for linking Chrome on Android and Chrome OS.
# This config enables using an orderfile for linking in LLD.
# TODO: Consider using call graph sort instead, at least on Android.
config("chrome_orderfile_config") {
if (chrome_orderfile_path != "" && !enable_call_graph_profile_sort) {
assert(use_lld)
_rebased_orderfile = rebase_path(chrome_orderfile_path, root_build_dir)
if (is_android || (is_chromeos && is_chromeos_device)) {
ldflags = [
"-Wl,--symbol-ordering-file",
"-Wl,$_rebased_orderfile",
"-Wl,--no-warn-symbol-ordering",
]
} else {
ldflags = [
"/order:@$_rebased_orderfile",
# Ignore warnings about missing functions or functions not in their
# own section.
"/ignore:4037",
"/ignore:4065",
]
}
ldflags = [
"-Wl,--symbol-ordering-file",
"-Wl,$_rebased_orderfile",
"-Wl,--no-warn-symbol-ordering",
]
inputs = [ chrome_orderfile_path ]
}
}
......
......@@ -579,21 +579,3 @@ config("lean_and_mean") {
config("nominmax") {
defines = [ "NOMINMAX" ]
}
# Generating order files -------------------------------------------------------
config("default_cygprofile_instrumentation") {
if (generate_order_files) {
assert(is_clang, "cygprofile instrumentation only works with clang")
assert(is_official_build, "order files should be made w/ official builds")
assert(!is_chrome_branded, "order files could leak internal symbol names")
configs = [ ":cygprofile_instrumentation" ]
}
}
config("cygprofile_instrumentation") {
cflags = [
"-Xclang",
"-finstrument-functions-after-inlining",
]
}
......@@ -360,8 +360,6 @@ if (is_win) {
"//content/public/app",
"//headless:headless_renderer",
]
configs += [ "//build/config/compiler:chrome_orderfile_config" ]
}
copy("copy_first_run") {
......
hans@chromium.org
thakis@chromium.org
per-file *.pgo.txt=liaoyuke@chromium.org
per-file *.pgo.txt=sebmarchand@chromium.org
liaoyuke@chromium.org
sebmarchand@chromium.org
See
https://chromium.googlesource.com/chromium/src/+/master/docs/win_order_files.md
for how to update the order files.
d5482a02f41670416a7302b49e5e3f9dede25e61
\ No newline at end of file
d00f8f154ccdf38ef8a3018ea5bb165e8b279c22
\ No newline at end of file
# Updating the Windows .order files
The `chrome/build/*.orderfile` files are used to specify the order in which
the linker should lay out symbols in the binary it's producing. By ordering
functions in the order they're typically executed during start-up, the start-up
time can be reduced slightly.
The order files are used automatically when building with Clang for Windows with
the gn flag `is_official_build` set to `true`.
To update the order files:
1. Build with instrumentation enabled:
The instrumentation will capture the couple of million function calls
in a binary as it runs and write them to a file in the `\src\tmp` directory.
Make sure this directory exists.
```shell
gn gen out\instrument --args="is_debug=false is_official_build=true generate_order_files=true symbol_level=1"
ninja -C out\instrument chrome
```
(If you have access to Goma, add `use_goma=true` to the gn args and `-j500`
to the Ninja invocation.)
1. Run the instrumented binaries:
(Some binaries such as `mksnapshot`, `yasm`, and `protoc` already ran with
instrumentation during the build process. The instrumentation output should
be available under `\src\tmp`.)
Open the Task Manager's Details tab or
[Process Explorer](https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer)
to be able to see the Process IDs of running programs.
Run Chrome:
```shell
out\instrument\chrome
```
Note the Process ID of the browser process.
Check in `\src\tmp\` for instrumentation output from the process, for
example `cygprofile_14652.txt`. The files are only written once a certain
number of function calls have been made, so sometimes you need to browse a
bit for the file to be produced.
1. If the file appears to have sensible contents (a long list of function names
that eventually seem related to what the browser should
do), copy it into `chrome\build\`:
```shell
copy \src\tmp\cygprofile_25392.txt chrome\build\chrome.x64.orderfile
```
1. Re-build the `chrome` target. This will re-link `chrome.dll`
using the new order file and surface any link errors if
the order file is broken.
```shell
ninja -C out\instrument chrome
```
1. Repeat the previous steps with a 32-bit build, i.e. passing
`target_cpu="x86"` to gn and storing the file as `.x86.orderfile`.
1. Upload the order files to Google Cloud Storage. They will get downloaded
by a `gclient` hook based on the contents of the `.orderfile.sha1` files.
You need to have write access to the `chromium-browser-clang` GCS bucket
for this step.
```shell
cd chrome\build\
upload_to_google_storage.py -b chromium-browser-clang/orderfiles -z orderfile chrome.x64.orderfile chrome.x86.orderfile
gsutil.py setacl public-read gs://chromium-browser-clang/orderfiles/*
```
1. Check in the `.sha1` files corresponding to the orderfiles created by the
previous step.
Since [#824529](https://crrev.com/824529), order files are no longer used for
linking Chromium on Windows. Instead, the linker orders the binary contents
based on profile-guided optimization (PGO) data, using LLD's call graph profile
sort feature. That provides similar benefits and uses use the existing PGO
infrastructure instead of requiring maintenance of the order files. See
[crbug.com/1077279](https://crbug.com/1077279).
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
static_library("cygprofile_win") {
sources = [ "cygprofile.cc" ]
# Don't instrument this library.
configs -= [ "//build/config/win:default_cygprofile_instrumentation" ]
}
// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdio.h>
#include <atomic>
#include <string>
#include <unordered_set>
#include <windows.h> // Needs to be included before the others.
#include <dbghelp.h>
#include <process.h>
namespace {
// The main purpose of the order file is to optimize startup time,
// so capturing the first N function calls is enough.
static constexpr int kSamplesCapacity = 25 * 1024 * 1024;
void* samples[kSamplesCapacity];
std::atomic_int num_samples;
std::atomic_int done;
// Path to the dump file. %lu will be substituted by the process id.
static const char kDumpFile[] = "/src/tmp/cygprofile_%lu.txt";
// Symbolize the samples and write them to disk.
void dump(void*) {
HMODULE dbghelp = LoadLibraryA("dbghelp.dll");
auto sym_from_addr = reinterpret_cast<decltype(::SymFromAddr)*>(
::GetProcAddress(dbghelp, "SymFromAddr"));
auto sym_initialize = reinterpret_cast<decltype(::SymInitialize)*>(
::GetProcAddress(dbghelp, "SymInitialize"));
auto sym_set_options = reinterpret_cast<decltype(::SymSetOptions)*>(
::GetProcAddress(dbghelp, "SymSetOptions"));
char filename[MAX_PATH];
snprintf(filename, sizeof(filename), kDumpFile, ::GetCurrentProcessId());
FILE* f = fopen(filename, "w");
if (!f)
return;
sym_initialize(::GetCurrentProcess(), NULL, TRUE);
sym_set_options(SYMOPT_DEFERRED_LOADS | SYMOPT_PUBLICS_ONLY);
char sym_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
std::unordered_set<void*> seen;
std::unordered_set<std::string> seen_names;
for (void* sample : samples) {
// Only print the first call of a function.
if (seen.count(sample))
continue;
seen.insert(sample);
SYMBOL_INFO* symbol = reinterpret_cast<SYMBOL_INFO*>(sym_buf);
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
symbol->MaxNameLen = MAX_SYM_NAME;
DWORD64 offset = 0;
if (sym_from_addr(::GetCurrentProcess(), reinterpret_cast<DWORD64>(sample),
&offset, symbol)) {
const char* name = symbol->Name;
if (name[0] == '_')
name++;
if (seen_names.count(name))
continue;
seen_names.insert(name);
fprintf(f, "%s\n", name);
}
}
fclose(f);
}
} // namespace
extern "C" {
void __cyg_profile_func_enter(void* this_fn, void* call_site_unused) {
if (done)
return;
// Get our index for the samples array atomically.
int n = num_samples++;
if (n < kSamplesCapacity) {
samples[n] = this_fn;
if (n + 1 == kSamplesCapacity) {
// This is the final sample; start dumping the samples to a file (on a
// separate thread so as not to disturb the main program).
done = 1;
_beginthread(dump, 0, nullptr);
}
}
}
void __cyg_profile_func_exit(void* this_fn, void* call_site) {}
} // extern "C"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment