Top Description Inners Fields Constructors Methods
java.lang.invoke

pack-priv abstract Class ClassSpecializer<T, K, S extends ClassSpecializer<T, K, S>.SpeciesData>

extends Object
Class Inheritance
Known Direct Subclasses
java.lang.invoke.BoundMethodHandle.Specializer
Type Parameters
<T>
top class under which species classes are created.
<K>
key which identifies individual specializations.
<S>
species data type.
Imports
jdk.internal.loader.BootLoader, jdk.internal.org.objectweb.asm.ClassWriter, .FieldVisitor, .MethodVisitor, jdk.internal.vm.annotation.Stable, sun.invoke.util.BytecodeName, java.lang.reflect.Constructor, .Field, .Modifier, java.util.ArrayList, .Collections, .List, .Objects, java.util.concurrent.ConcurrentHashMap, java.util.function.Function

Class specialization code.

Nested and Inner Type Summary

Modifier and TypeClass and Description
pack-priv class
ClassSpecializer.Factory

Code generation support for instances.

pack-priv abstract class
ClassSpecializer.SpeciesData

Meta-data wrapper for concrete subtypes of the top class.

Field Summary

Modifier and TypeField and Description
private final MethodType
private final ConcurrentHashMap<K, Object>
private static final Function<Object, Object>
private static final String[]
private final ClassSpecializer<T, K, S>.Factory
private final Class<K>
private final Class<S>
private static final String
private static final String
private final MemberName
private final String
private static final String
private static final String
private final Class<T>
private boolean
private final S
private final List<MemberName>

Constructor Summary

AccessConstructor and Description
protected
ClassSpecializer(Class<T>
type mirror for T
topClass
,
Class<K>
type mirror for K
keyType
,
Class<S>
type mirror for S
metaType
,
MethodType
principal constructor type
baseConstructorType
,
MemberName
the method used to get the speciesData
sdAccessor
,
String
the name of the species data field, inject the speciesData object
sdFieldName
,
List<MemberName>
optional list of transformMethods
transformMethods
)

Constructor for this class specializer.

Method Summary

Modifier and TypeMethod and Description
protected MethodType
baseConstructorType()

Report the leading arguments (if any) required by every species factory.

pack-priv static String
pack-priv static String
pack-priv static String
className(Class<?> cls)

pack-priv static String
classSig(Class<?> cls)

pack-priv static String
classSig(String bcName)

protected final ClassSpecializer<T, K, S>.Factory
factory()

Return the factory object used to build and load concrete species code.

public final S
findSpecies(K key)

public final Class<K>
keyType()

Return the key type mirror, for type K

protected ClassSpecializer<T, K, S>.Factory
makeFactory()

Hook that virtualizes the Factory class, allowing subclasses to extend it.

public final Class<S>
metaType()

Return the species metadata type mirror, for type S

pack-priv static String
private static RuntimeException
newIAE(String message, Throwable cause)

protected abstract S
protected static <T> Constructor<T>
reflectConstructor(Class<T> defc, Class<?>... ptypes)

protected static Field
reflectField(Class<?> defc, String name)

public final Class<T>
topClass()

Return the top type mirror, for type T

protected final S
topSpecies()

Return the trivial species for the null sequence of arguments.

protected K
protected final List<MemberName>
transformMethods()

Return the list of transform methods originally given at creation of this specializer.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

baseConstructorTypeback to summary
private final MethodType baseConstructorType
cacheback to summary
private final ConcurrentHashMap<K, Object> cache
CREATE_RESERVATIONback to summary
private static final Function<Object, Object> CREATE_RESERVATION
E_THROWABLEback to summary
private static final String[] E_THROWABLE
factoryback to summary
private final ClassSpecializer<T, K, S>.Factory factory
keyTypeback to summary
private final Class<K> keyType
metaTypeback to summary
private final Class<S> metaType
MHback to summary
private static final String MH
MH_SIGback to summary
private static final String MH_SIG
sdAccessorback to summary
private final MemberName sdAccessor
sdFieldNameback to summary
private final String sdFieldName
STABLEback to summary
private static final String STABLE
STABLE_SIGback to summary
private static final String STABLE_SIG
topClassback to summary
private final Class<T> topClass
topClassIsSuperback to summary
private boolean topClassIsSuper
Annotations
@Stable
topSpeciesback to summary
private final S topSpecies
transformMethodsback to summary
private final List<MemberName> transformMethods

