diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java index f3114f81e91b8..d40b17a7387f8 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java @@ -705,7 +705,8 @@ protected MethodCreator initConstructor(ClassOutput classOutput, ClassCreator be } // Bean types - ResultHandle typesHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class)); + ResultHandle typesArray = constructor.newArray(Object.class, bean.getTypes().size()); + int typeIndex = 0; for (org.jboss.jandex.Type type : bean.getTypes()) { ResultHandle typeHandle; try { @@ -713,54 +714,51 @@ protected MethodCreator initConstructor(ClassOutput classOutput, ClassCreator be } catch (IllegalArgumentException e) { throw new IllegalStateException("Unable to construct the type handle for " + bean + ": " + e.getMessage()); } - constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, typesHandle, typeHandle); + constructor.writeArrayValue(typesArray, constructor.load(typeIndex++), typeHandle); } - ResultHandle unmodifiableTypesHandle = constructor.invokeStaticMethod(MethodDescriptors.COLLECTIONS_UNMODIFIABLE_SET, - typesHandle); constructor.writeInstanceField( FieldDescriptor.of(beanCreator.getClassName(), FIELD_NAME_BEAN_TYPES, Set.class.getName()), constructor.getThis(), - unmodifiableTypesHandle); + constructor.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF, + typesArray)); // Qualifiers if (!bean.getQualifiers().isEmpty() && !bean.hasDefaultQualifiers()) { - - ResultHandle qualifiersHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class)); - + ResultHandle qualifiersArray = constructor.newArray(Object.class, bean.getQualifiers().size()); + int qualifierIndex = 0; for (AnnotationInstance qualifierAnnotation : bean.getQualifiers()) { BuiltinQualifier qualifier = BuiltinQualifier.of(qualifierAnnotation); if (qualifier != null) { - constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiersHandle, + constructor.writeArrayValue(qualifiersArray, constructor.load(qualifierIndex++), qualifier.getLiteralInstance(constructor)); } else { - // Create annotation literal first + // Create the annotation literal first ClassInfo qualifierClass = bean.getDeployment().getQualifier(qualifierAnnotation.name()); - constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiersHandle, + constructor.writeArrayValue(qualifiersArray, constructor.load(qualifierIndex++), annotationLiterals.process(constructor, classOutput, qualifierClass, qualifierAnnotation, Types.getPackageName(beanCreator.getClassName()))); } } - ResultHandle unmodifiableQualifiersHandle = constructor - .invokeStaticMethod(MethodDescriptors.COLLECTIONS_UNMODIFIABLE_SET, qualifiersHandle); constructor.writeInstanceField( FieldDescriptor.of(beanCreator.getClassName(), FIELD_NAME_QUALIFIERS, Set.class.getName()), constructor.getThis(), - unmodifiableQualifiersHandle); + constructor.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF, + qualifiersArray)); } // Stereotypes if (!bean.getStereotypes().isEmpty()) { - ResultHandle stereotypesHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class)); + ResultHandle stereotypesArray = constructor.newArray(Object.class, bean.getStereotypes().size()); + int stereotypesIndex = 0; for (StereotypeInfo stereotype : bean.getStereotypes()) { - constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, stereotypesHandle, + constructor.writeArrayValue(stereotypesArray, constructor.load(stereotypesIndex++), constructor.loadClass(stereotype.getTarget().name().toString())); } - ResultHandle unmodifiableStereotypesHandle = constructor - .invokeStaticMethod(MethodDescriptors.COLLECTIONS_UNMODIFIABLE_SET, stereotypesHandle); constructor.writeInstanceField( FieldDescriptor.of(beanCreator.getClassName(), FIELD_NAME_STEREOTYPES, Set.class.getName()), constructor.getThis(), - unmodifiableStereotypesHandle); + constructor.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF, + stereotypesArray)); } return constructor; } @@ -1391,18 +1389,20 @@ void implementCreateForClassBean(ClassOutput classOutput, ClassCreator beanCreat funcBytecode.returnValue(retHandle); // Interceptor bindings - ResultHandle bindingsHandle = create.newInstance(MethodDescriptor.ofConstructor(HashSet.class)); + ResultHandle bindingsArray = create.newArray(Object.class, aroundConstructs.bindings.size()); + int bindingsIndex = 0; for (AnnotationInstance binding : aroundConstructs.bindings) { // Create annotation literals first ClassInfo bindingClass = bean.getDeployment().getInterceptorBinding(binding.name()); - create.invokeInterfaceMethod(MethodDescriptors.SET_ADD, bindingsHandle, + create.writeArrayValue(bindingsArray, bindingsIndex++, annotationLiterals.process(create, classOutput, bindingClass, binding, Types.getPackageName(beanCreator.getClassName()))); } ResultHandle invocationContextHandle = create.invokeStaticMethod( MethodDescriptors.INVOCATION_CONTEXTS_AROUND_CONSTRUCT, constructorHandle, - aroundConstructsHandle, func.getInstance(), bindingsHandle); + aroundConstructsHandle, func.getInstance(), + create.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF, bindingsArray)); TryBlock tryCatch = create.tryBlock(); CatchBlockCreator exceptionCatch = tryCatch.addCatch(Exception.class); // throw new RuntimeException(e) @@ -1520,19 +1520,21 @@ void implementCreateForClassBean(ClassOutput classOutput, ClassCreator beanCreat if (!postConstructs.isEmpty()) { // Interceptor bindings - ResultHandle bindingsHandle = create.newInstance(MethodDescriptor.ofConstructor(HashSet.class)); + ResultHandle bindingsArray = create.newArray(Object.class, postConstructs.bindings.size()); + int bindingsIndex = 0; for (AnnotationInstance binding : postConstructs.bindings) { // Create annotation literals first ClassInfo bindingClass = bean.getDeployment().getInterceptorBinding(binding.name()); - create.invokeInterfaceMethod(MethodDescriptors.SET_ADD, bindingsHandle, + create.writeArrayValue(bindingsArray, bindingsIndex++, annotationLiterals.process(create, classOutput, bindingClass, binding, Types.getPackageName(beanCreator.getClassName()))); + } // InvocationContextImpl.postConstruct(instance,postConstructs).proceed() ResultHandle invocationContextHandle = create.invokeStaticMethod( MethodDescriptors.INVOCATION_CONTEXTS_POST_CONSTRUCT, instanceHandle, - postConstructsHandle, bindingsHandle); + postConstructsHandle, create.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF, bindingsArray)); TryBlock tryCatch = create.tryBlock(); CatchBlockCreator exceptionCatch = tryCatch.addCatch(Exception.class); diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/MethodDescriptors.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/MethodDescriptors.java index aa40bf2320ff3..01a932fbb31e4 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/MethodDescriptors.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/MethodDescriptors.java @@ -223,6 +223,8 @@ public final class MethodDescriptors { public static final MethodDescriptor COLLECTIONS_EMPTY_MAP = MethodDescriptor.ofMethod(Collections.class, "emptyMap", Map.class); + public static final MethodDescriptor SET_OF = MethodDescriptor.ofMethod(Set.class, "of", Set.class, Object[].class); + public static final MethodDescriptor ARC_CONTAINER = MethodDescriptor.ofMethod(Arc.class, "container", ArcContainer.class); public static final MethodDescriptor ARC_CONTAINER_BEAN = MethodDescriptor.ofMethod(ArcContainer.class, "bean", diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ObserverGenerator.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ObserverGenerator.java index bee4cb128f6a1..3f31a6fcf1759 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ObserverGenerator.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ObserverGenerator.java @@ -32,7 +32,6 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -548,29 +547,28 @@ protected void createConstructor(ClassOutput classOutput, ClassCreator observerC Set qualifiers = observer.getQualifiers(); if (!qualifiers.isEmpty()) { - ResultHandle qualifiersHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class)); + ResultHandle qualifiersArray = constructor.newArray(Object.class, qualifiers.size()); + int qualifiersIndex = 0; for (AnnotationInstance qualifierAnnotation : qualifiers) { BuiltinQualifier qualifier = BuiltinQualifier.of(qualifierAnnotation); if (qualifier != null) { - constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiersHandle, + constructor.writeArrayValue(qualifiersArray, constructor.load(qualifiersIndex++), qualifier.getLiteralInstance(constructor)); } else { // Create annotation literal first ClassInfo qualifierClass = observer.getBeanDeployment() .getQualifier(qualifierAnnotation.name()); - constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiersHandle, + constructor.writeArrayValue(qualifiersArray, constructor.load(qualifiersIndex++), annotationLiterals.process(constructor, classOutput, qualifierClass, qualifierAnnotation, Types.getPackageName(observerCreator.getClassName()))); } } - ResultHandle unmodifiableQualifiersHandle = constructor - .invokeStaticMethod(MethodDescriptor.ofMethod(Collections.class, "unmodifiableSet", Set.class, Set.class), - qualifiersHandle); constructor.writeInstanceField( FieldDescriptor.of(observerCreator.getClassName(), "qualifiers", Set.class.getName()), constructor.getThis(), - unmodifiableQualifiersHandle); + constructor.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF, + qualifiersArray)); } if (mockable) { diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/SubclassGenerator.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/SubclassGenerator.java index 5fe280aaf73af..2fb344c581850 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/SubclassGenerator.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/SubclassGenerator.java @@ -252,12 +252,13 @@ public ResultHandle apply(List keys) { return constructor.invokeStaticMethod(MethodDescriptors.COLLECTIONS_SINGLETON, bindingsLiterals.computeIfAbsent(keys.iterator().next(), bindingsLiteralFun)); } else { - ResultHandle bindingsHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class)); + ResultHandle bindingsArray = constructor.newArray(Object.class, keys.size()); + int bindingsIndex = 0; for (BindingKey binding : keys) { - constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, bindingsHandle, + constructor.writeArrayValue(bindingsArray, bindingsIndex++, bindingsLiterals.computeIfAbsent(binding, bindingsLiteralFun)); } - return bindingsHandle; + return constructor.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF, bindingsArray); } } }; @@ -790,11 +791,13 @@ protected void createDestroy(ClassOutput classOutput, BeanInfo bean, ClassCreato ResultHandle predestroysHandle = destroy.readInstanceField(preDestroysField, destroy.getThis()); // Interceptor bindings - ResultHandle bindingsHandle = destroy.newInstance(MethodDescriptor.ofConstructor(HashSet.class)); - for (AnnotationInstance binding : bean.getLifecycleInterceptors(InterceptionType.PRE_DESTROY).bindings) { + InterceptionInfo preDestroy = bean.getLifecycleInterceptors(InterceptionType.PRE_DESTROY); + ResultHandle bindingsArray = destroy.newArray(Object.class, preDestroy.bindings.size()); + int bindingsIndex = 0; + for (AnnotationInstance binding : preDestroy.bindings) { // Create annotation literals first ClassInfo bindingClass = bean.getDeployment().getInterceptorBinding(binding.name()); - destroy.invokeInterfaceMethod(MethodDescriptors.SET_ADD, bindingsHandle, + destroy.writeArrayValue(bindingsArray, bindingsIndex++, annotationLiterals.process(destroy, classOutput, bindingClass, binding, Types.getPackageName(subclass.getClassName()))); } @@ -809,7 +812,7 @@ protected void createDestroy(ClassOutput classOutput, BeanInfo bean, ClassCreato // InvocationContextImpl.preDestroy(this,predestroys) ResultHandle invocationContext = tryCatch.invokeStaticMethod(MethodDescriptors.INVOCATION_CONTEXTS_PRE_DESTROY, tryCatch.getThis(), predestroysHandle, - bindingsHandle); + tryCatch.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF, bindingsArray)); // InvocationContext.proceed() tryCatch.invokeInterfaceMethod(MethodDescriptors.INVOCATION_CONTEXT_PROCEED, invocationContext); diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/AbstractInvocationContext.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/AbstractInvocationContext.java index 49108c32f80ae..f9b31077d403c 100644 --- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/AbstractInvocationContext.java +++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/AbstractInvocationContext.java @@ -6,7 +6,6 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -36,7 +35,7 @@ protected AbstractInvocationContext(Object target, Method method, this.constructor = constructor; this.parameters = parameters != null ? parameters : EMPTY_PARAMS; this.contextData = contextData != null ? contextData : new LazyValue<>(this); - this.interceptorBindings = Collections.unmodifiableSet(interceptorBindings); + this.interceptorBindings = interceptorBindings; this.chain = chain; } diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/Qualifiers.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/Qualifiers.java index 7ba0a4c78c376..21caa918d176c 100644 --- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/Qualifiers.java +++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/Qualifiers.java @@ -7,7 +7,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.enterprise.inject.Any; @@ -17,7 +16,7 @@ public final class Qualifiers { - public static final Set DEFAULT_QUALIFIERS = initDefaultQualifiers(); + public static final Set DEFAULT_QUALIFIERS = Set.of(Default.Literal.INSTANCE, Any.Literal.INSTANCE); public static final Set IP_DEFAULT_QUALIFIERS = Collections.singleton(Default.Literal.INSTANCE); @@ -115,13 +114,6 @@ static boolean isSubset(Set observedQualifiers, Set even return true; } - private static Set initDefaultQualifiers() { - Set qualifiers = new HashSet<>(); - qualifiers.add(Default.Literal.INSTANCE); - qualifiers.add(Any.Literal.INSTANCE); - return Collections.unmodifiableSet(qualifiers); - } - private static Object invoke(Method method, Object instance) { try { if (!method.isAccessible()) {