Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: ea61f78edd22
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 09ecd355b151
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Oct 13, 2015

  1. Copy the full SHA
    c15f99b View commit details
  2. [Truffle] Removed boundary for string_substring primitive.

    This primitive is used by String#[] amongst others.
    nirvdrum committed Oct 13, 2015
    3
    Copy the full SHA
    09ecd35 View commit details
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ public class StringGuards {

public static boolean isSingleByteOptimizable(DynamicObject string) {
assert RubyGuards.isRubyString(string);
return StringSupport.isSingleByteOptimizable(StringOperations.getCodeRangeable(string), StringOperations.getByteList(string).getEncoding());
return Layouts.STRING.getCodeRange(string) == StringSupport.CR_7BIT || StringOperations.getByteList(string).getEncoding().maxLength() == 1;
}

public static boolean isAsciiCompatible(DynamicObject string) {
Original file line number Diff line number Diff line change
@@ -1188,20 +1188,23 @@ public DynamicObject stringByteAppend(DynamicObject string, DynamicObject other)
@ImportStatic(StringGuards.class)
public static abstract class StringSubstringPrimitiveNode extends RubiniusPrimitiveNode {

@Child private AllocateObjectNode allocateNode;
@Child private TaintResultNode taintResultNode;
private final ConditionProfile negativeLengthProfile = ConditionProfile.createBinaryProfile();
private final ConditionProfile tooLargeBeginProfile = ConditionProfile.createBinaryProfile();
private final ConditionProfile negativeBeginProfile = ConditionProfile.createBinaryProfile();

public StringSubstringPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public abstract Object execute(VirtualFrame frame, DynamicObject string, int beg, int len);

@TruffleBoundary
@Specialization(guards = "isSingleByteOptimizable(string)")
public Object stringSubstringSingleByteOptimizable(DynamicObject string, int beg, int len) {
// Taken from org.jruby.RubyString#substr19.

if (len < 0) {
if (negativeLengthProfile.profile(len < 0)) {
return nil();
}

@@ -1210,14 +1213,14 @@ public Object stringSubstringSingleByteOptimizable(DynamicObject string, int beg
len = 0;
}

if (beg > length) {
if (tooLargeBeginProfile.profile(beg > length)) {
return nil();
}

if (beg < 0) {
beg += length;

if (beg < 0) {
if (negativeBeginProfile.profile(beg < 0)) {
return nil();
}
}
@@ -1310,13 +1313,22 @@ public Object stringSubstring(DynamicObject string, int beg, int len) {
private DynamicObject makeSubstring(DynamicObject string, int beg, int len) {
assert RubyGuards.isRubyString(string);

if (allocateNode == null) {
CompilerDirectives.transferToInterpreter();
allocateNode = insert(AllocateObjectNodeGen.create(getContext(), getSourceSection(), null, null));
}

if (taintResultNode == null) {
CompilerDirectives.transferToInterpreter();
taintResultNode = insert(new TaintResultNode(getContext(), getSourceSection()));
}

final DynamicObject ret = Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.BASIC_OBJECT.getLogicalClass(string)), new ByteList(StringOperations.getByteList(string), beg, len), StringSupport.CR_UNKNOWN, null);
StringOperations.getByteList(ret).setEncoding(StringOperations.getByteList(string).getEncoding());
final DynamicObject ret = allocateNode.allocate(
Layouts.BASIC_OBJECT.getLogicalClass(string),
new ByteList(StringOperations.getByteList(string).unsafeBytes(), beg, len),
StringSupport.CR_UNKNOWN,
null);

taintResultNode.maybeTaint(string, ret);

return ret;