Skip to content

Commit 4c7a76a

Browse files
committed
Bump bytecode version of generated accessors to Java 1.8.
Also, use replace intermediate variable with this. access. Closes #3365
1 parent 789cd8c commit 4c7a76a

File tree

2 files changed

+45
-53
lines changed

2 files changed

+45
-53
lines changed

src/main/java/org/springframework/data/mapping/model/ClassGeneratingEntityInstantiator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ public byte[] generateBytecode(String internalClassName, PersistentEntity<?, ?>
469469

470470
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
471471

472-
cw.visit(Opcodes.V1_6, ACC_PUBLIC + ACC_SUPER, internalClassName.replace('.', '/'), null, JAVA_LANG_OBJECT,
472+
cw.visit(Opcodes.V1_8, ACC_PUBLIC + ACC_SUPER, internalClassName.replace('.', '/'), null, JAVA_LANG_OBJECT,
473473
IMPLEMENTED_INTERFACES);
474474

475475
visitDefaultConstructor(cw);

src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java

Lines changed: 44 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ static Class<?> generateCustomAccessorClass(PersistentEntity<?, ?> entity) {
384384
static byte[] generateBytecode(String internalClassName, PersistentEntity<?, ?> entity) {
385385

386386
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
387-
cw.visit(Opcodes.V1_6, ACC_PUBLIC + ACC_SUPER, internalClassName, null, JAVA_LANG_OBJECT, IMPLEMENTED_INTERFACES);
387+
cw.visit(Opcodes.V1_8, ACC_PUBLIC + ACC_SUPER, internalClassName, null, JAVA_LANG_OBJECT, IMPLEMENTED_INTERFACES);
388388

389389
List<PersistentProperty<?>> persistentProperties = getPersistentProperties(entity);
390390

@@ -778,19 +778,18 @@ private static void visitBeanGetter(PersistentEntity<?, ?> entity, String intern
778778
*
779779
* <pre class="code">
780780
* public Object getProperty(PersistentProperty<?> property) {
781-
* Object bean = this.bean;
782781
* switch (property.getName().hashCode()) {
783782
* case 3355:
784-
* return id_fieldGetter.invoke(bean);
783+
* return id_fieldGetter.invoke(this.bean);
785784
* case 3356:
786-
* return bean.getField();
785+
* return this.bean.getField();
787786
* // …
788787
* case 3357:
789-
* return bean.field;
788+
* return this.bean.field;
790789
* // …
791790
* }
792791
* throw new UnsupportedOperationException(
793-
* String.format("No MethodHandle to get property %s", new Object[] { property }));
792+
* String.format("No accessor to get property %s", new Object[] { property }));
794793
* }
795794
* </pre>
796795
*/
@@ -809,12 +808,6 @@ private static void visitGetProperty(PersistentEntity<?, ?> entity,
809808
// Assert.notNull(property)
810809
visitAssertNotNull(mv);
811810

812-
mv.visitVarInsn(ALOAD, 0);
813-
814-
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
815-
816-
mv.visitVarInsn(ASTORE, 2);
817-
818811
visitGetPropertySwitch(entity, persistentProperties, internalClassName, mv);
819812

820813
mv.visitLabel(l1);
@@ -824,8 +817,6 @@ private static void visitGetProperty(PersistentEntity<?, ?> entity,
824817
mv.visitLocalVariable("property", referenceName(PERSISTENT_PROPERTY),
825818
"Lorg/springframework/data/mapping/PersistentProperty<*>;", l0, l1, 1);
826819

827-
mv.visitLocalVariable(BEAN_FIELD, getAccessibleTypeReferenceName(entity), null, l0, l1, 2);
828-
829820
mv.visitMaxs(0, 0);
830821
mv.visitEnd();
831822
}
@@ -894,12 +885,14 @@ private static void visitGetProperty0(PersistentEntity<?, ?> entity, PersistentP
894885
// $getter.invoke(bean)
895886
mv.visitFieldInsn(GETSTATIC, internalClassName, getterName(property),
896887
referenceName(JAVA_LANG_INVOKE_METHOD_HANDLE));
897-
mv.visitVarInsn(ALOAD, 2);
888+
mv.visitVarInsn(ALOAD, 0);
889+
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
898890
mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_LANG_INVOKE_METHOD_HANDLE, "invoke",
899891
String.format("(%s)%s", referenceName(JAVA_LANG_OBJECT), referenceName(JAVA_LANG_OBJECT)), false);
900892
} else {
901893
// bean.get…
902-
mv.visitVarInsn(ALOAD, 2);
894+
mv.visitVarInsn(ALOAD, 0);
895+
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
903896

904897
int invokeOpCode = INVOKEVIRTUAL;
905898
Class<?> declaringClass = getter.getDeclaringClass();
@@ -921,12 +914,14 @@ private static void visitGetProperty0(PersistentEntity<?, ?> entity, PersistentP
921914
// $fieldGetter.invoke(bean)
922915
mv.visitFieldInsn(GETSTATIC, internalClassName, fieldGetterName(property),
923916
referenceName(JAVA_LANG_INVOKE_METHOD_HANDLE));
924-
mv.visitVarInsn(ALOAD, 2);
917+
mv.visitVarInsn(ALOAD, 0);
918+
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
925919
mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_LANG_INVOKE_METHOD_HANDLE, "invoke",
926920
String.format("(%s)%s", referenceName(JAVA_LANG_OBJECT), referenceName(JAVA_LANG_OBJECT)), false);
927921
} else {
928922
// bean.field
929-
mv.visitVarInsn(ALOAD, 2);
923+
mv.visitVarInsn(ALOAD, 0);
924+
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
930925
mv.visitFieldInsn(GETFIELD, Type.getInternalName(field.getDeclaringClass()), field.getName(),
931926
signatureTypeName(field.getType()));
932927
autoboxIfNeeded(field.getType(), autoboxType(field.getType()), mv);
@@ -941,19 +936,18 @@ private static void visitGetProperty0(PersistentEntity<?, ?> entity, PersistentP
941936
*
942937
* <pre class="code">
943938
* public void setProperty(PersistentProperty<?> property, Optional<? extends Object> value) {
944-
* Object bean = this.bean;
945939
* switch (property.getName().hashCode()) {
946940
* case 3355:
947-
* $id_fieldSetter.invoke(bean, value);
941+
* $id_fieldSetter.invoke(this.bean, value);
948942
* return;
949943
* case 3357:
950-
* this.bean = $id_fieldWither.invoke(bean, value);
944+
* this.bean = $id_fieldWither.invoke(this.bean, value);
951945
* return;
952946
* case 3358:
953-
* this.bean = bean.withId(value);
947+
* this.bean = this.bean.withId(value);
954948
* return;
955949
* case 3359:
956-
* this.bean = PersonWithId.copy$default(bean, value, 0, null); // Kotlin
950+
* this.bean = PersonWithId.copy$default(this.bean, value, 0, null); // Kotlin
957951
* return;
958952
* // …
959953
* }
@@ -975,12 +969,6 @@ private static void visitSetProperty(PersistentEntity<?, ?> entity,
975969

976970
visitAssertNotNull(mv);
977971

978-
mv.visitVarInsn(ALOAD, 0);
979-
980-
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
981-
982-
mv.visitVarInsn(ASTORE, 3);
983-
984972
visitSetPropertySwitch(entity, persistentProperties, internalClassName, mv);
985973

986974
Label l1 = new Label();
@@ -993,8 +981,6 @@ private static void visitSetProperty(PersistentEntity<?, ?> entity,
993981
"Lorg/springframework/data/mapping/PersistentProperty<*>;", l0, l1, 1);
994982
mv.visitLocalVariable("value", referenceName(JAVA_LANG_OBJECT), null, l0, l1, 2);
995983

996-
mv.visitLocalVariable(BEAN_FIELD, getAccessibleTypeReferenceName(entity), null, l0, l1, 3);
997-
998984
mv.visitMaxs(0, 0);
999985
mv.visitEnd();
1000986
}
@@ -1089,15 +1075,17 @@ private static void visitSetProperty0(PersistentEntity<?, ?> entity, PersistentP
10891075
private static void visitWithProperty(PersistentEntity<?, ?> entity, PersistentProperty<?> property,
10901076
MethodVisitor mv, String internalClassName, Method wither) {
10911077

1092-
if (generateMethodHandle(entity, wither)) {
1078+
// this. <- for later PUTFIELD
1079+
mv.visitVarInsn(ALOAD, 0);
10931080

1094-
// this. <- for later PUTFIELD
1095-
mv.visitVarInsn(ALOAD, 0);
1081+
if (generateMethodHandle(entity, wither)) {
10961082

10971083
// $wither.invoke(bean)
10981084
mv.visitFieldInsn(GETSTATIC, internalClassName, witherName(property),
10991085
referenceName(JAVA_LANG_INVOKE_METHOD_HANDLE));
1100-
mv.visitVarInsn(ALOAD, 3);
1086+
mv.visitVarInsn(ALOAD, 0);
1087+
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
1088+
11011089
mv.visitVarInsn(ALOAD, 2);
11021090
mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_LANG_INVOKE_METHOD_HANDLE, "invoke", String.format("(%s%s)%s",
11031091
referenceName(JAVA_LANG_OBJECT), referenceName(JAVA_LANG_OBJECT), getAccessibleTypeReferenceName(entity)),
@@ -1107,11 +1095,9 @@ private static void visitWithProperty(PersistentEntity<?, ?> entity, PersistentP
11071095
}
11081096
} else {
11091097

1110-
// this. <- for later PUTFIELD
1098+
// this.bean.set...(object)
11111099
mv.visitVarInsn(ALOAD, 0);
1112-
1113-
// bean.set...(object)
1114-
mv.visitVarInsn(ALOAD, 3);
1100+
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
11151101
mv.visitVarInsn(ALOAD, 2);
11161102

11171103
visitInvokeMethodSingleArg(mv, wither);
@@ -1146,7 +1132,8 @@ private static void visitKotlinCopy(PersistentEntity<?, ?> entity, PersistentPro
11461132
if (kotlinCopyMethod.shouldUsePublicCopyMethod(entity)) {
11471133

11481134
// PersonWithId.copy$(value)
1149-
mv.visitVarInsn(ALOAD, 3);
1135+
mv.visitVarInsn(ALOAD, 0);
1136+
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
11501137
mv.visitVarInsn(ALOAD, 2);
11511138

11521139
visitInvokeMethodSingleArg(mv, kotlinCopyMethod.getPublicCopyMethod());
@@ -1155,8 +1142,9 @@ private static void visitKotlinCopy(PersistentEntity<?, ?> entity, PersistentPro
11551142
Method copy = kotlinCopyMethod.getSyntheticCopyMethod();
11561143
Class<?>[] parameterTypes = copy.getParameterTypes();
11571144

1158-
// PersonWithId.copy$default..(bean, object, MASK, null)
1159-
mv.visitVarInsn(ALOAD, 3);
1145+
// PersonWithId.copy$default..(this.bean, object, MASK, null)
1146+
mv.visitVarInsn(ALOAD, 0);
1147+
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
11601148

11611149
KotlinCopyMethod.KotlinCopyByProperty copyByProperty = kotlinCopyMethod.forProperty(property)
11621150
.orElseThrow(() -> new IllegalStateException(
@@ -1200,25 +1188,27 @@ private static void visitKotlinCopy(PersistentEntity<?, ?> entity, PersistentPro
12001188
* or
12011189
*
12021190
* <pre class="code">
1203-
* bean.setId(value);
1191+
* this.bean.setId(value);
12041192
* </pre>
12051193
*/
12061194
private static void visitSetProperty(PersistentEntity<?, ?> entity, PersistentProperty<?> property,
12071195
MethodVisitor mv, String internalClassName, Method setter) {
12081196

12091197
if (generateMethodHandle(entity, setter)) {
12101198

1211-
// $setter.invoke(bean)
1199+
// $setter.invoke(this.bean)
12121200
mv.visitFieldInsn(GETSTATIC, internalClassName, setterName(property),
12131201
referenceName(JAVA_LANG_INVOKE_METHOD_HANDLE));
1214-
mv.visitVarInsn(ALOAD, 3);
1202+
mv.visitVarInsn(ALOAD, 0);
1203+
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
12151204
mv.visitVarInsn(ALOAD, 2);
12161205
mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_LANG_INVOKE_METHOD_HANDLE, "invoke",
12171206
String.format("(%s%s)V", referenceName(JAVA_LANG_OBJECT), referenceName(JAVA_LANG_OBJECT)), false);
12181207
} else {
12191208

1220-
// bean.set...(object)
1221-
mv.visitVarInsn(ALOAD, 3);
1209+
// this.bean.set...(object)
1210+
mv.visitVarInsn(ALOAD, 0);
1211+
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
12221212
mv.visitVarInsn(ALOAD, 2);
12231213

12241214
visitInvokeMethodSingleArg(mv, setter);
@@ -1229,7 +1219,7 @@ private static void visitSetProperty(PersistentEntity<?, ?> entity, PersistentPr
12291219
* Generate:
12301220
*
12311221
* <pre class="code">
1232-
* $id_fieldSetter.invoke(bean, value);
1222+
* $id_fieldSetter.invoke(this.bean, value);
12331223
* </pre>
12341224
*
12351225
* or
@@ -1244,16 +1234,18 @@ private static void visitSetField(PersistentEntity<?, ?> entity, PersistentPrope
12441234
Field field = property.getField();
12451235
if (field != null) {
12461236
if (generateSetterMethodHandle(entity, field)) {
1247-
// $fieldSetter.invoke(bean, object)
1237+
// $fieldSetter.invoke(this.bean, object)
12481238
mv.visitFieldInsn(GETSTATIC, internalClassName, fieldSetterName(property),
12491239
referenceName(JAVA_LANG_INVOKE_METHOD_HANDLE));
1250-
mv.visitVarInsn(ALOAD, 3);
1240+
mv.visitVarInsn(ALOAD, 0);
1241+
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
12511242
mv.visitVarInsn(ALOAD, 2);
12521243
mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_LANG_INVOKE_METHOD_HANDLE, "invoke",
12531244
String.format("(%s%s)V", referenceName(JAVA_LANG_OBJECT), referenceName(JAVA_LANG_OBJECT)), false);
12541245
} else {
1255-
// bean.field
1256-
mv.visitVarInsn(ALOAD, 3);
1246+
// this.bean.field
1247+
mv.visitVarInsn(ALOAD, 0);
1248+
mv.visitFieldInsn(GETFIELD, internalClassName, BEAN_FIELD, getAccessibleTypeReferenceName(entity));
12571249
mv.visitVarInsn(ALOAD, 2);
12581250

12591251
Class<?> fieldType = field.getType();

0 commit comments

Comments
 (0)