Skip to content

Commit d484abe

Browse files
committed
[GR-54743] [GR-18163] Upgrade joni version
PullRequest: truffleruby/4289
2 parents 80c63f8 + 09714b9 commit d484abe

File tree

5 files changed

+84
-63
lines changed

5 files changed

+84
-63
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Compatibility:
3131
* Fix `RegexpError` messages to match CRuby better (#3398, @andrykonchin).
3232
* Fix `Enumerable#reduce` to handle non-Symbol method name parameter (#2931, @andrykonchin).
3333
* Fix `RangeError` message to match CRuby for `Integer#chr` called with invalid codepoint argument (#2795, @andrykonchin).
34+
* Joni has been updated from 2.1.44 to 2.2.1 (@andrykonchin).
3435

3536
Performance:
3637

mx.truffleruby/suite.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@
7474
"maven": {
7575
"groupId": "org.jruby.joni",
7676
"artifactId": "joni",
77-
"version": "2.1.44"
77+
"version": "2.2.1"
7878
},
79-
"digest": "sha512:59b901333d93b8eaf0c28a2d269d159e6806701902505113148c4df6b2ade973e97f9b888b8b5b4dff4d3c667b4594eeee8133f4260e7f1f3d9af1a031b9cab4",
80-
"sourceDigest": "sha512:773051c47893799ecc0b916b80c4dedac0efe2988743d455ce8529460aed2d7664d4b12cd51e449a8b20ac0c37e32ead89d72f6acf4f6a780268b55fdd67e3cf",
79+
"digest": "sha512:e4fa4dda7478d5254b80aa77014d6df05317ac55d957da9ade6c9a80968aaf49d87d58930b8ddd44333270fa38984649858655b54c3aa8463602e0da8902d53a",
80+
"sourceDigest": "sha512:90b9a5216c748cc170a17bf58289553e0fe7695b16e7cacefd126d506ee7700e4cd7739e2d2500442ae7077fb88fcd64621c5a005b1fc6909ea75c88ce8cb536",
8181
"license": ["MIT"],
8282
},
8383

src/main/java/org/truffleruby/core/regexp/MatchDataNodes.java

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile;
2323
import com.oracle.truffle.api.strings.AbstractTruffleString;
2424
import com.oracle.truffle.api.strings.TruffleString;
25+
import org.graalvm.shadowed.org.joni.MultiRegion;
2526
import org.graalvm.shadowed.org.joni.NameEntry;
2627
import org.graalvm.shadowed.org.joni.Regex;
27-
import org.graalvm.shadowed.org.joni.Region;
2828
import org.graalvm.shadowed.org.joni.exception.ValueException;
2929
import org.truffleruby.annotations.CoreMethod;
3030
import org.truffleruby.builtins.CoreMethodArrayArgumentsNode;
@@ -78,46 +78,46 @@ private static int getGroupBound(InteropLibrary interop, RubyMatchData matchData
7878

7979
private static int getStart(Node node, RubyMatchData matchData, int index, InlinedConditionProfile lazyProfile,
8080
InteropLibrary interop) {
81-
int start = matchData.region.beg[index];
81+
int start = matchData.region.getBeg(index);
8282
if (lazyProfile.profile(node, start == RubyMatchData.LAZY)) {
83-
return matchData.region.beg[index] = getGroupBound(interop, matchData, "getStart", index);
83+
return matchData.region.setBeg(index, getGroupBound(interop, matchData, "getStart", index));
8484
} else {
8585
return start;
8686
}
8787
}
8888

8989
private static int getEnd(Node node, RubyMatchData matchData, int index, InlinedConditionProfile lazyProfile,
9090
InteropLibrary interop) {
91-
int end = matchData.region.end[index];
91+
int end = matchData.region.getEnd(index);
9292
if (lazyProfile.profile(node, end == RubyMatchData.LAZY)) {
93-
return matchData.region.end[index] = getGroupBound(interop, matchData, "getEnd", index);
93+
return matchData.region.setEnd(index, getGroupBound(interop, matchData, "getEnd", index));
9494
} else {
9595
return end;
9696
}
9797
}
9898

9999
private static void forceLazyMatchData(RubyMatchData matchData, InteropLibrary interop) {
100-
for (int i = 0; i < matchData.region.numRegs; i++) {
100+
for (int i = 0; i < matchData.region.getNumRegs(); i++) {
101101
getStart(null, matchData, i, InlinedConditionProfile.getUncached(), interop);
102102
getEnd(null, matchData, i, InlinedConditionProfile.getUncached(), interop);
103103
}
104104
}
105105

106106
@TruffleBoundary
107-
private static Region getCharOffsetsManyRegs(RubyMatchData matchData, AbstractTruffleString source,
107+
private static MultiRegion getCharOffsetsManyRegs(RubyMatchData matchData, AbstractTruffleString source,
108108
RubyEncoding encoding) {
109109
// Taken from org.jruby.RubyMatchData
110110

111111
assert !encoding.isSingleByte : "Should be checked by callers";
112112

113-
final Region regs = matchData.region;
114-
int numRegs = regs.numRegs;
113+
final MultiRegion regs = matchData.region;
114+
int numRegs = regs.getNumRegs();
115115

116116
if (matchData.tRegexResult != null) {
117117
forceLazyMatchData(matchData, InteropLibrary.getUncached(matchData.tRegexResult));
118118
}
119119

120-
final Region charOffsets = new Region(numRegs);
120+
final MultiRegion charOffsets = new MultiRegion(numRegs);
121121

122122
final Pair[] pairs = new Pair[numRegs * 2];
123123
for (int i = 0; i < pairs.length; i++) {
@@ -126,23 +126,24 @@ private static Region getCharOffsetsManyRegs(RubyMatchData matchData, AbstractTr
126126

127127
int numPos = 0;
128128
for (int i = 0; i < numRegs; i++) {
129-
if (regs.beg[i] != RubyMatchData.MISSING) {
130-
pairs[numPos++].bytePos = regs.beg[i];
131-
pairs[numPos++].bytePos = regs.end[i];
129+
if (regs.getBeg(i) != RubyMatchData.MISSING) {
130+
pairs[numPos++].bytePos = regs.getBeg(i);
131+
pairs[numPos++].bytePos = regs.getEnd(i);
132132
}
133133
}
134134

135135
updatePairs(source, encoding, pairs);
136136

137137
Pair key = new Pair();
138-
for (int i = 0; i < regs.numRegs; i++) {
139-
if (regs.beg[i] == RubyMatchData.MISSING) {
140-
charOffsets.beg[i] = charOffsets.end[i] = RubyMatchData.MISSING;
138+
for (int i = 0; i < regs.getNumRegs(); i++) {
139+
if (regs.getBeg(i) == RubyMatchData.MISSING) {
140+
charOffsets.setBeg(i, RubyMatchData.MISSING);
141+
charOffsets.setEnd(i, RubyMatchData.MISSING);
141142
} else {
142-
key.bytePos = regs.beg[i];
143-
charOffsets.beg[i] = pairs[Arrays.binarySearch(pairs, key)].charPos;
144-
key.bytePos = regs.end[i];
145-
charOffsets.end[i] = pairs[Arrays.binarySearch(pairs, key)].charPos;
143+
key.bytePos = regs.getBeg(i);
144+
charOffsets.setBeg(i, pairs[Arrays.binarySearch(pairs, key)].charPos);
145+
key.bytePos = regs.getEnd(i);
146+
charOffsets.setEnd(i, pairs[Arrays.binarySearch(pairs, key)].charPos);
146147
}
147148
}
148149

@@ -169,15 +170,16 @@ private static void updatePairs(AbstractTruffleString source, RubyEncoding encod
169170
}
170171

171172
@TruffleBoundary
172-
private static Region createCharOffsets(RubyMatchData matchData, AbstractTruffleString source,
173+
private static MultiRegion createCharOffsets(RubyMatchData matchData, AbstractTruffleString source,
173174
RubyEncoding encoding) {
174-
final Region charOffsets = getCharOffsetsManyRegs(matchData, source, encoding);
175+
final MultiRegion charOffsets = getCharOffsetsManyRegs(matchData, source, encoding);
175176
matchData.charOffsets = charOffsets;
176177
return charOffsets;
177178
}
178179

179-
private static Region getCharOffsets(RubyMatchData matchData, AbstractTruffleString source, RubyEncoding encoding) {
180-
final Region charOffsets = matchData.charOffsets;
180+
private static MultiRegion getCharOffsets(RubyMatchData matchData, AbstractTruffleString source,
181+
RubyEncoding encoding) {
182+
final MultiRegion charOffsets = matchData.charOffsets;
181183
if (charOffsets != null) {
182184
return charOffsets;
183185
} else {
@@ -188,13 +190,13 @@ private static Region getCharOffsets(RubyMatchData matchData, AbstractTruffleStr
188190
@TruffleBoundary
189191
private static void fixupMatchDataForStart(RubyMatchData matchData, int startPos) {
190192
assert startPos != 0;
191-
Region regs = matchData.region;
192-
for (int i = 0; i < regs.beg.length; i++) {
193-
assert regs.beg[i] != RubyMatchData.LAZY &&
194-
regs.end[i] != RubyMatchData.LAZY : "Group bounds must be computed before fixupMatchDataForStart()";
195-
if (regs.beg[i] >= 0) {
196-
regs.beg[i] += startPos;
197-
regs.end[i] += startPos;
193+
MultiRegion regs = matchData.region;
194+
for (int i = 0; i < regs.getNumRegs(); i++) {
195+
assert regs.getBeg(i) != RubyMatchData.LAZY && regs
196+
.getEnd(i) != RubyMatchData.LAZY : "Group bounds must be computed before fixupMatchDataForStart()";
197+
if (regs.getBeg(i) >= 0) {
198+
regs.setBeg(i, regs.getBeg(i) + startPos);
199+
regs.setEnd(i, regs.getEnd(i) + startPos);
198200
}
199201
}
200202
}
@@ -222,7 +224,7 @@ public abstract static class MatchDataCreateSingleGroupNode extends PrimitiveArr
222224

223225
@Specialization
224226
Object create(Object regexp, Object string, int start, int end) {
225-
final Region region = new Region(start, end);
227+
final MultiRegion region = new MultiRegion(start, end);
226228
RubyMatchData matchData = new RubyMatchData(
227229
coreLibrary().matchDataClass,
228230
getLanguage().matchDataShape,
@@ -254,12 +256,12 @@ Object getIndex(RubyMatchData matchData, int index, NotProvided length,
254256
@Cached @Exclusive InlinedConditionProfile hasValueProfile,
255257
@Cached TruffleString.SubstringByteIndexNode substringNode) {
256258

257-
final Region region = matchData.region;
259+
final MultiRegion region = matchData.region;
258260
if (normalizedIndexProfile.profile(this, index < 0)) {
259-
index += region.numRegs;
261+
index += region.getNumRegs();
260262
}
261263

262-
if (indexOutOfBoundsProfile.profile(this, index < 0 || index >= region.numRegs)) {
264+
if (indexOutOfBoundsProfile.profile(this, index < 0 || index >= region.getNumRegs())) {
263265
return nil;
264266
} else {
265267
final int start = getStart(this, matchData, index, lazyProfile, libInterop);
@@ -510,7 +512,7 @@ Object begin(RubyMatchData matchData, int index,
510512

511513
if (multiByteCharacterProfile.profile(this,
512514
!singleByteOptimizableNode.execute(this, matchDataSource, encoding))) {
513-
return getCharOffsets(matchData, matchDataSource, encoding).beg[index];
515+
return getCharOffsets(matchData, matchDataSource, encoding).getBeg(index);
514516
}
515517

516518
return begin;
@@ -525,7 +527,7 @@ Object beginError(RubyMatchData matchData, int index) {
525527
}
526528

527529
protected boolean inBounds(RubyMatchData matchData, int index) {
528-
return index >= 0 && index < matchData.region.numRegs;
530+
return index >= 0 && index < matchData.region.getNumRegs();
529531
}
530532
}
531533

@@ -548,12 +550,12 @@ Object[] getValues(RubyMatchData matchData,
548550
@Cached InlinedLoopConditionProfile loopProfile,
549551
@Cached TruffleString.SubstringByteIndexNode substringNode) {
550552
final Object source = matchData.source;
551-
final Region region = matchData.region;
552-
final Object[] values = new Object[region.numRegs];
553+
final MultiRegion region = matchData.region;
554+
final Object[] values = new Object[region.getNumRegs()];
553555

554556
int n = 0;
555557
try {
556-
for (; loopProfile.inject(this, n < region.numRegs); n++) {
558+
for (; loopProfile.inject(this, n < region.getNumRegs()); n++) {
557559
final int start = getStart(this, matchData, n, lazyProfile, interop);
558560
final int end = getEnd(this, matchData, n, lazyProfile, interop);
559561

@@ -596,7 +598,7 @@ Object end(RubyMatchData matchData, int index,
596598

597599
if (multiByteCharacterProfile.profile(this,
598600
!singleByteOptimizableNode.execute(this, matchDataSource, encoding))) {
599-
return getCharOffsets(matchData, matchDataSource, encoding).end[index];
601+
return getCharOffsets(matchData, matchDataSource, encoding).getEnd(index);
600602
}
601603

602604
return end;
@@ -611,7 +613,7 @@ Object endError(RubyMatchData matchData, int index) {
611613
}
612614

613615
protected boolean inBounds(RubyMatchData matchData, int index) {
614-
return index >= 0 && index < matchData.region.numRegs;
616+
return index >= 0 && index < matchData.region.getNumRegs();
615617
}
616618
}
617619

@@ -640,7 +642,7 @@ Object byteBeginError(RubyMatchData matchData, int index) {
640642
}
641643

642644
protected boolean inBounds(RubyMatchData matchData, int index) {
643-
return index >= 0 && index < matchData.region.numRegs;
645+
return index >= 0 && index < matchData.region.getNumRegs();
644646
}
645647
}
646648

@@ -669,7 +671,7 @@ Object byteEndError(RubyMatchData matchData, int index) {
669671
}
670672

671673
protected boolean inBounds(RubyMatchData matchData, int index) {
672-
return index >= 0 && index < matchData.region.numRegs;
674+
return index >= 0 && index < matchData.region.getNumRegs();
673675
}
674676
}
675677

@@ -678,7 +680,7 @@ public abstract static class LengthNode extends CoreMethodArrayArgumentsNode {
678680

679681
@Specialization
680682
int length(RubyMatchData matchData) {
681-
return matchData.region.numRegs;
683+
return matchData.region.getNumRegs();
682684
}
683685

684686
}

src/main/java/org/truffleruby/core/regexp/RubyMatchData.java

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

1212
import java.util.Set;
1313

14-
import org.graalvm.shadowed.org.joni.Region;
14+
import org.graalvm.shadowed.org.joni.MultiRegion;
1515
import org.truffleruby.core.klass.RubyClass;
1616
import org.truffleruby.core.string.RubyString;
1717
import org.truffleruby.core.string.ImmutableRubyString;
@@ -30,18 +30,20 @@ public final class RubyMatchData extends RubyDynamicObject implements ObjectGrap
3030
/** Either a Regexp or a String for the case of String#gsub(String) */
3131
public Object regexp;
3232
public Object source;
33-
/** Group bounds as byte offsets */
34-
public Region region;
35-
/** Group bounds as character offsets */
36-
public Region charOffsets = null;
33+
/** Group bounds as byte offsets. We avoid the abstract Region class because it has virtual methods calls which
34+
* cannot be inlined by PE. */
35+
public MultiRegion region;
36+
/** Group bounds as character offsets. We avoid the abstract Region class because it has virtual methods calls which
37+
* cannot be inlined by PE. */
38+
public MultiRegion charOffsets = null;
3739
public Object tRegexResult = null;
3840

3941
public RubyMatchData(
4042
RubyClass rubyClass,
4143
Shape shape,
4244
Object regexp,
4345
Object source,
44-
Region region) {
46+
MultiRegion region) {
4547
super(rubyClass, shape);
4648
assert regexp instanceof RubyRegexp || regexp instanceof RubyString || regexp instanceof ImmutableRubyString ||
4749
regexp == null;

src/main/java/org/truffleruby/core/regexp/TruffleRegexpNodes.java

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@
3939
import com.oracle.truffle.api.strings.TruffleString;
4040
import com.oracle.truffle.api.strings.TruffleString.AsTruffleStringNode;
4141
import org.graalvm.shadowed.org.joni.Matcher;
42+
import org.graalvm.shadowed.org.joni.MultiRegion;
4243
import org.graalvm.shadowed.org.joni.Option;
4344
import org.graalvm.shadowed.org.joni.Regex;
4445
import org.graalvm.shadowed.org.joni.Region;
46+
import org.graalvm.shadowed.org.joni.SingleRegion;
4547
import org.truffleruby.RubyContext;
4648
import org.truffleruby.RubyLanguage;
4749
import org.truffleruby.annotations.CoreMethod;
@@ -984,12 +986,12 @@ static Object matchInRegionTRegex(
984986
final int groupCount = groupCountProfile
985987
.profile(node, (int) InteropNodes.readMember(node, regexInterop, tRegex, "groupCount",
986988
translateInteropExceptionNode));
987-
final Region region = new Region(groupCount);
989+
final MultiRegion region = new MultiRegion(groupCount);
988990

989991
try {
990992
for (int group = 0; loopProfile.inject(node, group < groupCount); group++) {
991-
region.beg[group] = RubyMatchData.LAZY;
992-
region.end[group] = RubyMatchData.LAZY;
993+
region.setBeg(group, RubyMatchData.LAZY);
994+
region.setEnd(group, RubyMatchData.LAZY);
993995
TruffleSafepoint.poll(node);
994996
}
995997
} finally {
@@ -1028,7 +1030,7 @@ private static Object fallbackToJoni(Node node, RubyRegexp regexp, Object string
10281030
.executeMatchInRegion(regexp, string, fromPos, toPos, atStart, startPos, createMatchData);
10291031
}
10301032

1031-
private static Object createMatchData(Node node, RubyRegexp regexp, Object string, Region region,
1033+
private static Object createMatchData(Node node, RubyRegexp regexp, Object string, MultiRegion region,
10321034
Object tRegexResult) {
10331035
final RubyMatchData matchData = new RubyMatchData(
10341036
coreLibrary(node).matchDataClass,
@@ -1115,7 +1117,7 @@ Object match(
11151117

11161118
assert match >= 0;
11171119

1118-
final Region region = matcher.getEagerRegion();
1120+
final MultiRegion region = getMatcherEagerRegion(matcher);
11191121
assert assertValidRegion(region);
11201122
final RubyString dupedString = (RubyString) dupNode.call(string, "dup");
11211123
RubyMatchData result = new RubyMatchData(
@@ -1143,10 +1145,24 @@ private int runMatch(Matcher matcher, int startPos, int range, boolean onlyMatch
11431145
}
11441146
}
11451147

1146-
private boolean assertValidRegion(Region region) {
1147-
for (int i = 0; i < region.numRegs; i++) {
1148-
assert region.beg[i] >= 0 || region.beg[i] == RubyMatchData.MISSING;
1149-
assert region.end[i] >= 0 || region.end[i] == RubyMatchData.MISSING;
1148+
/** Is equivalent to {@link org.graalvm.shadowed.org.joni.Matcher#getEagerRegion()} but returns MultiRegion
1149+
* instead of abstract Region class */
1150+
private MultiRegion getMatcherEagerRegion(Matcher matcher) {
1151+
Region eagerRegion = matcher.getEagerRegion();
1152+
1153+
if (eagerRegion instanceof SingleRegion singleRegion) {
1154+
return new MultiRegion(singleRegion.getBeg(0), singleRegion.getEnd(0));
1155+
} else if (eagerRegion instanceof MultiRegion multiRegion) {
1156+
return multiRegion;
1157+
} else {
1158+
throw CompilerDirectives.shouldNotReachHere();
1159+
}
1160+
}
1161+
1162+
private boolean assertValidRegion(MultiRegion region) {
1163+
for (int i = 0; i < region.getNumRegs(); i++) {
1164+
assert region.getBeg(i) >= 0 || region.getBeg(i) == RubyMatchData.MISSING;
1165+
assert region.getEnd(i) >= 0 || region.getEnd(i) == RubyMatchData.MISSING;
11501166
}
11511167
return true;
11521168
}

0 commit comments

Comments
 (0)