Binding the MethodHandle means we are actually creating two
methodhandles, which is wasteful. Add a dummy CodecDataObject
constructor argument, unifying constructor signatures and allowing
us to use a single methodhandle, passing 'this' at the single
call site.
JIRA: MDSAL-444
Change-Id: Idd94638eb42d219b7370463d91dad3d00409bd5e
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
protected AugmentableCodecDataObject(final DataObjectCodecContext<T, ?> context,
final NormalizedNodeContainer<?, ?, ?> data) {
protected AugmentableCodecDataObject(final DataObjectCodecContext<T, ?> context,
final NormalizedNodeContainer<?, ?, ?> data) {
this.context = requireNonNull(context, "Context must not be null");
}
this.context = requireNonNull(context, "Context must not be null");
}
private volatile Integer cachedHashcode = null;
private volatile Integer cachedHashcode = null;
- protected CodecDataObject(final NormalizedNodeContainer<?, ?, ?> data) {
+ protected CodecDataObject(final DataObjectCodecContext<T, ?> context, final NormalizedNodeContainer<?, ?, ?> data) {
this.data = requireNonNull(data, "Data must not be null");
}
this.data = requireNonNull(data, "Data must not be null");
}
}
private static final Logger LOG = LoggerFactory.getLogger(DataObjectCodecContext.class);
}
private static final Logger LOG = LoggerFactory.getLogger(DataObjectCodecContext.class);
- private static final MethodType CONSTRUCTOR_TYPE = MethodType.methodType(void.class, NormalizedNodeContainer.class);
- private static final MethodType AUGMENTABLE_CONSTRUCTOR_TYPE = MethodType.methodType(void.class,
+ private static final MethodType CONSTRUCTOR_TYPE = MethodType.methodType(void.class,
DataObjectCodecContext.class, NormalizedNodeContainer.class);
private static final MethodType DATAOBJECT_TYPE = MethodType.methodType(DataObject.class,
DataObjectCodecContext.class, NormalizedNodeContainer.class);
private static final MethodType DATAOBJECT_TYPE = MethodType.methodType(DataObject.class,
- NormalizedNodeContainer.class);
- private static final MethodType AUGMENTABLE_DATAOBJECT_TYPE = MethodType.methodType(DataObject.class,
DataObjectCodecContext.class, NormalizedNodeContainer.class);
private static final Comparator<Method> METHOD_BY_ALPHABET = Comparator.comparing(Method::getName);
private static final Augmentations EMPTY_AUGMENTATIONS = new Augmentations(ImmutableMap.of(), ImmutableMap.of());
DataObjectCodecContext.class, NormalizedNodeContainer.class);
private static final Comparator<Method> METHOD_BY_ALPHABET = Comparator.comparing(Method::getName);
private static final Augmentations EMPTY_AUGMENTATIONS = new Augmentations(ImmutableMap.of(), ImmutableMap.of());
this.byBindingArgClass = ImmutableMap.copyOf(byBindingArgClassBuilder);
final Class<? extends CodecDataObject<?>> generatedClass;
this.byBindingArgClass = ImmutableMap.copyOf(byBindingArgClassBuilder);
final Class<? extends CodecDataObject<?>> generatedClass;
- final MethodType ctorType;
if (Augmentable.class.isAssignableFrom(bindingClass)) {
this.possibleAugmentations = factory().getRuntimeContext().getAvailableAugmentationTypes(getSchema());
generatedClass = CodecDataObjectGenerator.generateAugmentable(prototype.getFactory().getLoader(),
bindingClass, propBuilder.build(), keyMethod);
if (Augmentable.class.isAssignableFrom(bindingClass)) {
this.possibleAugmentations = factory().getRuntimeContext().getAvailableAugmentationTypes(getSchema());
generatedClass = CodecDataObjectGenerator.generateAugmentable(prototype.getFactory().getLoader(),
bindingClass, propBuilder.build(), keyMethod);
- ctorType = AUGMENTABLE_CONSTRUCTOR_TYPE;
} else {
this.possibleAugmentations = ImmutableMap.of();
generatedClass = CodecDataObjectGenerator.generate(prototype.getFactory().getLoader(), bindingClass,
propBuilder.build(), keyMethod);
} else {
this.possibleAugmentations = ImmutableMap.of();
generatedClass = CodecDataObjectGenerator.generate(prototype.getFactory().getLoader(), bindingClass,
propBuilder.build(), keyMethod);
- ctorType = CONSTRUCTOR_TYPE;
}
reloadAllAugmentations();
final MethodHandle ctor;
try {
}
reloadAllAugmentations();
final MethodHandle ctor;
try {
- ctor = MethodHandles.publicLookup().findConstructor(generatedClass, ctorType);
+ ctor = MethodHandles.publicLookup().findConstructor(generatedClass, CONSTRUCTOR_TYPE);
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new LinkageError("Failed to find contructor for class " + generatedClass, e);
}
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new LinkageError("Failed to find contructor for class " + generatedClass, e);
}
- if (Augmentable.class.isAssignableFrom(bindingClass)) {
- proxyConstructor = ctor.asType(AUGMENTABLE_DATAOBJECT_TYPE).bindTo(this);
- } else {
- proxyConstructor = ctor.asType(DATAOBJECT_TYPE);
- }
+ proxyConstructor = ctor.asType(DATAOBJECT_TYPE);
}
// This method could be synchronized, but that would mean that concurrent attempts to load an invalid augmentation
}
// This method could be synchronized, but that would mean that concurrent attempts to load an invalid augmentation
@SuppressWarnings("checkstyle:illegalCatch")
protected final D createBindingProxy(final NormalizedNodeContainer<?, ?, ?> node) {
try {
@SuppressWarnings("checkstyle:illegalCatch")
protected final D createBindingProxy(final NormalizedNodeContainer<?, ?, ?> node) {
try {
- return (D) proxyConstructor.invokeExact(node);
+ return (D) proxyConstructor.invokeExact(this, node);
} catch (final Throwable e) {
Throwables.throwIfUnchecked(e);
throw new IllegalStateException(e);
} catch (final Throwable e) {
Throwables.throwIfUnchecked(e);
throw new IllegalStateException(e);