Remove redundant object allocation in cglib proxy method calls

* Fixes gh-35542

Signed-off-by: Nurlan Turdaliev <nurlan0000@gmail.com>
This commit is contained in:
Nurlan Turdaliev 2025-09-25 17:19:14 +06:00 committed by Juergen Hoeller
parent 8631345b71
commit b4d501f888
1 changed files with 61 additions and 18 deletions

View File

@ -29,6 +29,22 @@ import org.springframework.asm.Type;
public class CodeEmitter extends LocalVariablesSorter { public class CodeEmitter extends LocalVariablesSorter {
private static final Signature BOOLEAN_VALUE = private static final Signature BOOLEAN_VALUE =
TypeUtils.parseSignature("boolean booleanValue()"); TypeUtils.parseSignature("boolean booleanValue()");
private static final Signature BOOLEAN_VALUE_OF =
TypeUtils.parseSignature("Boolean valueOf(boolean)");
private static final Signature INTEGER_VALUE_OF =
TypeUtils.parseSignature("Integer valueOf(int)");
private static final Signature BYTE_VALUE_OF =
TypeUtils.parseSignature("Byte valueOf(byte)");
private static final Signature SHORT_VALUE_OF =
TypeUtils.parseSignature("Short valueOf(short)");
private static final Signature LONG_VALUE_OF =
TypeUtils.parseSignature("Long valueOf(long)");
private static final Signature FLOAT_VALUE_OF =
TypeUtils.parseSignature("Float valueOf(float)");
private static final Signature DOUBLE_VALUE_OF =
TypeUtils.parseSignature("Double valueOf(double)");
private static final Signature CHARACTER_VALUE_OF =
TypeUtils.parseSignature("Character valueOf(char)");
private static final Signature CHAR_VALUE = private static final Signature CHAR_VALUE =
TypeUtils.parseSignature("char charValue()"); TypeUtils.parseSignature("char charValue()");
private static final Signature LONG_VALUE = private static final Signature LONG_VALUE =
@ -705,29 +721,56 @@ public class CodeEmitter extends LocalVariablesSorter {
/** /**
* If the argument is a primitive class, replaces the primitive value * If the argument is a primitive class, replaces the primitive value
* on the top of the stack with the wrapped (Object) equivalent. For * on the top of the stack with the wrapped (Object) equivalent using valueOf() methods.
* example, char -> Character. * For example, char -> Character.
* If the class is Void, a null is pushed onto the stack instead. * If the class is Void, a null is pushed onto the stack instead.
* @param type the class indicating the current type of the top stack value * @param type the class indicating the current type of the top stack value
*/ */
public void box(Type type) { public void box(Type type) {
if (TypeUtils.isPrimitive(type)) { if (TypeUtils.isPrimitive(type)) {
if (type == Type.VOID_TYPE) { switch (type.getSort()) {
aconst_null(); case Type.VOID:
} else { aconst_null();
Type boxed = TypeUtils.getBoxedType(type); break;
new_instance(boxed); case Type.BOOLEAN:
if (type.getSize() == 2) { invoke_static(Constants.TYPE_BOOLEAN, BOOLEAN_VALUE_OF);
// Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o break;
dup_x2(); case Type.INT:
dup_x2(); invoke_static(Constants.TYPE_INTEGER, INTEGER_VALUE_OF);
pop(); break;
} else { case Type.BYTE:
// p -> po -> opo -> oop -> o invoke_static(Constants.TYPE_BYTE, BYTE_VALUE_OF);
dup_x1(); break;
swap(); case Type.SHORT:
} invoke_static(Constants.TYPE_SHORT, SHORT_VALUE_OF);
invoke_constructor(boxed, new Signature(Constants.CONSTRUCTOR_NAME, Type.VOID_TYPE, new Type[]{ type })); break;
case Type.LONG:
invoke_static(Constants.TYPE_LONG, LONG_VALUE_OF);
break;
case Type.FLOAT:
invoke_static(Constants.TYPE_FLOAT, FLOAT_VALUE_OF);
break;
case Type.DOUBLE:
invoke_static(Constants.TYPE_DOUBLE, DOUBLE_VALUE_OF);
break;
case Type.CHAR:
invoke_static(Constants.TYPE_CHARACTER, CHARACTER_VALUE_OF);
break;
default:
Type boxed = TypeUtils.getBoxedType(type);
new_instance(boxed);
if (type.getSize() == 2) {
// Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o
dup_x2();
dup_x2();
pop();
} else {
// p -> po -> opo -> oop -> o
dup_x1();
swap();
}
invoke_constructor(boxed, new Signature(Constants.CONSTRUCTOR_NAME, Type.VOID_TYPE, new Type[]{ type }));
} }
} }
} }