Skip to content

Commit

Permalink
7154: [JFR Writer] Improve lazy evaluation of the type defining block
Browse files Browse the repository at this point in the history
Reviewed-by: hirt
  • Loading branch information
Jaroslav Bachorik authored and thegreystone committed Mar 15, 2021
1 parent c1937f1 commit e97d985
Showing 1 changed file with 28 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,7 @@ public void registerBuiltin(Types.Builtin typeDef) {
* @return registered type - either a new type or or a previously registered with the same name
*/
TypeImpl registerType(String typeName, String supertype, Supplier<TypeStructureImpl> typeStructureProvider) {
return registerType(typeName, supertype, true,
typeStructureProvider != null ? typeStructureProvider.get() : TypeStructureImpl.EMPTY);
return registerType(typeName, supertype, true, typeStructureProvider);
}

/**
Expand All @@ -150,8 +149,33 @@ TypeImpl registerType(String typeName, String supertype, Supplier<TypeStructureI
TypeImpl registerType(
String typeName, String supertype, boolean withConstantPool,
Supplier<TypeStructureImpl> typeStructureProvider) {
return registerType(typeName, supertype, withConstantPool,
typeStructureProvider != null ? typeStructureProvider.get() : TypeStructureImpl.EMPTY);
/*
* This needs to be slightly more involved than just calling 'computeIfAbsent' because the
* actual computation may (and will) call 'registerType' recursively which will make the
* next call to 'computeIfAbsent' to fail.
*
* The solution is a multi-step registration while still maintaining the atomicity of the
* updates.
* @formatter:off
* 1. Put atomically an unresolved resolvable instance as a placeholder if the map doesn't
* contain the resolved type yet
* 2. Build the type structure (which might involve calling registerType recursively)
* 3. Materialize the type
* 4. Replace the resolvable placeholder with the actual type in the type metadata map
* 5. Resolve the resolvable type so any other types linking to it will have access to the real type
* @formatter:on
*/
TypeImpl registered = metadata.computeIfAbsent(typeName, k -> new ResolvableType(k, this));
if (!registered.isResolved()) {
TypeStructureImpl structure = typeStructureProvider != null ? typeStructureProvider.get()
: TypeStructureImpl.EMPTY;
TypeImpl concreteType = createCustomType(typeName, supertype, structure, withConstantPool);
storeTypeStrings(concreteType);
metadata.replace(typeName, registered, concreteType);
((ResolvableType) registered).resolve();
registered = concreteType;
}
return registered;
}

/**
Expand Down

0 comments on commit e97d985

Please sign in to comment.