8072844: Use more efficient LambdaForm type representation

Reviewed-by: sundar, redestad
This commit is contained in:
Michael Haupt 2015-12-03 15:34:39 +01:00
parent b3fa048050
commit d66865cb0f
2 changed files with 34 additions and 41 deletions
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];