Skip to content

Commit 2e31939

Browse files
committed
cleaner way to make compact hashes the default
1 parent cf75526 commit 2e31939

File tree

5 files changed

+38
-27
lines changed

5 files changed

+38
-27
lines changed

src/main/java/org/truffleruby/core/hash/HashLiteralNode.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,18 @@ protected HashLiteralNode(RubyNode[] keyValues) {
3030
this.keyValues = keyValues;
3131
}
3232

33-
public static final class BigHashConfiguredStrategy extends RubyBaseNode {
34-
private BigHashConfiguredStrategy() {
35-
isBuckets = getContext().getOptions().BIG_HASH_STRATEGY;
33+
// This singleton serves no other purpose than being able to call .getContext() (an instance method) from
34+
static final class CreateBigHashLiteralNode extends RubyBaseNode {
35+
private CreateBigHashLiteralNode() {
3636
}
3737

38-
// dummy instance, so we can call getContext instance method, never used
39-
private static final BigHashConfiguredStrategy bh = new BigHashConfiguredStrategy();
40-
public static boolean isBuckets;
38+
private static final CreateBigHashLiteralNode INSTANCE = new CreateBigHashLiteralNode();
39+
40+
private HashLiteralNode execute(RubyNode[] keyValues) {
41+
return getContext().getOptions().BIG_HASH_STRATEGY_IS_BUCKETS
42+
? new BucketsHashStore.GenericHashLiteralNode(keyValues)
43+
: new CompactHashStore.CompactHashLiteralNode(keyValues);
44+
}
4145
}
4246

4347
public static HashLiteralNode create(RubyNode[] keyValues) {
@@ -46,9 +50,7 @@ public static HashLiteralNode create(RubyNode[] keyValues) {
4650
} else if (keyValues.length <= PackedHashStoreLibrary.MAX_ENTRIES * 2) {
4751
return PackedHashStoreLibraryFactory.SmallHashLiteralNodeGen.create(keyValues);
4852
} else {
49-
return BigHashConfiguredStrategy.isBuckets
50-
? new BucketsHashStore.GenericHashLiteralNode(keyValues)
51-
: new CompactHashStore.CompactHashLiteralNode(keyValues);
53+
return CreateBigHashLiteralNode.INSTANCE.execute(keyValues);
5254
}
5355
}
5456

src/main/java/org/truffleruby/core/hash/library/PackedHashStoreLibrary.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.oracle.truffle.api.dsl.Cached;
4040
import com.oracle.truffle.api.dsl.Cached.Exclusive;
4141
import com.oracle.truffle.api.dsl.Cached.Shared;
42+
import com.oracle.truffle.api.dsl.GenerateInline;
4243
import com.oracle.truffle.api.dsl.GenerateUncached;
4344
import com.oracle.truffle.api.dsl.ImportStatic;
4445
import com.oracle.truffle.api.dsl.Specialization;
@@ -208,6 +209,7 @@ static boolean set(Object[] store, RubyHash hash, Object key, Object value, bool
208209
@Cached @Shared CompareHashKeysNode compareHashKeys,
209210
@CachedLibrary(limit = "hashStrategyLimit()") HashStoreLibrary hashes,
210211
@Cached InlinedConditionProfile withinCapacity,
212+
@Cached(inline = true) PromoteToBigHashNode promoteToBigHash,
211213
@Bind("this") Node node) {
212214

213215
assert verify(store, hash);
@@ -235,19 +237,11 @@ static boolean set(Object[] store, RubyHash hash, Object key, Object value, bool
235237
return true;
236238
}
237239

238-
promoteToBigHash(store, hash, size);
240+
promoteToBigHash.execute(node, store, hash, size);
239241

240242
hashes.set(hash.store, hash, key2, value, byIdentity);
241243
return true;
242244
}
243-
244-
private static void promoteToBigHash(Object[] store, RubyHash hash, int size) {
245-
if (HashLiteralNode.BigHashConfiguredStrategy.isBuckets) {
246-
promoteToBuckets(hash, store, size);
247-
} else {
248-
promoteToCompact(hash, store, size);
249-
}
250-
}
251245
}
252246

253247
@ExportMessage
@@ -416,6 +410,21 @@ static boolean verify(Object[] store, RubyHash hash) {
416410
// endregion
417411
// region Nodes
418412

413+
@GenerateUncached
414+
@GenerateInline
415+
abstract static class PromoteToBigHashNode extends RubyBaseNode {
416+
public abstract void execute(Node node, Object[] store, RubyHash hash, int size);
417+
418+
@Specialization
419+
protected void promoteToBigHash(Object[] store, RubyHash hash, int size) {
420+
if (getContext().getOptions().BIG_HASH_STRATEGY_IS_BUCKETS) {
421+
promoteToBuckets(hash, store, size);
422+
} else {
423+
promoteToCompact(hash, store, size);
424+
}
425+
}
426+
}
427+
419428
@GenerateUncached
420429
@ImportStatic(HashGuards.class)
421430
public abstract static class LookupPackedEntryNode extends RubyBaseNode {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public final class Options {
9494
/** --backtraces-interleave-java=false */
9595
public final boolean BACKTRACES_INTERLEAVE_JAVA;
9696
/** --buckets-big-hash=false */
97-
public final boolean BIG_HASH_STRATEGY;
97+
public final boolean BIG_HASH_STRATEGY_IS_BUCKETS;
9898
/** --backtraces-on-interrupt=false */
9999
public final boolean BACKTRACE_ON_INTERRUPT;
100100
/** --backtraces-sigalrm=!EMBEDDED */
@@ -247,7 +247,7 @@ public Options(Env env, OptionValues options, LanguageOptions languageOptions) {
247247
EXCEPTIONS_WARN_STACKOVERFLOW = options.get(OptionsCatalog.EXCEPTIONS_WARN_STACKOVERFLOW_KEY);
248248
EXCEPTIONS_WARN_OUT_OF_MEMORY = options.get(OptionsCatalog.EXCEPTIONS_WARN_OUT_OF_MEMORY_KEY);
249249
BACKTRACES_INTERLEAVE_JAVA = options.get(OptionsCatalog.BACKTRACES_INTERLEAVE_JAVA_KEY);
250-
BIG_HASH_STRATEGY = options.get(OptionsCatalog.BIG_HASH_STRATEGY_KEY);
250+
BIG_HASH_STRATEGY_IS_BUCKETS = options.get(OptionsCatalog.BIG_HASH_STRATEGY_IS_BUCKETS_KEY);
251251
BACKTRACE_ON_INTERRUPT = options.get(OptionsCatalog.BACKTRACE_ON_INTERRUPT_KEY);
252252
BACKTRACE_ON_SIGALRM = options.hasBeenSet(OptionsCatalog.BACKTRACE_ON_SIGALRM_KEY) ? options.get(OptionsCatalog.BACKTRACE_ON_SIGALRM_KEY) : !EMBEDDED;
253253
BACKTRACE_ON_RAISE = options.get(OptionsCatalog.BACKTRACE_ON_RAISE_KEY);
@@ -379,7 +379,7 @@ public Object fromDescriptor(OptionDescriptor descriptor) {
379379
case "ruby.backtraces-interleave-java":
380380
return BACKTRACES_INTERLEAVE_JAVA;
381381
case "ruby.buckets-big-hash":
382-
return BIG_HASH_STRATEGY;
382+
return BIG_HASH_STRATEGY_IS_BUCKETS;
383383
case "ruby.backtraces-on-interrupt":
384384
return BACKTRACE_ON_INTERRUPT;
385385
case "ruby.backtraces-sigalrm":

src/options.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ EXPERT:
118118
BACKTRACES_OMIT_UNUSED: [backtraces-omit-unused, boolean, true, Omit backtraces that should be unused as they have pure rescue expressions]
119119

120120
# Big Hash Strategy
121-
BIG_HASH_STRATEGY: [buckets-big-hash, boolean, false, 'Whether to use chaining-style bukcets hash store for hash tables exceeding the small hash limit']
121+
BIG_HASH_STRATEGY_IS_BUCKETS: [buckets-big-hash, boolean, false, 'Whether to use chaining-style bukcets hash store for hash tables exceeding the small hash limit']
122122

123123
# Print backtraces at key events
124124
BACKTRACE_ON_INTERRUPT: [backtraces-on-interrupt, boolean, false, Show the backtraces of all Threads on Ctrl+C]

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public final class OptionsCatalog {
6464
public static final OptionKey<Boolean> EXCEPTIONS_WARN_OUT_OF_MEMORY_KEY = new OptionKey<>(true);
6565
public static final OptionKey<Boolean> BACKTRACES_INTERLEAVE_JAVA_KEY = new OptionKey<>(false);
6666
public static final OptionKey<Boolean> BACKTRACES_OMIT_UNUSED_KEY = new OptionKey<>(true);
67-
public static final OptionKey<Boolean> BIG_HASH_STRATEGY_KEY = new OptionKey<>(false);
67+
public static final OptionKey<Boolean> BIG_HASH_STRATEGY_IS_BUCKETS_KEY = new OptionKey<>(false);
6868
public static final OptionKey<Boolean> BACKTRACE_ON_INTERRUPT_KEY = new OptionKey<>(false);
6969
public static final OptionKey<Boolean> BACKTRACE_ON_SIGALRM_KEY = new OptionKey<>(!EMBEDDED_KEY.getDefaultValue());
7070
public static final OptionKey<Boolean> BACKTRACE_ON_RAISE_KEY = new OptionKey<>(false);
@@ -518,8 +518,8 @@ public final class OptionsCatalog {
518518
.usageSyntax("")
519519
.build();
520520

521-
public static final OptionDescriptor BIG_HASH_STRATEGY = OptionDescriptor
522-
.newBuilder(BIG_HASH_STRATEGY_KEY, "ruby.buckets-big-hash")
521+
public static final OptionDescriptor BIG_HASH_STRATEGY_IS_BUCKETS = OptionDescriptor
522+
.newBuilder(BIG_HASH_STRATEGY_IS_BUCKETS_KEY, "ruby.buckets-big-hash")
523523
.help("Whether to use chaining-style bukcets hash store for hash tables exceeding the small hash limit")
524524
.category(OptionCategory.EXPERT)
525525
.stability(OptionStability.EXPERIMENTAL)
@@ -1417,7 +1417,7 @@ public static OptionDescriptor fromName(String name) {
14171417
case "ruby.backtraces-omit-unused":
14181418
return BACKTRACES_OMIT_UNUSED;
14191419
case "ruby.buckets-big-hash":
1420-
return BIG_HASH_STRATEGY;
1420+
return BIG_HASH_STRATEGY_IS_BUCKETS;
14211421
case "ruby.backtraces-on-interrupt":
14221422
return BACKTRACE_ON_INTERRUPT;
14231423
case "ruby.backtraces-sigalrm":
@@ -1669,7 +1669,7 @@ public static OptionDescriptor[] allDescriptors() {
16691669
EXCEPTIONS_WARN_OUT_OF_MEMORY,
16701670
BACKTRACES_INTERLEAVE_JAVA,
16711671
BACKTRACES_OMIT_UNUSED,
1672-
BIG_HASH_STRATEGY,
1672+
BIG_HASH_STRATEGY_IS_BUCKETS,
16731673
BACKTRACE_ON_INTERRUPT,
16741674
BACKTRACE_ON_SIGALRM,
16751675
BACKTRACE_ON_RAISE,

0 commit comments

Comments
 (0)