Skip to content

Commit cca513e

Browse files
committed
Move string-related bootstrapping to StringSites
1 parent ad30637 commit cca513e

File tree

4 files changed

+148
-130
lines changed

4 files changed

+148
-130
lines changed

core/src/main/java/org/jruby/ir/targets/indy/Bootstrap.java

Lines changed: 0 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import com.headius.invokebinder.SmartBinder;
3232
import com.headius.invokebinder.SmartHandle;
3333
import org.jcodings.Encoding;
34-
import org.jcodings.EncodingDB;
3534
import org.jruby.Ruby;
3635
import org.jruby.RubyArray;
3736
import org.jruby.RubyBasicObject;
@@ -87,7 +86,6 @@
8786
import org.jruby.util.ByteList;
8887
import org.jruby.util.CodegenUtils;
8988
import org.jruby.util.JavaNameMangler;
90-
import org.jruby.util.StringSupport;
9189
import org.jruby.util.cli.Options;
9290
import org.jruby.util.log.Logger;
9391
import org.jruby.util.log.LoggerFactory;
@@ -126,55 +124,8 @@ public class Bootstrap {
126124
public final static String BOOTSTRAP_INT_SIG = sig(CallSite.class, Lookup.class, String.class, MethodType.class, int.class);
127125
private static final Logger LOG = LoggerFactory.getLogger(Bootstrap.class);
128126
static final Lookup LOOKUP = MethodHandles.lookup();
129-
public static final Handle EMPTY_STRING_BOOTSTRAP = new Handle(
130-
Opcodes.H_INVOKESTATIC,
131-
p(Bootstrap.class),
132-
"emptyString",
133-
sig(CallSite.class, Lookup.class, String.class, MethodType.class, String.class),
134-
false);
135-
public static final Handle BUFFER_STRING_BOOTSTRAP = new Handle(
136-
Opcodes.H_INVOKESTATIC,
137-
p(Bootstrap.class),
138-
"bufferString",
139-
sig(CallSite.class, Lookup.class, String.class, MethodType.class, String.class, int.class),
140-
false);
141127
private static final String[] GENERIC_CALL_PERMUTE = {"context", "self", "arg.*"};
142128

143-
public static CallSite string(Lookup lookup, String name, MethodType type, String value, String encodingName, int cr) {
144-
return new ConstantCallSite(insertArguments(STRING_HANDLE, 1, bytelist(value, encodingName), cr));
145-
}
146-
147-
private static final MethodHandle STRING_HANDLE =
148-
Binder
149-
.from(RubyString.class, ThreadContext.class, ByteList.class, int.class)
150-
.invokeStaticQuiet(LOOKUP, Bootstrap.class, "string");
151-
152-
public static CallSite fstring(Lookup lookup, String name, MethodType type, String value, String encodingName, int cr, String file, int line) {
153-
MutableCallSite site = new MutableCallSite(type);
154-
155-
site.setTarget(insertArguments(FSTRING_HANDLE, 1, site, bytelist(value, encodingName), cr, file, line));
156-
157-
return site;
158-
}
159-
160-
private static final MethodHandle FSTRING_HANDLE =
161-
Binder
162-
.from(RubyString.class, ThreadContext.class, MutableCallSite.class, ByteList.class, int.class, String.class, int.class)
163-
.invokeStaticQuiet(LOOKUP, Bootstrap.class, "frozenString");
164-
165-
public static CallSite emptyString(Lookup lookup, String name, MethodType type, String encodingName) {
166-
RubyString.EmptyByteListHolder holder = RubyString.getEmptyByteList(encodingFromName(encodingName));
167-
return new ConstantCallSite(insertArguments(STRING_HANDLE, 1, holder.bytes, holder.cr));
168-
}
169-
170-
public static CallSite bufferString(Lookup lookup, String name, MethodType type, String encodingName, int size) {
171-
return new ConstantCallSite(insertArguments(BUFFERSTRING_HANDLE, 1, encodingFromName(encodingName), size, StringSupport.CR_7BIT));
172-
}
173-
174-
private static final MethodHandle BUFFERSTRING_HANDLE =
175-
Binder
176-
.from(RubyString.class, ThreadContext.class, Encoding.class, int.class, int.class)
177-
.invokeStaticQuiet(LOOKUP, Bootstrap.class, "bufferString");
178129

179130
public static Handle isNilBoot() {
180131
return new Handle(
@@ -266,36 +217,6 @@ public static boolean isTruthy(IRubyObject obj, RubyNil nil, RubyBoolean.False f
266217
}
267218
}
268219

269-
public static CallSite bytelist(Lookup lookup, String name, MethodType type, String value, String encodingName) {
270-
return new ConstantCallSite(constant(ByteList.class, bytelist(value, encodingName)));
271-
}
272-
273-
public static ByteList bytelist(String value, String encodingName) {
274-
Encoding encoding = encodingFromName(encodingName);
275-
276-
if (value.length() == 0) {
277-
// special case empty string and don't create a new BL
278-
return RubyString.getEmptyByteList(encoding).bytes;
279-
}
280-
281-
return new ByteList(RubyEncoding.encodeISO(value), encoding, false);
282-
}
283-
284-
public static ByteList bytelist(int size, String encodingName) {
285-
Encoding encoding = encodingFromName(encodingName);
286-
287-
return new ByteList(size, encoding);
288-
}
289-
290-
private static Encoding encodingFromName(String encodingName) {
291-
Encoding encoding;
292-
EncodingDB.Entry entry = EncodingDB.getEncodings().get(encodingName.getBytes());
293-
if (entry == null) entry = EncodingDB.getAliases().get(encodingName.getBytes());
294-
if (entry == null) throw new RuntimeException("could not find encoding: " + encodingName);
295-
encoding = entry.getEncoding();
296-
return encoding;
297-
}
298-
299220
public static final Handle CALLSITE = new Handle(
300221
Opcodes.H_INVOKESTATIC,
301222
p(Bootstrap.class),
@@ -456,33 +377,6 @@ public static CallSite kwargsHash(Lookup lookup, String name, MethodType type) {
456377
.from(RubyHash.class, ThreadContext.class, RubyHash.class, IRubyObject[].class)
457378
.invokeStaticQuiet(LOOKUP, Bootstrap.class, "kwargsHash");
458379

459-
public static Handle string() {
460-
return new Handle(
461-
Opcodes.H_INVOKESTATIC,
462-
p(Bootstrap.class),
463-
"string",
464-
sig(CallSite.class, Lookup.class, String.class, MethodType.class, String.class, String.class, int.class),
465-
false);
466-
}
467-
468-
public static Handle fstring() {
469-
return new Handle(
470-
Opcodes.H_INVOKESTATIC,
471-
p(Bootstrap.class),
472-
"fstring",
473-
sig(CallSite.class, Lookup.class, String.class, MethodType.class, String.class, String.class, int.class, String.class, int.class),
474-
false);
475-
}
476-
477-
public static Handle bytelist() {
478-
return new Handle(
479-
Opcodes.H_INVOKESTATIC,
480-
p(Bootstrap.class),
481-
"bytelist",
482-
sig(CallSite.class, Lookup.class, String.class, MethodType.class, String.class, String.class),
483-
false);
484-
}
485-
486380
public static Handle array() {
487381
return new Handle(
488382
Opcodes.H_INVOKESTATIC,
@@ -523,23 +417,6 @@ public static Handle global() {
523417
false);
524418
}
525419

526-
public static RubyString string(ThreadContext context, ByteList value, int cr) {
527-
return RubyString.newStringShared(context.runtime, value, cr);
528-
}
529-
530-
public static RubyString bufferString(ThreadContext context, Encoding encoding, int size, int cr) {
531-
return RubyString.newString(context.runtime, new ByteList(size, encoding), cr);
532-
}
533-
534-
public static RubyString frozenString(ThreadContext context, MutableCallSite site, ByteList value, int cr, String file, int line) {
535-
RubyString frozen = IRRuntimeHelpers.newFrozenString(context, value, cr, file, line);
536-
537-
// Permanently bind to the new frozen string
538-
site.setTarget(dropArguments(constant(RubyString.class, frozen), 0, ThreadContext.class));
539-
540-
return frozen;
541-
}
542-
543420
public static RubyArray array(ThreadContext context, IRubyObject[] ary) {
544421
assert ary.length > RubyArraySpecialized.MAX_PACKED_SIZE;
545422
// Bootstrap.array() only dispatches here if ^^ holds

core/src/main/java/org/jruby/ir/targets/indy/IndyValueCompiler.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import org.jruby.util.CodegenUtils;
2525

2626
import java.math.BigInteger;
27-
import java.util.function.Consumer;
2827

2928
import static org.jruby.util.CodegenUtils.ci;
3029
import static org.jruby.util.CodegenUtils.p;
@@ -74,26 +73,26 @@ public void pushFloat(double d) {
7473

7574
public void pushString(ByteList bl, int cr) {
7675
compiler.loadContext();
77-
compiler.adapter.invokedynamic("string", sig(RubyString.class, ThreadContext.class), Bootstrap.string(), RubyEncoding.decodeRaw(bl), bl.getEncoding().toString(), cr);
76+
compiler.adapter.invokedynamic("string", sig(RubyString.class, ThreadContext.class), StringSites.STRING_BOOTSTRAP, RubyEncoding.decodeRaw(bl), bl.getEncoding().toString(), cr);
7877
}
7978

8079
public void pushFrozenString(ByteList bl, int cr, String file, int line) {
8180
compiler.loadContext();
82-
compiler.adapter.invokedynamic("frozen", sig(RubyString.class, ThreadContext.class), Bootstrap.fstring(), RubyEncoding.decodeRaw(bl), bl.getEncoding().toString(), cr, file, line);
81+
compiler.adapter.invokedynamic("frozen", sig(RubyString.class, ThreadContext.class), StringSites.FSTRING_BOOTSTRAP, RubyEncoding.decodeRaw(bl), bl.getEncoding().toString(), cr, file, line);
8382
}
8483

8584
public void pushEmptyString(Encoding encoding) {
8685
compiler.loadContext();
87-
compiler.adapter.invokedynamic("emptyString", sig(RubyString.class, ThreadContext.class), Bootstrap.EMPTY_STRING_BOOTSTRAP, encoding.toString());
86+
compiler.adapter.invokedynamic("emptyString", sig(RubyString.class, ThreadContext.class), StringSites.EMPTY_STRING_BOOTSTRAP, encoding.toString());
8887
}
8988

9089
public void pushBufferString(Encoding encoding, int size) {
9190
compiler.loadContext();
92-
compiler.adapter.invokedynamic("bufferString", sig(RubyString.class, ThreadContext.class), Bootstrap.BUFFER_STRING_BOOTSTRAP, encoding.toString(), size);
91+
compiler.adapter.invokedynamic("bufferString", sig(RubyString.class, ThreadContext.class), StringSites.BUFFER_STRING_BOOTSTRAP, encoding.toString(), size);
9392
}
9493

9594
public void pushByteList(ByteList bl) {
96-
compiler.adapter.invokedynamic("bytelist", sig(ByteList.class), Bootstrap.bytelist(), RubyEncoding.decodeRaw(bl), bl.getEncoding().toString());
95+
compiler.adapter.invokedynamic("bytelist", sig(ByteList.class), StringSites.BYTELIST_BOOTSTRAP, RubyEncoding.decodeRaw(bl), bl.getEncoding().toString());
9796
}
9897

9998
public void pushRange(Runnable begin, Runnable end, boolean exclusive) {

core/src/main/java/org/jruby/ir/targets/indy/RegexpObjectSite.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public RegexpObjectSite(MethodType type, ByteList pattern, int embeddedOptions)
3838
false);
3939

4040
public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, String value, String encodingName, int options) {
41-
return new RegexpObjectSite(type, Bootstrap.bytelist(value, encodingName), options).bootstrap(lookup);
41+
return new RegexpObjectSite(type, StringSites.bytelist(value, encodingName), options).bootstrap(lookup);
4242
}
4343

4444
// normal regexp
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package org.jruby.ir.targets.indy;
2+
3+
import com.headius.invokebinder.Binder;
4+
import org.jcodings.Encoding;
5+
import org.jcodings.EncodingDB;
6+
import org.jruby.RubyEncoding;
7+
import org.jruby.RubyString;
8+
import org.jruby.ir.runtime.IRRuntimeHelpers;
9+
import org.jruby.runtime.ThreadContext;
10+
import org.jruby.util.ByteList;
11+
import org.jruby.util.StringSupport;
12+
import org.objectweb.asm.Handle;
13+
import org.objectweb.asm.Opcodes;
14+
15+
import java.lang.invoke.CallSite;
16+
import java.lang.invoke.ConstantCallSite;
17+
import java.lang.invoke.MethodHandle;
18+
import java.lang.invoke.MethodHandles;
19+
import java.lang.invoke.MethodType;
20+
import java.lang.invoke.MutableCallSite;
21+
22+
import static java.lang.invoke.MethodHandles.constant;
23+
import static java.lang.invoke.MethodHandles.dropArguments;
24+
import static java.lang.invoke.MethodHandles.insertArguments;
25+
import static org.jruby.util.CodegenUtils.p;
26+
import static org.jruby.util.CodegenUtils.sig;
27+
28+
public class StringSites {
29+
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
30+
31+
public static final Handle BYTELIST_BOOTSTRAP = new Handle(
32+
Opcodes.H_INVOKESTATIC,
33+
p(StringSites.class),
34+
"bytelist",
35+
sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class, String.class),
36+
false);
37+
public static final Handle STRING_BOOTSTRAP = new Handle(
38+
Opcodes.H_INVOKESTATIC,
39+
p(StringSites.class),
40+
"string",
41+
sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class, String.class, int.class),
42+
false);
43+
public static final Handle EMPTY_STRING_BOOTSTRAP = new Handle(
44+
Opcodes.H_INVOKESTATIC,
45+
p(StringSites.class),
46+
"emptyString",
47+
sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class),
48+
false);
49+
public static final Handle BUFFER_STRING_BOOTSTRAP = new Handle(
50+
Opcodes.H_INVOKESTATIC,
51+
p(StringSites.class),
52+
"bufferString",
53+
sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class, int.class),
54+
false);
55+
public static final Handle FSTRING_BOOTSTRAP = new Handle(
56+
Opcodes.H_INVOKESTATIC,
57+
p(StringSites.class),
58+
"fstring",
59+
sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class, String.class, int.class, String.class, int.class),
60+
false);
61+
62+
private static final MethodHandle STRING_HANDLE =
63+
Binder
64+
.from(RubyString.class, ThreadContext.class, ByteList.class, int.class)
65+
.invokeStaticQuiet(LOOKUP, StringSites.class, "string");
66+
private static final MethodHandle FSTRING_HANDLE =
67+
Binder
68+
.from(RubyString.class, ThreadContext.class, MutableCallSite.class, ByteList.class, int.class, String.class, int.class)
69+
.invokeStaticQuiet(LOOKUP, StringSites.class, "frozenString");
70+
private static final MethodHandle BUFFERSTRING_HANDLE =
71+
Binder
72+
.from(RubyString.class, ThreadContext.class, Encoding.class, int.class, int.class)
73+
.invokeStaticQuiet(LOOKUP, StringSites.class, "bufferString");
74+
75+
public static CallSite bytelist(MethodHandles.Lookup lookup, String name, MethodType type, String value, String encodingName) {
76+
return new ConstantCallSite(constant(ByteList.class, bytelist(value, encodingName)));
77+
}
78+
79+
public static CallSite string(MethodHandles.Lookup lookup, String name, MethodType type, String value, String encodingName, int cr) {
80+
return new ConstantCallSite(insertArguments(STRING_HANDLE, 1, bytelist(value, encodingName), cr));
81+
}
82+
83+
public static CallSite emptyString(MethodHandles.Lookup lookup, String name, MethodType type, String encodingName) {
84+
RubyString.EmptyByteListHolder holder = RubyString.getEmptyByteList(encodingFromName(encodingName));
85+
return new ConstantCallSite(insertArguments(STRING_HANDLE, 1, holder.bytes, holder.cr));
86+
}
87+
88+
public static CallSite bufferString(MethodHandles.Lookup lookup, String name, MethodType type, String encodingName, int size) {
89+
return new ConstantCallSite(insertArguments(BUFFERSTRING_HANDLE, 1, encodingFromName(encodingName), size, StringSupport.CR_7BIT));
90+
}
91+
92+
public static CallSite fstring(MethodHandles.Lookup lookup, String name, MethodType type, String value, String encodingName, int cr, String file, int line) {
93+
MutableCallSite site = new MutableCallSite(type);
94+
95+
site.setTarget(insertArguments(FSTRING_HANDLE, 1, site, bytelist(value, encodingName), cr, file, line));
96+
97+
return site;
98+
}
99+
100+
public static RubyString string(ThreadContext context, ByteList value, int cr) {
101+
return RubyString.newStringShared(context.runtime, value, cr);
102+
}
103+
104+
public static RubyString bufferString(ThreadContext context, Encoding encoding, int size, int cr) {
105+
return RubyString.newString(context.runtime, new ByteList(size, encoding), cr);
106+
}
107+
108+
public static RubyString frozenString(ThreadContext context, MutableCallSite site, ByteList value, int cr, String file, int line) {
109+
RubyString frozen = IRRuntimeHelpers.newFrozenString(context, value, cr, file, line);
110+
111+
// Permanently bind to the new frozen string
112+
site.setTarget(dropArguments(constant(RubyString.class, frozen), 0, ThreadContext.class));
113+
114+
return frozen;
115+
}
116+
117+
public static ByteList bytelist(String value, String encodingName) {
118+
Encoding encoding = encodingFromName(encodingName);
119+
120+
if (value.length() == 0) {
121+
// special case empty string and don't create a new BL
122+
return RubyString.getEmptyByteList(encoding).bytes;
123+
}
124+
125+
return new ByteList(RubyEncoding.encodeISO(value), encoding, false);
126+
}
127+
128+
public static ByteList bytelist(int size, String encodingName) {
129+
Encoding encoding = encodingFromName(encodingName);
130+
131+
return new ByteList(size, encoding);
132+
}
133+
134+
private static Encoding encodingFromName(String encodingName) {
135+
Encoding encoding;
136+
EncodingDB.Entry entry = EncodingDB.getEncodings().get(encodingName.getBytes());
137+
if (entry == null) entry = EncodingDB.getAliases().get(encodingName.getBytes());
138+
if (entry == null) throw new RuntimeException("could not find encoding: " + encodingName);
139+
encoding = entry.getEncoding();
140+
return encoding;
141+
}
142+
}

0 commit comments

Comments
 (0)