Skip to content

Commit b9e1b19

Browse files
authored
[Java] Fix private record JIT (#1004)
* fix private record jit * add codegen param * lint code
1 parent 037239e commit b9e1b19

File tree

4 files changed

+61
-37
lines changed

4 files changed

+61
-37
lines changed

integration_tests/latest_jdk_tests/src/test/java/io/fury/integration_tests/RecordSerializersTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,16 @@ public void testPrivateRecords(boolean codegen) {
219219
Assert.assertEquals(fury.deserialize(bytes), o2);
220220
}
221221
}
222+
223+
@Test(dataProvider = "codegen")
224+
public void testPrivateRecord(boolean codegen) {
225+
Fury fury = Fury.builder().withCodegen(codegen).build();
226+
fury.register(PrivateRecord.class);
227+
byte[] serialized = fury.serialize(new PrivateRecord("foo")); // fails
228+
Object deserialized = fury.deserialize(serialized);
229+
System.out.println(deserialized);
230+
}
231+
232+
private record PrivateRecord(String foo) {
233+
}
222234
}

java/fury-core/src/main/java/io/fury/builder/BaseObjectCodecBuilder.java

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@
8282
import io.fury.serializer.Serializer;
8383
import io.fury.serializer.Serializers;
8484
import io.fury.serializer.StringSerializer;
85-
import io.fury.type.FinalObjectTypeStub;
8685
import io.fury.type.TypeUtils;
8786
import io.fury.util.ReflectionUtils;
8887
import io.fury.util.StringUtils;
@@ -946,40 +945,6 @@ private Expression writeContainerElement(
946945
return new ListExpression(elem, write);
947946
}
948947

949-
protected Expression tryInlineCast(Expression expression, TypeToken<?> targetType) {
950-
return tryCastIfPublic(expression, targetType, true);
951-
}
952-
953-
protected Expression tryCastIfPublic(Expression expression, TypeToken<?> targetType) {
954-
return tryCastIfPublic(expression, targetType, false);
955-
}
956-
957-
protected Expression tryCastIfPublic(
958-
Expression expression, TypeToken<?> targetType, boolean inline) {
959-
if (getRawType(targetType) == FinalObjectTypeStub.class) {
960-
// final field doesn't exist in this class, skip cast.
961-
return expression;
962-
}
963-
if (inline) {
964-
if (ReflectionUtils.isPublic(targetType)
965-
&& !expression.type().wrap().isSubtypeOf(targetType.wrap())) {
966-
return new Cast(expression, targetType);
967-
} else {
968-
return expression;
969-
}
970-
}
971-
return tryCastIfPublic(expression, targetType, "castedValue");
972-
}
973-
974-
protected Expression tryCastIfPublic(
975-
Expression expression, TypeToken<?> targetType, String valuePrefix) {
976-
if (ReflectionUtils.isPublic(targetType)
977-
&& !expression.type().wrap().isSubtypeOf(targetType.wrap())) {
978-
return new Cast(expression, targetType, valuePrefix);
979-
}
980-
return expression;
981-
}
982-
983948
/**
984949
* Return an expression to write a map to <code>buffer</code>. This expression can have better
985950
* efficiency for final key/value type. For final key/value type, it doesn't have to write class

java/fury-core/src/main/java/io/fury/builder/CodecBuilder.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package io.fury.builder;
1818

19+
import static io.fury.codegen.Expression.Invoke.inlineInvoke;
1920
import static io.fury.type.TypeUtils.OBJECT_ARRAY_TYPE;
2021
import static io.fury.type.TypeUtils.OBJECT_TYPE;
2122
import static io.fury.type.TypeUtils.PRIMITIVE_BOOLEAN_TYPE;
@@ -45,6 +46,7 @@
4546
import io.fury.resolver.ClassInfo;
4647
import io.fury.resolver.ClassInfoHolder;
4748
import io.fury.type.Descriptor;
49+
import io.fury.type.FinalObjectTypeStub;
4850
import io.fury.util.Platform;
4951
import io.fury.util.ReflectionUtils;
5052
import io.fury.util.StringUtils;
@@ -115,6 +117,40 @@ public CodecBuilder(CodegenContext ctx, TypeToken<?> beanType) {
115117
/** Returns an expression that serialize java bean of type {@link CodecBuilder#beanClass}. */
116118
public abstract Expression buildEncodeExpression();
117119

120+
protected Expression tryInlineCast(Expression expression, TypeToken<?> targetType) {
121+
return tryCastIfPublic(expression, targetType, true);
122+
}
123+
124+
protected Expression tryCastIfPublic(Expression expression, TypeToken<?> targetType) {
125+
return tryCastIfPublic(expression, targetType, false);
126+
}
127+
128+
protected Expression tryCastIfPublic(
129+
Expression expression, TypeToken<?> targetType, boolean inline) {
130+
if (getRawType(targetType) == FinalObjectTypeStub.class) {
131+
// final field doesn't exist in this class, skip cast.
132+
return expression;
133+
}
134+
if (inline) {
135+
if (ReflectionUtils.isPublic(targetType)
136+
&& !expression.type().wrap().isSubtypeOf(targetType.wrap())) {
137+
return new Cast(expression, targetType);
138+
} else {
139+
return expression;
140+
}
141+
}
142+
return tryCastIfPublic(expression, targetType, "castedValue");
143+
}
144+
145+
protected Expression tryCastIfPublic(
146+
Expression expression, TypeToken<?> targetType, String valuePrefix) {
147+
if (ReflectionUtils.isPublic(targetType)
148+
&& !expression.type().wrap().isSubtypeOf(targetType.wrap())) {
149+
return new Cast(expression, targetType, valuePrefix);
150+
}
151+
return expression;
152+
}
153+
118154
// left null check in sub class encode method to reduce data dependence.
119155
private final boolean fieldNullable = false;
120156

@@ -212,7 +248,14 @@ private Expression getRecordFieldValue(Expression inputBeanExpr, Descriptor desc
212248
ref = new Reference(key, getterType);
213249
fieldMap.put(key, ref);
214250
}
215-
return new Invoke(ref, methodInfo.f1, fieldType, fieldNullable, inputBeanExpr);
251+
if (!fieldType.isPrimitive()) {
252+
Expression v = inlineInvoke(ref, methodInfo.f1, OBJECT_TYPE, fieldNullable, inputBeanExpr);
253+
TypeToken<?> publicSuperType =
254+
ReflectionUtils.getPublicSuperType(descriptor.getTypeToken());
255+
return new Cast(v, publicSuperType, fieldName);
256+
} else {
257+
return new Invoke(ref, methodInfo.f1, fieldType, fieldNullable, inputBeanExpr);
258+
}
216259
}
217260
}
218261

java/fury-core/src/main/java/io/fury/util/unsafe/_JDKAccess.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,11 @@ public static <T> T makeFunction(Lookup lookup, MethodHandle handle, Class<T> fu
261261
}
262262

263263
public static Tuple2<Class<?>, String> getterMethodInfo(Class<?> type) {
264-
return methodMap.get(type);
264+
Tuple2<Class<?>, String> info = methodMap.get(type);
265+
if (info == null) {
266+
return Tuple2.of(Function.class, "apply");
267+
}
268+
return info;
265269
}
266270

267271
public static Object makeGetterFunction(

0 commit comments

Comments
 (0)