Top Description Inners Fields Constructors Methods
java.lang.invoke

pack-priv Class LambdaForm

extends Object
Class Inheritance
Imports
jdk.internal.perf.PerfCounter, jdk.internal.vm.annotation.DontInline, .Hidden, .Stable, sun.invoke.util.Wrapper, java.lang.annotation.ElementType, .Retention, .RetentionPolicy, .Target, java.lang.reflect.Method, java.util.Arrays, .HashMap

The symbolic, non-executable form of a method handle's invocation semantics. It consists of a series of names. The first N (N=arity) names are parameters, while any remaining names are temporary values. Each temporary specifies the application of a function to some arguments. The functions are method handles, while the arguments are mixes of constant values and local names. The result of the lambda is defined as one of the names, often the last one.

Here is an approximate grammar:

LambdaForm = "(" ArgName* ")=>{" TempName* Result "}"
ArgName = "a" N ":" T
TempName = "t" N ":" T "=" Function "(" Argument* ");"
Function = ConstantValue
Argument = NameRef | ConstantValue
Result = NameRef | "void"
NameRef = "a" N | "t" N
N = (any whole number)
T = "L" | "I" | "J" | "F" | "D" | "V"
Names are numbered consecutively from left to right starting at zero. (The letters are merely a taste of syntax sugar.) Thus, the first temporary (if any) is always numbered N (where N=arity). Every occurrence of a name reference in an argument list must refer to a name previously defined within the same lambda. A lambda has a void result if and only if its result index is -1. If a temporary has the type "V", it cannot be the subject of a NameRef, even though possesses a number. Note that all reference types are erased to "L", which stands for Object. All subword types (boolean, byte, short, char) are erased to "I" which is int. The other types stand for the usual primitive types.

Function invocation closely follows the static rules of the Java verifier. Arguments and return values must exactly match when their "Name" types are considered. Conversions are allowed only if they do not change the erased type.

Although implicit conversions are not allowed, explicit ones can easily be encoded by using temporary expressions which call type-transformed identity functions.

Examples:

(a0:J)=>{ a0 }
    == identity(long)
