Skip to content

Commit 55f4a97

Browse files
committed
[GR-48942] Cleanups for running C extensions natively
PullRequest: truffleruby/4060
2 parents 374383c + cf53b1f commit 55f4a97

Some content is hidden

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

51 files changed

+143
-288
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
New features:
44

5-
* C/C++ extensions are now compiled using the system toolchain and executed natively instead of using GraalVM LLVM (Sulong). This leads to faster startup, no warmup, better compatibility and faster installation for C/C++ extensions (#3118, @eregon).
5+
* C/C++ extensions are now compiled using the system toolchain and executed natively instead of using GraalVM LLVM (Sulong). This leads to faster startup, no warmup, better compatibility, smaller distribution and faster installation for C/C++ extensions (#3118, @eregon).
66

77
Bug fixes:
88

ci.jsonnet

+2-10
Original file line numberDiff line numberDiff line change
@@ -232,16 +232,7 @@ local part_definitions = {
232232
},
233233

234234
platform: {
235-
local devtoolset = { # Until there is a proper object in common.jsonnet for it
236-
packages+: if self.os == "linux" then
237-
(if self.arch == "aarch64" then {
238-
"00:devtoolset": "==10",
239-
} else {
240-
"00:devtoolset": "==11",
241-
})
242-
else {},
243-
},
244-
local common_deps = common.deps.truffleruby + common.deps.sulong + devtoolset,
235+
local common_deps = common.deps.truffleruby + common.deps.sulong,
245236

246237
linux: common.linux_amd64 + common_deps + {
247238
platform_name:: "LinuxAMD64",
@@ -377,6 +368,7 @@ local part_definitions = {
377368
},
378369

379370
test_cexts_sulong: {
371+
mx_env:: "toolchain",
380372
environment+: {
381373
TRUFFLERUBYOPT: "--experimental-options --cexts-sulong",
382374
},

doc/contributor/docker.md

+1-6
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ jt docker test --filter debian --standalone $PATH_TO_STANDALONE_TAR_GZ --test re
5050
For example, to run a full set of tests on a set of new release candidate tarballs:
5151

5252
```bash
53-
jt docker test --graalvm graalvm-ce.tar.gz llvm-toolchain-installable.jar:ruby-installable-ce.jar --test release_branch
54-
jt docker test --graalvm graalvm-ee.tar.gz llvm-toolchain-installable.jar:ruby-installable-ee.jar --test release_branch
5553
jt docker test --standalone truffleruby-linux-amd64.tar.gz --test release_branch
5654
```
5755

@@ -66,10 +64,7 @@ Pick one of the distributions in [docker-configs.yaml](../../tool/docker-configs
6664

6765
## Methods of installing
6866

69-
Pick one of:
70-
71-
* From a GraalVM binary tarball and Ruby component you have locally, `--graalvm graalvm.tar.gz llvm-toolchain-installable.jar:ruby-installable.jar`
72-
* From a TruffleRuby standalone distribution you have locally, `--standalone truffleruby-1.0.0-linux-amd64.tar.gz`
67+
From a TruffleRuby standalone distribution you have locally, `--standalone truffleruby-1.0.0-linux-amd64.tar.gz`
7368

7469
## What to do
7570

doc/contributor/workflow.md

-14
Original file line numberDiff line numberDiff line change
@@ -127,20 +127,6 @@ This warning is important.
127127
- If you want to set the `suite.py` import to that checked out in `graal` (unlikely), you should run
128128
jt mx scheckimports` beforehand.
129129

130-
### Building C Extensions more quickly
131-
132-
Speeding up compilation of C extensions can be achieved by using *native* toolchain launchers,
133-
instead of the Bash toolchain launchers used with the `jvm*` build configurations.
134-
135-
For bundled C extensions (that is, extensions under `src/main/c`),
136-
you can `export JT_CACHE_TOOLCHAIN=true` and that will then use native toolchain launchers for the
137-
[bootstrap toolchain](https://github.com/oracle/graal/blob/master/sulong/docs/contributor/TOOLCHAIN.md#using-a-prebuilt-graalvm-as-a-bootstrapping-toolchain).
138-
This has no effect after `jt build`.
139-
140-
For C extensions installed after `jt build` by e.g. `gem install` or `bundle install`,
141-
one can use the `jvm-ce-ntl` build configuration which includes *native* toolchain launchers,
142-
or use one of the `native*` build configuration (which also builds a native truffleruby launcher).
143-
144130
## Editors and IDEs
145131

146132
* [Using the IntelliJ IDE for Development](using-intellij.md) (recommended)

doc/user/installing-llvm.md

+2-23
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@ permalink: /reference-manual/ruby/InstallingLLVM/
66
---
77
# Installing Make and GCC
88

9-
Since TruffleRuby 19.3.0, TruffleRuby ships with its own LLVM toolchain.
10-
Therefore, it is no longer necessary to install LLVM.
11-
If you are using an older version, see [the documentation for that version](https://github.com/oracle/truffleruby/blob/vm-19.2.0/doc/user/installing-llvm.md).
12-
13-
The `make` utility as well as the dependencies of the toolchain still need to be available to build C and C++ extensions.
9+
Since TruffleRuby 24.0.0, TruffleRuby no longer needs a LLVM toolchain and instead uses the system toolchain.
10+
The packages below are required to build C and C++ extensions.
1411

1512
### Fedora-based: RHEL, Oracle Linux, etc
1613

@@ -24,28 +21,10 @@ sudo dnf install make gcc
2421
sudo apt-get install make gcc
2522
```
2623

27-
### Mandriva-based and other Linux distributions
28-
29-
Note: Such distributions are not tested and not [supported](../../README.md#system-compatibility).
30-
31-
First, install the `make` and `gcc` dependencies.
32-
33-
Mandriva uses a not-yet-upstreamed patch to let `clang` find the GCC installation (see [this comment](https://github.com/oracle/truffleruby/issues/2009#issuecomment-630019082)).
34-
Therefore the internal LLVM toolchain cannot find the necessary `libgcc_s` by default.
35-
The proper fix is for those distributions to upstream their changes to LLVM.
36-
37-
A workaround is to create a symlink explicitly so that the LLVM toolchain can find `libgcc_s`:
38-
```bash
39-
cd /usr/lib/gcc
40-
sudo ln -s x86_64-mandriva-linux-gnu x86_64-linux-gnu
41-
```
42-
4324
### macOS
4425

4526
On macOS, make sure you have installed the command line developer tools from Xcode:
4627

4728
```bash
4829
xcode-select --install
4930
```
50-
51-
You might need to add `export SDKROOT=$(xcrun --show-sdk-path)` in your shell profile.

doc/user/polyglot.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ The JVM configuration automatically has access to other languages.
2828
To use other GraalVM languages, you need the [JVM Standalone](../../README.md#getting-started).
2929
The Native Standalone does not support installing extra languages.
3030

31-
Note that `ruby`, `llvm`, the LLVM toolchain and host Java interop are available without installing anything extra.
31+
Note that `ruby`, `llvm` and host Java interop are available without installing anything extra.
3232

3333
Then you can install other languages with `truffleruby-polyglot-get $LANGUAGE`, for instance:
3434
```bash

lib/cext/include/truffleruby/truffleruby-abi-version.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
// $RUBY_VERSION must be the same as TruffleRuby.LANGUAGE_VERSION.
1111
// $ABI_NUMBER starts at 1 and is incremented for every ABI-incompatible change.
1212

13-
#define TRUFFLERUBY_ABI_VERSION "3.2.2.5"
13+
#define TRUFFLERUBY_ABI_VERSION "3.2.2.6"
1414

1515
#endif

lib/mri/mkmf.rb

+5-17
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,6 @@
4848
end
4949
end
5050

51-
if defined?(::TruffleRuby) and Truffle::Boot.get_option('cexts-prepend-toolchain-to-path') and Truffle::Boot.get_option('cexts-sulong')
52-
ENV['PATH'] = "#{RbConfig::CONFIG['toolchain_path']}:#{ENV['PATH']}"
53-
end
54-
5551
class String # :nodoc:
5652
# Wraps a string in escaped quotes if it contains whitespace.
5753
def quote
@@ -2891,19 +2887,11 @@ def MAIN_DOES_NOTHING(*refs)
28912887
"$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
28922888

28932889
if defined?(::TruffleRuby)
2894-
# We need to link to libtruffleruby for MakeMakefile#try_link to succeed.
2895-
# The created executable will link against both libgraalvm-llvm.so and libtruffleruby and
2896-
# might be executed for #try_constant and #try_run so we also need -rpath for both.
2897-
# TODO: could likely always use the second branch here
2898-
if Truffle::Boot.get_option('cexts-sulong')
2899-
libtruffleruby_dir = File.dirname(RbConfig::CONFIG['libtruffleruby'])
2900-
TRY_LINK << " -L#{libtruffleruby_dir} -rpath #{libtruffleruby_dir} -ltruffleruby"
2901-
libgraalvm_llvm_dir = ::Truffle::Boot.toolchain_paths(:LD_LIBRARY_PATH)
2902-
TRY_LINK << " -rpath #{libgraalvm_llvm_dir}"
2903-
else
2904-
libtrufflerubytrampoline_dir = File.dirname(RbConfig::CONFIG['libtrufflerubytrampoline'])
2905-
TRY_LINK << " -L#{libtrufflerubytrampoline_dir} -Wl,-rpath,#{libtrufflerubytrampoline_dir} -ltrufflerubytrampoline"
2906-
end
2890+
# We need to link to libtrufflerubytrampoline for MakeMakefile#try_link to succeed.
2891+
# The created executable will link against libtrufflerubytrampoline and
2892+
# might be executed for #try_constant and #try_run so we also need -rpath.
2893+
libtrufflerubytrampoline_dir = File.dirname(RbConfig::CONFIG['libtrufflerubytrampoline'])
2894+
TRY_LINK << " -L#{libtrufflerubytrampoline_dir} -Wl,-rpath,#{libtrufflerubytrampoline_dir} -ltrufflerubytrampoline"
29072895
end
29082896

29092897
##

lib/truffle/rbconfig.rb

-9
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,13 @@ module RbConfig
7272
strip = Truffle::Boot.toolchain_executable(:STRIP)
7373

7474
strip = "#{strip} --keep-section=.llvmbc" unless Truffle::Platform.darwin?
75-
gcc, clang = false, true
7675
else
7776
if Truffle::Platform.linux?
7877
ar = 'gcc-ar'
7978
cc = 'gcc' # -std=gnu99 ?
8079
cxx = 'g++'
8180
ranlib = 'gcc-ranlib'
8281
strip = 'strip -S -x'
83-
gcc, clang = true, false
8482
elsif Truffle::Platform.darwin?
8583
ar = 'ar'
8684
cc = 'clang'
@@ -90,7 +88,6 @@ module RbConfig
9088
# This is notably necessary for grpc where the current logic does not append -x for TruffleRuby:
9189
# https://github.com/grpc/grpc/blob/54f65e0dbd2151a3ba2ad364327c0c31b200a5ae/src/ruby/ext/grpc/extconf.rb#L125-L126
9290
strip = 'strip -A -n -x'
93-
gcc, clang = false, true
9491
cflags_pre = '-fdeclspec '
9592
else
9693
raise 'Unknown platform'
@@ -107,9 +104,6 @@ module RbConfig
107104
'-Wno-incompatible-pointer-types', # Fix byebug 8.2.1 compile (st_data_t error)
108105
'-Wno-format-extra-args', # Our PRIsVALUE generates this because compilers ignore printf extensions
109106
]
110-
warnflags << '-Wno-format-invalid-specifier' if clang # Our PRIsVALUE generates this because compilers ignore printf extensions
111-
# TODO fix it, happens in openssl
112-
warnflags << '-Wno-discarded-qualifiers' if gcc
113107

114108
defs = ''
115109
cppflags = ''
@@ -119,8 +113,6 @@ module RbConfig
119113
cext_dir = "#{prefix}/lib/cext"
120114
soext = Truffle::Platform::SOEXT
121115

122-
toolchain_path = Truffle::Boot.toolchain_paths(:PATH)
123-
124116
# Make C extensions use the same libssl as the one used for the openssl C extension
125117
if Truffle::Platform.darwin?
126118
require 'truffle/openssl-prefix'
@@ -225,7 +217,6 @@ module RbConfig
225217
'sysconfdir' => "#{prefix}/etc", # doesn't exist, as in MRI
226218
'target_cpu' => host_cpu,
227219
'target_os' => host_os,
228-
'toolchain_path' => toolchain_path,
229220
'UNICODE_VERSION' => Primitive.encoding_unicode_version,
230221
'UNICODE_EMOJI_VERSION' => Primitive.encoding_unicode_emoji_version,
231222
'warnflags' => warnflags,

lib/truffle/truffle/cext.rb

+13-5
Original file line numberDiff line numberDiff line change
@@ -2112,18 +2112,26 @@ def rb_imemo_tmpbuf_set_ptr(obj, ptr)
21122112
obj.pointer = ptr
21132113
end
21142114

2115-
def rb_debug_inspector_open_contexts
2116-
Truffle::Debug.get_frame_bindings.map do |binding|
2115+
RB_THREAD_CURRENT_BACKTRACE_LOCATIONS_OMIT = NFI ? 4 : 5
2116+
2117+
def rb_debug_inspector_open_contexts_and_backtrace
2118+
contexts = Truffle::Debug.get_frame_bindings.map do |binding|
21172119
if binding
21182120
[binding.receiver, Primitive.class(binding.receiver), binding]
21192121
else
21202122
[nil, nil, nil]
21212123
end
21222124
end.freeze
2123-
end
21242125

2125-
def rb_thread_current_backtrace_locations
2126-
Thread.current.backtrace_locations(4)
2126+
backtrace = Thread.current.backtrace_locations(RB_THREAD_CURRENT_BACKTRACE_LOCATIONS_OMIT)
2127+
2128+
if contexts.size != backtrace.size
2129+
STDERR.puts '', 'contexts:', contexts.map { |_,_,binding| binding.source_location.join(':') }
2130+
STDERR.puts '', 'backtrace:', backtrace, ''
2131+
raise 'debug_inspector contexts and backtrace lengths are not equal'
2132+
end
2133+
2134+
[contexts, backtrace]
21272135
end
21282136

21292137
def rb_syserr_new(errno, mesg)

lib/truffle/truffle/cext_constants.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# GNU General Public License version 2, or
99
# GNU Lesser General Public License version 2.1.
1010

11-
# From tool/generate-cext-constants.rb
11+
# GENERATED BY tool/generate-cext-constants.rb
1212

1313
module Truffle::CExt
1414
def rb_cArray

lib/truffle/truffle/cext_ruby.rb

+17-40
Original file line numberDiff line numberDiff line change
@@ -20,49 +20,26 @@ def rb_define_method(mod, name, function, argc)
2020
raise ArgumentError, "arity out of range: #{argc} for -2..15"
2121
end
2222

23-
if NFI
24-
wrapper = RB_DEFINE_METHOD_WRAPPERS[argc]
25-
method_body = Truffle::Graal.copy_captured_locals -> *args, &block do
26-
if argc == -1 # (int argc, VALUE *argv, VALUE obj)
27-
args = [function, args.size, Truffle::CExt.RARRAY_PTR(args), Primitive.cext_wrap(self)]
28-
elsif argc == -2 # (VALUE obj, VALUE rubyArrayArgs)
29-
args = [function, Primitive.cext_wrap(self), Primitive.cext_wrap(args)]
30-
elsif argc >= 0 # (VALUE obj); (VALUE obj, VALUE arg1); (VALUE obj, VALUE arg1, VALUE arg2); ...
31-
if args.size != argc
32-
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected #{argc})"
33-
end
34-
args = [function, Primitive.cext_wrap(self), *args.map! { |arg| Primitive.cext_wrap(arg) }]
23+
wrapper = RB_DEFINE_METHOD_WRAPPERS[argc]
24+
method_body = Truffle::Graal.copy_captured_locals -> *args, &block do
25+
if argc == -1 # (int argc, VALUE *argv, VALUE obj)
26+
args = [function, args.size, Truffle::CExt.RARRAY_PTR(args), Primitive.cext_wrap(self)]
27+
elsif argc == -2 # (VALUE obj, VALUE rubyArrayArgs)
28+
args = [function, Primitive.cext_wrap(self), Primitive.cext_wrap(args)]
29+
elsif argc >= 0 # (VALUE obj); (VALUE obj, VALUE arg1); (VALUE obj, VALUE arg1, VALUE arg2); ...
30+
if args.size != argc
31+
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected #{argc})"
3532
end
36-
37-
exc = $!
38-
Primitive.thread_set_exception(nil)
39-
# We must set block argument if given here so that the
40-
# `rb_block_*` functions will be able to find it by walking the stack.
41-
res = Primitive.call_with_c_mutex_and_frame_and_unwrap(wrapper, args, Primitive.caller_special_variables_if_available, block)
42-
Primitive.thread_set_exception(exc)
43-
res
33+
args = [function, Primitive.cext_wrap(self), *args.map! { |arg| Primitive.cext_wrap(arg) }]
4434
end
45-
else
46-
method_body = Truffle::Graal.copy_captured_locals -> *args, &block do
47-
if argc == -1 # (int argc, VALUE *argv, VALUE obj)
48-
args = [args.size, Truffle::CExt.RARRAY_PTR(args), Primitive.cext_wrap(self)]
49-
elsif argc == -2 # (VALUE obj, VALUE rubyArrayArgs)
50-
args = [Primitive.cext_wrap(self), Primitive.cext_wrap(args)]
51-
elsif argc >= 0 # (VALUE obj); (VALUE obj, VALUE arg1); (VALUE obj, VALUE arg1, VALUE arg2); ...
52-
if args.size != argc
53-
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected #{argc})"
54-
end
55-
args = [Primitive.cext_wrap(self), *args.map! { |arg| Primitive.cext_wrap(arg) }]
56-
end
5735

58-
exc = $!
59-
Primitive.thread_set_exception(nil)
60-
# We must set block argument if given here so that the
61-
# `rb_block_*` functions will be able to find it by walking the stack.
62-
res = Primitive.call_with_c_mutex_and_frame_and_unwrap(function, args, Primitive.caller_special_variables_if_available, block)
63-
Primitive.thread_set_exception(exc)
64-
res
65-
end
36+
exc = $!
37+
Primitive.thread_set_exception(nil)
38+
# We must set block argument if given here so that the
39+
# `rb_block_*` functions will be able to find it by walking the stack.
40+
res = Primitive.call_with_c_mutex_and_frame_and_unwrap(wrapper, args, Primitive.caller_special_variables_if_available, block)
41+
Primitive.thread_set_exception(exc)
42+
res
6643
end
6744

6845
# Even if the argc is -2, the arity number

mx.truffleruby/env_files.md

+8-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
Here is how the various env files relate to each other:
22
* `jvm`
33
* `jvm-ce`: + GraalVM Community Compiler
4-
* `jvm-ce-ntl`: + native toolchain launchers
5-
* `jvm-ce-libgraal`: + libgraal
6-
* `native`: + librubyvm + `Truffle Macro`
7-
* `native-host-inlining`: + `TruffleHostInliningPrintExplored`, - native toolchain launchers
8-
* `native-profiling`: + `-H:-DeleteLocalSymbols`
4+
* `jvm-ce-libgraal`: + libgraal
5+
* `native`: + librubyvm + `Truffle Macro`
6+
* `native-host-inlining`: + `TruffleHostInliningPrintExplored`
7+
* `native-profiling`: + `-H:-DeleteLocalSymbols`
98
* `jvm-ee`: + Oracle GraalVM Compiler + `Truffle enterprise` + license + `LLVM Runtime Native Enterprise`
10-
* `jvm-ee-ntl`: + native toolchain launchers
11-
* `jvm-ee-libgraal`: + libgraal
12-
* `native-ee`: + librubyvm + `Truffle Macro Enterprise` + Native Image G1
13-
* `native-ee-host-inlining`: + `TruffleHostInliningPrintExplored`, - native toolchain launchers
14-
* `native-ee-aux`: + `AuxiliaryEngineCache`, - Native Image G1 (currently incompatible)
9+
* `jvm-ee-libgraal`: + libgraal
10+
* `native-ee`: + librubyvm + `Truffle Macro Enterprise` + Native Image G1
11+
* `native-ee-host-inlining`: + `TruffleHostInliningPrintExplored`
12+
* `native-ee-aux`: + `AuxiliaryEngineCache`, - Native Image G1 (currently incompatible)
1513
* `jvm-js`: + Graal.js
1614
* `jvm-py`: + GraalPython

mx.truffleruby/jvm-ce-libgraal

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
GRAALVM_SKIP_ARCHIVE=true
22
DYNAMIC_IMPORTS=/tools,/compiler,/substratevm
33
COMPONENTS=TruffleRuby,suite:tools,GraalVM compiler,SubstrateVM,LibGraal
4-
NATIVE_IMAGES=suite:sulong,lib:jvmcicompiler
4+
NATIVE_IMAGES=lib:jvmcicompiler
55
# To also create the standalone
66
INSTALLABLES=TruffleRuby
77
BUILD_TARGETS=GRAALVM,GRAALVM_STANDALONES

mx.truffleruby/jvm-ce-ntl

-7
This file was deleted.

mx.truffleruby/jvm-ee-libgraal

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
GRAALVM_SKIP_ARCHIVE=true
22
DYNAMIC_IMPORTS=/tools,/truffleruby-enterprise,/graal-enterprise,/vm-enterprise,/sulong-managed,/substratevm-enterprise
33
COMPONENTS=TruffleRuby,suite:tools,GraalVM enterprise compiler,Truffle enterprise,GraalVM enterprise license files,LLVM Runtime Native Enterprise,SubstrateVM Enterprise,LibGraal Enterprise
4-
NATIVE_IMAGES=suite:sulong,lib:jvmcicompiler
4+
NATIVE_IMAGES=lib:jvmcicompiler
55
# To also create the standalone
66
INSTALLABLES=TruffleRuby
77
BUILD_TARGETS=GRAALVM,GRAALVM_STANDALONES

mx.truffleruby/jvm-ee-ntl

-7
This file was deleted.

0 commit comments

Comments
 (0)