Skip to content

Commit ebee0c7

Browse files
committed
Share code and nodes for ranges where possible.
1 parent 1d6bd76 commit ebee0c7

File tree

1 file changed

+27
-40
lines changed

1 file changed

+27
-40
lines changed

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

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
import com.oracle.truffle.api.dsl.NodeChild;
105105
import com.oracle.truffle.api.dsl.ReportPolymorphism;
106106
import com.oracle.truffle.api.dsl.Specialization;
107+
import com.oracle.truffle.api.dsl.Cached.Shared;
107108
import com.oracle.truffle.api.frame.VirtualFrame;
108109
import com.oracle.truffle.api.library.CachedLibrary;
109110
import com.oracle.truffle.api.nodes.DirectCallNode;
@@ -280,26 +281,27 @@ protected Object index(RubyArray array, int index, NotProvided length,
280281

281282
@Specialization
282283
protected Object indexRange(RubyArray array, RubyObjectRange range, NotProvided length,
283-
@Cached NormalizedStartLengthNode startLengthNode,
284-
@Cached ReadSliceNormalizedNode readSlice) {
285-
final int[] startLength = startLengthNode.execute(range, array.size);
286-
final int len = Math.max(startLength[1], 0); // negative range ending maps to zero length
287-
return readSlice.executeReadSlice(array, startLength[0], len);
284+
@Cached @Shared("starting") NormalizedStartLengthNode startLengthNode,
285+
@Cached @Shared("ending") ReadSliceNormalizedNode readSlice) {
286+
return readRange(array, range, startLengthNode, readSlice);
288287
}
289288

290289
@Specialization
291290
protected Object indexIntRange(RubyArray array, RubyIntRange range, NotProvided length,
292-
@Cached NormalizedStartLengthNode startLengthNode,
293-
@Cached ReadSliceNormalizedNode readSlice) {
294-
final int[] startLength = startLengthNode.execute(range, array.size);
295-
final int len = Math.max(startLength[1], 0); // negative range ending maps to zero length
296-
return readSlice.executeReadSlice(array, startLength[0], len);
291+
@Cached @Shared("starting") NormalizedStartLengthNode startLengthNode,
292+
@Cached @Shared("ending") ReadSliceNormalizedNode readSlice) {
293+
return readRange(array, range, startLengthNode, readSlice);
297294
}
298295

299296
@Specialization
300297
protected Object indexLongRange(RubyArray array, RubyLongRange range, NotProvided length,
301-
@Cached NormalizedStartLengthNode startLengthNode,
302-
@Cached ReadSliceNormalizedNode readSlice) {
298+
@Cached @Shared("starting") NormalizedStartLengthNode startLengthNode,
299+
@Cached @Shared("ending") ReadSliceNormalizedNode readSlice) {
300+
return readRange(array, range, startLengthNode, readSlice);
301+
}
302+
303+
private Object readRange(RubyArray array, Object range, NormalizedStartLengthNode startLengthNode,
304+
ReadSliceNormalizedNode readSlice) {
303305
final int[] startLength = startLengthNode.execute(range, array.size);
304306
final int len = Math.max(startLength[1], 0); // negative range ending maps to zero length
305307
return readSlice.executeReadSlice(array, startLength[0], len);
@@ -382,42 +384,27 @@ protected Object set(RubyArray array, int index, Object value, NotProvided unuse
382384

383385
@Specialization
384386
protected Object setRange(RubyArray array, RubyObjectRange range, Object value, NotProvided unused,
385-
@Cached NormalizedStartLengthNode normalizedStartLength,
386-
@Cached BranchProfile negativeStart) {
387-
final int[] startLength = normalizedStartLength.execute(range, array.size);
388-
final int start = startLength[0];
389-
if (start < 0) {
390-
negativeStart.enter();
391-
throw new RaiseException(
392-
getContext(),
393-
coreExceptions().rangeError(Utils.concat("index ", start, " out of bounds"), this));
394-
}
395-
final int length = Math.max(startLength[1], 0); // negative range ending maps to zero length
396-
return executeIntIndices(array, start, length, value);
387+
@Cached @Shared("startLength") NormalizedStartLengthNode normalizedStartLength,
388+
@Cached @Shared("nagativeStart") BranchProfile negativeStart) {
389+
return setRangeInternal(array, range, value, normalizedStartLength, negativeStart);
397390
}
398391

399-
400392
@Specialization
401393
protected Object setIngRange(RubyArray array, RubyIntRange range, Object value, NotProvided unused,
402-
@Cached NormalizedStartLengthNode normalizedStartLength,
403-
@Cached BranchProfile negativeStart) {
404-
final int[] startLength = normalizedStartLength.execute(range, array.size);
405-
final int start = startLength[0];
406-
if (start < 0) {
407-
negativeStart.enter();
408-
throw new RaiseException(
409-
getContext(),
410-
coreExceptions().rangeError(Utils.concat("index ", start, " out of bounds"), this));
411-
}
412-
final int length = Math.max(startLength[1], 0); // negative range ending maps to zero length
413-
return executeIntIndices(array, start, length, value);
394+
@Cached @Shared("startLength") NormalizedStartLengthNode normalizedStartLength,
395+
@Cached @Shared("nagativeStart") BranchProfile negativeStart) {
396+
return setRangeInternal(array, range, value, normalizedStartLength, negativeStart);
414397
}
415398

416-
417399
@Specialization
418400
protected Object setLongRange(RubyArray array, RubyLongRange range, Object value, NotProvided unused,
419-
@Cached NormalizedStartLengthNode normalizedStartLength,
420-
@Cached BranchProfile negativeStart) {
401+
@Cached @Shared("startLength") NormalizedStartLengthNode normalizedStartLength,
402+
@Cached @Shared("nagativeStart") BranchProfile negativeStart) {
403+
return setRangeInternal(array, range, value, normalizedStartLength, negativeStart);
404+
}
405+
406+
private Object setRangeInternal(RubyArray array, Object range, Object value,
407+
NormalizedStartLengthNode normalizedStartLength, BranchProfile negativeStart) {
421408
final int[] startLength = normalizedStartLength.execute(range, array.size);
422409
final int start = startLength[0];
423410
if (start < 0) {

0 commit comments

Comments
 (0)