Skip to content

Commit 4c5e1fe

Browse files
committed
ToLongNode converted to DSL inlinable node
1 parent 222dcf3 commit 4c5e1fe

File tree

7 files changed

+74
-88
lines changed

7 files changed

+74
-88
lines changed

src/main/java/org/truffleruby/core/array/ArrayNodes.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,11 +246,12 @@ protected Object at(RubyArray array, long index) {
246246
}
247247

248248
@Specialization(guards = "!isImplicitLong(index)")
249-
protected Object at(RubyArray array, Object index,
249+
protected static Object at(RubyArray array, Object index,
250250
@Cached ToLongNode toLongNode,
251251
@Cached FixnumLowerNode lowerNode,
252-
@Cached AtNode atNode) {
253-
return atNode.executeAt(array, lowerNode.executeLower(toLongNode.execute(index)));
252+
@Cached AtNode atNode,
253+
@Bind("this") Node node) {
254+
return atNode.executeAt(array, lowerNode.executeLower(toLongNode.execute(node, index)));
254255
}
255256
}
256257

src/main/java/org/truffleruby/core/cast/DurationToNanoSecondsNode.java

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,23 @@
99
*/
1010
package org.truffleruby.core.cast;
1111

12+
import com.oracle.truffle.api.dsl.Bind;
1213
import com.oracle.truffle.api.dsl.Cached;
14+
import com.oracle.truffle.api.dsl.Cached.Shared;
1315
import com.oracle.truffle.api.dsl.Fallback;
16+
import com.oracle.truffle.api.nodes.Node;
17+
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
1418
import org.truffleruby.language.RubyBaseNode;
1519
import org.truffleruby.language.NotProvided;
1620
import org.truffleruby.language.control.RaiseException;
1721

1822
import com.oracle.truffle.api.dsl.Specialization;
19-
import com.oracle.truffle.api.profiles.ConditionProfile;
2023
import org.truffleruby.language.dispatch.DispatchNode;
2124

2225
import java.util.concurrent.TimeUnit;
2326

