@@ -1318,11 +1318,12 @@ static int gc_collect_roots(uint32_t *flags, gc_stack *stack)
1318
1318
return count ;
1319
1319
}
1320
1320
1321
- static void gc_remove_nested_data_from_buffer (zend_refcounted * ref , gc_root_buffer * root )
1321
+ static int gc_remove_nested_data_from_buffer (zend_refcounted * ref , gc_root_buffer * root )
1322
1322
{
1323
1323
HashTable * ht = NULL ;
1324
1324
Bucket * p , * end ;
1325
1325
zval * zv ;
1326
+ int count = 0 ;
1326
1327
1327
1328
tail_call :
1328
1329
do {
@@ -1331,18 +1332,20 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
1331
1332
gc_remove_from_roots (root );
1332
1333
GC_REF_SET_INFO (ref , 0 );
1333
1334
root = NULL ;
1335
+ count ++ ;
1334
1336
} else if (GC_REF_ADDRESS (ref ) != 0
1335
1337
&& GC_REF_CHECK_COLOR (ref , GC_BLACK )) {
1336
1338
GC_TRACE_REF (ref , "removing from buffer" );
1337
1339
GC_REMOVE_FROM_BUFFER (ref );
1340
+ count ++ ;
1338
1341
} else if (GC_TYPE (ref ) == IS_REFERENCE ) {
1339
1342
if (Z_REFCOUNTED (((zend_reference * )ref )-> val )) {
1340
1343
ref = Z_COUNTED (((zend_reference * )ref )-> val );
1341
1344
goto tail_call ;
1342
1345
}
1343
- return ;
1346
+ return count ;
1344
1347
} else {
1345
- return ;
1348
+ return count ;
1346
1349
}
1347
1350
1348
1351
if (GC_TYPE (ref ) == IS_OBJECT ) {
@@ -1357,15 +1360,15 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
1357
1360
ht = obj -> handlers -> get_gc (& tmp , & zv , & n );
1358
1361
end = zv + n ;
1359
1362
if (EXPECTED (!ht )) {
1360
- if (!n ) return ;
1363
+ if (!n ) return count ;
1361
1364
while (!Z_REFCOUNTED_P (-- end )) {
1362
- if (zv == end ) return ;
1365
+ if (zv == end ) return count ;
1363
1366
}
1364
1367
}
1365
1368
while (zv != end ) {
1366
1369
if (Z_REFCOUNTED_P (zv )) {
1367
1370
ref = Z_COUNTED_P (zv );
1368
- gc_remove_nested_data_from_buffer (ref , NULL );
1371
+ count += gc_remove_nested_data_from_buffer (ref , NULL );
1369
1372
}
1370
1373
zv ++ ;
1371
1374
}
@@ -1374,15 +1377,15 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
1374
1377
goto tail_call ;
1375
1378
}
1376
1379
} else {
1377
- return ;
1380
+ return count ;
1378
1381
}
1379
1382
} else if (GC_TYPE (ref ) == IS_ARRAY ) {
1380
1383
ht = (zend_array * )ref ;
1381
1384
} else {
1382
- return ;
1385
+ return count ;
1383
1386
}
1384
1387
1385
- if (!ht -> nNumUsed ) return ;
1388
+ if (!ht -> nNumUsed ) return count ;
1386
1389
p = ht -> arData ;
1387
1390
end = p + ht -> nNumUsed ;
1388
1391
while (1 ) {
@@ -1394,7 +1397,7 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
1394
1397
if (Z_REFCOUNTED_P (zv )) {
1395
1398
break ;
1396
1399
}
1397
- if (p == end ) return ;
1400
+ if (p == end ) return count ;
1398
1401
}
1399
1402
while (p != end ) {
1400
1403
zv = & p -> val ;
@@ -1403,7 +1406,7 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
1403
1406
}
1404
1407
if (Z_REFCOUNTED_P (zv )) {
1405
1408
ref = Z_COUNTED_P (zv );
1406
- gc_remove_nested_data_from_buffer (ref , NULL );
1409
+ count += gc_remove_nested_data_from_buffer (ref , NULL );
1407
1410
}
1408
1411
p ++ ;
1409
1412
}
@@ -1510,7 +1513,7 @@ ZEND_API int zend_gc_collect_cycles(void)
1510
1513
if (GC_IS_GARBAGE (current -> ref )) {
1511
1514
p = GC_GET_PTR (current -> ref );
1512
1515
if (GC_REFCOUNT (p ) > refcounts [idx ]) {
1513
- gc_remove_nested_data_from_buffer (p , current );
1516
+ count -= gc_remove_nested_data_from_buffer (p , current );
1514
1517
}
1515
1518
}
1516
1519
current ++ ;
0 commit comments