Skip to content

Commit d9ae79b

Browse files
author
Nicolas Laurent
committed
fix potential issues do to Binding bug, and profile getState when opportune
1 parent c5ff2ff commit d9ae79b

File tree

2 files changed

+64
-40
lines changed

2 files changed

+64
-40
lines changed

src/main/java/org/truffleruby/core/rope/ConcatRope.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
*/
1010
package org.truffleruby.core.rope;
1111

12+
import com.oracle.truffle.api.CompilerAsserts;
1213
import com.oracle.truffle.api.CompilerDirectives;
1314
import com.oracle.truffle.api.CompilerDirectives.ValueType;
15+
import com.oracle.truffle.api.profiles.ConditionProfile;
1416
import org.jcodings.Encoding;
1517
import org.jcodings.specific.ASCIIEncoding;
1618

@@ -96,8 +98,13 @@ protected byte[] getBytesSlow() {
9698
return out;
9799
}
98100

99-
/** Access the state in a way that prevents race conditions. */
101+
/** Access the state in a way that prevents race conditions.
102+
*
103+
* <p>
104+
* This version is not allowed in compiled code, use {@link #getState(ConditionProfile)} there instead. */
100105
public ConcatState getState() {
106+
CompilerAsserts.neverPartOfCompilation("use getState(ConditionProfile) instead!");
107+
101108
if (this.bytes != null) {
102109
return new ConcatState(null, null, this.bytes);
103110
}
@@ -112,4 +119,24 @@ public ConcatState getState() {
112119
assert this.bytes != null;
113120
return new ConcatState(null, null, this.bytes);
114121
}
122+
123+
/** Access the state in a way that prevents race conditions.
124+
*
125+
* <p>
126+
* Outside compiled code, you can use {@link #getState()}. */
127+
public ConcatState getState(ConditionProfile bytesNotNull) {
128+
if (bytesNotNull.profile(this.bytes != null)) {
129+
return new ConcatState(null, null, this.bytes);
130+
}
131+
132+
final ManagedRope left = this.left;
133+
final ManagedRope right = this.right;
134+
if (left != null && right != null) {
135+
return new ConcatState(left, right, null);
136+
}
137+
138+
CompilerDirectives.transferToInterpreterAndInvalidate();
139+
assert this.bytes != null;
140+
return new ConcatState(null, null, this.bytes);
141+
}
115142
}

src/main/java/org/truffleruby/core/rope/RopeNodes.java

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -804,45 +804,35 @@ protected Object debugPrintSubstringRope(SubstringRope rope, int currentLevel, b
804804
}
805805

806806
@TruffleBoundary
807-
@Specialization(guards = "state.isBytes()")
808-
protected Object debugPrintConcatRopeBytes(ConcatRope rope, int currentLevel, boolean printString,
809-
@Bind("rope.getState()") ConcatState state) {
810-
printPreamble(currentLevel);
811-
812-
System.err
813-
.println(StringUtils.format(
814-
"%s (%s; BN: %b; BL: %d; CL: %d; CR: %s; E: %s)",
815-
printString ? rope.toString() : "<skipped>",
816-
rope.getClass().getSimpleName(),
817-
false,
818-
rope.byteLength(),
819-
rope.characterLength(),
820-
rope.getCodeRange(),
821-
rope.getEncoding()));
822-
823-
return nil;
824-
}
825-
826-
@TruffleBoundary
827-
@Specialization(guards = "state.isChildren()")
828-
protected Object debugPrintConcatRopeChildren(ConcatRope rope, int currentLevel, boolean printString,
829-
@Bind("rope.getState()") ConcatState state) {
807+
protected Object debugPrintConcatRopeBytes(ConcatRope rope, int currentLevel, boolean printString) {
830808
printPreamble(currentLevel);
831809

832-
System.err
833-
.println(StringUtils.format(
834-
"%s (%s; BN: %b; BL: %d; CL: %d; CR: %s; E: %s)",
835-
printString ? rope.toString() : "<skipped>",
836-
rope.getClass().getSimpleName(),
837-
// Note: converting a rope to a java.lang.String may populate the byte[].
838-
true, // are bytes null?
839-
rope.byteLength(),
840-
rope.characterLength(),
841-
rope.getCodeRange(),
842-
rope.getEncoding()));
843-
844-
executeDebugPrint(state.left, currentLevel + 1, printString);
845-
executeDebugPrint(state.right, currentLevel + 1, printString);
810+
final ConcatState state = rope.getState();
811+
if (state.isBytes()) {
812+
System.err.println(StringUtils.format(
813+
"%s (%s; BN: %b; BL: %d; CL: %d; CR: %s; E: %s)",
814+
printString ? rope.toString() : "<skipped>",
815+
rope.getClass().getSimpleName(),
816+
false,
817+
rope.byteLength(),
818+
rope.characterLength(),
819+
rope.getCodeRange(),
820+
rope.getEncoding()));
821+
} else {
822+
System.err.println(StringUtils.format(
823+
"%s (%s; BN: %b; BL: %d; CL: %d; CR: %s; E: %s)",
824+
printString ? rope.toString() : "<skipped>",
825+
rope.getClass().getSimpleName(),
826+
// Note: converting a rope to a java.lang.String may populate the byte[].
827+
true, // are bytes null?
828+
rope.byteLength(),
829+
rope.characterLength(),
830+
rope.getCodeRange(),
831+
rope.getEncoding()));
832+
833+
executeDebugPrint(state.left, currentLevel + 1, printString);
834+
executeDebugPrint(state.right, currentLevel + 1, printString);
835+
}
846836

847837
return nil;
848838
}
@@ -1015,9 +1005,15 @@ protected int getByteRepeatingRope(RepeatingRope rope, int index,
10151005
return rope.getChild().getRawBytes()[index % rope.getChild().byteLength()] & 0xff;
10161006
}
10171007

1008+
// NOTE(norswap, 12 Jan 2021): The order of the two next specialization is significant.
1009+
// Normally, @Bind expressions should only be run per node, but that's not the case currently (GR-28671).
1010+
// Therefore it's important to test isChildren first, as it's possible to transition from children to bytes
1011+
// but not the other way around.
1012+
10181013
@Specialization(guards = "state.isChildren()")
10191014
protected int getByteConcatRope(ConcatRope rope, int index,
1020-
@Bind("rope.getState()") ConcatState state,
1015+
@Cached ConditionProfile stateBytesNotNull,
1016+
@Bind("rope.getState(stateBytesNotNull)") ConcatState state,
10211017
@Cached ConditionProfile chooseLeftChildProfile,
10221018
@Cached ConditionProfile leftChildRawBytesNullProfile,
10231019
@Cached ConditionProfile rightChildRawBytesNullProfile,
@@ -1042,7 +1038,8 @@ protected int getByteConcatRope(ConcatRope rope, int index,
10421038
// before we get to run the other getByteConcatRope.
10431039
@Specialization(guards = "state.isBytes()")
10441040
protected int getByteConcatRope(ConcatRope rope, int index,
1045-
@Bind("rope.getState()") ConcatState state) {
1041+
@Cached ConditionProfile stateBytesNotNull,
1042+
@Bind("rope.getState(stateBytesNotNull)") ConcatState state) {
10461043
return state.bytes[index] & 0xff;
10471044
}
10481045
}

0 commit comments

Comments
 (0)