Constructor Detail

ClassSpecializerback to summary
protected ClassSpecializer(Class<T> topClass, Class<K> keyType, Class<S> metaType, MethodType baseConstructorType, MemberName sdAccessor, String sdFieldName, List<MemberName> transformMethods)

Constructor for this class specializer.

Parameters
topClass:Class<T>

type mirror for T

keyType:Class<K>

type mirror for K

metaType:Class<S>

type mirror for S

baseConstructorType:MethodType

principal constructor type

sdAccessor:MemberName

the method used to get the speciesData

sdFieldName:String

the name of the species data field, inject the speciesData object

transformMethods:List<MemberName>

optional list of transformMethods

Method Detail

baseConstructorTypeback to summary
protected MethodType baseConstructorType()

Report the leading arguments (if any) required by every species factory. Every species factory adds its own field types as additional arguments, but these arguments always come first, in every factory method.

classBCNameback to summary
pack-priv static String classBCName(Class<?> cls)
classBCNameback to summary
pack-priv static String classBCName(String str)
classNameback to summary
pack-priv static String className(Class<?> cls)
classSigback to summary
pack-priv static String classSig(Class<?> cls)
classSigback to summary
pack-priv static String classSig(String bcName)
factoryback to summary
protected final ClassSpecializer<T, K, S>.Factory factory()

Return the factory object used to build and load concrete species code.

findSpeciesback to summary
public final S findSpecies(K key)
keyTypeback to summary
public final Class<K> keyType()

Return the key type mirror, for type K

makeFactoryback to summary
protected ClassSpecializer<T, K, S>.Factory makeFactory()

Hook that virtualizes the Factory class, allowing subclasses to extend it.

metaTypeback to summary
public final Class<S> metaType()

Return the species metadata type mirror, for type S

methodSigback to summary
pack-priv static String methodSig(MethodType mt)
newIAEback to summary
private static RuntimeException newIAE(String message, Throwable cause)
newSpeciesDataback to summary
protected abstract S newSpeciesData(K key)
reflectConstructorback to summary
protected static <T> Constructor<T> reflectConstructor(Class<T> defc, Class<?>... ptypes)
reflectFieldback to summary
protected static Field reflectField(Class<?> defc, String name)
topClassback to summary
public final Class<T> topClass()

Return the top type mirror, for type T

topSpeciesback to summary
protected final S topSpecies()

Return the trivial species for the null sequence of arguments.

topSpeciesKeyback to summary
protected K topSpeciesKey()
transformMethodsback to summary
protected final List<MemberName> transformMethods()

Return the list of transform methods originally given at creation of this specializer.

java.lang.invoke back to summary

pack-priv Class ClassSpecializer.Factory

extends Object
Class Inheritance
Known Direct Subclasses
java.lang.invoke.BoundMethodHandle.Specializer.Factory

Code generation support for instances. Subclasses can modify the behavior.

Field Summary

Modifier and TypeField and Description
private static final int
private final String
private final int
private final String
private final String
private final List<Integer>
private final List<String>
private final List<MethodType>

Constructor Summary

AccessConstructor and Description
pack-priv
Factory()

Constructs a factory.

Method Summary

Modifier and TypeMethod and Description
protected String
chooseFieldName(Class<?> type, int index)

Field names in concrete species classes adhere to this pattern: type + index, where type is a single character (L, I, J, F, D).

private void
private List<MethodHandle>
findFactories(Class<? extends T> speciesCode, List<Class<?>> types)

pack-priv MethodHandle
findFactory(Class<? extends T> speciesCode, List<Class<?>> types)

