227 return "LIJFD".indexOf(c) >= 0;
228 }
229
230 static { assert(checkBasicType()); }
231 private static boolean checkBasicType() {
232 for (int i = 0; i < ARG_TYPE_LIMIT; i++) {
233 assert ARG_TYPES[i].ordinal() == i;
234 assert ARG_TYPES[i] == ALL_TYPES[i];
235 }
236 for (int i = 0; i < TYPE_LIMIT; i++) {
237 assert ALL_TYPES[i].ordinal() == i;
238 }
239 assert ALL_TYPES[TYPE_LIMIT - 1] == V_TYPE;
240 assert !Arrays.asList(ARG_TYPES).contains(V_TYPE);
241 return true;
242 }
243 }
244
245 LambdaForm(String debugName,
246 int arity, Name[] names, int result) {
247 this(debugName, arity, names, result, true);
248 }
249 LambdaForm(String debugName,
250 int arity, Name[] names, int result, boolean forceInline) {
251 assert(namesOK(arity, names));
252 this.arity = arity;
253 this.result = fixResult(result, names);
254 this.names = names.clone();
255 this.debugName = fixDebugName(debugName);
256 this.forceInline = forceInline;
257 int maxOutArity = normalize();
258 if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) {
259 // Cannot use LF interpreter on very high arity expressions.
260 assert(maxOutArity <= MethodType.MAX_JVM_ARITY);
261 compileToBytecode();
262 }
263 }
264 LambdaForm(String debugName,
265 int arity, Name[] names) {
266 this(debugName, arity, names, LAST_RESULT, true);
267 }
268 LambdaForm(String debugName,
269 int arity, Name[] names, boolean forceInline) {
270 this(debugName, arity, names, LAST_RESULT, forceInline);
271 }
272 LambdaForm(String debugName,
273 Name[] formals, Name[] temps, Name result) {
274 this(debugName,
275 formals.length, buildNames(formals, temps, result), LAST_RESULT, true);
276 }
277 LambdaForm(String debugName,
278 Name[] formals, Name[] temps, Name result, boolean forceInline) {
279 this(debugName,
280 formals.length, buildNames(formals, temps, result), LAST_RESULT, forceInline);
281 }
282
283 private static Name[] buildNames(Name[] formals, Name[] temps, Name result) {
284 int arity = formals.length;
285 int length = arity + temps.length + (result == null ? 0 : 1);
286 Name[] names = Arrays.copyOf(formals, length);
287 System.arraycopy(temps, 0, names, arity, temps.length);
288 if (result != null)
289 names[length - 1] = result;
290 return names;
291 }
292
293 private LambdaForm(String sig) {
294 this(sig, true);
295 }
296
297 private LambdaForm(String sig, boolean forceInline) {
298 // Make a blank lambda form, which returns a constant zero or null.
299 // It is used as a template for managing the invocation of similar forms that are non-empty.
300 // Called only from getPreparedForm.
301 assert(isValidSignature(sig));
302 this.arity = signatureArity(sig);
303 this.result = (signatureReturn(sig) == V_TYPE ? -1 : arity);
304 this.names = buildEmptyNames(arity, sig);
305 this.debugName = "LF.zero";
306 this.forceInline = forceInline;
307 assert(nameRefsAreLegal());
308 assert(isEmpty());
309 assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature();
310 }
311
312 private static Name[] buildEmptyNames(int arity, String basicTypeSignature) {
313 assert(isValidSignature(basicTypeSignature));
314 int resultPos = arity + 1; // skip '_'
315 if (arity < 0 || basicTypeSignature.length() != resultPos+1)
316 throw new IllegalArgumentException("bad arity for "+basicTypeSignature);
317 int numRes = (basicType(basicTypeSignature.charAt(resultPos)) == V_TYPE ? 0 : 1);
318 Name[] names = arguments(numRes, basicTypeSignature.substring(0, arity));
319 for (int i = 0; i < numRes; i++) {
320 Name zero = new Name(constantZero(basicType(basicTypeSignature.charAt(resultPos + i))));
321 names[arity + i] = zero.newIndex(arity + i);
322 }
323 return names;
324 }
325
326 private static int fixResult(int result, Name[] names) {
1778 private static void zero_V() { return; }
1779
1780 /**
1781 * Internal marker for byte-compiled LambdaForms.
1782 */
1783 /*non-public*/
1784 @Target(ElementType.METHOD)
1785 @Retention(RetentionPolicy.RUNTIME)
1786 @interface Compiled {
1787 }
1788
1789 /**
1790 * Internal marker for LambdaForm interpreter frames.
1791 */
1792 /*non-public*/
1793 @Target(ElementType.METHOD)
1794 @Retention(RetentionPolicy.RUNTIME)
1795 @interface Hidden {
1796 }
1797
1798 private static final HashMap<String,Integer> DEBUG_NAME_COUNTERS;
1799 static {
1800 if (debugEnabled())
1801 DEBUG_NAME_COUNTERS = new HashMap<>();
1802 else
1803 DEBUG_NAME_COUNTERS = null;
1804 }
1805
1806 // Put this last, so that previous static inits can run before.
1807 static {
1808 createIdentityForms();
1809 if (USE_PREDEFINED_INTERPRET_METHODS)
1810 computeInitialPreparedForms();
1811 NamedFunction.initializeInvokers();
1812 }
1813
1814 // The following hack is necessary in order to suppress TRACE_INTERPRETER
1815 // during execution of the static initializes of this class.
1816 // Turning on TRACE_INTERPRETER too early will cause
1817 // stack overflows and other misbehavior during attempts to trace events
|
227 return "LIJFD".indexOf(c) >= 0;
228 }
229
230 static { assert(checkBasicType()); }
231 private static boolean checkBasicType() {
232 for (int i = 0; i < ARG_TYPE_LIMIT; i++) {
233 assert ARG_TYPES[i].ordinal() == i;
234 assert ARG_TYPES[i] == ALL_TYPES[i];
235 }
236 for (int i = 0; i < TYPE_LIMIT; i++) {
237 assert ALL_TYPES[i].ordinal() == i;
238 }
239 assert ALL_TYPES[TYPE_LIMIT - 1] == V_TYPE;
240 assert !Arrays.asList(ARG_TYPES).contains(V_TYPE);
241 return true;
242 }
243 }
244
245 LambdaForm(String debugName,
246 int arity, Name[] names, int result) {
247 this(debugName, arity, names, result, /*forceInline=*/true);
248 }
249 LambdaForm(String debugName,
250 int arity, Name[] names, int result, boolean forceInline) {
251 assert(namesOK(arity, names));
252 this.arity = arity;
253 this.result = fixResult(result, names);
254 this.names = names.clone();
255 this.debugName = fixDebugName(debugName);
256 this.forceInline = forceInline;
257 int maxOutArity = normalize();
258 if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) {
259 // Cannot use LF interpreter on very high arity expressions.
260 assert(maxOutArity <= MethodType.MAX_JVM_ARITY);
261 compileToBytecode();
262 }
263 }
264 LambdaForm(String debugName,
265 int arity, Name[] names) {
266 this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true);
267 }
268 LambdaForm(String debugName,
269 int arity, Name[] names, boolean forceInline) {
270 this(debugName, arity, names, LAST_RESULT, forceInline);
271 }
272 LambdaForm(String debugName,
273 Name[] formals, Name[] temps, Name result) {
274 this(debugName,
275 formals.length, buildNames(formals, temps, result), LAST_RESULT, /*forceInline=*/true);
276 }
277 LambdaForm(String debugName,
278 Name[] formals, Name[] temps, Name result, boolean forceInline) {
279 this(debugName,
280 formals.length, buildNames(formals, temps, result), LAST_RESULT, forceInline);
281 }
282
283 private static Name[] buildNames(Name[] formals, Name[] temps, Name result) {
284 int arity = formals.length;
285 int length = arity + temps.length + (result == null ? 0 : 1);
286 Name[] names = Arrays.copyOf(formals, length);
287 System.arraycopy(temps, 0, names, arity, temps.length);
288 if (result != null)
289 names[length - 1] = result;
290 return names;
291 }
292
293 private LambdaForm(String sig) {
294 // Make a blank lambda form, which returns a constant zero or null.
295 // It is used as a template for managing the invocation of similar forms that are non-empty.
296 // Called only from getPreparedForm.
297 assert(isValidSignature(sig));
298 this.arity = signatureArity(sig);
299 this.result = (signatureReturn(sig) == V_TYPE ? -1 : arity);
300 this.names = buildEmptyNames(arity, sig);
301 this.debugName = "LF.zero";
302 this.forceInline = true;
303 assert(nameRefsAreLegal());
304 assert(isEmpty());
305 assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature();
306 }
307
308 private static Name[] buildEmptyNames(int arity, String basicTypeSignature) {
309 assert(isValidSignature(basicTypeSignature));
310 int resultPos = arity + 1; // skip '_'
311 if (arity < 0 || basicTypeSignature.length() != resultPos+1)
312 throw new IllegalArgumentException("bad arity for "+basicTypeSignature);
313 int numRes = (basicType(basicTypeSignature.charAt(resultPos)) == V_TYPE ? 0 : 1);
314 Name[] names = arguments(numRes, basicTypeSignature.substring(0, arity));
315 for (int i = 0; i < numRes; i++) {
316 Name zero = new Name(constantZero(basicType(basicTypeSignature.charAt(resultPos + i))));
317 names[arity + i] = zero.newIndex(arity + i);
318 }
319 return names;
320 }
321
322 private static int fixResult(int result, Name[] names) {
1774 private static void zero_V() { return; }
1775
1776 /**
1777 * Internal marker for byte-compiled LambdaForms.
1778 */
1779 /*non-public*/
1780 @Target(ElementType.METHOD)
1781 @Retention(RetentionPolicy.RUNTIME)
1782 @interface Compiled {
1783 }
1784
1785 /**
1786 * Internal marker for LambdaForm interpreter frames.
1787 */
1788 /*non-public*/
1789 @Target(ElementType.METHOD)
1790 @Retention(RetentionPolicy.RUNTIME)
1791 @interface Hidden {
1792 }
1793
1794 /**
1795 * Internal marker which signals JIT that gathered profile is mostly useless.
1796 */
1797 /*non-public*/
1798 @Target(ElementType.METHOD)
1799 @Retention(RetentionPolicy.RUNTIME)
1800 @interface Shared {
1801 }
1802
1803 private static final HashMap<String,Integer> DEBUG_NAME_COUNTERS;
1804 static {
1805 if (debugEnabled())
1806 DEBUG_NAME_COUNTERS = new HashMap<>();
1807 else
1808 DEBUG_NAME_COUNTERS = null;
1809 }
1810
1811 // Put this last, so that previous static inits can run before.
1812 static {
1813 createIdentityForms();
1814 if (USE_PREDEFINED_INTERPRET_METHODS)
1815 computeInitialPreparedForms();
1816 NamedFunction.initializeInvokers();
1817 }
1818
1819 // The following hack is necessary in order to suppress TRACE_INTERPRETER
1820 // during execution of the static initializes of this class.
1821 // Turning on TRACE_INTERPRETER too early will cause
1822 // stack overflows and other misbehavior during attempts to trace events
|