@@ -705,15 +705,21 @@ static void gc_scan_black(zend_refcounted *ref, gc_stack *stack)
705
705
zval * zv , * end ;
706
706
707
707
ht = obj -> handlers -> get_gc (obj , & zv , & n );
708
- if (EXPECTED (!ht ) || UNEXPECTED (GC_REF_CHECK_COLOR (ht , GC_BLACK ))) {
709
- ht = NULL ;
708
+ if (UNEXPECTED (ht )) {
709
+ GC_ADDREF (ht );
710
+ if (!GC_REF_CHECK_COLOR (ht , GC_BLACK )) {
711
+ GC_REF_SET_BLACK (ht );
712
+ } else {
713
+ ht = NULL ;
714
+ }
715
+ }
716
+ if (EXPECTED (!ht )) {
710
717
if (!n ) goto next ;
711
718
end = zv + n ;
712
719
while (!Z_REFCOUNTED_P (-- end )) {
713
720
if (zv == end ) goto next ;
714
721
}
715
722
} else {
716
- GC_REF_SET_BLACK (ht );
717
723
if (!n ) goto handle_ht ;
718
724
end = zv + n ;
719
725
}
@@ -823,15 +829,21 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
823
829
zval * zv , * end ;
824
830
825
831
ht = obj -> handlers -> get_gc (obj , & zv , & n );
826
- if (EXPECTED (!ht ) || UNEXPECTED (GC_REF_CHECK_COLOR (ht , GC_GREY ))) {
827
- ht = NULL ;
832
+ if (UNEXPECTED (ht )) {
833
+ GC_DELREF (ht );
834
+ if (!GC_REF_CHECK_COLOR (ht , GC_GREY )) {
835
+ GC_REF_SET_COLOR (ht , GC_GREY );
836
+ } else {
837
+ ht = NULL ;
838
+ }
839
+ }
840
+ if (EXPECTED (!ht )) {
828
841
if (!n ) goto next ;
829
842
end = zv + n ;
830
843
while (!Z_REFCOUNTED_P (-- end )) {
831
844
if (zv == end ) goto next ;
832
845
}
833
846
} else {
834
- GC_REF_SET_COLOR (ht , GC_GREY );
835
847
if (!n ) goto handle_ht ;
836
848
end = zv + n ;
837
849
}
@@ -1006,17 +1018,18 @@ static void gc_scan(zend_refcounted *ref, gc_stack *stack)
1006
1018
zval * zv , * end ;
1007
1019
1008
1020
ht = obj -> handlers -> get_gc (obj , & zv , & n );
1009
- if (EXPECTED (!ht ) || UNEXPECTED (!GC_REF_CHECK_COLOR (ht , GC_GREY ))) {
1010
- ht = NULL ;
1011
- if (!n ) goto next ;
1012
- end = zv + n ;
1013
- while (!Z_REFCOUNTED_P (-- end )) {
1014
- if (zv == end ) goto next ;
1021
+ if (UNEXPECTED (ht )) {
1022
+ if (GC_REF_CHECK_COLOR (ht , GC_GREY )) {
1023
+ GC_REF_SET_COLOR (ht , GC_WHITE );
1024
+ GC_STACK_PUSH ((zend_refcounted * ) ht );
1015
1025
}
1016
- } else {
1017
- GC_REF_SET_COLOR (ht , GC_WHITE );
1018
- if (!n ) goto handle_ht ;
1019
- end = zv + n ;
1026
+ ht = NULL ;
1027
+ }
1028
+
1029
+ if (!n ) goto next ;
1030
+ end = zv + n ;
1031
+ while (!Z_REFCOUNTED_P (-- end )) {
1032
+ if (zv == end ) goto next ;
1020
1033
}
1021
1034
while (zv != end ) {
1022
1035
if (Z_REFCOUNTED_P (zv )) {
@@ -1028,17 +1041,13 @@ static void gc_scan(zend_refcounted *ref, gc_stack *stack)
1028
1041
}
1029
1042
zv ++ ;
1030
1043
}
1031
- if (EXPECTED (!ht )) {
1032
- ref = Z_COUNTED_P (zv );
1033
- if (GC_REF_CHECK_COLOR (ref , GC_GREY )) {
1034
- GC_REF_SET_COLOR (ref , GC_WHITE );
1035
- goto tail_call ;
1036
- }
1037
- goto next ;
1044
+ ref = Z_COUNTED_P (zv );
1045
+ if (GC_REF_CHECK_COLOR (ref , GC_GREY )) {
1046
+ GC_REF_SET_COLOR (ref , GC_WHITE );
1047
+ goto tail_call ;
1038
1048
}
1039
- } else {
1040
- goto next ;
1041
1049
}
1050
+ goto next ;
1042
1051
} else if (GC_TYPE (ref ) == IS_ARRAY ) {
1043
1052
ZEND_ASSERT ((zend_array * )ref != & EG (symbol_table ));
1044
1053
ht = (zend_array * )ref ;
@@ -1055,7 +1064,6 @@ static void gc_scan(zend_refcounted *ref, gc_stack *stack)
1055
1064
goto next ;
1056
1065
}
1057
1066
1058
- handle_ht :
1059
1067
if (!ht -> nNumUsed ) goto next ;
1060
1068
p = ht -> arData ;
1061
1069
end = p + ht -> nNumUsed ;
@@ -1175,15 +1183,21 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
1175
1183
* flags |= GC_HAS_DESTRUCTORS ;
1176
1184
}
1177
1185
ht = obj -> handlers -> get_gc (obj , & zv , & n );
1178
- if (EXPECTED (!ht ) || UNEXPECTED (GC_REF_CHECK_COLOR (ht , GC_BLACK ))) {
1179
- ht = NULL ;
1186
+ if (UNEXPECTED (ht )) {
1187
+ GC_ADDREF (ht );
1188
+ if (GC_REF_CHECK_COLOR (ht , GC_WHITE )) {
1189
+ GC_REF_SET_BLACK (ht );
1190
+ } else {
1191
+ ht = NULL ;
1192
+ }
1193
+ }
1194
+ if (EXPECTED (!ht )) {
1180
1195
if (!n ) goto next ;
1181
1196
end = zv + n ;
1182
1197
while (!Z_REFCOUNTED_P (-- end )) {
1183
1198
if (zv == end ) goto next ;
1184
1199
}
1185
1200
} else {
1186
- GC_REF_SET_BLACK (ht );
1187
1201
if (!n ) goto handle_ht ;
1188
1202
end = zv + n ;
1189
1203
}
0 commit comments