private MethodHandle
findGetter(Class<?> speciesCode, List<Class<?>> types, int index)

private List<MethodHandle>
findGetters(Class<?> speciesCode, List<Class<?>> types)

pack-priv Class<? extends T>

Returns:

the generated concrete TopClass class
generateConcreteSpeciesCode
(String
of the species
className
,
ClassSpecializer<T, K, S>.SpeciesData
what species we are generating
speciesData
)

Generate a concrete subclass of the top class for a given combination of bound types.

pack-priv byte[]
protected void
linkCodeToSpeciesData(Class<? extends T> speciesCode, ClassSpecializer<T, K, S>.SpeciesData speciesData, boolean salvage)

protected void
linkSpeciesDataToCode(ClassSpecializer<T, K, S>.SpeciesData speciesData, Class<? extends T> speciesCode)

pack-priv S

Returns:

a linked version of the same species
loadSpecies
(S
the species requiring the class, not yet linked
speciesData
)

Get a concrete subclass of the top class for a given combination of bound types.

protected S
loadSpeciesDataFromCode(Class<? extends T> speciesCode)

pack-priv List<LambdaForm.NamedFunction>
private S
readSpeciesDataFromCode(Class<? extends T> speciesCode)

private Field
reflectSDField(Class<? extends T> speciesCode)

private int
typeLoadOp(char t)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

ACC_PPPback to summary
private static final int ACC_PPP
SPECIES_DATAback to summary
private final String SPECIES_DATA
SPECIES_DATA_MODSback to summary
private final int SPECIES_DATA_MODS
SPECIES_DATA_NAMEback to summary
private final String SPECIES_DATA_NAME
SPECIES_DATA_SIGback to summary
private final String SPECIES_DATA_SIG
TRANSFORM_MODSback to summary
private final List<Integer> TRANSFORM_MODS
TRANSFORM_NAMESback to summary
private final List<String> TRANSFORM_NAMES
TRANSFORM_TYPESback to summary
private final List<MethodType> TRANSFORM_TYPES

Constructor Detail

Factoryback to summary
pack-priv Factory()

Constructs a factory.

Method Detail

chooseFieldNameback to summary
protected String chooseFieldName(Class<?> type, int index)

Field names in concrete species classes adhere to this pattern: type + index, where type is a single character (L, I, J, F, D). The factory subclass can customize this. The name is purely cosmetic, since it applies to a private field.

emitIntConstantback to summary
private void emitIntConstant(int con, MethodVisitor mv)
findFactoriesback to summary
private List<MethodHandle> findFactories(Class<? extends T> speciesCode, List<Class<?>> types)
findFactoryback to summary
pack-priv MethodHandle findFactory(Class<? extends T> speciesCode, List<Class<?>> types)
findGetterback to summary
private MethodHandle findGetter(Class<?> speciesCode, List<Class<?>> types, int index)
findGettersback to summary
private List<MethodHandle> findGetters(Class<?> speciesCode, List<Class<?>> types)
generateConcreteSpeciesCodeback to summary
pack-priv Class<? extends T> generateConcreteSpeciesCode(String className, ClassSpecializer<T, K, S>.SpeciesData speciesData)

Generate a concrete subclass of the top class for a given combination of bound types. A concrete species subclass roughly matches the following schema:

