@@ -259,8 +259,6 @@ struct _gc_stack {
259
259
zend_refcounted * data [GC_STACK_SEGMENT_SIZE ];
260
260
};
261
261
262
- #ifdef PHP_ASYNC_API
263
-
264
262
typedef enum {
265
263
GC_ASYNC_STATE_NONE = 0 ,
266
264
GC_ASYNC_STATE_INIT , // initial state
@@ -280,7 +278,6 @@ typedef struct {
280
278
zend_hrtime_t start_time ; // start of full GC pass
281
279
zend_hrtime_t dtor_start_time ; // start of dtor phase
282
280
} gc_async_context_t ;
283
- #endif
284
281
285
282
typedef struct _zend_gc_globals {
286
283
gc_root_buffer * buf ; /* preallocated arrays of buffers */
@@ -308,13 +305,11 @@ typedef struct _zend_gc_globals {
308
305
uint32_t dtor_end ;
309
306
zend_fiber * dtor_fiber ;
310
307
bool dtor_fiber_running ;
311
- #ifdef PHP_ASYNC_API
312
308
gc_async_context_t async_context ; /* async context for gc */
313
309
gc_stack * gc_stack ; /* local mark/scan stack */
314
310
zend_coroutine_t * dtor_coroutine ;
315
311
zend_async_scope_t * dtor_scope ;
316
312
zend_async_microtask_t * microtask ;
317
- #endif
318
313
319
314
#if GC_BENCH
320
315
uint32_t root_buf_length ;
@@ -534,13 +529,11 @@ static void gc_globals_ctor_ex(zend_gc_globals *gc_globals)
534
529
gc_globals -> dtor_fiber = NULL ;
535
530
gc_globals -> dtor_fiber_running = false;
536
531
537
- #ifdef PHP_ASYNC_API
538
532
gc_globals -> dtor_coroutine = NULL ;
539
533
gc_globals -> dtor_scope = NULL ;
540
534
gc_globals -> microtask = NULL ;
541
535
gc_globals -> async_context .state = GC_ASYNC_STATE_NONE ;
542
536
gc_globals -> gc_stack = NULL ;
543
- #endif
544
537
545
538
#if GC_BENCH
546
539
gc_globals -> root_buf_length = 0 ;
@@ -567,11 +560,9 @@ void gc_globals_dtor(void)
567
560
root_buffer_dtor (& gc_globals );
568
561
#endif
569
562
570
- #ifdef PHP_ASYNC_API
571
563
if (GC_G (dtor_scope )) {
572
564
GC_G (dtor_scope ) = NULL ;
573
565
}
574
- #endif
575
566
}
576
567
577
568
void gc_reset (void )
@@ -1857,16 +1848,8 @@ static zend_always_inline zend_result gc_call_destructors(uint32_t idx, uint32_t
1857
1848
gc_root_buffer * current ;
1858
1849
zend_refcounted * p ;
1859
1850
1860
- #ifdef PHP_ASYNC_API
1861
1851
const bool in_coroutine = GC_G (dtor_coroutine ) != NULL ;
1862
1852
1863
- #define RESUMED_AFTER_SUSPENSION (fiber != NULL && GC_G(dtor_fiber) != fiber) \
1864
- || (in_coroutine && GC_G(dtor_coroutine) != ZEND_ASYNC_CURRENT_COROUTINE)
1865
- #else
1866
- const bool in_coroutine = false;
1867
- #define RESUMED_AFTER_SUSPENSION fiber != NULL && GC_G(dtor_fiber) != fiber
1868
- #endif
1869
-
1870
1853
/* The root buffer might be reallocated during destructors calls,
1871
1854
* make sure to reload pointers as necessary. */
1872
1855
while (idx != end ) {
@@ -1886,20 +1869,18 @@ static zend_always_inline zend_result gc_call_destructors(uint32_t idx, uint32_t
1886
1869
GC_TRACE_REF (obj , "calling destructor" );
1887
1870
GC_ADD_FLAGS (obj , IS_OBJ_DESTRUCTOR_CALLED );
1888
1871
GC_ADDREF (obj );
1889
- #ifdef PHP_ASYNC_API
1890
1872
if (in_coroutine ) {
1891
1873
ZEND_ASYNC_CURRENT_COROUTINE -> extended_data = obj ;
1892
1874
}
1893
- #endif
1875
+
1894
1876
obj -> handlers -> dtor_obj (obj );
1895
- #ifdef PHP_ASYNC_API
1896
1877
if (in_coroutine ) {
1897
1878
ZEND_ASYNC_CURRENT_COROUTINE -> extended_data = NULL ;
1898
1879
}
1899
- #endif
1900
1880
GC_TRACE_REF (obj , "returned from destructor" );
1901
1881
GC_DELREF (obj );
1902
- if (UNEXPECTED (RESUMED_AFTER_SUSPENSION )) {
1882
+ if (UNEXPECTED ((fiber != NULL && GC_G (dtor_fiber ) != fiber )
1883
+ || (in_coroutine && GC_G (dtor_coroutine ) != ZEND_ASYNC_CURRENT_COROUTINE ))) {
1903
1884
/* We resumed after suspension */
1904
1885
gc_check_possible_root ((zend_refcounted * )& obj -> gc );
1905
1886
return FAILURE ;
@@ -1974,7 +1955,6 @@ static zend_never_inline void gc_call_destructors_in_fiber(uint32_t end)
1974
1955
}
1975
1956
}
1976
1957
1977
- #ifdef PHP_ASYNC_API
1978
1958
static void zend_gc_collect_cycles_microtask (zend_async_microtask_t * task );
1979
1959
1980
1960
static void zend_gc_collect_cycles_microtask_dtor (zend_async_microtask_t * task )
@@ -2134,12 +2114,9 @@ static zend_always_inline void start_gc_in_coroutine(void)
2134
2114
zend_error_noreturn (E_ERROR , "Unable to spawn destructor coroutine" );
2135
2115
}
2136
2116
}
2137
- #endif
2138
2117
2139
2118
ZEND_API int zend_gc_collect_cycles (void )
2140
2119
{
2141
- #ifdef PHP_ASYNC_API
2142
-
2143
2120
if (UNEXPECTED (ZEND_ASYNC_IS_ACTIVE && ZEND_ASYNC_CURRENT_COROUTINE != GC_G (dtor_coroutine ))) {
2144
2121
2145
2122
if (GC_G (dtor_coroutine )) {
@@ -2150,24 +2127,8 @@ ZEND_API int zend_gc_collect_cycles(void)
2150
2127
return 0 ;
2151
2128
}
2152
2129
2153
- #endif
2154
-
2155
2130
zend_hrtime_t dtor_start_time = 0 ;
2156
2131
2157
- #ifdef PHP_ASYNC_API
2158
- #define GC_COLLECT_TOTAL_COUNT (context->total_count)
2159
- #define GC_COLLECT_COUNT (context->count)
2160
- #define GC_COLLECT_START_TIME (context->start_time)
2161
- #define GC_COLLECT_SHOULD_RERUN_GC (context->should_rerun_gc)
2162
- #define GC_COLLECT_DID_RERUN_GC (context->did_rerun_gc)
2163
- #define GC_COLLECT_GC_FLAGS (context->gc_flags)
2164
- #define GC_COLLECT_STACK (stack)
2165
- #define GC_COLLECT_FREE_STACK GC_G(gc_stack) = NULL;\
2166
- gc_stack_free(stack); \
2167
- efree(stack)
2168
- #define GC_COLLECT_FINISH_0 GC_G(async_context).state = GC_ASYNC_STATE_NONE; \
2169
- return 0
2170
-
2171
2132
// Someone is trying to invoke GC from within a destructor?
2172
2133
// We don’t know what that is, but we have nothing to do here.
2173
2134
if (UNEXPECTED (GC_G (async_context ).state == GC_ASYNC_STATE_RUNNING )) {
@@ -2225,23 +2186,6 @@ ZEND_API int zend_gc_collect_cycles(void)
2225
2186
2226
2187
context -> state = GC_ASYNC_STATE_RUNNING ;
2227
2188
2228
- #else
2229
- #define GC_COLLECT_COUNT count
2230
- #define GC_COLLECT_TOTAL_COUNT total_count
2231
- #define GC_COLLECT_START_TIME start_time
2232
- #define GC_COLLECT_SHOULD_RERUN_GC should_rerun_gc
2233
- #define GC_COLLECT_DID_RERUN_GC did_rerun_gc
2234
- #define GC_COLLECT_GC_FLAGS gc_flags
2235
- #define GC_COLLECT_STACK (&stack)
2236
- #define GC_COLLECT_FREE_STACK gc_stack_free(&stack);
2237
- #define GC_COLLECT_FINISH_0 return 0
2238
-
2239
- int total_count = 0 ;
2240
- bool should_rerun_gc = 0 ;
2241
- bool did_rerun_gc = 0 ;
2242
-
2243
- zend_hrtime_t start_time = zend_hrtime ();
2244
- #endif
2245
2189
2246
2190
if (GC_G (num_roots ) && !GC_G (gc_active )) {
2247
2191
zend_gc_remove_root_tmpvars ();
@@ -2252,38 +2196,35 @@ ZEND_API int zend_gc_collect_cycles(void)
2252
2196
gc_root_buffer * current , * last ;
2253
2197
zend_refcounted * p ;
2254
2198
uint32_t gc_flags = 0 ;
2255
- uint32_t idx , end ;
2256
- #ifdef PHP_ASYNC_API
2199
+ uint32_t idx , end = 0 ;
2200
+
2257
2201
stack -> next = NULL ;
2258
2202
stack -> prev = NULL ;
2259
- #else
2260
- int count ;
2261
- gc_stack stack ;
2262
- stack .prev = NULL ;
2263
- stack .next = NULL ;
2264
- #endif
2265
2203
2266
2204
if (GC_G (gc_active )) {
2267
- GC_G (collector_time ) += zend_hrtime () - GC_COLLECT_START_TIME ;
2268
- GC_COLLECT_FINISH_0 ;
2205
+ GC_G (collector_time ) += zend_hrtime () - context -> start_time ;
2206
+ GC_G (async_context ).state = GC_ASYNC_STATE_NONE ;
2207
+ return 0 ;
2269
2208
}
2270
2209
2271
2210
GC_TRACE ("Collecting cycles" );
2272
2211
GC_G (gc_runs )++ ;
2273
2212
GC_G (gc_active ) = 1 ;
2274
2213
2275
2214
GC_TRACE ("Marking roots" );
2276
- gc_mark_roots (GC_COLLECT_STACK );
2215
+ gc_mark_roots (stack );
2277
2216
GC_TRACE ("Scanning roots" );
2278
- gc_scan_roots (GC_COLLECT_STACK );
2217
+ gc_scan_roots (stack );
2279
2218
2280
2219
GC_TRACE ("Collecting roots" );
2281
- GC_COLLECT_COUNT = gc_collect_roots (& gc_flags , GC_COLLECT_STACK );
2220
+ context -> count = gc_collect_roots (& gc_flags , stack );
2282
2221
2283
2222
if (!GC_G (num_roots )) {
2284
2223
/* nothing to free */
2285
2224
GC_TRACE ("Nothing to free" );
2286
- GC_COLLECT_FREE_STACK ;
2225
+ GC_G (gc_stack ) = NULL ;
2226
+ gc_stack_free (stack );
2227
+ efree (stack );
2287
2228
GC_G (gc_active ) = 0 ;
2288
2229
goto finish ;
2289
2230
}
@@ -2298,7 +2239,7 @@ ZEND_API int zend_gc_collect_cycles(void)
2298
2239
* modify any refcounts, so we have no real way to detect this situation
2299
2240
* short of rerunning full GC tracing. What we do instead is to only run
2300
2241
* destructors at this point and automatically re-run GC afterwards. */
2301
- GC_COLLECT_SHOULD_RERUN_GC = 1 ;
2242
+ context -> should_rerun_gc = 1 ;
2302
2243
2303
2244
/* Mark all roots for which a dtor will be invoked as DTOR_GARBAGE. Additionally
2304
2245
* color them purple. This serves a double purpose: First, they should be
@@ -2332,7 +2273,7 @@ ZEND_API int zend_gc_collect_cycles(void)
2332
2273
while (idx != end ) {
2333
2274
if (GC_IS_DTOR_GARBAGE (current -> ref )) {
2334
2275
p = GC_GET_PTR (current -> ref );
2335
- GC_COLLECT_COUNT -= gc_remove_nested_data_from_buffer (p , current , GC_COLLECT_STACK );
2276
+ context -> count -= gc_remove_nested_data_from_buffer (p , current , stack );
2336
2277
}
2337
2278
current ++ ;
2338
2279
idx ++ ;
@@ -2341,9 +2282,7 @@ ZEND_API int zend_gc_collect_cycles(void)
2341
2282
/* Actually call destructors. */
2342
2283
dtor_start_time = zend_hrtime ();
2343
2284
if (EXPECTED (!EG (active_fiber ))) {
2344
- #ifdef PHP_ASYNC_API
2345
2285
continue_calling_destructors :
2346
- end = GC_G (first_unused );
2347
2286
if (UNEXPECTED (FAILURE == gc_call_destructors (GC_G (dtor_idx ), GC_G (first_unused ), NULL ))) {
2348
2287
//
2349
2288
// gc_call_destructors returns FAILURE when a destructor interrupts execution,
@@ -2352,11 +2291,8 @@ ZEND_API int zend_gc_collect_cycles(void)
2352
2291
// because the process continues elsewhere.
2353
2292
//
2354
2293
GC_G (dtor_time ) += zend_hrtime () - dtor_start_time ;
2355
- return GC_COLLECT_TOTAL_COUNT ;
2294
+ return context -> total_count ;
2356
2295
}
2357
- #else
2358
- gc_call_destructors (GC_FIRST_ROOT , end , NULL );
2359
- #endif
2360
2296
} else {
2361
2297
gc_call_destructors_in_fiber (end );
2362
2298
}
@@ -2365,18 +2301,17 @@ ZEND_API int zend_gc_collect_cycles(void)
2365
2301
if (GC_G (gc_protected )) {
2366
2302
/* something went wrong */
2367
2303
zend_get_gc_buffer_release ();
2368
- GC_G (collector_time ) += zend_hrtime () - GC_COLLECT_START_TIME ;
2369
- GC_COLLECT_FINISH_0 ;
2304
+ GC_G (collector_time ) += zend_hrtime () - context -> start_time ;
2305
+ GC_G (async_context ).state = GC_ASYNC_STATE_NONE ;
2306
+ return 0 ;
2370
2307
}
2371
2308
}
2372
2309
2373
- gc_stack_free (GC_COLLECT_STACK );
2310
+ gc_stack_free (stack );
2374
2311
2375
- #ifdef PHP_ASYNC_API
2376
2312
if (false == in_fiber ) {
2377
2313
end = GC_G (first_unused );
2378
2314
}
2379
- #endif
2380
2315
2381
2316
/* Destroy zvals. The root buffer may be reallocated. */
2382
2317
GC_TRACE ("Destroying zvals" );
@@ -2434,8 +2369,8 @@ ZEND_API int zend_gc_collect_cycles(void)
2434
2369
GC_G (free_time ) += zend_hrtime () - free_start_time ;
2435
2370
2436
2371
GC_TRACE ("Collection finished" );
2437
- GC_G (collected ) += GC_COLLECT_COUNT ;
2438
- GC_COLLECT_TOTAL_COUNT += GC_COLLECT_COUNT ;
2372
+ GC_G (collected ) += context -> count ;
2373
+ context -> total_count += context -> count ;
2439
2374
GC_G (gc_active ) = 0 ;
2440
2375
}
2441
2376
@@ -2444,8 +2379,8 @@ ZEND_API int zend_gc_collect_cycles(void)
2444
2379
/* Objects with destructors were removed from this GC run. Rerun GC right away to clean them
2445
2380
* up. We do this only once: If we encounter more destructors on the second run, we'll not
2446
2381
* run GC another time. */
2447
- if (GC_COLLECT_SHOULD_RERUN_GC && !GC_COLLECT_DID_RERUN_GC ) {
2448
- GC_COLLECT_DID_RERUN_GC = 1 ;
2382
+ if (context -> should_rerun_gc && !context -> did_rerun_gc ) {
2383
+ context -> did_rerun_gc = 1 ;
2449
2384
goto rerun_gc ;
2450
2385
}
2451
2386
@@ -2458,10 +2393,10 @@ ZEND_API int zend_gc_collect_cycles(void)
2458
2393
zend_gc_check_root_tmpvars ();
2459
2394
GC_G (gc_active ) = 0 ;
2460
2395
2461
- GC_G (collector_time ) += zend_hrtime () - GC_COLLECT_START_TIME ;
2462
- #ifdef PHP_ASYNC_API
2396
+ GC_G (collector_time ) += zend_hrtime () - context -> start_time ;
2397
+
2463
2398
if (in_fiber ) {
2464
- const int total_count = GC_COLLECT_TOTAL_COUNT ;
2399
+ const int total_count = context -> total_count ;
2465
2400
efree (context );
2466
2401
efree (stack );
2467
2402
return total_count ;
@@ -2472,8 +2407,8 @@ ZEND_API int zend_gc_collect_cycles(void)
2472
2407
efree (stack );
2473
2408
}
2474
2409
}
2475
- #endif
2476
- return GC_COLLECT_TOTAL_COUNT ;
2410
+
2411
+ return context -> total_count ;
2477
2412
}
2478
2413
2479
2414
ZEND_API void zend_gc_get_status (zend_gc_status * status )
0 commit comments