zval *zv;
tail_call:
- if (root ||
- (GC_REF_ADDRESS(ref) != 0 &&
- GC_REF_CHECK_COLOR(ref, GC_BLACK))) {
- GC_TRACE_REF(ref, "removing from buffer");
+ do {
if (root) {
- if (EXPECTED(GC_ADDRESS(GC_INFO(root->ref)) < GC_ROOT_BUFFER_MAX_ENTRIES)) {
- gc_remove_from_roots(root);
- } else {
- gc_remove_from_additional_roots(root);
- }
- GC_INFO(ref) = 0;
+ GC_TRACE_REF(ref, "removing from buffer");
+ gc_remove_from_roots(root);
+ GC_REF_SET_INFO(ref, 0);
root = NULL;
- } else {
- } else if (GC_ADDRESS(GC_INFO(ref)) != 0
- && GC_REF_GET_COLOR(ref) == GC_BLACK) {
++ } else if (GC_REF_ADDRESS(ref) != 0
++ && GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
+ GC_TRACE_REF(ref, "removing from buffer");
GC_REMOVE_FROM_BUFFER(ref);
+ } else if (GC_TYPE(ref) == IS_REFERENCE) {
+ if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
+ ref = Z_COUNTED(((zend_reference*)ref)->val);
+ goto tail_call;
+ }
+ return;
+ } else {
+ return;
}
if (GC_TYPE(ref) == IS_OBJECT) {