public class TypeRegistry
extends java.lang.Object
Modifier and Type | Class and Description |
---|---|
static class |
TypeRegistry.CouldBeReloadableDecision |
static class |
TypeRegistry.ReloadableTypeNameDecision |
Modifier and Type | Field and Description |
---|---|
boolean |
directlyDefineTypes
Controls if the registry will define types or will allow the caller (possibly a transformer running under an
agent) to define it.
|
java.util.Map<java.lang.String,java.util.Set<ReloadableType>> |
jdkProxiesForInterface |
static java.lang.String |
Key_ExcludedLoaders |
static java.lang.String |
Key_Exclusions |
static java.lang.String |
Key_Inclusions |
static java.lang.String |
Key_Profile |
static java.lang.String |
Key_ReloadableRebase |
static int |
nextFreeRegistryId |
static boolean |
nothingReloaded |
Modifier and Type | Method and Description |
---|---|
ReloadableType |
addType(java.lang.String dottedname,
byte[] initialbytes)
Add a type to the registry.
|
static void |
associateReloadableType(ReloadableType child,
java.lang.Class<?> parent)
Called from the static initializer of a reloadabletype, allowing it to connect itself to the parent type, such
that when reloading occurs we can mark all relevant types in the hierarchy as being impacted by the reload.
|
static java.lang.Object |
ccheck(int ids,
java.lang.String descriptor) |
void |
checkChildClassLoader(ReloadableType currentlyDefining)
To avoid leaking permgen we want to periodically discard the child classloader and recreate a new one.
|
void |
configure(java.util.Properties properties)
Configure this TypeRegistry using a specific set of properties - this will override any previous configuration.
|
TypeRegistry.CouldBeReloadableDecision |
couldBeReloadable(java.lang.String slashedName,
boolean usePackageNameDecisionCache)
Determine if the named type could be reloadable.
|
void |
ensureConfigured()
Configure (if not already done) this TypeRegistry by locating springloaded.properties (through a findResources
call) then loading it then processing any directives within it.
|
void |
fireReloadEvent(ReloadableType reloadableType,
java.lang.String versionsuffix) |
boolean |
fireUnableToReloadEvent(ReloadableType reloadableType,
TypeDelta td,
java.lang.String versionsuffix) |
ChildClassLoader |
getChildClassLoader() |
java.lang.Class<?> |
getClass_ClassInfo() |
java.lang.Class<?> |
getClass_GroovySystem() |
java.lang.ClassLoader |
getClassLoader() |
TypeDescriptor |
getDescriptorFor(java.lang.String slashedname) |
TypeDescriptor |
getDescriptorForReloadableType(java.lang.String slashedClassname)
Only checks the reloadable types this registry knows about, it doesn't search beyond that.
|
java.util.List<TypePattern> |
getExclusionPatterns() |
TypeDescriptorExtractor |
getExtractor() |
java.lang.reflect.Field |
getField_ClassInfo_cachedClassRef() |
int |
getId() |
java.util.List<TypePattern> |
getInclusionPatterns() |
java.util.Set<ReloadableType> |
getJDKProxiesFor(java.lang.String slashedInterfaceTypeName) |
TypeDescriptor |
getLatestDescriptorFor(java.lang.String slashedname) |
java.lang.reflect.Method |
getMethod_ClassInfo_getClassInfo() |
TypeRegistry |
getParentRegistry() |
java.util.Map<java.lang.String,java.lang.String> |
getRebasePaths() |
ReloadableType |
getReloadableSuperType(java.lang.String slashedClassname) |
ReloadableType |
getReloadableType(java.lang.Class<?> clazz) |
ReloadableType |
getReloadableType(int typeId) |
static ReloadableType |
getReloadableType(int typeRegistryId,
int typeId)
This method discovers the reloadable type instance for the registry and type id specified.
|
ReloadableType |
getReloadableType(java.lang.String slashedClassName)
Determine the reloadabletype object representation for a specified class.
|
ReloadableType |
getReloadableType(java.lang.String slashedClassname,
boolean allocateIdIfNotYetLoaded)
Find the ReloadableType object for a given classname.
|
ReloadableType[] |
getReloadableTypes() |
int |
getTypeIdFor(java.lang.String slashname,
boolean allocateIfNotFound)
Lookup the type ID for a string.
|
static TypeRegistry |
getTypeRegistryFor(java.lang.ClassLoader classloader)
Factory access method for obtaining TypeRegistry instances.
|
static java.lang.Object |
idycheck()
Used to determine if the invokedynamic needs to be intercepted.
|
static java.lang.Object |
idyrun(java.lang.Object[] indyParams,
int typeRegistryId,
int classId,
java.lang.Object caller,
java.lang.String nameAndDescriptor,
int bsmId) |
static java.lang.Object |
iiIntercept(java.lang.Object instance,
java.lang.Object[] params,
java.lang.Object instance2,
java.lang.String nameAndDescriptor)
See notes.md#001
|
static boolean |
iincheck(int ids,
java.lang.String nameAndDescriptor)
Determine if something has changed in a particular type related to a particular descriptor and so the dispatcher
interface should be used.
|
static boolean |
instanceFieldInterceptionRequired(int ids,
java.lang.String name)
Called for a field operation - trying to determine whether a particular field needs special handling.
|
static java.lang.Object |
invokespecialSearch(ReloadableType rt,
java.lang.String nameAndDescriptor) |
static __DynamicallyDispatchable |
ispcheck(int ids,
java.lang.String nameAndDescriptor) |
boolean |
isReloadableTypeName(java.lang.String slashedName) |
TypeRegistry.ReloadableTypeNameDecision |
isReloadableTypeName(java.lang.String slashedName,
java.security.ProtectionDomain protectionDomain,
byte[] bytes)
Determine if the type specified is a reloadable type.
|
boolean |
isResolved(java.lang.Class<?> clazz) |
static java.lang.Object |
istcheck(int ids,
java.lang.String nameAndDescriptor)
Determine if something has changed in a particular type related to a particular descriptor and so the dispatcher
interface should be used.
|
static boolean |
ivicheck(int ids,
java.lang.String nameAndDescriptor)
Used in code the generated code replaces invokevirtual calls.
|
void |
loadNewVersion(ReloadableType rtype,
java.io.File file) |
void |
loadNewVersion(ReloadableType rtype,
long lastModTime,
java.io.InputStream is) |
byte[] |
methodCallRewrite(byte[] bytes) |
byte[] |
methodCallRewriteUseCacheIfAvailable(java.lang.String slashedClassName,
byte[] bytes) |
void |
monitorForUpdates(ReloadableType rtype,
java.lang.String externalForm) |
int |
recordBootstrapMethod(java.lang.String slashedClassName,
org.objectweb.asm.Handle bsm,
java.lang.Object[] bsmArgs)
When an invokedynamic instruction is reached, we allocate an id that recognizes that bsm and the parameters to
that bsm.
|
static void |
reinitialize() |
void |
rememberReloadableType(int typeId,
ReloadableType rtype)
Sometimes we discover the reloadabletype during program execution, for example A calls B and we haven't yet seen
B.
|
static void |
resetAllConfiguration() |
void |
resetConfiguration() |
void |
setShouldDefineClasses(boolean should) |
boolean |
shouldDefineClasses() |
boolean |
shouldRerunStaticInitializer(ReloadableType reloadableType,
java.lang.String versionsuffix) |
static boolean |
staticFieldInterceptionRequired(int ids,
java.lang.String name)
Called for a field operation - trying to determine whether a particular field needs special handling.
|
java.lang.String |
toString() |
static boolean |
typeRegistryExistsForId(int typeRegistryId)
Check if a type registry exists for a specific type registry ID.
|
public static boolean nothingReloaded
public static final java.lang.String Key_ExcludedLoaders
public static final java.lang.String Key_Inclusions
public static final java.lang.String Key_Exclusions
public static final java.lang.String Key_ReloadableRebase
public static final java.lang.String Key_Profile
public static int nextFreeRegistryId
public boolean directlyDefineTypes
public java.util.Map<java.lang.String,java.util.Set<ReloadableType>> jdkProxiesForInterface
public static void reinitialize()
public static boolean typeRegistryExistsForId(int typeRegistryId)
typeRegistryId
- the ID of a type registrypublic static TypeRegistry getTypeRegistryFor(java.lang.ClassLoader classloader)
classloader
- The classloader to create/retrieve the type registry forpublic TypeDescriptor getDescriptorForReloadableType(java.lang.String slashedClassname)
slashedClassname
- the slashed classname (e.g. java/lang/String)public TypeDescriptor getDescriptorFor(java.lang.String slashedname)
public TypeDescriptor getLatestDescriptorFor(java.lang.String slashedname)
public void ensureConfigured()
public void configure(java.util.Properties properties)
properties
- the properties to use to configure this type registrypublic void resetConfiguration()
public static void resetAllConfiguration()
public java.util.List<TypePattern> getInclusionPatterns()
public java.util.List<TypePattern> getExclusionPatterns()
public TypeRegistry.CouldBeReloadableDecision couldBeReloadable(java.lang.String slashedName, boolean usePackageNameDecisionCache)
slashedName
- the typename of interest (e.g. com/foo/Bar)usePackageNameDecisionCache
- whether to base a decision on the contents of the name decision cachepublic boolean isReloadableTypeName(java.lang.String slashedName)
public TypeRegistry.ReloadableTypeNameDecision isReloadableTypeName(java.lang.String slashedName, java.security.ProtectionDomain protectionDomain, byte[] bytes)
slashedName
- the type name, eg. a/b/c/DprotectionDomain
- the protection domain this class is being loaded underbytes
- the class bytes for the class being loadedpublic int getTypeIdFor(java.lang.String slashname, boolean allocateIfNotFound)
slashname
- the slashed type name, eg. a/b/c/DallocateIfNotFound
- determines whether an id should be allocated for the type if it cannot be foundpublic byte[] methodCallRewrite(byte[] bytes)
public byte[] methodCallRewriteUseCacheIfAvailable(java.lang.String slashedClassName, byte[] bytes)
public void loadNewVersion(ReloadableType rtype, java.io.File file)
public void loadNewVersion(ReloadableType rtype, long lastModTime, java.io.InputStream is)
public java.lang.ClassLoader getClassLoader()
public int getId()
public ReloadableType addType(java.lang.String dottedname, byte[] initialbytes)
dottedname
- type name of the form a.b.c.Dinitialbytes
- the first version of the bytes as loadedpublic ReloadableType getReloadableType(int typeId)
public void rememberReloadableType(int typeId, ReloadableType rtype)
typeId
- the id for the typertype
- the ReloadableType to associate with the idpublic ReloadableType getReloadableType(java.lang.String slashedClassName)
slashedClassName
- the slashed (e.g. java/lang/String) class namepublic ReloadableType getReloadableSuperType(java.lang.String slashedClassname)
public ReloadableType getReloadableType(java.lang.String slashedClassname, boolean allocateIdIfNotYetLoaded)
slashedClassname
- the slashed class name (e.g. java/lang/String)allocateIdIfNotYetLoaded
- if true an id will be allocated because sometime later the type will be loaded
(and made reloadable)public TypeDescriptorExtractor getExtractor()
public java.util.Map<java.lang.String,java.lang.String> getRebasePaths()
public boolean shouldDefineClasses()
public void setShouldDefineClasses(boolean should)
public static java.lang.Object idycheck()
public static java.lang.Object istcheck(int ids, java.lang.String nameAndDescriptor)
ids
- packed representation of the registryId (top 16bits) and typeId (bottom 16bits)nameAndDescriptor
- the name and descriptor of the method about to be INVOKESTATIC'dpublic static java.lang.Object invokespecialSearch(ReloadableType rt, java.lang.String nameAndDescriptor)
public static java.lang.Object iiIntercept(java.lang.Object instance, java.lang.Object[] params, java.lang.Object instance2, java.lang.String nameAndDescriptor)
instance
- the object instance on which the INVOKEINTERFACE is being calledparams
- the parameters to the INVOKEINTERFACE callinstance2
- the object instance on which the INVOKEINTERFACE is being callednameAndDescriptor
- the name and descriptor of what is being called (e.g. foo(Ljava/lang/String)I)public static __DynamicallyDispatchable ispcheck(int ids, java.lang.String nameAndDescriptor)
public static java.lang.Object ccheck(int ids, java.lang.String descriptor)
public static boolean iincheck(int ids, java.lang.String nameAndDescriptor)
Methods on interfaces cannot really 'change' - the visibility is always public and they are never static. This means everything that the descriptor embodies everything about a method interface. Therefore, if something changes about the descriptor it is considered an entirely different method (and the old form is a deleted method). For this reason there is no need to consider 'changed' methods, because the static-ness nor visibility cannot change.
ids
- packed representation of the registryId (top 16bits) and typeId (bottom 16bits)nameAndDescriptor
- the name and descriptor of the method about to be INVOKEINTERFACE'dpublic static boolean instanceFieldInterceptionRequired(int ids, java.lang.String name)
ids
- packed representation of the registryId (top 16bits) and typeId (bottom 16bits)name
- the name of the instance field about to be accessedpublic static boolean staticFieldInterceptionRequired(int ids, java.lang.String name)
ids
- packed representation of the registryId (top 16bits) and typeId (bottom 16bits)name
- the name of the static field about to be accessedpublic static java.lang.Object idyrun(java.lang.Object[] indyParams, int typeRegistryId, int classId, java.lang.Object caller, java.lang.String nameAndDescriptor, int bsmId)
public static boolean ivicheck(int ids, java.lang.String nameAndDescriptor)
ids
- packed representation of the registryId (top 16bits) and typeId (bottom 16bits)nameAndDescriptor
- the name and descriptor of the method about to be INVOKEVIRTUAL'dpublic static ReloadableType getReloadableType(int typeRegistryId, int typeId)
typeRegistryId
- the type registry idtypeId
- the type idpublic java.lang.String toString()
toString
in class java.lang.Object
public void monitorForUpdates(ReloadableType rtype, java.lang.String externalForm)
public boolean shouldRerunStaticInitializer(ReloadableType reloadableType, java.lang.String versionsuffix)
public void fireReloadEvent(ReloadableType reloadableType, java.lang.String versionsuffix)
public boolean fireUnableToReloadEvent(ReloadableType reloadableType, TypeDelta td, java.lang.String versionsuffix)
public java.lang.Class<?> getClass_GroovySystem()
public java.lang.Class<?> getClass_ClassInfo()
public java.lang.reflect.Method getMethod_ClassInfo_getClassInfo()
public java.lang.reflect.Field getField_ClassInfo_cachedClassRef()
public void checkChildClassLoader(ReloadableType currentlyDefining)
currentlyDefining
- the reloadable type currently being defined reloadedpublic ChildClassLoader getChildClassLoader()
public boolean isResolved(java.lang.Class<?> clazz)
public ReloadableType getReloadableType(java.lang.Class<?> clazz)
public TypeRegistry getParentRegistry()
public ReloadableType[] getReloadableTypes()
public java.util.Set<ReloadableType> getJDKProxiesFor(java.lang.String slashedInterfaceTypeName)
public int recordBootstrapMethod(java.lang.String slashedClassName, org.objectweb.asm.Handle bsm, java.lang.Object[] bsmArgs)
slashedClassName
- the slashed class name containing the bootstrap methodbsm
- the bootstrap methodsbsmArgs
- the bootstrap method arguments (asm types)public static void associateReloadableType(ReloadableType child, java.lang.Class<?> parent)
child
- the ReloadableType actively being initializedparent
- the superclass of the reloadable type (may or may not be reloadable!)