Skip to content

Commit 885b262

Browse files
committed
refactor dispatch
1 parent d99bcab commit 885b262

52 files changed

Lines changed: 1213 additions & 841 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

java/fory-core/src/main/java/org/apache/fory/Fory.java

Lines changed: 75 additions & 192 deletions
Large diffs are not rendered by default.

java/fory-core/src/main/java/org/apache/fory/builder/BaseObjectCodecBuilder.java

Lines changed: 63 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ public abstract class BaseObjectCodecBuilder extends CodecBuilder {
174174
protected final Fory fory;
175175
protected final TypeRef<?> concreteTypeResolverType;
176176
protected final Reference typeResolverRef;
177+
protected final Reference writeContextRef;
178+
protected final Reference readContextRef;
177179
protected final TypeResolver typeResolver;
178180
protected final Reference stringSerializerRef;
179181
private final Map<Class<?>, Reference> serializerMap = new HashMap<>();
@@ -200,6 +202,8 @@ public BaseObjectCodecBuilder(TypeRef<?> beanType, Fory fory, Class<?> parentSer
200202
// use concrete type to avoid virtual methods call in generated code
201203
concreteTypeResolverType = TypeRef.of(typeResolver.getClass());
202204
typeResolverRef = fieldRef(TYPE_RESOLVER_NAME, concreteTypeResolverType);
205+
writeContextRef = new Reference(WRITE_CONTEXT_NAME, TypeRef.of(WriteContext.class), false);
206+
readContextRef = new Reference(READ_CONTEXT_NAME, TypeRef.of(ReadContext.class), false);
203207
ctx.addField(ctx.type(concreteTypeResolverType), TYPE_RESOLVER_NAME);
204208
ctx.reserveName(STRING_SERIALIZER_NAME);
205209
stringSerializerRef = fieldRef(STRING_SERIALIZER_NAME, STRING_SERIALIZER_TYPE_TOKEN);
@@ -214,12 +218,12 @@ public BaseObjectCodecBuilder(TypeRef<?> beanType, Fory fory, Class<?> parentSer
214218
public String codecClassName(Class<?> beanClass) {
215219
String name = ReflectionUtils.getClassNameWithoutPackage(beanClass).replace("$", "_");
216220
StringBuilder nameBuilder = new StringBuilder(name);
217-
if (fory.isCrossLanguage()) {
221+
if (typeResolver.isCrossLanguage()) {
218222
// Generated classes are different when xlang mode is enabled.
219223
// So we need to use a different class name for generated serializers.
220224
nameBuilder.append("Xlang");
221225
}
222-
if (fory.trackingRef()) {
226+
if (typeResolver.trackingRef()) {
223227
// Generated classes are different when referenceTracking is switched.
224228
// So we need to use a different name.
225229
nameBuilder.append("ForyRef");
@@ -486,7 +490,7 @@ private Expression serializeForNotNullForField(
486490
return serializePrimitiveField(inputObject, buffer, descriptor);
487491
} else {
488492
if (clz == String.class) {
489-
return fory.getStringSerializer().writeStringExpr(stringSerializerRef, buffer, inputObject);
493+
return typeResolver.getStringSerializer().writeStringExpr(stringSerializerRef, buffer, inputObject);
490494
}
491495
Expression action;
492496
if (useCollectionSerialization(typeRef)) {
@@ -554,10 +558,10 @@ private Expression serializePrimitive(Expression inputObject, Expression buffer,
554558
} else if (clz == short.class || clz == Short.class) {
555559
return new Invoke(buffer, "writeInt16", inputObject);
556560
} else if (clz == int.class || clz == Integer.class) {
557-
String func = fory.compressInt() ? "writeVarInt32" : "writeInt32";
561+
String func = typeResolver.getConfig().compressInt() ? "writeVarInt32" : "writeInt32";
558562
return new Invoke(buffer, func, inputObject);
559563
} else if (clz == long.class || clz == Long.class) {
560-
return LongSerializer.writeInt64(buffer, inputObject, fory.longEncoding(), true);
564+
return LongSerializer.writeInt64(buffer, inputObject, typeResolver.getConfig().longEncoding(), true);
561565
} else if (clz == float.class || clz == Float.class) {
562566
return new Invoke(buffer, "writeFloat32", inputObject);
563567
} else if (clz == double.class || clz == Double.class) {
@@ -659,7 +663,7 @@ private Expression serializeForNotNull(
659663
return serializePrimitive(inputObject, buffer, clz);
660664
} else {
661665
if (clz == String.class) {
662-
return fory.getStringSerializer().writeStringExpr(stringSerializerRef, buffer, inputObject);
666+
return typeResolver.getStringSerializer().writeStringExpr(stringSerializerRef, buffer, inputObject);
663667
}
664668
Expression action;
665669
// this is different from ITERABLE_TYPE in RowCodecBuilder. In row-format we don't need to
@@ -768,7 +772,11 @@ protected Expression writeForNotNullNonFinalObject(
768772
writeContextRef(),
769773
inputObject));
770774
return invokeGenerated(
771-
ctx, ofHashSet(buffer, inputObject), writeClassAndObject, "writeClassAndObject", false);
775+
ctx,
776+
writeCutPoints(buffer, inputObject),
777+
writeClassAndObject,
778+
"writeClassAndObject",
779+
false);
772780
}
773781

774782
protected Expression writeTypeInfo(
@@ -810,8 +818,8 @@ private Expression getOrCreateSerializer(Class<?> cls, boolean isField) {
810818
serializerClass = Serializer.class;
811819
}
812820
boolean finalClassAsFieldCondition =
813-
!fory.isShareMeta()
814-
&& !fory.isCompatible()
821+
!typeResolver.isShareMeta()
822+
&& !typeResolver.isCompatible()
815823
&& isField
816824
&& Modifier.isFinal(cls.getModifiers())
817825
&& serializerClass == ReplaceResolveSerializer.class;
@@ -1068,7 +1076,7 @@ protected Expression serializeForCollection(
10681076
serializer =
10691077
invokeGenerated(
10701078
ctx,
1071-
ofHashSet(buffer, collection),
1079+
writeCutPoints(buffer, collection),
10721080
writeClassAction,
10731081
"writeCollectionTypeInfo",
10741082
false);
@@ -1091,7 +1099,11 @@ protected Expression serializeForCollection(
10911099
ListExpression actions = new ListExpression(collection, ifExpr);
10921100
if (generateNewMethod) {
10931101
return invokeGenerated(
1094-
ctx, ofHashSet(buffer, collection, serializer), actions, "writeCollection", false);
1102+
ctx,
1103+
writeCutPoints(buffer, collection, serializer),
1104+
actions,
1105+
"writeCollection",
1106+
false);
10951107
}
10961108
return actions;
10971109
}
@@ -1178,7 +1190,8 @@ protected Expression writeCollectionData(
11781190
writeContainerElements(
11791191
elementType, false, elemSerializer, hasNull, buffer, collection, size),
11801192
false));
1181-
Set<Expression> cutPoint = ofHashSet(buffer, collection, size, trackRef, hasNull);
1193+
Set<Expression> cutPoint =
1194+
writeCutPoints(buffer, collection, size, trackRef, hasNull);
11821195
if (maybeDecl) {
11831196
cutPoint.add(flags);
11841197
}
@@ -1202,7 +1215,7 @@ protected Expression writeCollectionData(
12021215
writeBuilder.add(
12031216
writeContainerElements(
12041217
elementType, false, elemSerializer, hasNull, buffer, collection, size));
1205-
Set<Expression> cutPoint = ofHashSet(buffer, collection, size, hasNull);
1218+
Set<Expression> cutPoint = writeCutPoints(buffer, collection, size, hasNull);
12061219
if (maybeDecl) {
12071220
cutPoint.add(flags);
12081221
}
@@ -1421,7 +1434,11 @@ protected Expression serializeForMap(
14211434
// Spit this into a separate method to avoid method too big to inline.
14221435
serializer =
14231436
invokeGenerated(
1424-
ctx, ofHashSet(buffer, map), writeClassAction, "writeMapTypeInfo", false);
1437+
ctx,
1438+
writeCutPoints(buffer, map),
1439+
writeClassAction,
1440+
"writeMapTypeInfo",
1441+
false);
14251442
}
14261443
} else if (!MapLikeSerializer.class.isAssignableFrom(serializer.type().getRawType())) {
14271444
serializer = cast(serializer, TypeRef.of(MapLikeSerializer.class), "mapSerializer");
@@ -1437,7 +1454,8 @@ protected Expression serializeForMap(
14371454
// and then try to use that variable name in the else-branch where it's out of scope.
14381455
Expression write = new ListExpression(map, ifExpr);
14391456
if (generateNewMethod) {
1440-
return invokeGenerated(ctx, ofHashSet(buffer, map, serializer), write, "writeMap", false);
1457+
return invokeGenerated(
1458+
ctx, writeCutPoints(buffer, map, serializer), write, "writeMap", false);
14411459
}
14421460
return write;
14431461
}
@@ -1779,7 +1797,7 @@ entry, cast(inlineInvoke(iterator, "next", OBJECT_TYPE), MAP_ENTRY_TYPE)),
17791797
// Serializer keySerializer,
17801798
// Serializer valueSerializer
17811799
// )
1782-
Set<Expression> params = ofHashSet(buffer, entry, iterator);
1800+
Set<Expression> params = writeCutPoints(buffer, entry, iterator);
17831801
return invokeGenerated(ctx, params, expressions, "writeChunk", false);
17841802
}
17851803
return expressions;
@@ -1957,7 +1975,7 @@ protected Expression deserializeForNotNull(
19571975
return deserializePrimitive(buffer, cls);
19581976
} else {
19591977
if (cls == String.class) {
1960-
return fory.getStringSerializer().readStringExpr(stringSerializerRef, buffer);
1978+
return typeResolver.getStringSerializer().readStringExpr(stringSerializerRef, buffer);
19611979
}
19621980
Expression obj;
19631981
if (useCollectionSerialization(typeRef)) {
@@ -2052,7 +2070,7 @@ private Expression deserializeForNotNullForField(
20522070
return deserializePrimitiveField(buffer, descriptor);
20532071
} else {
20542072
if (cls == String.class) {
2055-
return fory.getStringSerializer().readStringExpr(stringSerializerRef, buffer);
2073+
return typeResolver.getStringSerializer().readStringExpr(stringSerializerRef, buffer);
20562074
}
20572075
Expression obj;
20582076
if (useCollectionSerialization(typeRef)) {
@@ -2140,9 +2158,9 @@ private Expression deserializePrimitive(Expression buffer, Class<?> cls) {
21402158
} else if (cls == short.class || cls == Short.class) {
21412159
return readInt16(buffer);
21422160
} else if (cls == int.class || cls == Integer.class) {
2143-
return fory.compressInt() ? readVarInt32(buffer) : readInt32(buffer);
2161+
return typeResolver.getConfig().compressInt() ? readVarInt32(buffer) : readInt32(buffer);
21442162
} else if (cls == long.class || cls == Long.class) {
2145-
return LongSerializer.readInt64(buffer, fory.longEncoding());
2163+
return LongSerializer.readInt64(buffer, typeResolver.getConfig().longEncoding());
21462164
} else if (cls == float.class || cls == Float.class) {
21472165
return readFloat32(buffer);
21482166
} else if (cls == double.class || cls == Double.class) {
@@ -2184,7 +2202,7 @@ protected Expression readForNotNullNonFinal(
21842202
if (serializer == null) {
21852203
Expression classInfo;
21862204
Class<?> rawType = typeRef.getRawType();
2187-
if (fory.isCompatible() && rawType != Object.class) {
2205+
if (typeResolver.isCompatible() && rawType != Object.class) {
21882206
TypeInfo typeInfo = typeResolver(r -> r.getTypeInfo(rawType, false));
21892207
if (typeInfo == null
21902208
|| (typeInfo.getTypeId() == Types.COMPATIBLE_STRUCT
@@ -2241,6 +2259,7 @@ protected Expression deserializeForCollection(
22412259
false);
22422260
if (invokeHint != null && invokeHint.genNewMethod) {
22432261
invokeHint.add(buffer);
2262+
invokeHint.add(readContextRef());
22442263
return invokeGenerated(
22452264
ctx,
22462265
invokeHint.cutPoints,
@@ -2259,7 +2278,7 @@ protected Expression readCollectionCodegen(
22592278
Class<?> elemClass = TypeUtils.getRawType(elementType);
22602279
walkPath.add(elementType.toString());
22612280
boolean finalType = isMonomorphic(elemClass);
2262-
boolean trackingRef = fory.trackingRef() && !(isPrimitive(elemClass) || isBoxed(elemClass));
2281+
boolean trackingRef = typeResolver.trackingRef() && !(isPrimitive(elemClass) || isBoxed(elemClass));
22632282
Literal trackingRefFlag = ofInt(CollectionFlags.TRACKING_REF);
22642283
Expression trackRef = eq(new BitAnd(flags, trackingRefFlag), trackingRefFlag, "trackRef");
22652284
if (finalType) {
@@ -2308,15 +2327,15 @@ protected Expression readCollectionCodegen(
23082327
Literal hasNullFlag = ofInt(CollectionFlags.HAS_NULL);
23092328
Expression hasNull = eq(new BitAnd(flags, hasNullFlag), hasNullFlag, "hasNull");
23102329
builder.add(hasNull);
2311-
Set<Expression> cutPoint = ofHashSet(buffer, collection, size);
2330+
Set<Expression> cutPoint = readCutPoints(buffer, collection, size);
23122331
Expression differentElemTypeRead =
23132332
invokeGenerated(
23142333
ctx,
23152334
cutPoint,
23162335
readContainerElements(elementType, true, null, null, buffer, collection, size),
23172336
"differentTypeElemsRead",
23182337
false);
2319-
Set<Expression> noRefCutPoint = ofHashSet(buffer, collection, size, hasNull);
2338+
Set<Expression> noRefCutPoint = readCutPoints(buffer, collection, size, hasNull);
23202339
Expression noRefDifferentTypeElemsRead =
23212340
invokeGenerated(
23222341
ctx,
@@ -2347,7 +2366,7 @@ protected Expression readCollectionCodegen(
23472366
readContainerElements(
23482367
elementType, false, elemSerializer, hasNull, buffer, collection, size));
23492368
// Same element class read end
2350-
Set<Expression> cutPoint = ofHashSet(buffer, collection, size, hasNull);
2369+
Set<Expression> cutPoint = readCutPoints(buffer, collection, size, hasNull);
23512370
Expression differentTypeElemsRead =
23522371
invokeGenerated(
23532372
ctx,
@@ -2534,7 +2553,7 @@ chunkHeader, cast(bitand(sizeAndHeader2, ofInt(0xff)), PRIMITIVE_INT_TYPE)),
25342553
return exprs;
25352554
});
25362555
Set<Expression> chunkLoopCutPoints =
2537-
ofHashSet(buffer, newMap, chunkHeader, size, mapSerializer, keySerializer, valueSerializer);
2556+
readCutPoints(buffer, newMap, chunkHeader, size, mapSerializer, keySerializer, valueSerializer);
25382557
Expression chunkLoopExpr =
25392558
invokeGenerated(ctx, chunkLoopCutPoints, chunksLoop, "readMapChunks", false);
25402559
expressions.add(chunkLoopExpr, newMap);
@@ -2544,6 +2563,7 @@ chunkHeader, cast(bitand(sizeAndHeader2, ofInt(0xff)), PRIMITIVE_INT_TYPE)),
25442563
if (invokeHint != null && invokeHint.genNewMethod) {
25452564
invokeHint.add(buffer);
25462565
invokeHint.add(serializer);
2566+
invokeHint.add(readContextRef());
25472567
return invokeGenerated(
25482568
ctx,
25492569
invokeHint.cutPoints,
@@ -2555,7 +2575,7 @@ chunkHeader, cast(bitand(sizeAndHeader2, ofInt(0xff)), PRIMITIVE_INT_TYPE)),
25552575
}
25562576

25572577
private boolean mayTrackRefForCollectionRead(Class<?> type) {
2558-
if (!fory.trackingRef()) {
2578+
if (!typeResolver.trackingRef()) {
25592579
return false;
25602580
}
25612581
if (type.isPrimitive() || isBoxed(type)) {
@@ -2568,7 +2588,7 @@ private boolean mayTrackRefForCollectionRead(Class<?> type) {
25682588
// 2. we can't use `needWriteRef`, the collection/map read must follow ref track header
25692589
// in serialized data. other language may write ref for elements even `needWriteRef` return
25702590
// false
2571-
if (type == String.class && !fory.isCrossLanguage()) {
2591+
if (type == String.class && !typeResolver.isCrossLanguage()) {
25722592
return !fory.getConfig().isStringRefIgnored();
25732593
}
25742594
return true;
@@ -2700,7 +2720,7 @@ private Expression readChunk(
27002720
// Serializer keySerializer,
27012721
// Serializer valueSerializer
27022722
// )
2703-
Set<Expression> params = ofHashSet(buffer, size, chunkHeader, map);
2723+
Set<Expression> params = readCutPoints(buffer, size, chunkHeader, map);
27042724
return invokeGenerated(ctx, params, expressions, "readChunk", false);
27052725
}
27062726
}
@@ -2732,10 +2752,22 @@ protected Expression beanClassExpr() {
27322752
}
27332753

27342754
protected Expression writeContextRef() {
2735-
return new StaticInvoke(WriteContext.class, "current", TypeRef.of(WriteContext.class));
2755+
return writeContextRef;
27362756
}
27372757

27382758
protected Expression readContextRef() {
2739-
return new StaticInvoke(ReadContext.class, "current", TypeRef.of(ReadContext.class));
2759+
return readContextRef;
2760+
}
2761+
2762+
protected Set<Expression> writeCutPoints(Expression... expressions) {
2763+
Set<Expression> cutPoints = ofHashSet(expressions);
2764+
cutPoints.add(writeContextRef());
2765+
return cutPoints;
2766+
}
2767+
2768+
protected Set<Expression> readCutPoints(Expression... expressions) {
2769+
Set<Expression> cutPoints = ofHashSet(expressions);
2770+
cutPoints.add(readContextRef());
2771+
return cutPoints;
27402772
}
27412773
}

java/fory-core/src/main/java/org/apache/fory/builder/ObjectCodecBuilder.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public ObjectCodecBuilder(Class<?> beanClass, Fory fory) {
118118
}
119119
}
120120
classVersionHash =
121-
fory.checkClassVersion()
121+
typeResolver.checkClassVersion()
122122
? new Literal(
123123
ObjectSerializer.computeStructHash(typeResolver, grouper), PRIMITIVE_INT_TYPE)
124124
: null;
@@ -164,7 +164,7 @@ public Expression buildEncodeExpression() {
164164
ListExpression expressions = new ListExpression();
165165
Expression bean = tryCastIfPublic(inputObject, beanType, ctx.newName(beanClass));
166166
expressions.add(bean);
167-
if (fory.checkClassVersion()) {
167+
if (typeResolver.checkClassVersion()) {
168168
expressions.add(new Invoke(buffer, "writeInt32", classVersionHash));
169169
}
170170
expressions.addAll(serializePrimitives(bean, buffer, objectCodecOptimizer.primitiveGroups));
@@ -226,7 +226,8 @@ private Expression serializeGroup(
226226
if (inline) {
227227
return expressionSupplier.get();
228228
}
229-
return objectCodecOptimizer.invokeGenerated(expressionSupplier, "writeFields");
229+
return objectCodecOptimizer.invokeGenerated(
230+
writeCutPoints(bean, buffer), expressionSupplier.get(), "writeFields");
230231
}
231232

232233
/**
@@ -239,7 +240,7 @@ private List<Expression> serializePrimitives(
239240
if (totalSize == 0) {
240241
return new ArrayList<>();
241242
}
242-
if (fory.compressInt() || fory.compressLong()) {
243+
if (typeResolver.getConfig().compressInt() || typeResolver.getConfig().compressLong()) {
243244
return serializePrimitivesCompressed(bean, buffer, primitiveGroups, totalSize);
244245
} else {
245246
return serializePrimitivesUnCompressed(bean, buffer, primitiveGroups, totalSize);
@@ -466,7 +467,7 @@ private Expression getWriterPos(Expression writerPos, long acc) {
466467
public Expression buildDecodeExpression() {
467468
Reference buffer = new Reference(BUFFER_NAME, bufferTypeRef, false);
468469
ListExpression expressions = new ListExpression();
469-
if (fory.checkClassVersion()) {
470+
if (typeResolver.checkClassVersion()) {
470471
expressions.add(checkClassVersion(buffer));
471472
}
472473
Expression bean;
@@ -603,7 +604,8 @@ protected Expression deserializeGroup(
603604
if (inline) {
604605
return exprSupplier.get();
605606
} else {
606-
return objectCodecOptimizer.invokeGenerated(exprSupplier, "readFields");
607+
return objectCodecOptimizer.invokeGenerated(
608+
readCutPoints(bean, buffer), exprSupplier.get(), "readFields");
607609
}
608610
}
609611

@@ -641,7 +643,7 @@ private List<Expression> deserializePrimitives(
641643
if (totalSize == 0) {
642644
return new ArrayList<>();
643645
}
644-
if (fory.compressInt() || fory.compressLong()) {
646+
if (typeResolver.getConfig().compressInt() || typeResolver.getConfig().compressLong()) {
645647
return deserializeCompressedPrimitives(bean, buffer, primitiveGroups);
646648
} else {
647649
return deserializeUnCompressedPrimitives(bean, buffer, primitiveGroups, totalSize);

0 commit comments

Comments
 (0)