Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
048e094
Do not create an InterceptionDecorationContext stack in client proxie…
AngeloRubens Oct 3, 2026
d5d3c8e
Avoid ThreadLocal.remove() churn of the InterceptionDecorationContext…
AngeloRubens Oct 3, 2026
fea84fd
Avoid the container registry lookup on every client proxy invocation
AngeloRubens Oct 3, 2026
a6bccbb
Reuse a per-thread InterceptionDecorationContext stack
AngeloRubens Oct 3, 2026
31d6764
Skip the interception context lookup in client proxies until it is fi…
AngeloRubens Oct 3, 2026
efe6684
Resolve the contextual instance strategy of Weld beans without a type…
AngeloRubens Oct 3, 2026
52c8d48
Use a plain array for the per-thread InterceptionDecorationContext stack
AngeloRubens Oct 4, 2026
534cc43
Invoke interceptor methods and the proceed method through method handles
AngeloRubens Oct 4, 2026
d63ab90
Skip the per-call accessibility and interceptor method checks for cac…
AngeloRubens Oct 4, 2026
b975e82
Remember the interception chain of the first intercepted method of an…
AngeloRubens Oct 4, 2026
3ca101c
Remove the unused timer and constructor fields from around invoke inv…
AngeloRubens Oct 4, 2026
6361eda
Do not allocate an empty arguments array for intercepted methods with…
AngeloRubens Oct 4, 2026
308855f
Avoid the thread-local lookup in InvocationContext.proceed() on the i…
AngeloRubens Oct 4, 2026
b0a2699
Preserve method access overrides in cached invokers and cover stack h…
AngeloRubens Oct 5, 2026
27b3a92
Invoke simple methods through LambdaMetafactory generated functions
AngeloRubens Oct 4, 2026
c6d6bca
Apply access-override guard to lambda invokers
AngeloRubens Oct 5, 2026
9d8a605
Apply Weld formatter output from CI to lambda access guard
AngeloRubens Oct 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions impl/src/main/java/org/jboss/weld/Container.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ public static void initialize(String contextId, BeanManagerImpl deploymentManage

private ContainerState state = ContainerState.STOPPED;

// set at the very beginning of cleanup(); a container that is not cleaned up is still registered
private volatile boolean cleanedUp;

public Container(String contextId, BeanManagerImpl deploymentManager, ServiceRegistry deploymentServices) {
this(contextId, deploymentManager, deploymentServices, null);
}
Expand All @@ -141,6 +144,7 @@ public Container(String contextId, BeanManagerImpl deploymentManager, ServiceReg
* managers, and all deployment services
*/
public void cleanup() {
cleanedUp = true;
managers.clear();
for (BeanManagerImpl beanManager : beanDeploymentArchives.values()) {
beanManager.cleanup();
Expand Down Expand Up @@ -202,6 +206,16 @@ public void putBeanDeployments(BeanDeploymentArchiveMapping bdaMapping) {
}
}

/**
* Cheap check suitable for hot paths: as long as this method returns {@code false}, this container has not been cleaned
* up and is therefore still registered, i.e. {@link #isSet(String)} returns {@code true} for its context id.
*
* @return {@code true} if {@link #cleanup()} has been called on this container
*/
public boolean isCleanedUp() {
return cleanedUp;
}

public ContainerState getState() {
return state;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
*/
public class CombinedInterceptorAndDecoratorStackMethodHandler implements StackAwareMethodHandler, Serializable {

/**
* The (immutable) arguments array passed to the handler by intercepted subclasses for methods without parameters.
*/
public static final Object[] NO_ARGUMENTS = new Object[0];

public static final CombinedInterceptorAndDecoratorStackMethodHandler NULL_INSTANCE = new CombinedInterceptorAndDecoratorStackMethodHandler() {
@Override
public void setInterceptorMethodHandler(InterceptorMethodHandler interceptorMethodHandler) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import org.jboss.weld.Container;
import org.jboss.weld.bean.ContextualInstance;
import org.jboss.weld.bean.RIBean;
import org.jboss.weld.contexts.CreationalContextImpl;
import org.jboss.weld.contexts.WeldCreationalContext;
import org.jboss.weld.injection.CurrentInjectionPoint;
Expand All @@ -53,11 +54,14 @@ public class ContextBeanInstance<T> extends AbstractBeanInstance implements Seri
private static final long serialVersionUID = -8144230657830556503L;
// The bean
private transient Bean<T> bean;
// The same bean if it is a Weld bean (null otherwise); avoids the type check of ContextualInstance on every invocation
private final transient RIBean<T> riBean;
// The bean index in the manager
private final BeanIdentifier id;
private final String contextId;
// The actual type of the resulting bean instance
private final transient Class<?> instanceType;
private final transient Container container;
private final transient BeanManagerImpl manager;
private final transient CurrentInjectionPoint currentInjectionPoint;

Expand All @@ -71,19 +75,25 @@ public class ContextBeanInstance<T> extends AbstractBeanInstance implements Seri
*/
public ContextBeanInstance(Bean<T> bean, BeanIdentifier id, String contextId) {
this.bean = bean;
this.riBean = bean instanceof RIBean ? cast(bean) : null;
this.id = id;
this.contextId = contextId;
this.instanceType = computeInstanceType(bean);
BeanLogger.LOG.createdContextInstance(bean, id);
this.manager = Container.instance(contextId).deploymentManager();
this.container = Container.instance(contextId);
this.manager = container.deploymentManager();
this.currentInjectionPoint = manager.getServices().get(CurrentInjectionPoint.class);
}

public T getInstance() {
if (!Container.isSet(contextId)) {
// Checking the container we were created for is a single volatile read; the registry lookup in
// Container.isSet() is only needed once that container has been cleaned up (shut down)
if (container.isCleanedUp() && !Container.isSet(contextId)) {
throw ContextLogger.LOG.contextualReferenceNotValidAfterShutdown(bean, contextId);
}
T existingInstance = ContextualInstance.getIfExists(bean, manager);
// for an @ApplicationScoped bean this is a single volatile read of the instance cached by its strategy
T existingInstance = riBean != null ? ContextualInstance.getIfExists(riBean, manager)
: ContextualInstance.getIfExists(bean, manager);
if (existingInstance != null) {
return existingInstance;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,8 +494,14 @@ protected void invokeMethodHandler(ClassMethod method, MethodInformation methodI
b.aconstNull();
}

b.iconst(methodInfo.getParameterTypes().length);
b.anewarray(Object.class.getName());
if (methodInfo.getParameterTypes().length == 0) {
// share an empty array instead of allocating one upon every invocation
b.getstatic(COMBINED_INTERCEPTOR_AND_DECORATOR_STACK_METHOD_HANDLER_CLASS_NAME, "NO_ARGUMENTS",
"[" + LJAVA_LANG_OBJECT);
} else {
b.iconst(methodInfo.getParameterTypes().length);
b.anewarray(Object.class.getName());
}

int localVariableCount = 1;

Expand Down
Loading