Skip to content

Commit c1096d0

Browse files
authored
Count mallocs. (#16)
1 parent 3cd1ffd commit c1096d0

File tree

28 files changed

+1538
-0
lines changed

28 files changed

+1538
-0
lines changed

.github/workflows/ci.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,25 @@ jobs:
6464
- name: Run test
6565
run: .build/release/Base64KitPerformanceTest
6666

67+
"tuxOS-Integration-Tests":
68+
runs-on: ubuntu-latest
69+
strategy:
70+
matrix:
71+
images:
72+
- swift:5.2
73+
- swiftlang/swift:nightly-5.3
74+
container:
75+
image: ${{ matrix.images }}
76+
env:
77+
MAX_ALLOCS_ALLOWED_base64_decoding: 1000
78+
MAX_ALLOCS_ALLOWED_base64_encoding: 2000
79+
steps:
80+
- name: Checkout
81+
uses: actions/checkout@v2
82+
- name: Test
83+
run: ./run-tests.sh
84+
working-directory: ./IntegrationTests
85+
6786
"macOS-Tests":
6887
runs-on: macOS-latest
6988
steps:
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
#!/bin/bash
2+
##===----------------------------------------------------------------------===##
3+
##
4+
## This source file is part of the SwiftNIO open source project
5+
##
6+
## Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors
7+
## Licensed under Apache License v2.0
8+
##
9+
## See LICENSE.txt for license information
10+
## See CONTRIBUTORS.txt for the list of SwiftNIO project authors
11+
##
12+
## SPDX-License-Identifier: Apache-2.0
13+
##
14+
##===----------------------------------------------------------------------===##
15+
16+
set -eu
17+
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
18+
build_opts=( -c release )
19+
20+
function die() {
21+
echo >&2 "ERROR: $*"
22+
exit 1
23+
}
24+
25+
function make_git_commit_all() {
26+
git init > /dev/null
27+
if [[ "$(git config user.email)" == "" ]]; then
28+
git config --local user.email does@really-not.matter
29+
git config --local user.name 'Does Not Matter'
30+
fi
31+
git add . > /dev/null
32+
git commit -m 'everything' > /dev/null
33+
}
34+
35+
# <extra_dependencies_file> <swiftpm_pkg_name> <targets...>
36+
function hooked_package_swift_start() {
37+
local extra_dependencies_file=$1
38+
local swiftpm_pkg_name=$2
39+
shift 2
40+
41+
cat <<"EOF"
42+
// swift-tools-version:5.0
43+
import PackageDescription
44+
45+
let package = Package(
46+
name: "allocation-counter-tests",
47+
products: [
48+
EOF
49+
for f in "$@"; do
50+
local module
51+
module=$(module_name_from_path "$f")
52+
echo ".executable(name: \"$module\", targets: [\"bootstrap_$module\"]),"
53+
done
54+
cat <<EOF
55+
],
56+
dependencies: [
57+
.package(url: "HookedFunctions/", .branch("master")),
58+
.package(url: "$swiftpm_pkg_name/", .branch("master")),
59+
EOF
60+
if [[ -n "$extra_dependencies_file" ]]; then
61+
cat "$extra_dependencies_file"
62+
fi
63+
cat <<EOF
64+
],
65+
targets: [
66+
EOF
67+
}
68+
69+
# <target_name> <deps...>
70+
function hooked_package_swift_target() {
71+
local target_name="$1"
72+
shift
73+
local deps=""
74+
for dep in "$@"; do
75+
deps="$deps \"$dep\","
76+
done
77+
cat <<EOF
78+
.target(name: "Test_$target_name", dependencies: [$deps]),
79+
.target(name: "bootstrap_$target_name",
80+
dependencies: ["Test_$target_name", "HookedFunctions"]),
81+
EOF
82+
}
83+
84+
function hooked_package_swift_end() {
85+
cat <<"EOF"
86+
]
87+
)
88+
EOF
89+
}
90+
91+
function abs_path() {
92+
if [[ "${1:0:1}" == "/" ]]; then
93+
echo "$1"
94+
else
95+
echo "$PWD/$1"
96+
fi
97+
}
98+
99+
function dir_basename() {
100+
test -d "$1"
101+
basename "$(cd "$1" && pwd)"
102+
}
103+
104+
function fake_package_swift() {
105+
cat > Package.swift <<EOF
106+
// swift-tools-version:4.0
107+
import PackageDescription
108+
109+
let package = Package(name: "$1")
110+
EOF
111+
}
112+
113+
# <target> <template> <swiftpm_pkg_root> <swiftpm_pkg_name> <hooked_function_module> <bootstrap_module>
114+
# <shared file> <extra_dependencies_file> <modules...> -- <test_files...>
115+
function build_package() {
116+
local target=$1
117+
local template=$2
118+
local swiftpm_pkg_root=$3
119+
local swiftpm_pkg_name=$4
120+
local hooked_function_module=$5
121+
local bootstrap_module=$6
122+
local shared_file=$7
123+
local extra_dependencies_file=$8
124+
shift 8
125+
126+
local modules=()
127+
while [[ "$1" != "--" ]]; do
128+
modules+=( "$1" )
129+
shift
130+
done
131+
shift
132+
133+
test -d "$target" || die "target dir '$target' not a directory"
134+
test -d "$template" || die "template dir '$template' not a directory"
135+
test -d "$swiftpm_pkg_root" || die "root dir '$swiftpm_pkg_root' not a directory"
136+
test -n "$hooked_function_module" || die "hooked function module empty"
137+
test -n "$bootstrap_module" || die "bootstrap module empty"
138+
139+
cp -R "$template"/* "$target/"
140+
mv "$target/$hooked_function_module" "$target/HookedFunctions"
141+
mv "$target/Sources/$bootstrap_module" "$target/Sources/bootstrap"
142+
143+
(
144+
set -eu
145+
146+
cd "$target"
147+
148+
cd HookedFunctions
149+
make_git_commit_all
150+
cd ..
151+
152+
cd AtomicCounter
153+
make_git_commit_all
154+
cd ..
155+
156+
mkdir "$swiftpm_pkg_name"
157+
cd "$swiftpm_pkg_name"
158+
fake_package_swift "$swiftpm_pkg_name"
159+
make_git_commit_all
160+
cd ..
161+
162+
hooked_package_swift_start "$extra_dependencies_file" "$swiftpm_pkg_name" "$@" > Package.swift
163+
for f in "$@"; do
164+
local module
165+
module=$(module_name_from_path "$f")
166+
hooked_package_swift_target "$module" "${modules[@]}" >> Package.swift
167+
mkdir "Sources/bootstrap_$module"
168+
ln -s "../bootstrap/main.c" "Sources/bootstrap_$module"
169+
mkdir "Sources/Test_$module"
170+
cat > "Sources/Test_$module/trampoline.swift" <<EOF
171+
@_cdecl("swift_main")
172+
func swift_main() {
173+
run(identifier: "$module")
174+
}
175+
EOF
176+
ln -s "$f" "Sources/Test_$module/file.swift"
177+
ln -s "../../scaffolding.swift" "Sources/Test_$module/"
178+
if [[ -n "$shared_file" ]]; then
179+
ln -s "$shared_file" "Sources/Test_$module/shared.swift"
180+
fi
181+
done
182+
hooked_package_swift_end >> Package.swift
183+
184+
swift package edit --path "$swiftpm_pkg_root" "$swiftpm_pkg_name"
185+
)
186+
}
187+
188+
function module_name_from_path() {
189+
basename "${1%.*}" | tr ". " "__"
190+
}
191+
192+
# <pkg_root>
193+
function find_swiftpm_package_name() {
194+
(
195+
set -eu
196+
cd "$1"
197+
swift package dump-package | grep '^ "name"' | cut -d'"' -f4
198+
)
199+
}
200+
201+
do_hooking=true
202+
pkg_root="$here/.."
203+
shared_file=""
204+
modules=()
205+
extra_dependencies_file=""
206+
tmp_dir="/tmp"
207+
208+
while getopts "ns:p:m:d:t:" opt; do
209+
case "$opt" in
210+
n)
211+
do_hooking=false
212+
;;
213+
s)
214+
shared_file="$OPTARG"
215+
;;
216+
p)
217+
pkg_root=$(abs_path "$OPTARG")
218+
;;
219+
m)
220+
modules+=( "$OPTARG" )
221+
;;
222+
d)
223+
extra_dependencies_file="$OPTARG"
224+
;;
225+
t)
226+
tmp_dir="$OPTARG"
227+
;;
228+
\?)
229+
die "unknown option $opt"
230+
;;
231+
esac
232+
done
233+
234+
shift $(( OPTIND - 1 ))
235+
if [[ $# -lt 1 ]]; then
236+
die "not enough files provided"
237+
fi
238+
239+
if [[ "${#modules}" == 0 ]]; then
240+
die "no modules specified, use '-m <MODULE>' for every module you plan to use"
241+
fi
242+
243+
if [[ ! -f "$pkg_root/Package.swift" ]]; then
244+
die "package root '$pkg_root' doesn't contain a Package.swift file, use -p"
245+
fi
246+
247+
files=()
248+
for f in "$@"; do
249+
files+=( "$(abs_path "$f")" )
250+
done
251+
252+
if [[ -n "$shared_file" ]]; then
253+
shared_file=$(abs_path "$shared_file")
254+
fi
255+
256+
test -d "$pkg_root" || die "package root '$pkg_root' not a directory"
257+
for f in "${files[@]}"; do
258+
test -f "$f" || die "file '$f' not a file"
259+
done
260+
261+
working_dir=$(mktemp -d "$tmp_dir/.nio_alloc_counter_tests_XXXXXX")
262+
263+
selected_hooked_functions="HookedFunctionsDoHook"
264+
selected_bootstrap="bootstrapDoHook"
265+
266+
if ! $do_hooking; then
267+
selected_hooked_functions=HookedFunctionsDoNotHook
268+
selected_bootstrap=bootstrapDoNotHook
269+
fi
270+
271+
build_package \
272+
"$working_dir" \
273+
"$here/template" \
274+
"$pkg_root" \
275+
"$(find_swiftpm_package_name "$pkg_root")" \
276+
"$selected_hooked_functions" \
277+
"$selected_bootstrap" \
278+
"$shared_file" \
279+
"$extra_dependencies_file" \
280+
"${modules[@]}" \
281+
-- \
282+
"${files[@]}"
283+
(
284+
set -eu
285+
cd "$working_dir"
286+
swift build "${build_opts[@]}"
287+
for f in "${files[@]}"; do
288+
echo "- $f"
289+
swift run "${build_opts[@]}" "$(module_name_from_path "$f")"
290+
done
291+
)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// swift-tools-version:5.0
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
//===----------------------------------------------------------------------===//
4+
//
5+
// This source file is part of the SwiftNIO open source project
6+
//
7+
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
8+
// Licensed under Apache License v2.0
9+
//
10+
// See LICENSE.txt for license information
11+
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
12+
//
13+
// SPDX-License-Identifier: Apache-2.0
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
import PackageDescription
18+
19+
let package = Package(
20+
name: "AtomicCounter",
21+
products: [
22+
.library(name: "AtomicCounter", targets: ["AtomicCounter"]),
23+
],
24+
dependencies: [],
25+
targets: [
26+
.target(
27+
name: "AtomicCounter",
28+
dependencies: []
29+
),
30+
]
31+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftNIO open source project
4+
//
5+
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef ATOMIC_COUNTER
16+
#define ATOMIC_COUNTER
17+
18+
#include <stdatomic.h>
19+
20+
void inc_free_counter(void);
21+
void reset_free_counter(void);
22+
long read_free_counter(void);
23+
24+
void inc_malloc_counter(void);
25+
void reset_malloc_counter(void);
26+
long read_malloc_counter(void);
27+
28+
void add_malloc_bytes_counter(intptr_t v);
29+
void reset_malloc_bytes_counter(void);
30+
intptr_t read_malloc_bytes_counter(void);
31+
32+
#endif

0 commit comments

Comments
 (0)