Skip to content

Commit 09714b9

Browse files
committed
Replace abstract Region class with MultiRegion
1 parent 44311a0 commit 09714b9

File tree

3 files changed

+41
-22
lines changed

3 files changed

+41
-22
lines changed

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

Lines changed: 13 additions & 12 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;
@@ -104,20 +104,20 @@ private static void forceLazyMatchData(RubyMatchData matchData, InteropLibrary i
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;
113+
final MultiRegion regs = matchData.region;
114114
int numRegs = regs.getNumRegs();
115115

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

120-
final Region charOffsets = Region.newRegion(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++) {
@@ -170,15 +170,16 @@ private static void updatePairs(AbstractTruffleString source, RubyEncoding encod
170170
}
171171

172172
@TruffleBoundary
173-
private static Region createCharOffsets(RubyMatchData matchData, AbstractTruffleString source,
173+
private static MultiRegion createCharOffsets(RubyMatchData matchData, AbstractTruffleString source,
174174
RubyEncoding encoding) {
175-
final Region charOffsets = getCharOffsetsManyRegs(matchData, source, encoding);
175+
final MultiRegion charOffsets = getCharOffsetsManyRegs(matchData, source, encoding);
176176
matchData.charOffsets = charOffsets;
177177
return charOffsets;
178178
}
179179

180-
private static Region getCharOffsets(RubyMatchData matchData, AbstractTruffleString source, RubyEncoding encoding) {
181-
final Region charOffsets = matchData.charOffsets;
180+
private static MultiRegion getCharOffsets(RubyMatchData matchData, AbstractTruffleString source,
181+
RubyEncoding encoding) {
182+
final MultiRegion charOffsets = matchData.charOffsets;
182183
if (charOffsets != null) {
183184
return charOffsets;
184185
} else {
@@ -189,7 +190,7 @@ private static Region getCharOffsets(RubyMatchData matchData, AbstractTruffleStr
189190
@TruffleBoundary
190191
private static void fixupMatchDataForStart(RubyMatchData matchData, int startPos) {
191192
assert startPos != 0;
192-
Region regs = matchData.region;
193+
MultiRegion regs = matchData.region;
193194
for (int i = 0; i < regs.getNumRegs(); i++) {
194195
assert regs.getBeg(i) != RubyMatchData.LAZY && regs
195196
.getEnd(i) != RubyMatchData.LAZY : "Group bounds must be computed before fixupMatchDataForStart()";
@@ -223,7 +224,7 @@ public abstract static class MatchDataCreateSingleGroupNode extends PrimitiveArr
223224

224225
@Specialization
225226
Object create(Object regexp, Object string, int start, int end) {
226-
final Region region = Region.newRegion(start, end);
227+
final MultiRegion region = new MultiRegion(start, end);
227228
RubyMatchData matchData = new RubyMatchData(
228229
coreLibrary().matchDataClass,
229230
getLanguage().matchDataShape,
@@ -255,7 +256,7 @@ Object getIndex(RubyMatchData matchData, int index, NotProvided length,
255256
@Cached @Exclusive InlinedConditionProfile hasValueProfile,
256257
@Cached TruffleString.SubstringByteIndexNode substringNode) {
257258

258-
final Region region = matchData.region;
259+
final MultiRegion region = matchData.region;
259260
if (normalizedIndexProfile.profile(this, index < 0)) {
260261
index += region.getNumRegs();
261262
}
@@ -544,7 +545,7 @@ Object[] getValues(RubyMatchData matchData,
544545
@Cached InlinedLoopConditionProfile loopProfile,
545546
@Cached TruffleString.SubstringByteIndexNode substringNode) {
546547
final Object source = matchData.source;
547-
final Region region = matchData.region;
548+
final MultiRegion region = matchData.region;
548549
final Object[] values = new Object[region.getNumRegs()];
549550

550551
int n = 0;

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: 20 additions & 4 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,7 +986,7 @@ static Object matchInRegionTRegex(
984986
final int groupCount = groupCountProfile
985987
.profile(node, (int) InteropNodes.readMember(node, regexInterop, tRegex, "groupCount",
986988
translateInteropExceptionNode));
987-
final Region region = Region.newRegion(groupCount);
989+
final MultiRegion region = new MultiRegion(groupCount);
988990

989991
try {
990992
for (int group = 0; loopProfile.inject(node, group < groupCount); group++) {
@@ -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,7 +1145,21 @@ private int runMatch(Matcher matcher, int startPos, int range, boolean onlyMatch
11431145
}
11441146
}
11451147

1146-
private boolean assertValidRegion(Region region) {
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) {
11471163
for (int i = 0; i < region.getNumRegs(); i++) {
11481164
assert region.getBeg(i) >= 0 || region.getBeg(i) == RubyMatchData.MISSING;
11491165
assert region.getEnd(i) >= 0 || region.getEnd(i) == RubyMatchData.MISSING;

0 commit comments

Comments
 (0)