class Species_[[types]] extends [[T]] {
    final [[S]] speciesData() { return ... }
    static [[T]] make([[fields]]) { return ... }
    [[fields]]
    final [[T]] transform([[args]]) { return ... }
}
The [[types]] signature is precisely the key for the species. The [[fields]] section consists of one field definition per character in the type signature, adhering to the naming schema described in the definition of chooseFieldName. For example, a concrete species for two references and one integral bound value has a shape like the following:
class TopClass {
    ...
    private static final class Species_LLI extends TopClass {
        final Object argL0;
        final Object argL1;
        final int argI2;
        private Species_LLI(CT ctarg, ..., Object argL0, Object argL1, int argI2) {
            super(ctarg, ...);
            this.argL0 = argL0;
            this.argL1 = argL1;
            this.argI2 = argI2;
        }
        final SpeciesData speciesData() { return BMH_SPECIES; }
        @Stable static SpeciesData BMH_SPECIES; // injected afterwards
        static TopClass make(CT ctarg, ..., Object argL0, Object argL1, int argI2) {
            return new Species_LLI(ctarg, ..., argL0, argL1, argI2);
        }
        final TopClass copyWith(CT ctarg, ...) {
            return new Species_LLI(ctarg, ..., argL0, argL1, argI2);
        }
        // two transforms, for the sake of illustration:
        final TopClass copyWithExtendL(CT ctarg, ..., Object narg) {
            return BMH_SPECIES.transform(L_TYPE).invokeBasic(ctarg, ..., argL0, argL1, argI2, narg);
        }
        final TopClass copyWithExtendI(CT ctarg, ..., int narg) {
            return BMH_SPECIES.transform(I_TYPE).invokeBasic(ctarg, ..., argL0, argL1, argI2, narg);
        }
    }
}
Parameters
className:String

of the species

speciesData:ClassSpecializer<T, K, S>.SpeciesData

what species we are generating

Returns:Class<? extends T>

the generated concrete TopClass class

Annotations
@SuppressWarnings:removal
generateConcreteSpeciesCodeFileback to summary
pack-priv byte[] generateConcreteSpeciesCodeFile(String className0, ClassSpecializer<T, K, S>.SpeciesData speciesData)
linkCodeToSpeciesDataback to summary
protected void linkCodeToSpeciesData(Class<? extends T> speciesCode, ClassSpecializer<T, K, S>.SpeciesData speciesData, boolean salvage)
linkSpeciesDataToCodeback to summary
protected void linkSpeciesDataToCode(ClassSpecializer<T, K, S>.SpeciesData speciesData, Class<? extends T> speciesCode)
loadSpeciesback to summary
pack-priv S loadSpecies(S speciesData)

Get a concrete subclass of the top class for a given combination of bound types.

Parameters
speciesData:S

the species requiring the class, not yet linked

Returns:S

a linked version of the same species

loadSpeciesDataFromCodeback to summary
protected S loadSpeciesDataFromCode(Class<? extends T> speciesCode)
makeNominalGettersback to summary
pack-priv List<LambdaForm.NamedFunction> makeNominalGetters(List<Class<?>> types, List<MethodHandle> getters)
readSpeciesDataFromCodeback to summary
private S readSpeciesDataFromCode(Class<? extends T> speciesCode)
reflectSDFieldback to summary
private Field reflectSDField(Class<? extends T> speciesCode)
typeLoadOpback to summary
private int typeLoadOp(char t)
java.lang.invoke back to summary

pack-priv abstract Class ClassSpecializer.SpeciesData

extends Object
Class Inheritance
Known Direct Subclasses
java.lang.invoke.BoundMethodHandle.SpeciesData

Meta-data wrapper for concrete subtypes of the top class. Each concrete subtype corresponds to a given sequence of basic field types (LIJFD). The fields are immutable; their values are fully specified at object construction. Each species supplies an array of getter functions which may be used in lambda forms. A concrete value is always constructed from the full tuple of its field values, accompanied by the required constructor parameters. There *may* also be transforms which cloning a species instance and either replace a constructor parameter or add one or more new field values. The shortest possible species has zero fields. Subtypes are not interrelated among themselves by subtyping, even though it would appear that a shorter species could serve as a supertype of a longer one which extends it.

Field Summary

Modifier and TypeField and Description
private List<MethodHandle>
private final List<Class<?>>
private List<MethodHandle>
private final K
private List<LambdaForm.NamedFunction>
private Class<? extends T>
private final MethodHandle[]

Constructor Summary

AccessConstructor and Description
protected
SpeciesData(K key)

Method Summary

Modifier and TypeMethod and Description
protected String

Returns:

class name, which by default is outer().topClass().getName() + "$Species_" + deriveTypeString(key)
deriveClassName
()

