Skip to content

Commit be93227

Browse files
committed
Use an inlined node for the class of immutable value
* That way the coreLibrary is only used when needed and there is less duplication. * 874 -> 945 for org.truffleruby.language.objects.MetaClassNodeGen.execute
1 parent 7dde61f commit be93227

File tree

4 files changed

+122
-144
lines changed

4 files changed

+122
-144
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ public static boolean isPrimitive(Object value) {
9595
return value instanceof Boolean || value instanceof Integer || value instanceof Long || value instanceof Double;
9696
}
9797

98+
public static boolean isPrimitiveOrImmutable(Object value) {
99+
assert assertIsValidRubyValue(value);
100+
return isPrimitive(value) || value instanceof ImmutableRubyObject;
101+
}
102+
98103
@Idempotent
99104
public static boolean isPrimitiveClass(Class<?> clazz) {
100105
return clazz == Boolean.class || clazz == Integer.class || clazz == Long.class || clazz == Double.class;
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved. This
3+
* code is released under a tri EPL/GPL/LGPL license. You can use it,
4+
* redistribute it and/or modify it under the terms of the:
5+
*
6+
* Eclipse Public License version 2.0, or
7+
* GNU General Public License version 2, or
8+
* GNU Lesser General Public License version 2.1.
9+
*/
10+
package org.truffleruby.language.objects;
11+
12+
import com.oracle.truffle.api.dsl.GenerateCached;
13+
import com.oracle.truffle.api.dsl.GenerateInline;
14+
import com.oracle.truffle.api.nodes.Node;
15+
import org.truffleruby.core.CoreLibrary;
16+
import org.truffleruby.core.encoding.RubyEncoding;
17+
import org.truffleruby.core.klass.RubyClass;
18+
import org.truffleruby.core.numeric.RubyBignum;
19+
import org.truffleruby.core.range.RubyIntOrLongRange;
20+
import org.truffleruby.core.regexp.RubyRegexp;
21+
import org.truffleruby.core.string.ImmutableRubyString;
22+
import org.truffleruby.core.symbol.RubySymbol;
23+
import org.truffleruby.language.Nil;
24+
import org.truffleruby.language.NoImplicitCastsToLong;
25+
import org.truffleruby.language.RubyBaseNode;
26+
27+
import com.oracle.truffle.api.dsl.GenerateUncached;
28+
import com.oracle.truffle.api.dsl.Specialization;
29+
import com.oracle.truffle.api.dsl.TypeSystemReference;
30+
31+
@GenerateInline
32+
@GenerateCached(false)
33+
@GenerateUncached
34+
@TypeSystemReference(NoImplicitCastsToLong.class)
35+
public abstract class ImmutableClassNode extends RubyBaseNode {
36+
37+
public final RubyClass execute(Node node, Object value) {
38+
return execute(node, value, coreLibrary());
39+
}
40+
41+
protected abstract RubyClass execute(Node node, Object value, CoreLibrary coreLibrary);
42+
43+
// Cover all primitives, nil and symbols
44+
45+
@Specialization(guards = "value")
46+
protected RubyClass metaClassTrue(boolean value, CoreLibrary coreLibrary) {
47+
return coreLibrary.trueClass;
48+
}
49+
50+
@Specialization(guards = "!value")
51+
protected RubyClass metaClassFalse(boolean value, CoreLibrary coreLibrary) {
52+
return coreLibrary.falseClass;
53+
}
54+
55+
@Specialization
56+
protected RubyClass metaClassInt(int value, CoreLibrary coreLibrary) {
57+
return coreLibrary.integerClass;
58+
}
59+
60+
@Specialization
61+
protected RubyClass metaClassLong(long value, CoreLibrary coreLibrary) {
62+
return coreLibrary.integerClass;
63+
}
64+
65+
@Specialization
66+
protected RubyClass metaClassBignum(RubyBignum value, CoreLibrary coreLibrary) {
67+
return coreLibrary.integerClass;
68+
}
69+
70+
@Specialization
71+
protected RubyClass metaClassDouble(double value, CoreLibrary coreLibrary) {
72+
return coreLibrary.floatClass;
73+
}
74+
75+
@Specialization
76+
protected RubyClass metaClassNil(Nil value, CoreLibrary coreLibrary) {
77+
return coreLibrary.nilClass;
78+
}
79+
80+
@Specialization
81+
protected RubyClass metaClassSymbol(RubySymbol value, CoreLibrary coreLibrary) {
82+
return coreLibrary.symbolClass;
83+
}
84+
85+
@Specialization
86+
protected RubyClass metaClassEncoding(RubyEncoding value, CoreLibrary coreLibrary) {
87+
return coreLibrary.encodingClass;
88+
}
89+
90+
@Specialization
91+
protected RubyClass metaClassImmutableString(ImmutableRubyString value, CoreLibrary coreLibrary) {
92+
return coreLibrary.stringClass;
93+
}
94+
95+
@Specialization
96+
protected RubyClass metaClassRegexp(RubyRegexp value, CoreLibrary coreLibrary) {
97+
return coreLibrary.regexpClass;
98+
}
99+
100+
@Specialization
101+
protected RubyClass metaClassIntRange(RubyIntOrLongRange value, CoreLibrary coreLibrary) {
102+
return coreLibrary.rangeClass;
103+
}
104+
105+
}

src/main/java/org/truffleruby/language/objects/LogicalClassNode.java

Lines changed: 4 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,7 @@
1313
import com.oracle.truffle.api.dsl.Cached;
1414
import com.oracle.truffle.api.dsl.NeverDefault;
1515
import com.oracle.truffle.api.dsl.TypeSystemReference;
16-
import org.truffleruby.core.encoding.RubyEncoding;
1716
import org.truffleruby.core.klass.RubyClass;
18-
import org.truffleruby.core.numeric.RubyBignum;
19-
import org.truffleruby.core.range.RubyIntOrLongRange;
20-
import org.truffleruby.core.regexp.RubyRegexp;
21-
import org.truffleruby.core.symbol.RubySymbol;
22-
import org.truffleruby.core.string.ImmutableRubyString;
23-
import org.truffleruby.language.Nil;
2417
import org.truffleruby.language.NoImplicitCastsToLong;
2518
import org.truffleruby.language.RubyBaseNode;
2619
import org.truffleruby.language.RubyDynamicObject;
@@ -43,64 +36,10 @@ public static LogicalClassNode getUncached() {
4336

4437
public abstract RubyClass execute(Object value);
4538

46-
@Specialization(guards = "value")
47-
protected RubyClass logicalClassTrue(boolean value) {
48-
return coreLibrary().trueClass;
49-
}
50-
51-
@Specialization(guards = "!value")
52-
protected RubyClass logicalClassFalse(boolean value) {
53-
return coreLibrary().falseClass;
54-
}
55-
56-
@Specialization
57-
protected RubyClass logicalClassInt(int value) {
58-
return coreLibrary().integerClass;
59-
}
60-
61-
@Specialization
62-
protected RubyClass logicalClassLong(long value) {
63-
return coreLibrary().integerClass;
64-
}
65-
66-
@Specialization
67-
protected RubyClass logicalClassRubyBignum(RubyBignum value) {
68-
return coreLibrary().integerClass;
69-
}
70-
71-
@Specialization
72-
protected RubyClass logicalClassDouble(double value) {
73-
return coreLibrary().floatClass;
74-
}
75-
76-
@Specialization
77-
protected RubyClass logicalClassNil(Nil value) {
78-
return coreLibrary().nilClass;
79-
}
80-
81-
@Specialization
82-
protected RubyClass logicalClassSymbol(RubySymbol value) {
83-
return coreLibrary().symbolClass;
84-
}
85-
86-
@Specialization
87-
protected RubyClass logicalClassEncoding(RubyEncoding value) {
88-
return coreLibrary().encodingClass;
89-
}
90-
91-
@Specialization
92-
protected RubyClass logicalImmutableString(ImmutableRubyString value) {
93-
return coreLibrary().stringClass;
94-
}
95-
96-
@Specialization
97-
protected RubyClass logicalClassRegexp(RubyRegexp value) {
98-
return coreLibrary().regexpClass;
99-
}
100-
101-
@Specialization
102-
protected RubyClass logicalClassIntRange(RubyIntOrLongRange value) {
103-
return coreLibrary().rangeClass;
39+
@Specialization(guards = "isPrimitiveOrImmutable(value)")
40+
protected RubyClass logicalClassImmutable(Object value,
41+
@Cached ImmutableClassNode immutableClassNode) {
42+
return immutableClassNode.execute(this, value);
10443
}
10544

10645
@Specialization

src/main/java/org/truffleruby/language/objects/MetaClassNode.java

Lines changed: 8 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,7 @@
1111

1212
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
1313
import com.oracle.truffle.api.dsl.NeverDefault;
14-
import com.oracle.truffle.api.dsl.TypeSystemReference;
15-
import org.truffleruby.core.CoreLibrary;
16-
import org.truffleruby.core.encoding.RubyEncoding;
1714
import org.truffleruby.core.klass.RubyClass;
18-
import org.truffleruby.core.numeric.RubyBignum;
19-
import org.truffleruby.core.range.RubyIntOrLongRange;
20-
import org.truffleruby.core.regexp.RubyRegexp;
21-
import org.truffleruby.core.symbol.RubySymbol;
22-
import org.truffleruby.core.string.ImmutableRubyString;
23-
import org.truffleruby.language.Nil;
24-
import org.truffleruby.language.NoImplicitCastsToLong;
2515
import org.truffleruby.language.RubyBaseNode;
2616
import org.truffleruby.language.RubyDynamicObject;
2717

@@ -30,7 +20,6 @@
3020
import com.oracle.truffle.api.dsl.Specialization;
3121

3222
@GenerateUncached
33-
@TypeSystemReference(NoImplicitCastsToLong.class)
3423
public abstract class MetaClassNode extends RubyBaseNode {
3524

3625
@NeverDefault
@@ -42,94 +31,34 @@ public static MetaClassNode getUncached() {
4231
return MetaClassNodeGen.getUncached();
4332
}
4433

45-
public final RubyClass execute(Object value) {
46-
return execute(value, coreLibrary());
47-
}
48-
49-
protected abstract RubyClass execute(Object value, CoreLibrary coreLibrary);
50-
51-
// Cover all primitives, nil and symbols
52-
53-
@Specialization(guards = "value")
54-
protected RubyClass metaClassTrue(boolean value, CoreLibrary coreLibrary) {
55-
return coreLibrary.trueClass;
56-
}
57-
58-
@Specialization(guards = "!value")
59-
protected RubyClass metaClassFalse(boolean value, CoreLibrary coreLibrary) {
60-
return coreLibrary.falseClass;
61-
}
62-
63-
@Specialization
64-
protected RubyClass metaClassInt(int value, CoreLibrary coreLibrary) {
65-
return coreLibrary.integerClass;
66-
}
67-
68-
@Specialization
69-
protected RubyClass metaClassLong(long value, CoreLibrary coreLibrary) {
70-
return coreLibrary.integerClass;
71-
}
72-
73-
@Specialization
74-
protected RubyClass metaClassBignum(RubyBignum value, CoreLibrary coreLibrary) {
75-
return coreLibrary.integerClass;
76-
}
77-
78-
@Specialization
79-
protected RubyClass metaClassDouble(double value, CoreLibrary coreLibrary) {
80-
return coreLibrary.floatClass;
81-
}
82-
83-
@Specialization
84-
protected RubyClass metaClassNil(Nil value, CoreLibrary coreLibrary) {
85-
return coreLibrary.nilClass;
86-
}
87-
88-
@Specialization
89-
protected RubyClass metaClassSymbol(RubySymbol value, CoreLibrary coreLibrary) {
90-
return coreLibrary.symbolClass;
91-
}
92-
93-
@Specialization
94-
protected RubyClass metaClassEncoding(RubyEncoding value, CoreLibrary coreLibrary) {
95-
return coreLibrary.encodingClass;
96-
}
97-
98-
@Specialization
99-
protected RubyClass metaClassImmutableString(ImmutableRubyString value, CoreLibrary coreLibrary) {
100-
return coreLibrary.stringClass;
101-
}
102-
103-
@Specialization
104-
protected RubyClass metaClassRegexp(RubyRegexp value, CoreLibrary coreLibrary) {
105-
return coreLibrary.regexpClass;
106-
}
34+
public abstract RubyClass execute(Object value);
10735

108-
@Specialization
109-
protected RubyClass metaClassIntRange(RubyIntOrLongRange value, CoreLibrary coreLibrary) {
110-
return coreLibrary.rangeClass;
36+
@Specialization(guards = "isPrimitiveOrImmutable(value)")
37+
protected RubyClass metaClassImmutable(Object value,
38+
@Cached ImmutableClassNode immutableClassNode) {
39+
return immutableClassNode.execute(this, value);
11140
}
11241

11342
// Cover all RubyDynamicObject cases with cached and uncached
11443

11544
@Specialization(
11645
guards = { "object == cachedObject", "metaClass.isSingleton" },
11746
limit = "getIdentityCacheContextLimit()")
118-
protected RubyClass singletonClassCached(RubyDynamicObject object, CoreLibrary coreLibrary,
47+
protected RubyClass singletonClassCached(RubyDynamicObject object,
11948
@Cached("object") RubyDynamicObject cachedObject,
12049
@Cached("object.getMetaClass()") RubyClass metaClass) {
12150
return metaClass;
12251
}
12352

12453
@Specialization(replaces = "singletonClassCached")
125-
protected RubyClass metaClassObject(RubyDynamicObject object, CoreLibrary coreLibrary) {
54+
protected RubyClass metaClassObject(RubyDynamicObject object) {
12655
return object.getMetaClass();
12756
}
12857

12958
// Foreign object
13059
@InliningCutoff
13160
@Specialization(guards = "isForeignObject(object)")
132-
protected RubyClass metaClassForeign(Object object, CoreLibrary coreLibrary,
61+
protected RubyClass metaClassForeign(Object object,
13362
@Cached ForeignClassNode foreignClassNode) {
13463
return foreignClassNode.execute(object);
13564
}

0 commit comments

Comments
 (0)