forked from pantsbuild/pants
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[engine] Move to new-style CFFI callbacks. (pantsbuild#4324)
Fixes pantsbuild#4036 Problem We currently use "old-style callbacks" with CFFI. These are known to be slower and cause more complicated stack traces during debugging/performance analysis. Solution Switch to "new-style callbacks" using the following approach: Bootstrap CFFI C sources pre-pants execution by way of a simple, venv-backed entrypoint fed by native.py and integrated into bootstrap.sh. Compile and link the generated CFFI C sources into the rust binary at build time with cargo, by way of a build script + the gcc-rs package. On OSX, we instruct cargo to use a linker flag (via .cargo/config) that enables weak linking to avoid missing python symbols during linking (this behavior is the default on Linux). The weakly linked symbols (e.g. _PyImport_ImportModule) are then dynamically resolved within the address space of the parent binary (python) at runtime. Rename the native-engine rust binary to native_engine.so to be python import compatible. Dynamically load the native_engine.so binary as a python module by injecting the binaryutil dir into sys.path at runtime and initializing the new-style callbacks with the closed-loop ffi object. This results in a single native-engine binary that can be loaded both as a python module (import) and as a C module (dlopen) and is not statically or dynamically linked to python. Result As tested on my Sierra laptop, this is good for a >10% speedup as measured by ./pants --enable-v2-engine list :: in the pants repo.
- Loading branch information
Showing
10 changed files
with
541 additions
and
387 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# N.B. On OSX, we force weak linking by passing the param `-undefined dynamic_lookup` to | ||
# the underlying linker used by cargo/rustc via RUSTFLAGS. This avoids "missing symbol" | ||
# errors for Python symbols (e.g. `_PyImport_ImportModule`) at build time when bundling | ||
# the CFFI C sources. The missing symbols will instead by dynamically resolved in the | ||
# address space of the parent binary (e.g. `python`) at runtime - obviating a need to | ||
# link to libpython. | ||
|
||
[target.x86_64-apple-darwin] | ||
rustflags = ["-C", "link-args=-undefined dynamic_lookup"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# coding=utf-8 | ||
# Copyright 2017 Pants project contributors (see CONTRIBUTORS.md). | ||
# Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
|
||
from __future__ import (absolute_import, division, generators, nested_scopes, print_function, | ||
unicode_literals, with_statement) | ||
|
||
import sys | ||
|
||
from pants.engine.subsystem.native import bootstrap_c_source | ||
|
||
|
||
if __name__ == '__main__': | ||
try: | ||
output_dir = sys.argv[1] | ||
except Exception: | ||
print('usage: {} <output dir>'.format(sys.argv[0])) | ||
|
||
bootstrap_c_source(output_dir) |
Oops, something went wrong.