Skip to content

Commit

Permalink
bolt -instrument
Browse files Browse the repository at this point in the history
  • Loading branch information
ijl committed Nov 5, 2024
1 parent 8ece0d4 commit 3bdc6af
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 5 deletions.
15 changes: 12 additions & 3 deletions .github/workflows/artifact.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ jobs:
cc: "clang",
cflags: "-Os -fstrict-aliasing -fno-plt -flto=full -emit-llvm",
features: "avx512,no-panic,unstable-simd,yyjson",
ldflags: "-fuse-ld=lld -Wl,-plugin-opt=also-emit-llvm -Wl,--as-needed -Wl,-zrelro,-znow",
rustflags: "-C linker=clang -C link-arg=-fuse-ld=lld -C linker-plugin-lto -C lto=fat -C link-arg=-Wl,-zrelro,-znow -Z mir-opt-level=4 -Z threads=4 -D warnings",
ldflags: "-fuse-ld=lld -Wl,-plugin-opt=also-emit-llvm -Wl,--as-needed -Wl,-zrelro,-znow -Wl,--emit-relocs",
rustflags: "-C linker=clang -C link-arg=-fuse-ld=lld -C linker-plugin-lto -C lto=fat -C link-arg=-Wl,-zrelro,-znow -C link-arg=-Wl,--emit-relocs -Z mir-opt-level=4 -Z threads=2 -D warnings",
tag: null,
target: "x86_64-unknown-linux-gnu",
},
Expand Down Expand Up @@ -126,6 +126,7 @@ jobs:
export PATH="/root/.cargo/bin:/home/runner/work/orjson/orjson/.venv:/home/runner/.cargo/bin:$PATH"
./script/install-fedora
dnf install --setopt=install_weak_deps=false -y llvm-bolt zip unzip perf
source "${VENV}/bin/activate"
Expand All @@ -135,6 +136,14 @@ jobs:
--interpreter="${PYTHON}" \
--target="${TARGET}"
uv pip install ${CARGO_TARGET_DIR}/wheels/orjson*.whl
uv pip install auditwheel
pytest -v test
./integration/run thread
./script/bolt
auditwheel show $(find target/wheels/*.whl) | grep "${COMPATIBILITY}_x86_64"
uv pip install ${CARGO_TARGET_DIR}/wheels/orjson*.whl
pytest -v test
Expand All @@ -145,7 +154,7 @@ jobs:
cp ${CARGO_TARGET_DIR}/wheels/orjson*.whl dist
- name: Store wheels
if: "startsWith(github.ref, 'refs/tags/')"
# if: "startsWith(github.ref, 'refs/tags/')"
uses: actions/upload-artifact@v4
with:
name: orjson_manylinux_2_17_amd64_${{ matrix.python.interpreter }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
/include/cargo
/perf.*
/target
/tmp
/vendor
__pycache__
78 changes: 78 additions & 0 deletions script/bolt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env bash

set -eou pipefail

rm -f ./perf.fdata
rm -rf tmp

wheel=$(find "${CARGO_TARGET_DIR}/wheels" -type f -name "orjson*.whl" -exec basename {} \;)

unzip -q -o "${CARGO_TARGET_DIR}/wheels/${wheel}" -d tmp
sharedob=$(find tmp/orjson -type f -name "orjson*.so" -exec basename {} \;)

installedobj=$(find .venv -type f -name "orjson*.so")
llvm-bolt "${installedobj}" --instrument --o orjson.so
mv orjson.so "${installedobj}"

echo "collecting perf data..."

./script/profdata
mv /tmp/prof.fdata ./perf.fdata

llvm-bolt \
"tmp/orjson/${sharedob}" \
--o "${sharedob}" \
--data=perf.fdata \
--strict \
--use-gnu-stack \
--assume-abi \
--use-gnu-stack \
--sequential-disassembly \
--update-debug-sections \
--use-old-text \
--relocs \
--hot-data \
--cg-from-perf-data \
--cg-use-split-hot-size \
--frame-opt=all \
--frame-opt-rm-stores \
--inline-ap \
--inline-small-functions \
--inline-memcpy \
--eliminate-unreachable \
--peepholes=all \
--plt=all \
--icf \
--icp-eliminate-loads \
--indirect-call-promotion=all \
--jump-tables=aggressive \
--preserve-blocks-alignment \
--reg-reassign \
--sctc-mode=always \
--shorten-instructions \
--simplify-conditional-tail-calls \
--simplify-rodata-loads \
--split-all-cold \
--reorder-blocks=cache+ \
--reorder-functions=cdsort \
--reorder-functions-use-hot-size \
--strip-rep-ret \
--use-aggr-reg-reassign \
--use-compact-aligner \
--use-edge-counts \
--x86-align-branch-boundary-hot-only \
--x86-strip-redundant-address-size \
--dyno-stats

if [[ "$@" == *"strip"* ]]; then
strip --strip-debug "${sharedob}"
fi

mv -f "${sharedob}" tmp/orjson

./script/fix-dist-info $(find tmp -type f -name "RECORD") $(find tmp -type f -name "orjson*.so")

cd tmp
zip -9 -r "${wheel}" -xi *
cd ..
mv -f "tmp/${wheel}" "${CARGO_TARGET_DIR}/wheels"
5 changes: 3 additions & 2 deletions script/develop
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ export CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-target}"
echo "CC: ${CC}, LD: ${LD}, LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}"

export CFLAGS="-Os -fstrict-aliasing -fno-plt -flto=full -emit-llvm"
export LDFLAGS="-fuse-ld=${LD} -Wl,-plugin-opt=also-emit-llvm -Wl,--as-needed -Wl,-zrelro,-znow"
export RUSTFLAGS="-C linker=${CC} -C link-arg=-fuse-ld=${LD} -C linker-plugin-lto -C lto=fat -C link-arg=-Wl,-zrelro,-znow -Z mir-opt-level=4 -Z threads=8"

export LDFLAGS="-fuse-ld=${LD} -Wl,-plugin-opt=also-emit-llvm -Wl,--as-needed -Wl,-zrelro,-znow -Wl,--emit-relocs"
export RUSTFLAGS="-C linker=${CC} -C link-arg=-fuse-ld=${LD} -C linker-plugin-lto -C lto=fat -C link-arg=-Wl,-zrelro,-znow -C link-arg=-Wl,--emit-relocs -Z mir-opt-level=4 -Z threads=8"

rm -f ${CARGO_TARGET_DIR}/wheels/*.whl

Expand Down
38 changes: 38 additions & 0 deletions script/fix-dist-info
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
# usage:
# ./script/fix-dist-info $(find tmp -type f -name "RECORD") $(find tmp -type f -name "orjson*.so")

import base64
import hashlib
import pathlib
import sys

record_path = pathlib.Path(sys.argv[1])
so_path = pathlib.Path(sys.argv[2])
so_name = sys.argv[2].split("/")[-1]

print(f"Fixing hash of {so_path} in {record_path} ...")

so_bytes = so_path.read_bytes()
so_len = len(so_bytes)

# URL_SAFE_NO_PAD.encode(Sha256::digest(bytes));
so_hash = (
base64.urlsafe_b64encode(hashlib.sha256(so_bytes).digest())
.rstrip(b"=")
.decode("utf-8")
)

record_original = record_path.read_bytes().decode("utf-8")
record_fixed = []
for line in record_original.split("\n"):
print(line)
if line.startswith(f"orjson/{so_name}"):
new_line = f"orjson/{so_name},sha256={so_hash},{so_len}"
print(f"fixed: {new_line}")
record_fixed.append(new_line)
else:
record_fixed.append(line)

record_path.write_bytes("\n".join(record_fixed).encode("utf-8"))
123 changes: 123 additions & 0 deletions script/profdata
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

import datetime
import gc
import lzma
import os
import sys

import pytest
from faker import Faker

from orjson import (
OPT_APPEND_NEWLINE,
OPT_INDENT_2,
OPT_NAIVE_UTC,
OPT_OMIT_MICROSECONDS,
dumps,
loads,
)

os.sched_setaffinity(os.getpid(), {0, 1})
gc.disable()


N = 200

NUM_LOOPS = 20
NUM_ENTRIES = 5

FAKER_LOCALES = [
"ar_AA",
"fi_FI",
"fil_PH",
"he_IL",
"ja_JP",
"th_TH",
"tr_TR",
"uk_UA",
"vi_VN",
]

NOW = datetime.datetime.now()


class Default:

def __str__(self):
return "aaa"

def default(obj, /):
return str(obj)


def fake():
print("fake ...")
fake = Faker(FAKER_LOCALES)
profile_keys = tuple(set(fake.profile().keys()) - {"current_location"})

DATA = [
[
{
"id": "jzoijxzzoijx",
"created_at": NOW,
"person": fake.profile(profile_keys),
"emoji": fake.emoji(),
"😾": "",
"z": Default(),
"a": 12123,
"int": 19298012910,
}
for _ in range(0, NUM_ENTRIES)
]
for _ in range(0, NUM_LOOPS)
]

orjson_opt = OPT_NAIVE_UTC | OPT_OMIT_MICROSECONDS
for _ in range(N):
for each in DATA:
loads(dumps(each, default=default, option=orjson_opt))


def _run_fixture(fixture: str, iterations: int):
with lzma.open(fixture, "rb") as fileh:
file_bytes = fileh.read()

file_str = file_bytes.decode("utf-8")

for _ in range(iterations):
dumps(loads(file_bytes))

for _ in range(iterations):
dumps(loads(file_str))



def fixture():
print("fixture ...")
_run_fixture("data/github.json.xz", 500 * N)
_run_fixture("data/twitter.json.xz", 100 * N)
_run_fixture("data/citm_catalog.json.xz", 20 * N)
_run_fixture("data/canada.json.xz", 2 * N)


def run_pytest():
print("pytest ...")
pytest.main(
[
"--quiet",
"--ignore=test/test_api.py",
"--ignore=test/test_fake.py",
"--ignore=test/test_fixture.py",
"--ignore=test/test_memory.py",
"--ignore=test/test_ujson.py",
"test",
]
)


if __name__ == "__main__":
run_pytest()
fake()
fixture()

0 comments on commit 3bdc6af

Please sign in to comment.