Skip to content

Commit 5c28a17

Browse files
author
Travis Wagner
committed
imported library/backtrace into main repository
1 parent c0883e0 commit 5c28a17

File tree

104 files changed

+10953
-4
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+10953
-4
lines changed

.gitmodules

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,3 @@
22
path = src/llvm-project
33
url = https://github.com/rust-lang/llvm-project.git
44
branch = rustc/16.0-2023-06-05
5-
[submodule "library/backtrace"]
6-
path = library/backtrace
7-
url = https://github.com/rust-lang/backtrace-rs.git

library/backtrace

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Github composite action to build a single-source-file test binary with an
2+
# already-checked-out version of Rust's stdlib, that will be patched with a
3+
# given revision of the backtrace crate.
4+
5+
name: Build with patched std
6+
description: >
7+
Build a binary with a version of std that's had a specific revision of
8+
backtrace patched in.
9+
inputs:
10+
backtrace-commit:
11+
description: The git commit of backtrace to patch in to std
12+
required: true
13+
main-rs:
14+
description: The (single) source code file to compile
15+
required: true
16+
rustc-dir:
17+
description: The root directory of the rustc repo
18+
required: true
19+
outputs:
20+
test-binary-size:
21+
description: The size in bytes of the built test binary
22+
value: ${{ steps.measure.outputs.test-binary-size }}
23+
runs:
24+
using: composite
25+
steps:
26+
- shell: bash
27+
id: measure
28+
env:
29+
RUSTC_FLAGS: -Copt-level=3 -Cstrip=symbols
30+
# This symlink is made by Build::new() in the bootstrap crate, using a
31+
# symlink on Linux and a junction on Windows, so it will exist on both
32+
# platforms.
33+
RUSTC_BUILD_DIR: build/host
34+
working-directory: ${{ inputs.rustc-dir }}
35+
run: |
36+
rm -rf "$RUSTC_BUILD_DIR/stage0-std"
37+
38+
(cd library/backtrace && git checkout ${{ inputs.backtrace-commit }})
39+
git add library/backtrace
40+
41+
python3 x.py build library --stage 0
42+
43+
TEMP_BUILD_OUTPUT=$(mktemp test-binary-XXXXXXXX)
44+
"$RUSTC_BUILD_DIR/stage0-sysroot/bin/rustc" $RUSTC_FLAGS "${{ inputs.main-rs }}" -o "$TEMP_BUILD_OUTPUT"
45+
BINARY_SIZE=$(stat -c '%s' "$TEMP_BUILD_OUTPUT")
46+
rm "$TEMP_BUILD_OUTPUT"
47+
48+
echo "test-binary-size=$BINARY_SIZE" >> "$GITHUB_OUTPUT"
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Github composite action to report on code size changes across different
2+
# platforms.
3+
4+
name: Report binary size changes on PR
5+
description: |
6+
Report on code size changes across different platforms resulting from a PR.
7+
The only input argument is the path to a directory containing a set of
8+
"*.json" files (extension required), each file containing the keys:
9+
10+
- platform: the platform that the code size change was measured on
11+
- reference: the size in bytes of the reference binary (base of PR)
12+
- updated: the size in bytes of the updated binary (head of PR)
13+
14+
The size is reported as a comment on the PR (accessed via context).
15+
inputs:
16+
data-directory:
17+
description: >
18+
Path to directory containing size data as a set of "*.json" files.
19+
required: true
20+
runs:
21+
using: composite
22+
steps:
23+
- name: Post a PR comment if the size has changed
24+
uses: actions/github-script@v6
25+
env:
26+
DATA_DIRECTORY: ${{ inputs.data-directory }}
27+
with:
28+
script: |
29+
const fs = require("fs");
30+
31+
const size_dir = process.env.DATA_DIRECTORY;
32+
33+
// Map the set of all the *.json files into an array of objects.
34+
const globber = await glob.create(`${size_dir}/*.json`);
35+
const files = await globber.glob();
36+
const sizes = files.map(path => {
37+
const contents = fs.readFileSync(path);
38+
return JSON.parse(contents);
39+
});
40+
41+
// Map each object into some text, but only if it shows any difference
42+
// to report.
43+
const size_reports = sizes.flatMap(size_data => {
44+
const platform = size_data["platform"];
45+
const reference = size_data["reference"];
46+
const updated = size_data["updated"];
47+
48+
if (!(reference > 0)) {
49+
core.setFailed(`Reference size invalid: ${reference}`);
50+
return;
51+
}
52+
53+
if (!(updated > 0)) {
54+
core.setFailed(`Updated size invalid: ${updated}`);
55+
return;
56+
}
57+
58+
const formatter = Intl.NumberFormat("en", {
59+
useGrouping: "always"
60+
});
61+
62+
const updated_str = formatter.format(updated);
63+
const reference_str = formatter.format(reference);
64+
65+
const diff = updated - reference;
66+
const diff_pct = (updated / reference) - 1;
67+
68+
const diff_str = Intl.NumberFormat("en", {
69+
useGrouping: "always",
70+
sign: "exceptZero"
71+
}).format(diff);
72+
73+
const diff_pct_str = Intl.NumberFormat("en", {
74+
style: "percent",
75+
useGrouping: "always",
76+
sign: "exceptZero",
77+
maximumFractionDigits: 2
78+
}).format(diff_pct);
79+
80+
if (diff !== 0) {
81+
// The body is created here and wrapped so "weirdly" to avoid whitespace at the start of the lines,
82+
// which is interpreted as a code block by Markdown.
83+
const report = `On platform \`${platform}\`:
84+
85+
- Original binary size: **${reference_str} B**
86+
- Updated binary size: **${updated_str} B**
87+
- Difference: **${diff_str} B** (${diff_pct_str})
88+
89+
`;
90+
91+
return [report];
92+
} else {
93+
return [];
94+
}
95+
});
96+
97+
// If there are any size changes to report, format a comment and post
98+
// it.
99+
if (size_reports.length > 0) {
100+
const comment_sizes = size_reports.join("");
101+
const body = `Code size changes for a hello-world Rust program linked with libstd with backtrace:
102+
103+
${comment_sizes}`;
104+
105+
github.rest.issues.createComment({
106+
issue_number: context.issue.number,
107+
owner: context.repo.owner,
108+
repo: context.repo.repo,
109+
body
110+
});
111+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# This workflow checks if a PR commit has changed the size of a hello world Rust program.
2+
# It downloads Rustc and compiles two versions of a stage0 compiler - one using the base commit
3+
# of the PR, and one using the latest commit in the PR.
4+
# If the size of the hello world program has changed, it posts a comment to the PR.
5+
name: Check binary size
6+
7+
on:
8+
pull_request_target:
9+
# HACK(jubilee): something broke the distributed LLVM libso and I don't know what.
10+
branches: []
11+
# - master
12+
13+
# Both the "measure" and "report" jobs need to know this.
14+
env:
15+
SIZE_DATA_DIR: sizes
16+
17+
# Responsibility is divided between two jobs "measure" and "report", so that the
18+
# job that builds (and potentnially runs) untrusted code does not have PR write
19+
# permission, and vice-versa.
20+
jobs:
21+
measure:
22+
name: Check binary size
23+
strategy:
24+
matrix:
25+
platform: [ubuntu-latest, windows-latest]
26+
runs-on: ${{ matrix.platform }}
27+
permissions:
28+
contents: read
29+
env:
30+
# This cannot be used as a context variable in the 'uses' key later. If it
31+
# changes, update those steps too.
32+
BACKTRACE_DIR: backtrace
33+
RUSTC_DIR: rustc
34+
TEST_MAIN_RS: foo.rs
35+
BASE_COMMIT: ${{ github.event.pull_request.base.sha }}
36+
HEAD_COMMIT: ${{ github.event.pull_request.head.sha }}
37+
SIZE_DATA_FILE: size-${{ strategy.job-index }}.json
38+
steps:
39+
- name: Print info
40+
shell: bash
41+
run: |
42+
echo "Current SHA: $HEAD_COMMIT"
43+
echo "Base SHA: $BASE_COMMIT"
44+
# Note: the backtrace source that's cloned here is NOT the version to be
45+
# patched in to std. It's cloned here to access the Github action for
46+
# building and measuring the test binary.
47+
- name: Clone backtrace to access Github action
48+
uses: actions/checkout@v3
49+
with:
50+
path: ${{ env.BACKTRACE_DIR }}
51+
- name: Clone Rustc
52+
uses: actions/checkout@v3
53+
with:
54+
repository: rust-lang/rust
55+
path: ${{ env.RUSTC_DIR }}
56+
- name: Set up std repository and backtrace submodule for size test
57+
shell: bash
58+
working-directory: ${{ env.RUSTC_DIR }}
59+
env:
60+
PR_SOURCE_REPO: ${{ github.event.pull_request.head.repo.full_name }}
61+
run: |
62+
# Bootstrap config
63+
cat <<EOF > config.toml
64+
[llvm]
65+
download-ci-llvm = true
66+
[rust]
67+
incremental = false
68+
EOF
69+
70+
# Test program source
71+
cat <<EOF > $TEST_MAIN_RS
72+
fn main() {
73+
panic!();
74+
}
75+
EOF
76+
77+
git submodule update --init library/backtrace
78+
79+
cd library/backtrace
80+
git remote add head-pr "https://github.com/$PR_SOURCE_REPO"
81+
git fetch --all
82+
- name: Build binary with base version of backtrace
83+
uses: ./backtrace/.github/actions/build-with-patched-std
84+
with:
85+
backtrace-commit: ${{ env.BASE_COMMIT }}
86+
main-rs: ${{ env.TEST_MAIN_RS }}
87+
rustc-dir: ${{ env.RUSTC_DIR }}
88+
id: size-reference
89+
- name: Build binary with PR version of backtrace
90+
uses: ./backtrace/.github/actions/build-with-patched-std
91+
with:
92+
backtrace-commit: ${{ env.HEAD_COMMIT }}
93+
main-rs: ${{ env.TEST_MAIN_RS }}
94+
rustc-dir: ${{ env.RUSTC_DIR }}
95+
id: size-updated
96+
# There is no built-in way to "collect" all the outputs of a set of jobs
97+
# run with a matrix strategy. Subsequent jobs that have a "needs"
98+
# dependency on this one will be run once, when the last matrix job is
99+
# run. Appending data to a single file within a matrix is subject to race
100+
# conditions. So we write the size data to files with distinct names
101+
# generated from the job index.
102+
- name: Write sizes to file
103+
uses: actions/github-script@v6
104+
env:
105+
SIZE_REFERENCE: ${{ steps.size-reference.outputs.test-binary-size }}
106+
SIZE_UPDATED: ${{ steps.size-updated.outputs.test-binary-size }}
107+
PLATFORM: ${{ matrix.platform }}
108+
with:
109+
script: |
110+
const fs = require("fs");
111+
const path = require("path");
112+
113+
fs.mkdirSync(process.env.SIZE_DATA_DIR, {recursive: true});
114+
115+
const output_data = JSON.stringify({
116+
platform: process.env.PLATFORM,
117+
reference: process.env.SIZE_REFERENCE,
118+
updated: process.env.SIZE_UPDATED,
119+
});
120+
121+
// The "wx" flag makes this fail if the file exists, which we want,
122+
// because there should be no collisions.
123+
fs.writeFileSync(
124+
path.join(process.env.SIZE_DATA_DIR, process.env.SIZE_DATA_FILE),
125+
output_data,
126+
{ flag: "wx" },
127+
);
128+
- name: Upload size data
129+
uses: actions/upload-artifact@v3
130+
with:
131+
name: size-files
132+
path: ${{ env.SIZE_DATA_DIR }}/${{ env.SIZE_DATA_FILE }}
133+
retention-days: 1
134+
if-no-files-found: error
135+
report:
136+
name: Report binary size changes
137+
runs-on: ubuntu-latest
138+
needs: measure
139+
permissions:
140+
pull-requests: write
141+
steps:
142+
# Clone backtrace to access Github composite actions to report size.
143+
- uses: actions/checkout@v3
144+
- name: Download size data
145+
uses: actions/download-artifact@v3
146+
with:
147+
name: size-files
148+
path: ${{ env.SIZE_DATA_DIR }}
149+
- name: Analyze and report size changes
150+
uses: ./.github/actions/report-code-size-changes
151+
with:
152+
data-directory: ${{ env.SIZE_DATA_DIR }}

0 commit comments

Comments
 (0)