2427
public abstract class DurationToNanoSecondsNode extends RubyBaseNode {
2528

26-
private final ConditionProfile durationLessThanZeroProfile = ConditionProfile.create();
27-
2829
public abstract long execute(Object duration);
2930

3031
@Specialization
@@ -33,29 +34,33 @@ protected long noDuration(NotProvided duration) {
3334
}
3435

3536
@Specialization
36-
protected long duration(long duration) {
37-
return validate(TimeUnit.SECONDS.toNanos(duration));
37+
protected long duration(long duration,
38+
@Cached @Shared InlinedConditionProfile durationLessThanZeroProfile) {
39+
return validate(this, TimeUnit.SECONDS.toNanos(duration), durationLessThanZeroProfile);
3840
}
3941

4042
@Specialization
41-
protected long duration(double duration) {
42-
return validate((long) (duration * 1e9));
43+
protected long duration(double duration,
44+
@Cached @Shared InlinedConditionProfile durationLessThanZeroProfile) {
45+
return validate(this, (long) (duration * 1e9), durationLessThanZeroProfile);
4346
}
4447

4548
@Fallback
46-
protected long duration(Object duration,
49+
protected static long duration(Object duration,
4750
@Cached DispatchNode durationToNanoSeconds,
48-
@Cached ToLongNode toLongNode) {
51+
@Cached @Shared InlinedConditionProfile durationLessThanZeroProfile,
52+
@Cached ToLongNode toLongNode,
53+
@Bind("this") Node node) {
4954
final Object nanoseconds = durationToNanoSeconds.call(
50-
coreLibrary().truffleKernelOperationsModule,
55+
coreLibrary(node).truffleKernelOperationsModule,
5156
"convert_duration_to_nanoseconds",
5257
duration);
53-
return validate(toLongNode.execute(nanoseconds));
58+
return validate(node, toLongNode.execute(node, nanoseconds), durationLessThanZeroProfile);
5459
}
5560

56-
private long validate(long durationInNanos) {
57-
if (durationLessThanZeroProfile.profile(durationInNanos < 0)) {
58-
throw new RaiseException(getContext(), coreExceptions().argumentErrorTimeIntervalPositive(this));
61+
private static long validate(Node node, long durationInNanos, InlinedConditionProfile durationLessThanZeroProfile) {
62+
if (durationLessThanZeroProfile.profile(node, durationInNanos < 0)) {
63+
throw new RaiseException(getContext(node), coreExceptions(node).argumentErrorTimeIntervalPositive(node));
5964
}
6065
return durationInNanos;
6166
}

src/main/java/org/truffleruby/core/cast/ToLongNode.java

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,89 +11,77 @@
1111

1212
import com.oracle.truffle.api.dsl.Cached;
1313
import com.oracle.truffle.api.dsl.Fallback;
14+
import com.oracle.truffle.api.dsl.GenerateInline;
1415
import com.oracle.truffle.api.dsl.GenerateUncached;
15-
import com.oracle.truffle.api.dsl.NeverDefault;
16-
import com.oracle.truffle.api.dsl.NodeChild;
1716
import com.oracle.truffle.api.dsl.Specialization;
17+
import com.oracle.truffle.api.nodes.Node;
1818
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
1919
import org.truffleruby.core.numeric.RubyBignum;
2020
import org.truffleruby.language.Nil;
21-
import org.truffleruby.language.RubyBaseNodeWithExecute;
21+
import org.truffleruby.language.RubyBaseNode;
2222
import org.truffleruby.language.control.RaiseException;
2323
import org.truffleruby.language.dispatch.DispatchNode;
2424
import org.truffleruby.utils.Utils;
2525

2626
/** See {@link ToIntNode} for a comparison of different integer conversion nodes. */
2727
@GenerateUncached
28-
@NodeChild(value = "childNode", type = RubyBaseNodeWithExecute.class)
29-
public abstract class ToLongNode extends RubyBaseNodeWithExecute {
28+
@GenerateInline(inlineByDefault = true)
29+
public abstract class ToLongNode extends RubyBaseNode {
3030

31-
@NeverDefault
32-
public static ToLongNode create() {
33-
return ToLongNodeGen.create(null);
34-
}
31+
public abstract long execute(Node node, Object object);
3532

36-
public static ToLongNode create(RubyBaseNodeWithExecute child) {
37-
return ToLongNodeGen.create(child);
33+
public final long executeCached(Object object) {
34+
return execute(this, object);
3835
}
3936

40-
public abstract long execute(Object object);
41-
42-
abstract RubyBaseNodeWithExecute getChildNode();
43-
4437
@Specialization
45-
protected long coerceInt(int value) {
38+
protected static long coerceInt(int value) {
4639
return value;
4740
}
4841

4942
@Specialization
50-
protected long coerceLong(long value) {
43+
protected static long coerceLong(long value) {
5144
return value;
5245
}
5346

5447
@Specialization
55-
protected long coerceRubyBignum(RubyBignum value) {
48+
protected static long coerceRubyBignum(Node node, RubyBignum value) {
5649
throw new RaiseException(
57-
getContext(),
58-
coreExceptions().rangeError("bignum too big to convert into `long'", this));
50+
getContext(node),
51+
coreExceptions(node).rangeError("bignum too big to convert into `long'", node));
5952
}
6053

6154
@Specialization
62-
protected long coerceDouble(double value,
55+
protected static long coerceDouble(Node node, double value,
6356
@Cached InlinedBranchProfile errorProfile) {
6457
// emulate MRI logic
6558
// We check for `value < MAX_VALUE` because casting Long.MAX_VALUE to double yields a double value of 2^63 which is >
6659
// Long.MAX_VALUE.
6760
if (Long.MIN_VALUE <= value && value < Long.MAX_VALUE) {
6861
return (long) value;
6962
} else {
70-
errorProfile.enter(this);
63+
errorProfile.enter(node);
7164
throw new RaiseException(
72-
getContext(),
73-
coreExceptions().rangeError(Utils.concat("float ", value, " out of range of integer"), this));
65+
getContext(node),
66+
coreExceptions(node).rangeError(Utils.concat("float ", value, " out of range of integer"), node));
7467
}
7568
}
7669

7770
@Specialization
78-
protected long coerceNil(Nil nil) {
71+
protected static long coerceNil(Node node, Nil nil) {
7972
// MRI hardcodes this specific error message, which is slightly different from the one we would get in the
8073
// catch-all case.
8174
throw new RaiseException(
82-
getContext(),
83-
coreExceptions().typeError("no implicit conversion from nil to integer", this));
75+
getContext(node),
76+
coreExceptions(node).typeError("no implicit conversion from nil to integer", node));
8477
}
8578

8679
@Fallback
87-
protected long coerceObject(Object object,
88-
@Cached DispatchNode toIntNode,
89-
@Cached ToLongNode fitNode) {
80+
protected static long coerceObject(Node node, Object object,
81+
@Cached(inline = false) DispatchNode toIntNode,
82+
@Cached(inline = false) ToLongNode fitNode) {
9083
final Object coerced = toIntNode
91-
.call(coreLibrary().truffleTypeModule, "rb_to_int_fallback", object);
92-
return fitNode.execute(coerced);
93-
}
94-
95-
@Override
96-
public RubyBaseNodeWithExecute cloneUninitialized() {
97-
return create(getChildNode().cloneUninitialized());
84+
.call(coreLibrary(node).truffleTypeModule, "rb_to_int_fallback", object);
85+
return fitNode.executeCached(coerced);
9886
}
9987
}

src/main/java/org/truffleruby/core/exception/CoreExceptions.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ public RubyException argumentErrorTooFewArguments(Node currentNode) {
139139
null);
140140
}
141141

142-
public RubyException argumentErrorTimeIntervalPositive(RubyBaseNode currentNode) {
143-
return argumentError(coreStrings().TIME_INTERVAL_MUST_BE_POS.createInstance(currentNode.getContext()),
142+
public RubyException argumentErrorTimeIntervalPositive(Node currentNode) {
143+
return argumentError(coreStrings().TIME_INTERVAL_MUST_BE_POS.createInstance(RubyContext.get(currentNode)),
144144
currentNode, null);
145145
}
146146

src/main/java/org/truffleruby/core/string/StringNodes.java

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@
127127
import org.truffleruby.core.format.unpack.UnpackCompiler;
128128
import org.truffleruby.core.kernel.KernelNodes;
129129
import org.truffleruby.core.klass.RubyClass;
130-
import org.truffleruby.core.numeric.FixnumLowerNode;
131130
import org.truffleruby.core.numeric.FixnumOrBignumNode;
132131
import org.truffleruby.core.proc.RubyProc;
133132
import org.truffleruby.core.range.RangeNodes;
@@ -163,7 +162,6 @@
163162
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
164163
import com.oracle.truffle.api.RootCallTarget;
165164
import com.oracle.truffle.api.dsl.Cached;
166-
import com.oracle.truffle.api.dsl.CreateCast;
167165
import com.oracle.truffle.api.dsl.Fallback;
168166
import com.oracle.truffle.api.dsl.ImportStatic;
169167
import com.oracle.truffle.api.dsl.NodeChild;
@@ -237,12 +235,12 @@ protected RubyString add(Object string, Object other,
237235
@ImportStatic(StringGuards.class)
238236
public abstract static class MulNode extends CoreMethodNode {
239237

240-
@CreateCast("times")
241-
protected RubyBaseNodeWithExecute coerceToInteger(RubyBaseNodeWithExecute times) {
242-
// Not ToIntNode, because this works with empty strings, and must throw a different error
243-
// for long values that don't fit in an int.
244-
return FixnumLowerNode.create(ToLongNode.create(times));
245-
}
238+
// @CreateCast("times")
239+
// protected RubyBaseNodeWithExecute coerceToInteger(RubyBaseNodeWithExecute times) {
240+
// // Not ToIntNode, because this works with empty strings, and must throw a different error
241+
// // for long values that don't fit in an int.
242+
// return FixnumLowerNode.create(ToLongNode.create(times));
243+
// }
246244

247245
@Specialization(guards = "times == 0")
248246
protected RubyString multiplyZero(Object string, int times,
@@ -547,8 +545,9 @@ protected Object getIndex(Object string, long index, NotProvided length) {
547545
"!isRubyRegexp(index)",
548546
"isNotRubyString(index)" })
549547
protected Object getIndex(Object string, Object index, NotProvided length,
548+
@Cached @Shared ToLongNode toLongNode,
550549
@Cached @Shared RubyStringLibrary strings) {
551-
long indexLong = toLong(index);
550+
long indexLong = toLongNode.execute(this, index);
552551
int indexInt = (int) indexLong;
553552
return indexInt != indexLong
554553
? outOfBoundsNil()
@@ -577,8 +576,9 @@ protected Object slice(Object string, long start, long length) {
577576
}
578577

579578
@Specialization(guards = "wasProvided(length)")
580-
protected Object slice(Object string, long start, Object length) {
581-
return slice(string, start, toLong(length));
579+
protected Object slice(Object string, long start, Object length,
580+
@Cached @Shared ToLongNode toLongNode) {
581+
return slice(string, start, toLongNode.execute(this, length));
582582
}
583583

584584
@Specialization(
@@ -587,8 +587,9 @@ protected Object slice(Object string, long start, Object length) {
587587
"!isRubyRegexp(start)",
588588
"isNotRubyString(start)",
589589
"wasProvided(length)" })
590-
protected Object slice(Object string, Object start, Object length) {
591-
return slice(string, toLong(start), toLong(length));
590+
protected Object slice(Object string, Object start, Object length,
591+
@Cached @Shared ToLongNode toLongNode) {
592+
return slice(string, toLongNode.execute(this, start), toLongNode.execute(this, length));
592593
}
593594

594595
// endregion
@@ -688,16 +689,6 @@ private Object substring(Object string, int start, int length) {
688689
return substringNode.execute(string, start, length);
689690
}
690691

691-
private long toLong(Object value) {
692-
if (toLongNode == null) {
693-
CompilerDirectives.transferToInterpreterAndInvalidate();
694-
toLongNode = insert(ToLongNode.create());
695-
}
696-
697-
// The long cast is necessary to avoid the invalid `(long) Integer` situation.
698-
return toLongNode.execute(value);
699-
}
700-
701692
private int codePointLength(AbstractTruffleString string, RubyEncoding encoding) {
702693
if (codePointLengthNode == null) {
703694
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -2489,10 +2480,11 @@ protected Object sum(Object string, NotProvided bits,
24892480
}
24902481

24912482
@Specialization(guards = { "!isImplicitLong(bits)", "wasProvided(bits)" })
2492-
protected Object sum(Object string, Object bits,
2483+
protected static Object sum(Object string, Object bits,
24932484
@Cached ToLongNode toLongNode,
2494-
@Cached SumNode sumNode) {
2495-
return sumNode.executeSum(string, toLongNode.execute(bits));
2485+
@Cached SumNode sumNode,
2486+
@Bind("this") Node node) {
2487+
return sumNode.executeSum(string, toLongNode.execute(node, bits));
24962488
}
24972489

24982490
}

src/main/java/org/truffleruby/core/support/TypeNodes.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -414,11 +414,10 @@ protected Object moduleName(RubyModule module) {
414414

415415
@Primitive(name = "rb_num2long")
416416
public abstract static class RbNum2LongPrimitiveNode extends PrimitiveArrayArgumentsNode {
417-
@Child private ToLongNode toLongNode = ToLongNode.create();
418-
419417
@Specialization
420-
protected long numToLong(Object value) {
421-
return toLongNode.execute(value);
418+
protected long numToLong(Object value,
419+
@Cached ToLongNode toLongNode) {
420+
return toLongNode.execute(this, value);
422421
}
423422
}
424423

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,13 +295,14 @@ public boolean hasHashEntries(
295295
public long getHashSize(
296296
@Exclusive @Cached DispatchNode dispatchNode,
297297
@Shared @Cached BranchProfile errorProfile,
298-
@Exclusive @Cached ToLongNode toInt) throws UnsupportedMessageException {
298+
@Exclusive @Cached ToLongNode toInt,
299+
@Bind("$node") Node node) throws UnsupportedMessageException {
299300
final Object value = dispatchNode.call(PRIVATE_RETURN_MISSING, this, "polyglot_hash_size");
300301
if (value == DispatchNode.MISSING) {
301302
errorProfile.enter();
302303
throw UnsupportedMessageException.create();
303304
}
304-
return toInt.execute(value);
305+
return toInt.execute(node, value);
305306
}
306307

307308
@ExportMessage

0 commit comments

Comments
 (0)