(a0:I)=>{ t1:V = System.out#println(a0); void }
    == System.out#println(int)
(a0:L)=>{ t1:V = System.out#println(a0); a0 }
    == identity, with printing side-effect
(a0:L, a1:L)=>{ t2:L = BoundMethodHandle#argument(a0);
                t3:L = BoundMethodHandle#target(a0);
                t4:L = MethodHandle#invoke(t3, t2, a1); t4 }
    == general invoker for unary insertArgument combination
(a0:L, a1:L)=>{ t2:L = FilterMethodHandle#filter(a0);
                t3:L = MethodHandle#invoke(t2, a1);
                t4:L = FilterMethodHandle#target(a0);
                t5:L = MethodHandle#invoke(t4, t3); t5 }
    == general invoker for unary filterArgument combination
(a0:L, a1:L)=>{ ...(same as previous example)...
                t5:L = MethodHandle#invoke(t4, t3, a1); t5 }
    == general invoker for unary/unary foldArgument combination
(a0:L, a1:I)=>{ t2:I = identity(long).asType((int)->long)(a1); t2 }
    == invoker for identity method handle which performs i2l
(a0:L, a1:L)=>{ t2:L = BoundMethodHandle#argument(a0);
                t3:L = Class#cast(t2,a1); t3 }
    == invoker for identity method handle which performs cast

Author
John Rose, JSR 292 EG

Nested and Inner Type Summary

Modifier and TypeClass and Description
pack-priv static enum
pack-priv static @interface
LambdaForm.Compiled

Internal marker for byte-compiled LambdaForms.

pack-priv class
pack-priv static enum
pack-priv static class
pack-priv static class

Field Summary

Modifier and TypeField and Description
pack-priv final int
private static final int
COMPILE_THRESHOLD

If the invocation count hits the threshold we spin bytecodes and call that subsequently.

private static final Object
pack-priv final MethodHandle
private static final HashMap<String, Integer>
private static final HashMap<LambdaForm, String>
private static final MethodHandle
private static final boolean
private static final LambdaForm.Kind
private static final int
pack-priv final boolean
private static final MemberName.Factory
pack-priv static final int
private static final LambdaForm.Name[][]
private int
private boolean
pack-priv final LambdaForm.Kind
public static final int
private static PerfCounter
private static final LambdaForm[]
private static final LambdaForm[]
pack-priv final LambdaForm.Name[]
private static final LambdaForm.NamedFunction[]
private static final LambdaForm.NamedFunction[]
pack-priv final int
private static final boolean
pack-priv volatile Object
pack-priv MemberName
public static final int

Constructor Summary

AccessConstructor and Description
private
LambdaForm(int arity, int result, boolean forceInline, MethodHandle customized, LambdaForm.Name[] names, LambdaForm.Kind kind)

Method Summary

Modifier and TypeMethod and Description
pack-priv static LambdaForm.Name
argument(int which, LambdaForm.BasicType type)

pack-priv static LambdaForm.Name[]
arguments(int extra, MethodType types)

private static boolean
pack-priv int
arity()

Report the arity.

private boolean
arityCheck(Object[] argumentValues)

pack-priv static void
pack-priv final String
basicTypeSignature()

Return ABC_Z, where the ABC are parameter type characters, and Z is the return type character.

public static String
private static LambdaForm.Name[]
buildEmptyNames(int arity, MethodType mt, boolean isVoid)

private static boolean
checkInt(Class<?> type, Object x)

private void
private static boolean
checkRef(Class<?> type, Object x)

pack-priv void
compileToBytecode()

Generate optimizable bytecode for this form.

pack-priv static LambdaForm.NamedFunction
pack-priv boolean
private static LambdaForm
create(int arity, LambdaForm.Name[] names, int result, boolean forceInline, MethodHandle customized, LambdaForm.Kind kind)

pack-priv static LambdaForm
create(int arity, LambdaForm.Name[] names, int result)

pack-priv static LambdaForm
create(int arity, LambdaForm.Name[] names, int result, LambdaForm.Kind kind)

pack-priv static LambdaForm
create(int arity, LambdaForm.Name[] names)

pack-priv static LambdaForm
create(int arity, LambdaForm.Name[] names, LambdaForm.Kind kind)

pack-priv static LambdaForm
create(int arity, LambdaForm.Name[] names, boolean forceInline, LambdaForm.Kind kind)

private static LambdaForm
private static void
pack-priv LambdaForm
customize(MethodHandle mh)

Customize LambdaForm for a particular MethodHandle

pack-priv static boolean
pack-priv String
debugString(int indentLevel)

pack-priv LambdaFormEditor
public boolean
equals(Object
the reference object with which to compare.
obj
)

Overrides java.lang.Object.equals.

Indicates whether some other object is "equal to" this one.

public boolean
pack-priv int
expressionCount()

Report the number of expressions (non-parameter names).

private static PerfCounter
private static int
fixResult(int result, LambdaForm.Name[] names)

private boolean
private String
public int
hashCode()

Overrides java.lang.Object.hashCode.

Returns a hash code value for this object.

pack-priv static LambdaForm.NamedFunction
private static double
identity_D(double x)

private static float
identity_F(float x)

private static int
identity_I(int x)

private static long
identity_J(long x)

private static Object
private static void
pack-priv static LambdaForm
pack-priv static LambdaForm.Name
pack-priv Object
interpretName(LambdaForm.Name name, Object[] values)

Evaluate a single Name within this form, applying its function to its arguments.

pack-priv Object
interpretWithArguments(Object... argumentValues)

Interpretively invoke this form on the given arguments.

pack-priv Object
private boolean
pack-priv boolean
isGuardWithCatch(int pos)

Check if i-th name is a start of GuardWithCatch idiom.

pack-priv boolean
isLoop(int pos)

Check if i-th name is a start of the loop idiom.

private boolean
isMatchingIdiom(int pos, String idiomName, int nArgs)

pack-priv boolean
isSelectAlternative(int pos)

Check if i-th name is a call to MethodHandleImpl.selectAlternative.

pack-priv boolean
isTableSwitch(int pos)

Check if i-th name is a start of the tableSwitch idiom.

pack-priv boolean
isTryFinally(int pos)

Check if i-th name is a start of the tryFinally idiom.

pack-priv static boolean
pack-priv String
pack-priv int
lastUseIndex(LambdaForm.Name n)

Return the index of the last name which contains n as an argument.

pack-priv MethodType
methodType()

Return the method type corresponding to my basic type signature.

pack-priv boolean
nameRefsAreLegal()

Check that all embedded Name references are localizable to this lambda, and are properly ordered after their corresponding definitions.

private static boolean
namesOK(int arity, LambdaForm.Name[] names)

private static boolean

Returns:

true if we can interpret
normalizeNames
(int arity, LambdaForm.Name[] names)

Renumber and/or replace params so that they are interned and canonically numbered.

pack-priv LambdaForm.Name
parameter(int n)

Report the N-th argument name.

pack-priv Object
parameterConstraint(int n)

Report the N-th argument type constraint.

pack-priv LambdaForm.BasicType
parameterType(int n)

Report the N-th argument type.

public void
prepare()

Make this LF directly executable, as part of a MethodHandle.

private boolean
resultCheck(Object[] argumentValues, Object result)

pack-priv LambdaForm.BasicType
returnType()

Report the return type.

public static String

Returns:

same sequence, with repetitions counted by decimal numerals
shortenSignature
(String
sequence of uppercase ASCII letters with possible repetitions
signature
)

Hack to make signatures more readable when they show up in method names.

pack-priv static int
public String
toString()

Overrides java.lang.Object.toString.

Returns a string representation of the object.

pack-priv static void
traceInterpreter(String event, Object obj, Object... args)

pack-priv static void
pack-priv LambdaForm
uncustomize()

Get uncustomized flavor of the LambdaForm

pack-priv int
useCount(LambdaForm.Name n)

Return the number of times n is used as an argument or return value.

private static boolean
private static double
private static float
private static int
private static long
private static Object
pack-priv static LambdaForm
Inherited from java.lang.Object:
clonefinalizegetClassnotifynotifyAllwaitwaitwait