Skip to content

Commit ea6537d

Browse files
committed
Use the system libyaml for psych as it is faster for warmup
* And it has similar peak performance. * See #2089
1 parent b37e9e5 commit ea6537d

File tree

19 files changed

+98
-13030
lines changed

19 files changed

+98
-13030
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ Performance:
9898
* Marking of native structures wrapped in objects is now done on C call exit to reduce memory overhead (@aardvark179).
9999
* Splitting (copying) of call targets has been optimized by implementing `cloneUninitialized()` (@andrykonchin, @eregon).
100100
* `Process.pid` is now cached per process like `$$` (#2882, @horakivo)
101+
* Use the system `libyaml` for `psych` to improve warmup when parsing YAML (#2089, @eregon).
101102

102103
Changes:
103104

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ environment, for example, by unmounting system filesystems such as `/dev/shm`.
103103

104104
* [make and gcc](doc/user/installing-llvm.md) for building C and C++ extensions
105105
* [libssl](doc/user/installing-libssl.md) for the `openssl` C extension
106+
* [libyaml](doc/user/installing-libyaml.md) for the `psych` C extension
106107
* [zlib](doc/user/installing-zlib.md) for the `zlib` C extension
107108

108109
Without these dependencies, many libraries including RubyGems will not work.

ci.jsonnet

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,14 @@ local part_definitions = {
228228
packages+: {
229229
binutils: ">=2.30",
230230
ruby: "==" + mri_version,
231+
libyaml: "==0.2.5",
231232
},
232233
},
233234

234235
local linux_aarch64_deps = common.deps.sulong + {
235236
packages+: {
236237
ruby: "==3.0.2",
238+
libyaml: "==0.2.5",
237239
},
238240
},
239241

doc/user/installing-libyaml.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
layout: docs-experimental
3+
toc_group: ruby
4+
link_title: Installing LibYAML
5+
permalink: /reference-manual/ruby/InstallingLibYAML/
6+
---
7+
# Installing LibYAML
8+
9+
TruffleRuby requires to have `libyaml` installed, much like CRuby 3.2+ and Psych 5+.
10+
11+
### Fedora-based: RHEL, Oracle Linux, etc
12+
13+
```bash
14+
sudo dnf install libyaml-devel
15+
```
16+
17+
### Debian-based: Ubuntu, etc
18+
19+
```bash
20+
sudo apt-get install libyaml-dev
21+
```
22+
23+
### macOS
24+
25+
#### Homebrew
26+
27+
We recommend installing libssl via [Homebrew](https://brew.sh).
28+
29+
```bash
30+
brew install libyaml
31+
```
32+
33+
#### MacPorts
34+
35+
MacPorts should also work but is not actively tested.
36+
37+
```bash
38+
sudo port install libyaml
39+
```

lib/truffle/truffle/libyaml-prefix.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved. This
2+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
3+
# redistribute it and/or modify it under the terms of the:
4+
#
5+
# Eclipse Public License version 2.0, or
6+
# GNU General Public License version 2, or
7+
# GNU Lesser General Public License version 2.1.
8+
9+
# Set LIBYAML_PREFIX in ENV to find the libyaml headers
10+
11+
search_homebrew = -> homebrew {
12+
if prefix = "#{homebrew}/opt/libyaml" and Dir.exist?(prefix)
13+
prefix
14+
end
15+
}
16+
17+
if Truffle::Platform.darwin? && !ENV['LIBYAML_PREFIX']
18+
default_homebrew_prefix = Truffle::System.host_cpu == 'aarch64' ? '/opt/homebrew' : '/usr/local'
19+
if prefix = search_homebrew.call(default_homebrew_prefix)
20+
# found
21+
else
22+
homebrew = `brew --prefix 2>/dev/null`.strip
23+
homebrew = nil unless $?.success? and !homebrew.empty? and Dir.exist?(homebrew)
24+
25+
if homebrew and prefix = search_homebrew.call(homebrew)
26+
# found
27+
elsif Dir.exist?('/opt/local/include/libyaml') # MacPorts
28+
prefix = '/opt/local'
29+
end
30+
end
31+
32+
if prefix
33+
ENV['LIBYAML_PREFIX'] = prefix
34+
else
35+
abort 'Could not find libyaml headers, install via Homebrew or MacPorts or set LIBYAML_PREFIX'
36+
end
37+
end
38+
39+
if libyaml_prefix = ENV['LIBYAML_PREFIX']
40+
Truffle::Debug.log_config("Found libyaml in #{libyaml_prefix}")
41+
end

src/main/c/Makefile

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,10 @@ rbconfig-sizeof/sizeof.$(DLEXT): rbconfig-sizeof/Makefile rbconfig-sizeof/sizes.
159159
$(Q) cd rbconfig-sizeof && $(MAKE) $(MKMF_MAKEFILE_SUBPROCESS_FLAGS)
160160

161161
# psych
162-
# Always use the bundled libyaml, as we want it as bitcode and avoid extra handles
163162
psych/Makefile: psych/extconf.rb $(EXTCONF_DEPS)
164-
$(Q) cd psych && $(RUBY) extconf.rb --enable-bundled-libyaml || $(IF_EXTCONF_FAIL)
163+
$(Q) cd psych && $(RUBY) extconf.rb || $(IF_EXTCONF_FAIL)
165164

166-
psych/psych.$(DLEXT): psych/Makefile psych/*.c psych/*.h psych/yaml/*.c psych/yaml/*.h
165+
psych/psych.$(DLEXT): psych/Makefile psych/*.c psych/*.h
167166
$(Q) cd psych && $(MAKE) $(MKMF_MAKEFILE_SUBPROCESS_FLAGS)
168167

169168
# debug bundled gem

src/main/c/psych/extconf.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,18 @@
55

66
# :stopdoc:
77

8-
dir_config 'libyaml'
8+
if defined?(::TruffleRuby)
9+
require 'truffle/libyaml-prefix'
10+
dir_config('libyaml', ENV['LIBYAML_PREFIX'])
11+
else
12+
dir_config 'libyaml'
13+
end
914

15+
if defined?(::TruffleRuby)
16+
# From https://github.com/ruby/psych/blob/v5.0.0/ext/psych/extconf.rb#L42-L43
17+
find_header('yaml.h') or abort "yaml.h not found"
18+
find_library('yaml', 'yaml_get_version') or abort "libyaml not found"
19+
else
1020
if enable_config("bundled-libyaml", false) || !(find_header('yaml.h') && find_library('yaml', 'yaml_get_version'))
1121
# Embed libyaml since we could not find it.
1222

@@ -35,6 +45,7 @@
3545
find_header 'yaml.h'
3646
have_header 'config.h'
3747
end
48+
end
3849

3950
create_makefile 'psych' do |mk|
4051
mk << "YAML_H = #{header}".strip << "\n"

0 commit comments

Comments
 (0)