From edaec886ef5141b7c9aa41a062d0c20a3c9ed811 Mon Sep 17 00:00:00 2001 From: Andrew Konchin Date: Mon, 13 May 2024 18:32:46 +0300 Subject: [PATCH] Add option --reuse-as-binary --- CHANGELOG.md | 3 +++ lib/truffle/rubygems/defaults/truffleruby.rb | 2 +- .../options/reuse_precompiled_gems_tags.txt | 1 + .../options/reuse_precompiled_gems_spec.rb | 15 +++++++++++++++ .../truffleruby/launcher/CommandLineParser.java | 4 ++-- .../java/org/truffleruby/options/Options.java | 5 +++++ src/options.yml | 2 ++ .../shared/options/OptionsCatalog.java | 12 ++++++++++++ 8 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 spec/tags/truffle/options/reuse_precompiled_gems_tags.txt create mode 100644 spec/truffle/options/reuse_precompiled_gems_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ac36fa3ae68..cd0548b0acfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ New features: +* Add `--reuse-precompiled-gems` option (@andrykonchin). + Bug fixes: * Add missing thread-safe objects write barriers for `TruffleRuby::ConcurrentMap` (#3179, @eregon). @@ -23,6 +25,7 @@ Compatibility: * Set `$!` when a `Kernel#at_exit` hook raises an exception (#3535, @andrykonchin). Performance: + * Fix inline caching for Regexp creation from Strings (#3492, @andrykonchin, @eregon). * Optimize `Integer#pow` method for small modulus values (#3544, @andrykonchin). diff --git a/lib/truffle/rubygems/defaults/truffleruby.rb b/lib/truffle/rubygems/defaults/truffleruby.rb index e0eabac9fff7..752d0a6382a0 100644 --- a/lib/truffle/rubygems/defaults/truffleruby.rb +++ b/lib/truffle/rubygems/defaults/truffleruby.rb @@ -30,5 +30,5 @@ def self.platform_defaults class Gem::Platform # The list of gems we want to install precompiled (using the local platform) on TruffleRuby - REUSE_AS_BINARY_ON_TRUFFLERUBY = %w[libv8 libv8-node sass-embedded sorbet-static] + REUSE_AS_BINARY_ON_TRUFFLERUBY = %w[libv8 libv8-node sass-embedded sorbet-static] + Truffle::Boot.get_option('reuse-precompiled-gems') end diff --git a/spec/tags/truffle/options/reuse_precompiled_gems_tags.txt b/spec/tags/truffle/options/reuse_precompiled_gems_tags.txt new file mode 100644 index 000000000000..9eed5a167a3c --- /dev/null +++ b/spec/tags/truffle/options/reuse_precompiled_gems_tags.txt @@ -0,0 +1 @@ +slow:The --reuse-precompiled-gems option adds listed gems into a Gem::Platform::REUSE_AS_BINARY_ON_TRUFFLERUBY list diff --git a/spec/truffle/options/reuse_precompiled_gems_spec.rb b/spec/truffle/options/reuse_precompiled_gems_spec.rb new file mode 100644 index 000000000000..edd889c2fd33 --- /dev/null +++ b/spec/truffle/options/reuse_precompiled_gems_spec.rb @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved. This +# code is released under a tri EPL/GPL/LGPL license. You can use it, +# redistribute it and/or modify it under the terms of the: +# +# Eclipse Public License version 2.0, or +# GNU General Public License version 2, or +# GNU Lesser General Public License version 2.1. + +require_relative '../../ruby/spec_helper' + +describe "The --reuse-precompiled-gems option" do + it "adds listed gems into a Gem::Platform::REUSE_AS_BINARY_ON_TRUFFLERUBY list" do + ruby_exe("p Gem::Platform::REUSE_AS_BINARY_ON_TRUFFLERUBY", options: "--experimental-options --reuse-precompiled-gems=foo,bar").should.include? '"foo", "bar"' + end +end diff --git a/src/launcher/java/org/truffleruby/launcher/CommandLineParser.java b/src/launcher/java/org/truffleruby/launcher/CommandLineParser.java index d6b39240d4d9..56dd474e5ee9 100644 --- a/src/launcher/java/org/truffleruby/launcher/CommandLineParser.java +++ b/src/launcher/java/org/truffleruby/launcher/CommandLineParser.java @@ -118,8 +118,8 @@ private void processArgv() { value = null; } - // Switches without values are stored separately in ARGV_GLOBAL_FLAGS. Otherwise it would not be - // possible to determine if the value is suppose to be `true` or `"true"`. + // Switches without values are stored separately in ARGV_GLOBAL_FLAGS. Otherwise, it would not be + // possible to determine if the value is supposed to be `true` or `"true"`. final OptionDescriptor optionDescription = value != null ? OptionsCatalog.ARGV_GLOBAL_VALUES : OptionsCatalog.ARGV_GLOBAL_FLAGS; diff --git a/src/main/java/org/truffleruby/options/Options.java b/src/main/java/org/truffleruby/options/Options.java index b40d3699ac94..18ddae869636 100644 --- a/src/main/java/org/truffleruby/options/Options.java +++ b/src/main/java/org/truffleruby/options/Options.java @@ -135,6 +135,8 @@ public final class Options { public final boolean WARN_TRUFFLE_REGEX_MATCH_FALLBACK; /** --truffle-regex-ignore-atomic-groups=false */ public final boolean TRUFFLE_REGEX_IGNORE_ATOMIC_GROUPS; + /** --reuse-precompiled-gems=StringArrayOptionType.EMPTY_STRING_ARRAY */ + public final String[] REUSE_PRECOMPILED_GEMS; /** --argv-globals=false */ public final boolean ARGV_GLOBALS; /** --chomp-loop=false */ @@ -262,6 +264,7 @@ public Options(Env env, OptionValues options, LanguageOptions languageOptions) { WARN_TRUFFLE_REGEX_COMPILE_FALLBACK = options.get(OptionsCatalog.WARN_TRUFFLE_REGEX_COMPILE_FALLBACK_KEY); WARN_TRUFFLE_REGEX_MATCH_FALLBACK = options.get(OptionsCatalog.WARN_TRUFFLE_REGEX_MATCH_FALLBACK_KEY); TRUFFLE_REGEX_IGNORE_ATOMIC_GROUPS = options.get(OptionsCatalog.TRUFFLE_REGEX_IGNORE_ATOMIC_GROUPS_KEY); + REUSE_PRECOMPILED_GEMS = options.get(OptionsCatalog.REUSE_PRECOMPILED_GEMS_KEY); ARGV_GLOBALS = options.get(OptionsCatalog.ARGV_GLOBALS_KEY); CHOMP_LOOP = options.get(OptionsCatalog.CHOMP_LOOP_KEY); GETS_LOOP = options.get(OptionsCatalog.GETS_LOOP_KEY); @@ -411,6 +414,8 @@ public Object fromDescriptor(OptionDescriptor descriptor) { return WARN_TRUFFLE_REGEX_MATCH_FALLBACK; case "ruby.truffle-regex-ignore-atomic-groups": return TRUFFLE_REGEX_IGNORE_ATOMIC_GROUPS; + case "ruby.reuse-precompiled-gems": + return REUSE_PRECOMPILED_GEMS; case "ruby.argv-globals": return ARGV_GLOBALS; case "ruby.chomp-loop": diff --git a/src/options.yml b/src/options.yml index 05c960135b8e..a8604741b9bd 100644 --- a/src/options.yml +++ b/src/options.yml @@ -155,6 +155,8 @@ EXPERT: WARN_TRUFFLE_REGEX_MATCH_FALLBACK: [warn-truffle-regex-match-fallback, boolean, false, 'Warn every time Truffle Regex cannot be used for a Regexp match (and instead Joni is used)'] TRUFFLE_REGEX_IGNORE_ATOMIC_GROUPS: [truffle-regex-ignore-atomic-groups, boolean, false, 'Treat atomic groups (?>...) as ordinary groups (?:...) with Truffle Regex.'] + REUSE_PRECOMPILED_GEMS: [reuse-precompiled-gems, string-array, ',,...', 'A list of gems we want to install precompiled (using the local platform) on TruffleRuby. Can only be used for gem extensions which do not depend on the Ruby C API.'] + INTERNAL: # Options for debugging the TruffleRuby implementation EXPERIMENTAL: # Options corresponding to MRI options, which are only meaningful when using the TruffleRuby launcher diff --git a/src/shared/java/org/truffleruby/shared/options/OptionsCatalog.java b/src/shared/java/org/truffleruby/shared/options/OptionsCatalog.java index c1213f376775..b5c6775e6aae 100644 --- a/src/shared/java/org/truffleruby/shared/options/OptionsCatalog.java +++ b/src/shared/java/org/truffleruby/shared/options/OptionsCatalog.java @@ -85,6 +85,7 @@ public final class OptionsCatalog { public static final OptionKey WARN_TRUFFLE_REGEX_COMPILE_FALLBACK_KEY = new OptionKey<>(false); public static final OptionKey WARN_TRUFFLE_REGEX_MATCH_FALLBACK_KEY = new OptionKey<>(false); public static final OptionKey TRUFFLE_REGEX_IGNORE_ATOMIC_GROUPS_KEY = new OptionKey<>(false); + public static final OptionKey REUSE_PRECOMPILED_GEMS_KEY = new OptionKey<>(StringArrayOptionType.EMPTY_STRING_ARRAY, StringArrayOptionType.INSTANCE); public static final OptionKey ARGV_GLOBALS_KEY = new OptionKey<>(false); public static final OptionKey CHOMP_LOOP_KEY = new OptionKey<>(false); public static final OptionKey GETS_LOOP_KEY = new OptionKey<>(false); @@ -684,6 +685,14 @@ public final class OptionsCatalog { .usageSyntax("") .build(); + public static final OptionDescriptor REUSE_PRECOMPILED_GEMS = OptionDescriptor + .newBuilder(REUSE_PRECOMPILED_GEMS_KEY, "ruby.reuse-precompiled-gems") + .help("A list of gems we want to install precompiled (using the local platform) on TruffleRuby. Can only be used for gem extensions which do not depend on the Ruby C API.") + .category(OptionCategory.EXPERT) + .stability(OptionStability.EXPERIMENTAL) + .usageSyntax(",,...") + .build(); + public static final OptionDescriptor ARGV_GLOBALS = OptionDescriptor .newBuilder(ARGV_GLOBALS_KEY, "ruby.argv-globals") .help("Parse options in script argv into global variables (configured by the -s Ruby option)") @@ -1440,6 +1449,8 @@ public static OptionDescriptor fromName(String name) { return WARN_TRUFFLE_REGEX_MATCH_FALLBACK; case "ruby.truffle-regex-ignore-atomic-groups": return TRUFFLE_REGEX_IGNORE_ATOMIC_GROUPS; + case "ruby.reuse-precompiled-gems": + return REUSE_PRECOMPILED_GEMS; case "ruby.argv-globals": return ARGV_GLOBALS; case "ruby.chomp-loop": @@ -1668,6 +1679,7 @@ public static OptionDescriptor[] allDescriptors() { WARN_TRUFFLE_REGEX_COMPILE_FALLBACK, WARN_TRUFFLE_REGEX_MATCH_FALLBACK, TRUFFLE_REGEX_IGNORE_ATOMIC_GROUPS, + REUSE_PRECOMPILED_GEMS, ARGV_GLOBALS, CHOMP_LOOP, GETS_LOOP,