Given a key, generate the name of the class which implements the species for that key.

protected abstract List<Class<?>>
deriveFieldTypes(K key)

Given a key, derive the list of field types, which all instances of this species must store.

protected Class<? extends T>

Returns:

the super-class of the class to be generated
deriveSuperClass
()

Report what immediate super-class to use for the concrete class of this species.

protected abstract MethodHandle

Returns:

the method handle which creates a new result from a mix of transform arguments and field values
deriveTransformHelper
(MemberName
the transform being implemented
transform
,
int
the index of that transform in the original list of transforms
whichtm
)

Given the index of a method in the transforms list, supply a factory method that takes the arguments of the transform, plus the local fields, and produce a value of the required type.

protected abstract <
the common element type of the various lists
X
>
List<X>

Returns:

a new list
deriveTransformHelperArguments
(MemberName
the transform being implemented
transform
,
int
the index of that transform in the original list of transforms
whichtm
,
List<X>
a list of opaque objects representing the incoming transform arguments
args
,
List<X>
a list of opaque objects representing the field values of the receiver
fields
)

During code generation, this method is called once per transform to determine what is the mix of arguments to hand to the transform-helper.

protected String

Returns:

a string suitable for use in a class name
deriveTypeString
()

Default implementation collects basic type characters, plus possibly type names, if some types don't correspond to basic types.

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.

protected MethodHandle
protected final int
protected final List<Class<?>>
protected MethodHandle
getter(int i)

Return a MethodHandle which can get the indexed field of this species.

protected LambdaForm.NamedFunction
getterFunction(int i)

Return a LambdaForm.Name containing a LambdaForm.NamedFunction that represents a MH bound to a generic invoker, which in turn forwards to the corresponding getter.

protected List<LambdaForm.NamedFunction>
protected List<MethodHandle>
public int
hashCode()

Overrides java.lang.Object.hashCode.

Returns a hash code value for this object.

protected final boolean
public final K
key()

protected ClassSpecializer<T, K, S>
protected final Class<? extends T>
speciesCode()

Throws NPE if this species is not yet resolved.

public String
toString()

Overrides java.lang.Object.toString.

Returns a string representation of the object.

protected MethodHandle
transformHelper(int whichtm)

private final MethodType
transformHelperType(int whichtm)

Inherited from java.lang.Object:
clonefinalizegetClassnotifynotifyAllwaitwaitwait

Field Detail

factoriesback to summary
private List<MethodHandle> factories
Annotations
@Stable
fieldTypesback to summary
private final List<Class<?>> fieldTypes
gettersback to summary
private List<MethodHandle> getters
Annotations
@Stable
keyback to summary
private final K key
nominalGettersback to summary
private List<LambdaForm.NamedFunction> nominalGetters
Annotations
@Stable
speciesCodeback to summary
private Class<? extends T> speciesCode
Annotations
@Stable
transformHelpersback to summary
private final MethodHandle[] transformHelpers
Annotations
@Stable

Constructor Detail

SpeciesDataback to summary
protected SpeciesData(K key)

Method Detail

deriveClassNameback to summary
protected String deriveClassName()

Given a key, generate the name of the class which implements the species for that key. This algorithm must be stable.

Returns:String

class name, which by default is outer().topClass().getName() + "$Species_" + deriveTypeString(key)

deriveFieldTypesback to summary
protected abstract List<Class<?>> deriveFieldTypes(K key)

Given a key, derive the list of field types, which all instances of this species must store.

deriveSuperClassback to summary
protected Class<? extends T> deriveSuperClass()

Report what immediate super-class to use for the concrete class of this species. Normally this is topClass, but if that is an interface, the factory must override. The super-class must provide a constructor which takes the baseConstructorType arguments, if any. This hook also allows the code generator to use more than one canned supertype for species.

Returns:Class<? extends T>

the super-class of the class to be generated

deriveTransformHelperback to summary
protected abstract MethodHandle deriveTransformHelper(MemberName transform, int whichtm)

