8072844: Use more efficient LambdaForm type representation
Reviewed-by: sundar, redestad
This commit is contained in:
parent
b3fa048050
commit
d66865cb0f
@ -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());
|
||||||
|
@ -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];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user