@@ -29,6 +29,7 @@ static const ptrint_t SmallInt64_tag = 27;
29
29
static const ptrint_t IdTable_tag = 28 ;
30
30
static const ptrint_t Int32_tag = 29 ;
31
31
static const ptrint_t Array1d_tag = 30 ;
32
+ static const ptrint_t Singleton_tag = 31 ;
32
33
static const ptrint_t Null_tag = 253 ;
33
34
static const ptrint_t ShortBackRef_tag = 254 ;
34
35
static const ptrint_t BackRef_tag = 255 ;
@@ -95,7 +96,6 @@ static void write_as_tag(ios_t *s, uint8_t tag)
95
96
#define jl_serialize_value (s , v ) jl_serialize_value_(s,(jl_value_t*)(v))
96
97
static void jl_serialize_value_ (ios_t * s , jl_value_t * v );
97
98
static jl_value_t * jl_deserialize_value (ios_t * s );
98
- static jl_value_t * jl_deserialize_value_internal (ios_t * s );
99
99
jl_value_t * * * sysimg_gvars = NULL ;
100
100
101
101
extern int globalUnique ;
@@ -286,24 +286,24 @@ static void jl_serialize_datatype(ios_t *s, jl_datatype_t *dt)
286
286
size_t nf = jl_tuple_len (dt -> names );
287
287
write_uint16 (s , nf );
288
288
write_int32 (s , dt -> size );
289
+ int has_instance = !!(dt -> instance != NULL );
290
+ write_uint8 (s , dt -> abstract | (dt -> mutabl <<1 ) | (dt -> pointerfree <<2 ) | (has_instance <<3 ));
291
+ if (!dt -> abstract )
292
+ write_int32 (s , dt -> uid );
293
+ if (has_instance )
294
+ jl_serialize_value (s , dt -> instance );
289
295
if (nf > 0 ) {
290
296
write_int32 (s , dt -> alignment );
291
297
ios_write (s , (char * )& dt -> fields [0 ], nf * sizeof (jl_fielddesc_t ));
292
298
jl_serialize_value (s , dt -> names );
293
299
jl_serialize_value (s , dt -> types );
294
300
}
295
- int has_instance = !!(dt -> instance != NULL );
296
- write_uint8 (s , dt -> abstract | (dt -> mutabl <<1 ) | (dt -> pointerfree <<2 ) | (has_instance <<3 ));
297
- if (!dt -> abstract )
298
- write_int32 (s , dt -> uid );
299
301
300
302
jl_serialize_value (s , dt -> parameters );
301
303
jl_serialize_value (s , dt -> name );
302
304
jl_serialize_value (s , dt -> super );
303
305
jl_serialize_value (s , dt -> env );
304
306
jl_serialize_value (s , dt -> linfo );
305
- if (has_instance )
306
- jl_serialize_value (s , dt -> instance );
307
307
jl_serialize_fptr (s , (void * )dt -> fptr );
308
308
}
309
309
@@ -546,6 +546,10 @@ static void jl_serialize_value_(ios_t *s, jl_value_t *v)
546
546
write_int32 (s , (int32_t )* (int32_t * )data );
547
547
}
548
548
else {
549
+ if (v == t -> instance ) {
550
+ writetag (s , (jl_value_t * )Singleton_tag );
551
+ return ;
552
+ }
549
553
if ((jl_value_t * )t == jl_idtable_type )
550
554
writetag (s , (jl_value_t * )IdTable_tag );
551
555
else
@@ -598,13 +602,12 @@ static jl_fptr_t jl_deserialize_fptr(ios_t *s)
598
602
return * (jl_fptr_t * )pbp ;
599
603
}
600
604
601
- #define DTINSTANCE_PLACEHOLDER ((void*)2)
602
-
603
605
static jl_value_t * jl_deserialize_datatype (ios_t * s , int pos )
604
606
{
605
607
int tag = read_uint8 (s );
606
608
uint16_t nf = read_uint16 (s );
607
609
size_t size = read_int32 (s );
610
+ uint8_t flags = read_uint8 (s );
608
611
jl_datatype_t * dt ;
609
612
if (tag == 2 )
610
613
dt = jl_int32_type ;
@@ -617,7 +620,18 @@ static jl_value_t *jl_deserialize_datatype(ios_t *s, int pos)
617
620
dt -> size = size ;
618
621
dt -> struct_decl = NULL ;
619
622
dt -> instance = NULL ;
620
-
623
+ dt -> abstract = flags & 1 ;
624
+ dt -> mutabl = (flags >>1 )& 1 ;
625
+ dt -> pointerfree = (flags >>2 )& 1 ;
626
+ if (!dt -> abstract )
627
+ dt -> uid = read_int32 (s );
628
+ else
629
+ dt -> uid = 0 ;
630
+ int has_instance = (flags >>3 )& 1 ;
631
+ if (has_instance ) {
632
+ dt -> instance = jl_deserialize_value (s );
633
+ dt -> instance -> type = (jl_value_t * )dt ;
634
+ }
621
635
assert (tree_literal_values == NULL );
622
636
ptrhash_put (& backref_table , (void * )(ptrint_t )pos , dt );
623
637
@@ -633,26 +647,11 @@ static jl_value_t *jl_deserialize_datatype(ios_t *s, int pos)
633
647
dt -> alignment = MAX_ALIGN ;
634
648
dt -> names = dt -> types = jl_null ;
635
649
}
636
- uint8_t flags = read_uint8 (s );
637
- dt -> abstract = flags & 1 ;
638
- dt -> mutabl = (flags >>1 )& 1 ;
639
- dt -> pointerfree = (flags >>2 )& 1 ;
640
- int has_instance = (flags >>3 )& 1 ;
641
- if (!dt -> abstract )
642
- dt -> uid = read_int32 (s );
643
- else
644
- dt -> uid = 0 ;
645
650
dt -> parameters = (jl_tuple_t * )jl_deserialize_value (s );
646
651
dt -> name = (jl_typename_t * )jl_deserialize_value (s );
647
652
dt -> super = (jl_datatype_t * )jl_deserialize_value (s );
648
653
dt -> env = jl_deserialize_value (s );
649
654
dt -> linfo = (jl_lambda_info_t * )jl_deserialize_value (s );
650
- if (has_instance ) {
651
- jl_value_t * instance = (jl_value_t * )jl_deserialize_value_internal (s );
652
- if (instance == DTINSTANCE_PLACEHOLDER )
653
- instance = jl_new_struct_uninit (dt );
654
- dt -> instance = instance ;
655
- }
656
655
dt -> fptr = jl_deserialize_fptr (s );
657
656
if (dt -> name == jl_array_type -> name || dt -> name == jl_pointer_type -> name ||
658
657
dt -> name == jl_type_type -> name || dt -> name == jl_vararg_type -> name ||
@@ -663,14 +662,12 @@ static jl_value_t *jl_deserialize_datatype(ios_t *s, int pos)
663
662
// parametric types here.
664
663
jl_cell_1d_push (datatype_list , (jl_value_t * )dt );
665
664
}
666
-
667
665
return (jl_value_t * )dt ;
668
666
}
669
667
670
668
jl_array_t * jl_eqtable_put (jl_array_t * h , void * key , void * val );
671
669
672
- // Internal jl_deserialize_value. May return the placeholder value DTINSTANCE_PLACEHOLDER, unlike jl_deserialize_value
673
- static jl_value_t * jl_deserialize_value_internal (ios_t * s )
670
+ static jl_value_t * jl_deserialize_value (ios_t * s )
674
671
{
675
672
int pos = ios_pos (s );
676
673
int32_t tag = read_uint8 (s );
@@ -873,14 +870,6 @@ static jl_value_t *jl_deserialize_value_internal(ios_t *s)
873
870
return v ;
874
871
}
875
872
else if (vtag == (jl_value_t * )jl_datatype_type || vtag == (jl_value_t * )IdTable_tag ) {
876
- // If the value v we are about to deserialize is some dt->instance, we have a circular
877
- // reference, because v == v->type->instance. To avoid this, we put a null value in
878
- // the backref table to reserve the space. If jl_deserialize_value encounters this,
879
- // it knows to do the allocation itself. This work, because in all instances where
880
- // v->type->instance != null, v->type has no fields, so there is no further serialized
881
- // data stored that we would need to construct the type.
882
- if (usetable )
883
- ptrhash_put (& backref_table , (void * )(ptrint_t )pos , DTINSTANCE_PLACEHOLDER );
884
873
jl_datatype_t * dt = (jl_datatype_t * )jl_deserialize_value (s );
885
874
if (dt == jl_datatype_type )
886
875
return jl_deserialize_datatype (s , pos );
@@ -913,11 +902,6 @@ static jl_value_t *jl_deserialize_value_internal(ios_t *s)
913
902
ptrhash_put (& backref_table , (void * )(ptrint_t )pos , v );
914
903
}
915
904
else {
916
- if (dt -> instance ) {
917
- if (usetable )
918
- * ptrhash_bp (& backref_table , (void * )(ptrint_t )pos ) = dt -> instance ;
919
- return dt -> instance ;
920
- }
921
905
v = jl_new_struct_uninit (dt );
922
906
if (usetable )
923
907
ptrhash_put (& backref_table , (void * )(ptrint_t )pos , v );
@@ -941,17 +925,16 @@ static jl_value_t *jl_deserialize_value_internal(ios_t *s)
941
925
// TODO: put WeakRefs on the weak_refs list
942
926
return v ;
943
927
}
928
+ else if (vtag == (jl_value_t * )Singleton_tag ) {
929
+ jl_value_t * v = allocobj (sizeof (void * ));
930
+ if (usetable )
931
+ ptrhash_put (& backref_table , (void * )(ptrint_t )pos , v );
932
+ return v ;
933
+ }
944
934
assert (0 );
945
935
return NULL ;
946
936
}
947
937
948
- static jl_value_t * jl_deserialize_value (ios_t * s )
949
- {
950
- jl_value_t * v = jl_deserialize_value_internal (s );
951
- assert (v != DTINSTANCE_PLACEHOLDER );
952
- return v ;
953
- }
954
-
955
938
// --- entry points ---
956
939
957
940
extern jl_array_t * jl_module_init_order ;
@@ -1215,7 +1198,7 @@ void jl_init_serializer(void)
1215
1198
jl_expr_type , (void * )LongSymbol_tag , (void * )LongTuple_tag ,
1216
1199
(void * )LongExpr_tag , (void * )LiteralVal_tag ,
1217
1200
(void * )SmallInt64_tag , (void * )IdTable_tag ,
1218
- (void * )Int32_tag , (void * )Array1d_tag ,
1201
+ (void * )Int32_tag , (void * )Array1d_tag , ( void * ) Singleton_tag ,
1219
1202
jl_module_type , jl_tvar_type , jl_lambda_info_type ,
1220
1203
1221
1204
jl_null , jl_false , jl_true , jl_any_type , jl_symbol ("Any" ),
0 commit comments