Skip to content

Commit 4c773e2

Browse files
committed
Profile the encoding argument in String#force_encoding
1 parent 081387d commit 4c773e2

File tree

2 files changed

+46
-22
lines changed

2 files changed

+46
-22
lines changed

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,39 +1357,46 @@ protected RubyString sameEncoding(RubyString string, RubyEncoding newEncoding) {
13571357
@Specialization(guards = { "encoding != newEncoding", "tstring.isImmutable()" })
13581358
protected RubyString immutable(RubyString string, RubyEncoding newEncoding,
13591359
@Cached RubyStringLibrary libString,
1360+
@Cached RubyStringLibrary profileEncoding,
13601361
@Cached TruffleString.ForceEncodingNode forceEncodingNode,
13611362
@Bind("string.tstring") AbstractTruffleString tstring,
13621363
@Bind("libString.getEncoding(string)") RubyEncoding encoding) {
1363-
var newTString = forceEncodingNode.execute(tstring, encoding.tencoding, newEncoding.tencoding);
1364-
string.setTString(newTString, newEncoding);
1364+
var newEncodingProfiled = profileEncoding.profileEncoding(newEncoding);
1365+
var newTString = forceEncodingNode.execute(tstring, encoding.tencoding, newEncodingProfiled.tencoding);
1366+
string.setTString(newTString, newEncodingProfiled);
13651367
return string;
13661368
}
13671369

13681370
@Specialization(
13691371
guards = { "encoding != newEncoding", "!tstring.isImmutable()", "!tstring.isNative()" })
13701372
protected RubyString mutableManaged(RubyString string, RubyEncoding newEncoding,
13711373
@Cached RubyStringLibrary libString,
1374+
@Cached RubyStringLibrary profileEncoding,
13721375
@Cached MutableTruffleString.ForceEncodingNode forceEncodingNode,
13731376
@Bind("string.tstring") AbstractTruffleString tstring,
13741377
@Bind("libString.getEncoding(string)") RubyEncoding encoding) {
1375-
var newTString = forceEncodingNode.execute(tstring, encoding.tencoding, newEncoding.tencoding);
1376-
string.setTString(newTString, newEncoding);
1378+
var newEncodingProfiled = profileEncoding.profileEncoding(newEncoding);
1379+
var newTString = forceEncodingNode.execute(tstring, encoding.tencoding, newEncodingProfiled.tencoding);
1380+
string.setTString(newTString, newEncodingProfiled);
13771381
return string;
13781382
}
13791383

13801384
@Specialization(
13811385
guards = { "encoding != newEncoding", "!tstring.isImmutable()", "tstring.isNative()" })
13821386
protected RubyString mutableNative(RubyString string, RubyEncoding newEncoding,
13831387
@Cached RubyStringLibrary libString,
1388+
@Cached RubyStringLibrary profileEncoding,
13841389
@Cached TruffleString.GetInternalNativePointerNode getInternalNativePointerNode,
13851390
@Cached MutableTruffleString.FromNativePointerNode fromNativePointerNode,
13861391
@Bind("string.tstring") AbstractTruffleString tstring,
13871392
@Bind("libString.getEncoding(string)") RubyEncoding encoding) {
1393+
var newEncodingProfiled = profileEncoding.profileEncoding(newEncoding);
13881394
var currentEncoding = encoding.tencoding;
13891395
var pointer = (Pointer) getInternalNativePointerNode.execute(tstring, currentEncoding);
13901396
var byteLength = tstring.byteLength(currentEncoding);
1391-
var newTString = fromNativePointerNode.execute(pointer, 0, byteLength, newEncoding.tencoding, false);
1392-
string.setTString(newTString, newEncoding);
1397+
var newTString = fromNativePointerNode.execute(pointer, 0, byteLength, newEncodingProfiled.tencoding,
1398+
false);
1399+
string.setTString(newTString, newEncodingProfiled);
13931400
return string;
13941401
}
13951402

src/main/java/org/truffleruby/language/library/RubyStringLibrary.java

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public final TruffleString.Encoding getTEncoding(Object object) {
4949

5050
public abstract int byteLength(Object object);
5151

52+
public abstract RubyEncoding profileEncoding(RubyEncoding encoding);
53+
5254
static final class Cached extends RubyStringLibrary {
5355

5456
@CompilationFinal private boolean seenMutable, seenImmutable, seenOther;
@@ -123,6 +125,28 @@ private AbstractTruffleString specializeGetTString(Object object) {
123125
}
124126
}
125127

128+
public RubyEncoding profileEncoding(RubyEncoding encoding) {
129+
var localCachedEncoding = this.cachedEncoding;
130+
if (encoding == localCachedEncoding) {
131+
return (RubyEncoding) localCachedEncoding;
132+
} else if (localCachedEncoding == GENERIC) {
133+
return encoding;
134+
} else {
135+
CompilerDirectives.transferToInterpreterAndInvalidate();
136+
return specializeProfileEncoding(encoding);
137+
}
138+
}
139+
140+
private RubyEncoding specializeProfileEncoding(RubyEncoding encoding) {
141+
var localCachedEncoding = this.cachedEncoding;
142+
if (localCachedEncoding == null) {
143+
this.cachedEncoding = encoding;
144+
} else if (encoding != localCachedEncoding) {
145+
this.cachedEncoding = GENERIC;
146+
}
147+
return encoding;
148+
}
149+
126150
@Override
127151
public RubyEncoding getEncoding(Object object) {
128152
final RubyEncoding encoding;
@@ -135,15 +159,7 @@ public RubyEncoding getEncoding(Object object) {
135159
return specializeGetEncoding(object);
136160
}
137161

138-
var localCachedEncoding = this.cachedEncoding;
139-
if (encoding == localCachedEncoding) {
140-
return (RubyEncoding) localCachedEncoding;
141-
} else if (localCachedEncoding == GENERIC) {
142-
return encoding;
143-
} else {
144-
CompilerDirectives.transferToInterpreterAndInvalidate();
145-
return specializeGetEncoding(object);
146-
}
162+
return profileEncoding(encoding);
147163
}
148164

149165
private RubyEncoding specializeGetEncoding(Object object) {
@@ -158,13 +174,7 @@ private RubyEncoding specializeGetEncoding(Object object) {
158174
throw CompilerDirectives.shouldNotReachHere();
159175
}
160176

161-
var localCachedEncoding = this.cachedEncoding;
162-
if (localCachedEncoding == null) {
163-
this.cachedEncoding = encoding;
164-
} else if (encoding != localCachedEncoding) {
165-
this.cachedEncoding = GENERIC;
166-
}
167-
return encoding;
177+
return specializeProfileEncoding(encoding);
168178
}
169179

170180
@Override
@@ -193,6 +203,7 @@ static final class Uncached extends RubyStringLibrary {
193203

194204
@Override
195205
public boolean seen(Object object) {
206+
CompilerAsserts.neverPartOfCompilation("Only behind @TruffleBoundary");
196207
assert object instanceof RubyString || object instanceof ImmutableRubyString;
197208
return true;
198209
}
@@ -215,6 +226,12 @@ public AbstractTruffleString getTString(Object object) {
215226
}
216227
}
217228

229+
@Override
230+
public RubyEncoding profileEncoding(RubyEncoding encoding) {
231+
CompilerAsserts.neverPartOfCompilation("Only behind @TruffleBoundary");
232+
return encoding;
233+
}
234+
218235
@Override
219236
public RubyEncoding getEncoding(Object object) {
220237
CompilerAsserts.neverPartOfCompilation("Only behind @TruffleBoundary");

0 commit comments

Comments
 (0)