summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-03-18 10:04:29 +0100
committerNikita Popov <nikita.ppv@gmail.com>2019-03-18 10:04:29 +0100
commit61eebb559e6c473aaee91a545c14134969752783 (patch)
tree88478b21198995591ca9cc24904eb245f00a5247
parentd209ccd4ccf1b2ea63e79bd9f6d7d474693143a2 (diff)
parentbd6eabd6591ae5a7c9ad75dfbe7cc575fa907eac (diff)
downloadphp-git-61eebb559e6c473aaee91a545c14134969752783.tar.gz
Merge branch 'PHP-7.2' into PHP-7.3
-rw-r--r--Zend/tests/object_gc_in_shutdown.phpt14
-rw-r--r--Zend/zend_globals.h5
-rw-r--r--Zend/zend_objects_API.c5
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 {