From 63fb4422efb5581eab76855aaa2d11aa456da6cd Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Thu, 26 Jun 2025 10:17:39 +0200 Subject: [PATCH] HHH-19577 Avoid duplicate stack map frames for SetPropertyValues --- .../bytebuddy/BytecodeProviderImpl.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java index 8b14942383a5..25cba0cef8c1 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java @@ -886,17 +886,17 @@ public Size apply( Label nextLabel = new Label(); for ( int index = 0; index < setters.length; index++ ) { final Member setterMember = setters[index]; - if ( enhanced && currentLabel != null ) { + if ( setterMember == EMBEDDED_MEMBER ) { + // The embedded property access does a no-op + continue; + } + if ( currentLabel != null ) { methodVisitor.visitLabel( currentLabel ); implementationContext.getFrameGeneration().same( methodVisitor, instrumentedMethod.getParameters().asTypeList() ); } - if ( setterMember == EMBEDDED_MEMBER ) { - // The embedded property access does a no-op - continue; - } // Push entity on stack methodVisitor.visitVarInsn( Opcodes.ALOAD, 1 ); methodVisitor.visitTypeInsn( Opcodes.CHECKCAST, Type.getInternalName( clazz ) ); @@ -1023,6 +1023,7 @@ else if ( setterMember instanceof Field field ) { } if ( enhanced ) { final boolean compositeTracker = CompositeTracker.class.isAssignableFrom( type ); + boolean alreadyHasFrame = false; // The composite owner check and setting only makes sense if // * the value type is a composite tracker // * a value subtype can be a composite tracker @@ -1104,6 +1105,7 @@ else if ( setterMember instanceof Field field ) { // Clean stack after the if block methodVisitor.visitLabel( compositeTrackerEndLabel ); implementationContext.getFrameGeneration().same(methodVisitor, instrumentedMethod.getParameters().asTypeList()); + alreadyHasFrame = true; } if ( persistentAttributeInterceptable ) { // Load the owner @@ -1168,9 +1170,20 @@ else if ( setterMember instanceof Field field ) { // Clean stack after the if block methodVisitor.visitLabel( instanceofEndLabel ); implementationContext.getFrameGeneration().same(methodVisitor, instrumentedMethod.getParameters().asTypeList()); + alreadyHasFrame = true; } - currentLabel = nextLabel; + if ( alreadyHasFrame ) { + // Usually, the currentLabel is visited as well generating a frame, + // but if a frame was already generated, only visit the label here, + // otherwise two frames for the same bytecode index are generated, + // which is wrong and will produce an error when the JDK ClassFile API is used + methodVisitor.visitLabel( nextLabel ); + currentLabel = null; + } + else { + currentLabel = nextLabel; + } nextLabel = new Label(); } }