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

View File

@ -1276,10 +1276,10 @@ class InvokerBytecodeGenerator {
/** /**
* Generate bytecode for a LambdaForm.vmentry which calls interpretWithArguments. * Generate bytecode for a LambdaForm.vmentry which calls interpretWithArguments.
*/ */
static MemberName generateLambdaFormInterpreterEntryPoint(String sig) { static MemberName generateLambdaFormInterpreterEntryPoint(MethodType mt) {
assert(isValidSignature(sig)); assert(isValidSignature(basicTypeSignature(mt)));
String name = "interpret_"+signatureReturn(sig).basicTypeChar(); String name = "interpret_"+basicTypeChar(mt.returnType());
MethodType type = signatureType(sig); // sig includes leading argument MethodType type = mt; // includes leading argument
type = type.changeParameterType(0, MethodHandle.class); type = type.changeParameterType(0, MethodHandle.class);
InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("LFI", name, type); InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("LFI", name, type);
return g.loadMethod(g.generateLambdaFormInterpreterEntryPointBytes()); return g.loadMethod(g.generateLambdaFormInterpreterEntryPointBytes());

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -288,32 +288,28 @@ class LambdaForm {
return names; return names;
} }
private LambdaForm(String sig) { private LambdaForm(MethodType mt) {
// Make a blank lambda form, which returns a constant zero or null. // 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. // It is used as a template for managing the invocation of similar forms that are non-empty.
// Called only from getPreparedForm. // Called only from getPreparedForm.
assert(isValidSignature(sig)); this.arity = mt.parameterCount();
this.arity = signatureArity(sig); this.result = (mt.returnType() == void.class || mt.returnType() == Void.class) ? -1 : arity;
this.result = (signatureReturn(sig) == V_TYPE ? -1 : arity); this.names = buildEmptyNames(arity, mt, result == -1);
this.names = buildEmptyNames(arity, sig);
this.debugName = "LF.zero"; this.debugName = "LF.zero";
this.forceInline = true; this.forceInline = true;
this.customized = null; this.customized = null;
assert(nameRefsAreLegal()); assert(nameRefsAreLegal());
assert(isEmpty()); assert(isEmpty());
String sig = null;
assert(isValidSignature(sig = basicTypeSignature()));
assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature(); assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature();
} }
private static Name[] buildEmptyNames(int arity, String basicTypeSignature) { private static Name[] buildEmptyNames(int arity, MethodType mt, boolean isVoid) {
assert(isValidSignature(basicTypeSignature)); Name[] names = arguments(isVoid ? 0 : 1, mt);
int resultPos = arity + 1; // skip '_' if (!isVoid) {
if (arity < 0 || basicTypeSignature.length() != resultPos+1) Name zero = new Name(constantZero(basicType(mt.returnType())));
throw new IllegalArgumentException("bad arity for "+basicTypeSignature); names[arity] = zero.newIndex(arity);
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);
} }
return names; return names;
} }
@ -520,8 +516,13 @@ class LambdaForm {
/** Return the method type corresponding to my basic type signature. */ /** Return the method type corresponding to my basic type signature. */
MethodType methodType() { 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. */ /** Return ABC_Z, where the ABC are parameter type characters, and Z is the return type character. */
final String basicTypeSignature() { final String basicTypeSignature() {
StringBuilder buf = new StringBuilder(arity() + 3); StringBuilder buf = new StringBuilder(arity() + 3);
@ -633,7 +634,14 @@ class LambdaForm {
// already prepared (e.g., a primitive DMH invoker form) // already prepared (e.g., a primitive DMH invoker form)
return; 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; this.vmentry = prep.vmentry;
// TO DO: Maybe add invokeGeneric, invokeWithArguments // TO DO: Maybe add invokeGeneric, invokeWithArguments
} }
@ -664,9 +672,10 @@ class LambdaForm {
if (mt.parameterCount() > 0 && if (mt.parameterCount() > 0 &&
mt.parameterType(0) == MethodHandle.class && mt.parameterType(0) == MethodHandle.class &&
m.getName().startsWith("interpret_")) { m.getName().startsWith("interpret_")) {
String sig = basicTypeSignature(mt); String sig = null;
assert(m.getName().equals("interpret" + sig.substring(sig.indexOf('_')))); assert((sig = basicTypeSignature(mt)) != null &&
LambdaForm form = new LambdaForm(sig); m.getName().equals("interpret" + sig.substring(sig.indexOf('_'))));
LambdaForm form = new LambdaForm(mt);
form.vmentry = m; form.vmentry = m;
form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, form); form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, form);
} }
@ -702,15 +711,6 @@ class LambdaForm {
assert(returnTypesMatch(sig, av, res)); assert(returnTypesMatch(sig, av, res));
return 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 // The next few routines are called only from assert expressions
// They verify that the built-in invokers process the correct raw data types. // 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; if (n.constraint != null) return n;
return argument(n.index, n.type); 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) { static Name[] arguments(int extra, MethodType types) {
int length = types.parameterCount(); int length = types.parameterCount();
Name[] names = new Name[length + extra]; Name[] names = new Name[length + extra];