8072844: Use more efficient LambdaForm type representation
Reviewed-by: sundar, redestad
This commit is contained in:
parent
b3fa048050
commit
d66865cb0f
jdk/src/java.base/share/classes/java/lang/invoke
@ -1276,10 +1276,10 @@ class InvokerBytecodeGenerator {
|
||||
/**
|
||||
* Generate bytecode for a LambdaForm.vmentry which calls interpretWithArguments.
|
||||
*/
|
||||
static MemberName generateLambdaFormInterpreterEntryPoint(String sig) {
|
||||
assert(isValidSignature(sig));
|
||||
String name = "interpret_"+signatureReturn(sig).basicTypeChar();
|
||||
MethodType type = signatureType(sig); // sig includes leading argument
|
||||
static MemberName generateLambdaFormInterpreterEntryPoint(MethodType mt) {
|
||||
assert(isValidSignature(basicTypeSignature(mt)));
|
||||
String name = "interpret_"+basicTypeChar(mt.returnType());
|
||||
MethodType type = mt; // includes leading argument
|
||||
type = type.changeParameterType(0, MethodHandle.class);
|
||||
InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("LFI", name, type);
|
||||
return g.loadMethod(g.generateLambdaFormInterpreterEntryPointBytes());
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -288,32 +288,28 @@ class LambdaForm {
|
||||
return names;
|
||||
}
|
||||
|
||||
private LambdaForm(String sig) {
|
||||
private LambdaForm(MethodType mt) {
|
||||
// Make a blank lambda form, which returns a constant zero or null.
|
||||
// It is used as a template for managing the invocation of similar forms that are non-empty.
|
||||
// Called only from getPreparedForm.
|
||||
assert(isValidSignature(sig));
|
||||
this.arity = signatureArity(sig);
|
||||
this.result = (signatureReturn(sig) == V_TYPE ? -1 : arity);
|
||||
this.names = buildEmptyNames(arity, sig);
|
||||
this.arity = mt.parameterCount();
|
||||
this.result = (mt.returnType() == void.class || mt.returnType() == Void.class) ? -1 : arity;
|
||||
this.names = buildEmptyNames(arity, mt, result == -1);
|
||||
this.debugName = "LF.zero";
|
||||
this.forceInline = true;
|
||||
this.customized = null;
|
||||
assert(nameRefsAreLegal());
|
||||
assert(isEmpty());
|
||||
String sig = null;
|
||||
assert(isValidSignature(sig = basicTypeSignature()));
|
||||
assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature();
|
||||
}
|
||||
|
||||
private static Name[] buildEmptyNames(int arity, String basicTypeSignature) {
|
||||
assert(isValidSignature(basicTypeSignature));
|
||||
int resultPos = arity + 1; // skip '_'
|
||||
if (arity < 0 || basicTypeSignature.length() != resultPos+1)
|
||||
throw new IllegalArgumentException("bad arity for "+basicTypeSignature);
|
||||
int numRes = (basicType(basicTypeSignature.charAt(resultPos)) == V_TYPE ? 0 : 1);
|
||||
Name[] names = arguments(numRes, basicTypeSignature.substring(0, arity));
|
||||
for (int i = 0; i < numRes; i++) {
|
||||
Name zero = new Name(constantZero(basicType(basicTypeSignature.charAt(resultPos + i))));
|
||||
names[arity + i] = zero.newIndex(arity + i);
|
||||
private static Name[] buildEmptyNames(int arity, MethodType mt, boolean isVoid) {
|
||||
Name[] names = arguments(isVoid ? 0 : 1, mt);
|
||||
if (!isVoid) {
|
||||
Name zero = new Name(constantZero(basicType(mt.returnType())));
|
||||
names[arity] = zero.newIndex(arity);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
@ -520,8 +516,13 @@ class LambdaForm {
|
||||
|
||||
/** Return the method type corresponding to my basic type signature. */
|
||||
MethodType methodType() {
|
||||
return signatureType(basicTypeSignature());
|
||||
Class<?>[] ptypes = new Class<?>[arity];
|
||||
for (int i = 0; i < arity; ++i) {
|
||||
ptypes[i] = parameterType(i).btClass;
|
||||
}
|
||||
return MethodType.methodType(returnType().btClass, ptypes);
|
||||
}
|
||||
|
||||
/** Return ABC_Z, where the ABC are parameter type characters, and Z is the return type character. */
|
||||
final String basicTypeSignature() {
|
||||
StringBuilder buf = new StringBuilder(arity() + 3);
|
||||
@ -633,7 +634,14 @@ class LambdaForm {
|
||||
// already prepared (e.g., a primitive DMH invoker form)
|
||||
return;
|
||||
}
|
||||
LambdaForm prep = getPreparedForm(basicTypeSignature());
|
||||
MethodType mtype = methodType();
|
||||
LambdaForm prep = mtype.form().cachedLambdaForm(MethodTypeForm.LF_INTERPRET);
|
||||
if (prep == null) {
|
||||
assert (isValidSignature(basicTypeSignature()));
|
||||
prep = new LambdaForm(mtype);
|
||||
prep.vmentry = InvokerBytecodeGenerator.generateLambdaFormInterpreterEntryPoint(mtype);
|
||||
prep = mtype.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, prep);
|
||||
}
|
||||
this.vmentry = prep.vmentry;
|
||||
// TO DO: Maybe add invokeGeneric, invokeWithArguments
|
||||
}
|
||||
@ -664,9 +672,10 @@ class LambdaForm {
|
||||
if (mt.parameterCount() > 0 &&
|
||||
mt.parameterType(0) == MethodHandle.class &&
|
||||
m.getName().startsWith("interpret_")) {
|
||||
String sig = basicTypeSignature(mt);
|
||||
assert(m.getName().equals("interpret" + sig.substring(sig.indexOf('_'))));
|
||||
LambdaForm form = new LambdaForm(sig);
|
||||
String sig = null;
|
||||
assert((sig = basicTypeSignature(mt)) != null &&
|
||||
m.getName().equals("interpret" + sig.substring(sig.indexOf('_'))));
|
||||
LambdaForm form = new LambdaForm(mt);
|
||||
form.vmentry = m;
|
||||
form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, form);
|
||||
}
|
||||
@ -702,15 +711,6 @@ class LambdaForm {
|
||||
assert(returnTypesMatch(sig, av, res));
|
||||
return res;
|
||||
}
|
||||
private static LambdaForm getPreparedForm(String sig) {
|
||||
MethodType mtype = signatureType(sig);
|
||||
LambdaForm prep = mtype.form().cachedLambdaForm(MethodTypeForm.LF_INTERPRET);
|
||||
if (prep != null) return prep;
|
||||
assert(isValidSignature(sig));
|
||||
prep = new LambdaForm(sig);
|
||||
prep.vmentry = InvokerBytecodeGenerator.generateLambdaFormInterpreterEntryPoint(sig);
|
||||
return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, prep);
|
||||
}
|
||||
|
||||
// The next few routines are called only from assert expressions
|
||||
// They verify that the built-in invokers process the correct raw data types.
|
||||
@ -1558,13 +1558,6 @@ class LambdaForm {
|
||||
if (n.constraint != null) return n;
|
||||
return argument(n.index, n.type);
|
||||
}
|
||||
static Name[] arguments(int extra, String types) {
|
||||
int length = types.length();
|
||||
Name[] names = new Name[length + extra];
|
||||
for (int i = 0; i < length; i++)
|
||||
names[i] = argument(i, basicType(types.charAt(i)));
|
||||
return names;
|
||||
}
|
||||
static Name[] arguments(int extra, MethodType types) {
|
||||
int length = types.parameterCount();
|
||||
Name[] names = new Name[length + extra];
|
||||
|
Loading…
x
Reference in New Issue
Block a user