Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class BuildDynamicStringSite extends MutableCallSite {
false);
private static final int MAX_ELEMENTS_FOR_SPECIALIZE1 = 4;
private static final int MAX_DYNAMIC_ARGS_FOR_SPECIALIZE2 = 5;
public static final int MAX_ELEMENTS = 50;
private static final int METADATA_ARGS_COUNT = 6;

public static CallSite buildDString(MethodHandles.Lookup lookup, String name, MethodType type, Object[] args) {
return new BuildDynamicStringSite(type, args);
Expand All @@ -55,12 +57,14 @@ record ByteListAndCodeRange(ByteList bl, int cr) {}
public BuildDynamicStringSite(MethodType type, Object[] stringArgs) {
super(type);

initialSize = (Integer) stringArgs[stringArgs.length - 6];
encoding = StringBootstrap.encodingFromName((String) stringArgs[stringArgs.length - 5]);
chilled = ((Integer) stringArgs[stringArgs.length - 4]) != 0;
frozen = ((Integer) stringArgs[stringArgs.length - 3]) != 0;
descriptor = (Long) stringArgs[stringArgs.length - 2];
elementCount = (Integer) stringArgs[stringArgs.length - 1];
int metadataIndex = stringArgs.length - METADATA_ARGS_COUNT;

initialSize = (Integer) stringArgs[metadataIndex];
encoding = StringBootstrap.encodingFromName((String) stringArgs[metadataIndex + 1]);
frozen = ((Integer) stringArgs[metadataIndex + 2]) != 0;
chilled = ((Integer) stringArgs[metadataIndex + 3]) != 0;
descriptor = (Long) stringArgs[metadataIndex + 4];
elementCount = (Integer) stringArgs[metadataIndex + 5];

ByteListAndCodeRange[] strings = new ByteListAndCodeRange[elementCount];
int stringArgsIdx = 0;
Expand All @@ -85,7 +89,7 @@ public BuildDynamicStringSite(MethodType type, Object[] stringArgs) {

boolean specialize = elementCount <= MAX_ELEMENTS_FOR_SPECIALIZE1;
for (int i = 0; i < elementCount; i++) {
if ((descriptor & (1 << i)) != 0) {
if (isStringElement(descriptor, i)) {
ByteListAndCodeRange blcr = new ByteListAndCodeRange(StringBootstrap.bytelist((String) stringArgs[stringArgsIdx * 3], (String) stringArgs[stringArgsIdx * 3 + 1]), (Integer) stringArgs[stringArgsIdx * 3 + 2]);
strings[i] = blcr;
if (specialize) {
Expand Down Expand Up @@ -483,15 +487,21 @@ private static RubyString createBufferFromStaticString(ThreadContext context, in
}

private static boolean isDynamicElement(long descriptor, int i) {
return (descriptor & (1 << i)) == 0;
if (i > 63) throw new ArrayIndexOutOfBoundsException("bit " + i + " out of long range");
return (descriptor & (1L << i)) == 0;
}

private static boolean isStringElement(long descriptor, int i) {
if (i > 63) throw new ArrayIndexOutOfBoundsException("bit " + i + " out of long range");
return (descriptor & (1L << i)) != 0;
}

public RubyString buildString(ThreadContext context, IRubyObject... values) {
RubyString buffer = StringBootstrap.bufferString(context, encoding, initialSize, StringSupport.CR_7BIT);

int valueIdx = 0;
for (int i = 0; i < elementCount; i++) {
if ((descriptor & (1 << i)) != 0) {
if (isStringElement(descriptor, i)) {
buffer.catWithCodeRange(strings[i].bl, strings[i].cr);
} else {
buffer.appendAsStringOrAny(values[valueIdx++]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public void pushBufferString(Encoding encoding, int size) {
}

public void buildDynamicString(Encoding encoding, int estimatedSize, boolean frozen, boolean chilled, boolean debugFrozen, String file, int line, List<DStringElement> elements) {
if (elements.size() > 50 || !Options.COMPILE_INVOKEDYNAMIC.load()) {
if (elements.size() > BuildDynamicStringSite.MAX_ELEMENTS || !Options.COMPILE_INVOKEDYNAMIC.load()) {
normalValueCompiler.buildDynamicString(encoding, estimatedSize, frozen, chilled, debugFrozen, file, line, elements);
return;
}
Expand Down
5 changes: 5 additions & 0 deletions spec/compiler/general_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,11 @@ def self.name; "aot"; end
run('i = 1; a = "hello#{i + 42}"; a') {|result| expect(result).to eq("hello43") }
# same cases in presence of refinements
run('class NoToS; end; module AddToS; refine(NoToS){def to_s; "42"; end}; end; class TryToS; using AddToS; def self.a; "hello#{NoToS.new}"; end; end; TryToS.a') {|result| expect(result).to eq('hello42') }

# https://github.com/jruby/jruby/issues/8847
pid_dstr_32_times = '#{$$}' * 32
pid_32_times = ([$$] * 32).join('')
run("\"hello#{pid_dstr_32_times}\"") {|result| expect(result).to eq('hello' + pid_32_times) }
end

it "compiles calls" do
Expand Down
Loading