@@ -701,11 +701,14 @@ static void gc_scan_black(zend_refcounted *ref, gc_stack *stack)
701
701
ZVAL_OBJ (& tmp , obj );
702
702
ht = obj -> handlers -> get_gc (& tmp , & zv , & n );
703
703
end = zv + n ;
704
- if (EXPECTED (!ht )) {
704
+ if (EXPECTED (!ht ) || UNEXPECTED (GC_REF_CHECK_COLOR (ht , GC_BLACK ))) {
705
+ ht = NULL ;
705
706
if (!n ) goto next ;
706
707
while (!Z_REFCOUNTED_P (-- end )) {
707
708
if (zv == end ) goto next ;
708
709
}
710
+ } else {
711
+ GC_REF_SET_BLACK (ht );
709
712
}
710
713
while (zv != end ) {
711
714
if (Z_REFCOUNTED_P (zv )) {
@@ -818,11 +821,14 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
818
821
ZVAL_OBJ (& tmp , obj );
819
822
ht = obj -> handlers -> get_gc (& tmp , & zv , & n );
820
823
end = zv + n ;
821
- if (EXPECTED (!ht )) {
824
+ if (EXPECTED (!ht ) || UNEXPECTED (GC_REF_CHECK_COLOR (ht , GC_GREY ))) {
825
+ ht = NULL ;
822
826
if (!n ) goto next ;
823
827
while (!Z_REFCOUNTED_P (-- end )) {
824
828
if (zv == end ) goto next ;
825
829
}
830
+ } else {
831
+ GC_REF_SET_COLOR (ht , GC_GREY );
826
832
}
827
833
while (zv != end ) {
828
834
if (Z_REFCOUNTED_P (zv )) {
@@ -1006,11 +1012,14 @@ static void gc_scan(zend_refcounted *ref, gc_stack *stack)
1006
1012
ZVAL_OBJ (& tmp , obj );
1007
1013
ht = obj -> handlers -> get_gc (& tmp , & zv , & n );
1008
1014
end = zv + n ;
1009
- if (EXPECTED (!ht )) {
1015
+ if (EXPECTED (!ht ) || UNEXPECTED (!GC_REF_CHECK_COLOR (ht , GC_GREY ))) {
1016
+ ht = NULL ;
1010
1017
if (!n ) goto next ;
1011
1018
while (!Z_REFCOUNTED_P (-- end )) {
1012
1019
if (zv == end ) goto next ;
1013
1020
}
1021
+ } else {
1022
+ GC_REF_SET_COLOR (ht , GC_WHITE );
1014
1023
}
1015
1024
while (zv != end ) {
1016
1025
if (Z_REFCOUNTED_P (zv )) {
@@ -1175,7 +1184,8 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
1175
1184
ZVAL_OBJ (& tmp , obj );
1176
1185
ht = obj -> handlers -> get_gc (& tmp , & zv , & n );
1177
1186
end = zv + n ;
1178
- if (EXPECTED (!ht )) {
1187
+ if (EXPECTED (!ht ) || UNEXPECTED (GC_REF_CHECK_COLOR (ht , GC_BLACK ))) {
1188
+ ht = NULL ;
1179
1189
if (!n ) goto next ;
1180
1190
while (!Z_REFCOUNTED_P (-- end )) {
1181
1191
/* count non-refcounted for compatibility ??? */
@@ -1184,6 +1194,8 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
1184
1194
}
1185
1195
if (zv == end ) goto next ;
1186
1196
}
1197
+ } else {
1198
+ GC_REF_SET_BLACK (ht );
1187
1199
}
1188
1200
while (zv != end ) {
1189
1201
if (Z_REFCOUNTED_P (zv )) {
0 commit comments