From 2afc83732c1eb416acabace042eb0f5384bea721 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 13 Jun 2018 11:10:17 +0300 Subject: Allow access to some garbage collection internals (Benjamin Eberlei) --- Zend/tests/gc_037.phpt | 30 ++++++++++++++++++++++++++++++ Zend/zend_builtin_functions.c | 18 ++++++++++++++++++ Zend/zend_gc.c | 7 +++++++ Zend/zend_gc.h | 9 +++++++++ 4 files changed, 64 insertions(+) create mode 100644 Zend/tests/gc_037.phpt diff --git a/Zend/tests/gc_037.phpt b/Zend/tests/gc_037.phpt new file mode 100644 index 0000000000..fc60bcab29 --- /dev/null +++ b/Zend/tests/gc_037.phpt @@ -0,0 +1,30 @@ +--TEST-- +GC 037: gc_status() +--INI-- +zend.enable_gc = 1 +--FILE-- + + int(0) + ["collected"]=> + int(0) + ["gc_threshold"]=> + int(10001) +} +array(3) { + ["gc_runs"]=> + int(1) + ["collected"]=> + int(1) + ["gc_threshold"]=> + int(10001) +} diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index c2380f622b..feee2ddf1d 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -21,6 +21,7 @@ #include "zend.h" #include "zend_API.h" +#include "zend_gc.h" #include "zend_builtin_functions.h" #include "zend_constants.h" #include "zend_ini.h" @@ -85,6 +86,7 @@ static ZEND_FUNCTION(gc_collect_cycles); static ZEND_FUNCTION(gc_enabled); static ZEND_FUNCTION(gc_enable); static ZEND_FUNCTION(gc_disable); +static ZEND_FUNCTION(gc_status); /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO(arginfo_zend__void, 0) @@ -293,6 +295,7 @@ static const zend_function_entry builtin_functions[] = { /* {{{ */ ZEND_FE(gc_enabled, arginfo_zend__void) ZEND_FE(gc_enable, arginfo_zend__void) ZEND_FE(gc_disable, arginfo_zend__void) + ZEND_FE(gc_status, arginfo_zend__void) ZEND_FE_END }; /* }}} */ @@ -385,6 +388,21 @@ ZEND_FUNCTION(gc_disable) } /* }}} */ +/* {{{ proto array gc_status(void) + Returns current GC statistics */ +ZEND_FUNCTION(gc_status) +{ + zend_gc_status status; + + zend_gc_get_status(&status); + + array_init_size(return_value, 3); + + add_assoc_long_ex(return_value, "gc_runs", sizeof("gc_runs")-1, (long)status.gc_runs); + add_assoc_long_ex(return_value, "collected", sizeof("collected")-1, (long)status.collected); + add_assoc_long_ex(return_value, "gc_threshold", sizeof("gc_threshold")-1, (long)status.gc_threshold); +} + /* {{{ proto int func_num_args(void) Get the number of arguments that were passed to the function */ ZEND_FUNCTION(func_num_args) diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index 40402a5a7d..3900837a7d 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -1442,6 +1442,13 @@ ZEND_API int zend_gc_collect_cycles(void) return count; } +ZEND_API void zend_gc_get_status(zend_gc_status *status) +{ + status->gc_runs = GC_G(gc_runs); + status->collected = GC_G(collected); + status->gc_threshold = GC_G(gc_threshold); +} + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_gc.h b/Zend/zend_gc.h index 9328e2c59c..f1bd7a7b92 100644 --- a/Zend/zend_gc.h +++ b/Zend/zend_gc.h @@ -23,6 +23,13 @@ #define ZEND_GC_H BEGIN_EXTERN_C() + +typedef struct _zend_gc_status { + uint32_t gc_runs; + uint32_t collected; + uint32_t gc_threshold; +} zend_gc_status; + ZEND_API extern int (*gc_collect_cycles)(void); ZEND_API void ZEND_FASTCALL gc_possible_root(zend_refcounted *ref); @@ -39,6 +46,8 @@ ZEND_API zend_bool gc_protected(void); /* The default implementation of the gc_collect_cycles callback. */ ZEND_API int zend_gc_collect_cycles(void); +ZEND_API void zend_gc_get_status(zend_gc_status *status); + void gc_globals_ctor(void); void gc_globals_dtor(void); void gc_reset(void); -- cgit v1.2.1