Skip to content

Commit 14e0cc5

Browse files
andrykonchineregon
authored andcommitted
[GR-45621] [GR-47996] [GR-45678] Follow-up on "Ruby 3.2.2 import" and implement performance warnings
PullRequest: truffleruby/3946
2 parents 66ca27b + 4b9a371 commit 14e0cc5

File tree

18 files changed

+77
-39
lines changed

18 files changed

+77
-39
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Compatibility:
3939
* Add `Enumerator#product` (#3039, @itarato).
4040
* Add `Module#const_added` (#3039, @itarato).
4141
* Show the pointer size information (if available) in `FFI::Pointer#inspect` (@nirvdrum).
42+
* Implement performance warnings (`Warning[:performance]`) like in CRuby 3.3 (@eregon).
4243

4344
Performance:
4445

spec/ruby/core/warning/element_reference_spec.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
describe "Warning.[]" do
44
ruby_version_is '2.7.2' do
55
it "returns default values for categories :deprecated and :experimental" do
6-
ruby_exe('p Warning[:deprecated]').chomp.should == "false"
7-
ruby_exe('p Warning[:experimental]').chomp.should == "true"
6+
ruby_exe('p [Warning[:deprecated], Warning[:experimental]]').chomp.should == "[false, true]"
7+
ruby_exe('p [Warning[:deprecated], Warning[:experimental]]', options: "-w").chomp.should == "[true, true]"
88
end
99
end
1010

spec/ruby/core/warning/element_set_spec.rb

+12
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@
1717
end
1818
end
1919

20+
ruby_version_is '3.3' do
21+
it "enables or disables performance warnings" do
22+
original = Warning[:performance]
23+
begin
24+
Warning[:performance] = !original
25+
Warning[:performance].should == !original
26+
ensure
27+
Warning[:performance] = original
28+
end
29+
end
30+
end
31+
2032
it "raises for unknown category" do
2133
-> { Warning[:noop] = false }.should raise_error(ArgumentError, /unknown category: noop/)
2234
end
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
slow:Warning.[] returns default values for categories :deprecated and :experimental
2+
slow:Warning.[] returns default values for :performance category

spec/truffleruby.next-specs

+2-32
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,5 @@
99
# Use spec/ruby/core/nil/nil_spec.rb as a dummy file to avoid being empty (what causes mspec to error)
1010
spec/ruby/core/nil/nil_spec.rb
1111

12-
spec/ruby/core/array/slice_spec.rb
13-
spec/ruby/core/array/element_reference_spec.rb
14-
15-
spec/ruby/core/hash/shift_spec.rb
16-
spec/ruby/core/range/size_spec.rb
17-
18-
spec/ruby/core/string/dedup_spec.rb
19-
20-
spec/ruby/core/string/bytesplice_spec.rb
21-
22-
spec/ruby/core/string/byteindex_spec.rb
23-
spec/ruby/core/string/byterindex_spec.rb
24-
25-
spec/ruby/core/queue/deq_spec.rb
26-
spec/ruby/core/queue/pop_spec.rb
27-
spec/ruby/core/queue/shift_spec.rb
28-
29-
spec/ruby/core/sizedqueue/deq_spec.rb
30-
spec/ruby/core/sizedqueue/pop_spec.rb
31-
spec/ruby/core/sizedqueue/shift_spec.rb
32-
spec/ruby/core/sizedqueue/append_spec.rb
33-
spec/ruby/core/sizedqueue/enq_spec.rb
34-
spec/ruby/core/sizedqueue/push_spec.rb
35-
36-
spec/ruby/core/module/const_added_spec.rb
37-
spec/ruby/core/module/refinements_spec.rb
38-
spec/ruby/core/module/undefined_instance_methods_spec.rb
39-
spec/ruby/core/refinement/refined_class_spec.rb
40-
spec/ruby/core/module/used_refinements_spec.rb
41-
42-
spec/ruby/core/thread/each_caller_location_spec.rb
43-
spec/ruby/core/enumerator/product_spec.rb
12+
spec/ruby/core/warning/element_reference_spec.rb
13+
spec/ruby/core/warning/element_set_spec.rb

src/launcher/java/org/truffleruby/launcher/CommandLineParser.java

+7
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,12 @@ private void processArgument() throws CommandLineException {
361361
case ":no-experimental":
362362
config.setOption(OptionsCatalog.WARN_EXPERIMENTAL, false);
363363
break;
364+
case ":performance":
365+
config.setOption(OptionsCatalog.WARN_PERFORMANCE, true);
366+
break;
367+
case ":no-performance":
368+
config.setOption(OptionsCatalog.WARN_PERFORMANCE, false);
369+
break;
364370
default:
365371
LOGGER.warning("unknown warning category: `" + temp.substring(1) + "'");
366372
break;
@@ -494,6 +500,7 @@ private void processArgument() throws CommandLineException {
494500
private void setAllWarningCategories(boolean value) {
495501
config.setOption(OptionsCatalog.WARN_DEPRECATED, value);
496502
config.setOption(OptionsCatalog.WARN_EXPERIMENTAL, value);
503+
// WARN_PERFORMANCE is excluded here, it is not set by -w/-W2 on CRuby
497504
}
498505

499506
private void enableDisableFeature(String name, boolean enable) {

src/launcher/java/org/truffleruby/launcher/RubyLauncher.java

+1
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ private static void printHelp(PrintStream out) {
437437
out.println("Warning categories:");
438438
out.println(" deprecated deprecated features");
439439
out.println(" experimental experimental features");
440+
out.println(" performance performance issues");
440441
}
441442

442443
// Same as above, but with "ruby -h"

src/main/java/org/truffleruby/RubyContext.java

+9
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ public final class RubyContext {
166166

167167
private final AssumedValue<Boolean> warningCategoryDeprecated;
168168
private final AssumedValue<Boolean> warningCategoryExperimental;
169+
private final AssumedValue<Boolean> warningCategoryPerformance;
169170

170171
private ImmutableRubyString mainScriptName;
171172

@@ -189,6 +190,7 @@ public RubyContext(RubyLanguage language, TruffleLanguage.Env env) {
189190

190191
warningCategoryDeprecated = new AssumedValue<>(options.WARN_DEPRECATED);
191192
warningCategoryExperimental = new AssumedValue<>(options.WARN_EXPERIMENTAL);
193+
warningCategoryPerformance = new AssumedValue<>(options.WARN_PERFORMANCE);
192194

193195
safepointManager = new SafepointManager(this);
194196
coreExceptions = new CoreExceptions(this, language);
@@ -305,6 +307,9 @@ protected boolean patch(Env newEnv) {
305307
if (newOptions.WARN_EXPERIMENTAL != oldOptions.WARN_EXPERIMENTAL) {
306308
warningCategoryExperimental.set(newOptions.WARN_EXPERIMENTAL);
307309
}
310+
if (newOptions.WARN_PERFORMANCE != oldOptions.WARN_PERFORMANCE) {
311+
warningCategoryPerformance.set(newOptions.WARN_PERFORMANCE);
312+
}
308313

309314
// Re-read the value of $TZ as it can be different in the new process
310315
GetTimeZoneNode.invalidateTZ();
@@ -758,6 +763,10 @@ public AssumedValue<Boolean> getWarningCategoryExperimental() {
758763
return warningCategoryExperimental;
759764
}
760765

766+
public AssumedValue<Boolean> getWarningCategoryPerformance() {
767+
return warningCategoryPerformance;
768+
}
769+
761770
public PrintStream getEnvOutStream() {
762771
return outStream;
763772
}

src/main/java/org/truffleruby/core/kernel/KernelNodes.java

+7
Original file line numberDiff line numberDiff line change
@@ -1851,6 +1851,11 @@ protected boolean getCategoryExperimental(RubySymbol category) {
18511851
return getContext().getWarningCategoryExperimental().get();
18521852
}
18531853

1854+
@Specialization(guards = "category == coreSymbols().PERFORMANCE")
1855+
protected boolean getCategoryPerformance(RubySymbol category) {
1856+
return getContext().getWarningCategoryPerformance().get();
1857+
}
1858+
18541859
}
18551860

18561861
@Primitive(name = "warning_set_category")
@@ -1864,6 +1869,8 @@ protected boolean setCategory(RubySymbol category, boolean newValue) {
18641869
existingValue = getContext().getWarningCategoryDeprecated();
18651870
} else if (category == coreSymbols().EXPERIMENTAL) {
18661871
existingValue = getContext().getWarningCategoryExperimental();
1872+
} else if (category == coreSymbols().PERFORMANCE) {
1873+
existingValue = getContext().getWarningCategoryPerformance();
18671874
} else {
18681875
throw CompilerDirectives.shouldNotReachHere("unexpected warning category");
18691876
}

src/main/java/org/truffleruby/core/symbol/CoreSymbols.java

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public final class CoreSymbols {
4040
public final RubySymbol ON_BLOCKING = createRubySymbol("on_blocking");
4141
public final RubySymbol DEPRECATED = createRubySymbol("deprecated");
4242
public final RubySymbol EXPERIMENTAL = createRubySymbol("experimental");
43+
public final RubySymbol PERFORMANCE = createRubySymbol("performance");
4344
public final RubySymbol BIG = createRubySymbol("big");
4445
public final RubySymbol LITTLE = createRubySymbol("little");
4546
public final RubySymbol NATIVE = createRubySymbol("native");

src/main/java/org/truffleruby/language/NotOptimizedWarningNode.java

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ protected void warnOnce(String message) throws Warned {
5757
return;
5858
}
5959

60+
// Only warn if Warning[:performance] is true
61+
if (!getContext().getWarningCategoryPerformance().get()) {
62+
return;
63+
}
64+
6065
log(message);
6166
throw new Warned();
6267
}

src/main/java/org/truffleruby/options/Options.java

+5
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ public final class Options {
131131
public final boolean WARN_DEPRECATED;
132132
/** --warn-experimental=true */
133133
public final boolean WARN_EXPERIMENTAL;
134+
/** --warn-performance=false */
135+
public final boolean WARN_PERFORMANCE;
134136
/** --use-truffle-regex=true */
135137
public final boolean USE_TRUFFLE_REGEX;
136138
/** --warn-truffle-regex-compile-fallback=false */
@@ -262,6 +264,7 @@ public Options(Env env, OptionValues options, LanguageOptions languageOptions) {
262264
CEXTS_LOG_WARNINGS = options.get(OptionsCatalog.CEXTS_LOG_WARNINGS_KEY);
263265
WARN_DEPRECATED = options.get(OptionsCatalog.WARN_DEPRECATED_KEY);
264266
WARN_EXPERIMENTAL = options.get(OptionsCatalog.WARN_EXPERIMENTAL_KEY);
267+
WARN_PERFORMANCE = options.get(OptionsCatalog.WARN_PERFORMANCE_KEY);
265268
USE_TRUFFLE_REGEX = options.get(OptionsCatalog.USE_TRUFFLE_REGEX_KEY);
266269
WARN_TRUFFLE_REGEX_COMPILE_FALLBACK = options.get(OptionsCatalog.WARN_TRUFFLE_REGEX_COMPILE_FALLBACK_KEY);
267270
WARN_TRUFFLE_REGEX_MATCH_FALLBACK = options.get(OptionsCatalog.WARN_TRUFFLE_REGEX_MATCH_FALLBACK_KEY);
@@ -410,6 +413,8 @@ public Object fromDescriptor(OptionDescriptor descriptor) {
410413
return WARN_DEPRECATED;
411414
case "ruby.warn-experimental":
412415
return WARN_EXPERIMENTAL;
416+
case "ruby.warn-performance":
417+
return WARN_PERFORMANCE;
413418
case "ruby.use-truffle-regex":
414419
return USE_TRUFFLE_REGEX;
415420
case "ruby.warn-truffle-regex-compile-fallback":

src/main/ruby/truffleruby/core/truffle/warning_operations.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
module Truffle
1212
module WarningOperations
1313
def self.check_category(category)
14-
return if category == :deprecated || category == :experimental
14+
return if category == :deprecated || category == :experimental || category == :performance
1515

1616
raise ArgumentError, "unknown category: #{category}"
1717
end

src/main/ruby/truffleruby/core/warning.rb

+4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ def self.[](category)
4242
Primitive.warning_get_category(:deprecated)
4343
when :experimental
4444
Primitive.warning_get_category(:experimental)
45+
when :performance
46+
Primitive.warning_get_category(:performance)
4547
else
4648
raise ArgumentError, "unknown category: #{category}"
4749
end
@@ -55,6 +57,8 @@ def self.[]=(category, value)
5557
Primitive.warning_set_category(:deprecated, Primitive.as_boolean(value))
5658
when :experimental
5759
Primitive.warning_set_category(:experimental, Primitive.as_boolean(value))
60+
when :performance
61+
Primitive.warning_set_category(:performance, Primitive.as_boolean(value))
5862
else
5963
raise ArgumentError, "unknown category: #{category}"
6064
end

src/options.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,9 @@ EXPERT:
142142
CEXTS_LOG_LOAD: [cexts-log-load, boolean, false, Log loading of cexts]
143143
CEXTS_LOG_WARNINGS: [cexts-log-warnings, boolean, false, Log cexts warnings]
144144

145-
WARN_DEPRECATED: [[warn-deprecated, -W], boolean, false, 'Sets deprecated Warning category']
146-
WARN_EXPERIMENTAL: [[warn-experimental, -W], boolean, true, 'Sets experimental Warning category']
145+
WARN_DEPRECATED: [[warn-deprecated, -W], boolean, false, 'Sets the deprecated Warning category']
146+
WARN_EXPERIMENTAL: [[warn-experimental, -W], boolean, true, 'Sets the experimental Warning category']
147+
WARN_PERFORMANCE: [[warn-performance, -W], boolean, false, 'Sets the performance Warning category']
147148

148149
# Controlling the regular expression engines
149150
USE_TRUFFLE_REGEX: [use-truffle-regex, boolean, true, 'Use the Truffle regular expression engine when possible and fallback to Joni otherwise']

src/shared/java/org/truffleruby/shared/options/OptionsCatalog.java

+14-2
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public final class OptionsCatalog {
8383
public static final OptionKey<Boolean> CEXTS_LOG_WARNINGS_KEY = new OptionKey<>(false);
8484
public static final OptionKey<Boolean> WARN_DEPRECATED_KEY = new OptionKey<>(false);
8585
public static final OptionKey<Boolean> WARN_EXPERIMENTAL_KEY = new OptionKey<>(true);
86+
public static final OptionKey<Boolean> WARN_PERFORMANCE_KEY = new OptionKey<>(false);
8687
public static final OptionKey<Boolean> USE_TRUFFLE_REGEX_KEY = new OptionKey<>(true);
8788
public static final OptionKey<Boolean> WARN_TRUFFLE_REGEX_COMPILE_FALLBACK_KEY = new OptionKey<>(false);
8889
public static final OptionKey<Boolean> WARN_TRUFFLE_REGEX_MATCH_FALLBACK_KEY = new OptionKey<>(false);
@@ -654,15 +655,23 @@ public final class OptionsCatalog {
654655

655656
public static final OptionDescriptor WARN_DEPRECATED = OptionDescriptor
656657
.newBuilder(WARN_DEPRECATED_KEY, "ruby.warn-deprecated")
657-
.help("Sets deprecated Warning category (configured by the -W Ruby option)")
658+
.help("Sets the deprecated Warning category (configured by the -W Ruby option)")
658659
.category(OptionCategory.EXPERT)
659660
.stability(OptionStability.EXPERIMENTAL)
660661
.usageSyntax("")
661662
.build();
662663

663664
public static final OptionDescriptor WARN_EXPERIMENTAL = OptionDescriptor
664665
.newBuilder(WARN_EXPERIMENTAL_KEY, "ruby.warn-experimental")
665-
.help("Sets experimental Warning category (configured by the -W Ruby option)")
666+
.help("Sets the experimental Warning category (configured by the -W Ruby option)")
667+
.category(OptionCategory.EXPERT)
668+
.stability(OptionStability.EXPERIMENTAL)
669+
.usageSyntax("")
670+
.build();
671+
672+
public static final OptionDescriptor WARN_PERFORMANCE = OptionDescriptor
673+
.newBuilder(WARN_PERFORMANCE_KEY, "ruby.warn-performance")
674+
.help("Sets the performance Warning category (configured by the -W Ruby option)")
666675
.category(OptionCategory.EXPERT)
667676
.stability(OptionStability.EXPERIMENTAL)
668677
.usageSyntax("")
@@ -1436,6 +1445,8 @@ public static OptionDescriptor fromName(String name) {
14361445
return WARN_DEPRECATED;
14371446
case "ruby.warn-experimental":
14381447
return WARN_EXPERIMENTAL;
1448+
case "ruby.warn-performance":
1449+
return WARN_PERFORMANCE;
14391450
case "ruby.use-truffle-regex":
14401451
return USE_TRUFFLE_REGEX;
14411452
case "ruby.warn-truffle-regex-compile-fallback":
@@ -1666,6 +1677,7 @@ public static OptionDescriptor[] allDescriptors() {
16661677
CEXTS_LOG_WARNINGS,
16671678
WARN_DEPRECATED,
16681679
WARN_EXPERIMENTAL,
1680+
WARN_PERFORMANCE,
16691681
USE_TRUFFLE_REGEX,
16701682
WARN_TRUFFLE_REGEX_COMPILE_FALLBACK,
16711683
WARN_TRUFFLE_REGEX_MATCH_FALLBACK,

test/mri/excludes/TestFiddle.rb

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
exclude :test_nil_true_etc, "NameError: uninitialized constant Fiddle::Qtrue"
22
exclude :test_dlopen_linker_script_group_linux, "NotImplementedError: NotImplementedError"
3+
exclude :test_dlopen_linker_script_input_linux, "NotImplementedError: NotImplementedError"

tool/generate-core-symbols.rb

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
public final RubySymbol ON_BLOCKING = createRubySymbol("on_blocking");
6060
public final RubySymbol DEPRECATED = createRubySymbol("deprecated");
6161
public final RubySymbol EXPERIMENTAL = createRubySymbol("experimental");
62+
public final RubySymbol PERFORMANCE = createRubySymbol("performance");
6263
public final RubySymbol BIG = createRubySymbol("big");
6364
public final RubySymbol LITTLE = createRubySymbol("little");
6465
public final RubySymbol NATIVE = createRubySymbol("native");

0 commit comments

Comments
 (0)