Given the index of a method in the transforms list, supply a factory method that takes the arguments of the transform, plus the local fields, and produce a value of the required type. You can override this to return null or throw if there are no transforms. This method exists so that the transforms can be "grown" lazily. This is necessary if the transform *adds* a field to an instance, which sometimes requires the creation, on the fly, of an extended species. This method is only called once for any particular parameter. The species caches the result in a private array.

Parameters
transform:MemberName

the transform being implemented

whichtm:int

the index of that transform in the original list of transforms

Returns:MethodHandle

the method handle which creates a new result from a mix of transform arguments and field values

deriveTransformHelperArgumentsback to summary
protected abstract <X> List<X> deriveTransformHelperArguments(MemberName transform, int whichtm, List<X> args, List<X> fields)

During code generation, this method is called once per transform to determine what is the mix of arguments to hand to the transform-helper. The bytecode which marshals these arguments is open-coded in the species-specific transform. The two lists are of opaque objects, which you shouldn't do anything with besides reordering them into the output list. (They are both mutable, to make editing easier.) The imputed types of the args correspond to the transform's parameter list, while the imputed types of the fields correspond to the species field types. After code generation, this method may be called occasionally by error-checking code.

Parameters
<X>
the common element type of the various lists
transform:MemberName

the transform being implemented

whichtm:int

the index of that transform in the original list of transforms

args:List<X>

a list of opaque objects representing the incoming transform arguments

fields:List<X>

a list of opaque objects representing the field values of the receiver

Returns:List<X>

a new list

deriveTypeStringback to summary
protected String deriveTypeString()

Default implementation collects basic type characters, plus possibly type names, if some types don't correspond to basic types.

Returns:String

a string suitable for use in a class name

equalsback to summary
public boolean equals(Object obj)

Overrides java.lang.Object.equals.

Doc from java.lang.Object.equals.

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

The equals method implements an equivalence relation on non-null object references:

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x, x.equals(null) should return false.

An equivalence relation partitions the elements it operates on into equivalence classes; all the members of an equivalence class are equal to each other. Members of an equivalence class are substitutable for each other, at least for some purposes.

Parameters
obj:Object

the reference object with which to compare.

Returns:boolean

true if this object is the same as the obj argument; false otherwise.

Annotations
@Override
factoryback to summary
protected MethodHandle factory()
fieldCountback to summary
protected final int fieldCount()
fieldTypesback to summary
protected final List<Class<?>> fieldTypes()
getterback to summary
protected MethodHandle getter(int i)

Return a MethodHandle which can get the indexed field of this species. The return type is the type of the species field it accesses. The argument type is the fieldHolder class of this species.

getterFunctionback to summary
protected LambdaForm.NamedFunction getterFunction(int i)

Return a LambdaForm.Name containing a LambdaForm.NamedFunction that represents a MH bound to a generic invoker, which in turn forwards to the corresponding getter.

getterFunctionsback to summary
protected List<LambdaForm.NamedFunction> getterFunctions()
gettersback to summary
protected List<MethodHandle> getters()
hashCodeback to summary
public int hashCode()

Overrides java.lang.Object.hashCode.

Doc from java.lang.Object.hashCode.

Returns a hash code value for this object. This method is supported for the benefit of hash tables such as those provided by java.util.HashMap.

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
Returns:int

a hash code value for this object

Annotations
@Override
isResolvedback to summary
protected final boolean isResolved()
keyback to summary
public final K key()
outerback to summary
protected ClassSpecializer<T, K, S> outer()
speciesCodeback to summary
protected final Class<? extends T> speciesCode()

Throws NPE if this species is not yet resolved.

toStringback to summary
public String toString()

Overrides java.lang.Object.toString.

Doc from java.lang.Object.toString.

Returns a string representation of the object. Satisfying this method's contract implies a non-null result must be returned.

Returns:String

a string representation of the object

Annotations
@Override
transformHelperback to summary
protected MethodHandle transformHelper(int whichtm)
transformHelperTypeback to summary
private final MethodType transformHelperType(int whichtm)