-
Notifications
You must be signed in to change notification settings - Fork 8k
Implement acyclic object tracking #17130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -705,6 +705,8 @@ void zend_register_closure_ce(void) /* {{{ */ | |
| zend_ce_closure = register_class_Closure(); | ||
| zend_ce_closure->create_object = zend_closure_new; | ||
| zend_ce_closure->default_object_handlers = &closure_handlers; | ||
| /* FIXME: Potentially infer ZEND_ACC_MAY_BE_CYCLIC during construction of | ||
| * closure? static closures not binding by references can't be cyclic. */ | ||
|
Comment on lines
+708
to
+709
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 this looks worth it
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm afraid my comment was incorrect. class Test {
public \Closure $c;
}
$test = new Test();
$c = static function () use ($test) {}; // acyclic
$test->c = $c; // now it's cyclic
unset($test);
gc_collect_cycles();
unset($c); // leaksThis is only ok if
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be worth mentioning:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, your test case doesn't show any dynamic property usage @iluuu1994, wouldn't that still be an issue in non-readonly cases even in PHP 9.0?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I was referring to:
I.e. it's safe to assume
Yes, but it's not a priority since it's a rare case and unlikely to make a big difference. |
||
|
|
||
| memcpy(&closure_handlers, &std_object_handlers, sizeof(zend_object_handlers)); | ||
| closure_handlers.free_obj = zend_closure_free_storage; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -70,6 +70,8 @@ ZEND_API HashTable *rebuild_object_properties_internal(zend_object *zobj) /* {{{ | |
| zend_class_entry *ce = zobj->ce; | ||
| int i; | ||
|
|
||
| GC_TYPE_INFO(zobj) &= ~(GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT); | ||
|
||
|
|
||
| zobj->properties = zend_new_array(ce->default_properties_count); | ||
| if (ce->default_properties_count) { | ||
| zend_hash_real_init_mixed(zobj->properties); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -432,6 +432,8 @@ public function getNamespaceName(): string {} | |
| public function getShortName(): string {} | ||
|
|
||
| public function getAttributes(?string $name = null, int $flags = 0): array {} | ||
|
|
||
| public function mayBeCyclic(): bool {} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 for exposing this. This may be beneficial for understanding the GC behaviour as PHP user. |
||
| } | ||
|
|
||
| class ReflectionObject extends ReflectionClass | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also mark classes with custom
get_propertieshandler as potentially cyclic, as this is called byzend_std_get_gc.Otherwise this looks right to me, as objects with std
get_gcandget_propertiescan not expose anything other than standard properties to the GC.Lazy objects need to take care of updating
GC_NOT_COLLECTABLE: RemoveGC_NOT_COLLECTABLEinzend_object_make_lazy()when the initializer is cyclic or may have a ref to the object itself, and add it again inzend_lazy_object_init().