diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-03-18 10:04:29 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-03-18 10:04:29 +0100 |
commit | 61eebb559e6c473aaee91a545c14134969752783 (patch) | |
tree | 88478b21198995591ca9cc24904eb245f00a5247 /Zend | |
parent | d209ccd4ccf1b2ea63e79bd9f6d7d474693143a2 (diff) | |
parent | bd6eabd6591ae5a7c9ad75dfbe7cc575fa907eac (diff) | |
download | php-git-61eebb559e6c473aaee91a545c14134969752783.tar.gz |
Merge branch 'PHP-7.2' into PHP-7.3
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/tests/object_gc_in_shutdown.phpt | 14 | ||||
-rw-r--r-- | Zend/zend_globals.h | 5 | ||||
-rw-r--r-- | Zend/zend_objects_API.c | 5 |
3 files changed, 20 insertions, 4 deletions
diff --git a/Zend/tests/object_gc_in_shutdown.phpt b/Zend/tests/object_gc_in_shutdown.phpt new file mode 100644 index 0000000000..d55c08dfb1 --- /dev/null +++ b/Zend/tests/object_gc_in_shutdown.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug object gc not working in shutdown +--FILE-- +<?php +ini_set('memory_limit', '2M'); +register_shutdown_function(function () { + for ($n = 1000 * 1000; $n--;) { + new stdClass; + } + echo "OK\n"; +}); +?> +--EXPECT-- +OK diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 45744cedbf..486336414f 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -233,8 +233,9 @@ struct _zend_executor_globals { void *reserved[ZEND_MAX_RESERVED_RESOURCES]; }; -#define EG_FLAGS_INITIAL 0x00 -#define EG_FLAGS_IN_SHUTDOWN 0x01 +#define EG_FLAGS_INITIAL (0) +#define EG_FLAGS_IN_SHUTDOWN (1<<0) +#define EG_FLAGS_OBJECT_STORE_NO_REUSE (1<<1) struct _zend_ini_scanner_globals { zend_file_handle *yy_in; diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c index 3389b64608..c5ac9708e5 100644 --- a/Zend/zend_objects_API.c +++ b/Zend/zend_objects_API.c @@ -41,6 +41,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_destroy(zend_objects_store *objec ZEND_API void ZEND_FASTCALL zend_objects_store_call_destructors(zend_objects_store *objects) { + EG(flags) |= EG_FLAGS_OBJECT_STORE_NO_REUSE; if (objects->top > 1) { uint32_t i; for (i = 1; i < objects->top; i++) { @@ -131,10 +132,10 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_put(zend_object *object) { int handle; - /* When in shutdown sequesnce - do not reuse previously freed handles, to make sure + /* When in shutdown sequence - do not reuse previously freed handles, to make sure * the dtors for newly created objects are called in zend_objects_store_call_destructors() loop */ - if (!(EG(flags) & EG_FLAGS_IN_SHUTDOWN) && EG(objects_store).free_list_head != -1) { + if (EG(objects_store).free_list_head != -1 && EXPECTED(!(EG(flags) & EG_FLAGS_OBJECT_STORE_NO_REUSE))) { handle = EG(objects_store).free_list_head; EG(objects_store).free_list_head = GET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[handle]); } else { |