Skip to content

Commit 5bde82a

Browse files
committed
Clean up gc_scan() implementation
The HT handling no longer needs to be shared, so move it into the right branch. Also use a couple of early gotos to reduce nesting.
1 parent 5f8ed77 commit 5bde82a

File tree

1 file changed

+77
-83
lines changed

1 file changed

+77
-83
lines changed

Zend/zend_gc.c

Lines changed: 77 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -991,112 +991,106 @@ static void gc_mark_roots(gc_stack *stack)
991991

992992
static void gc_scan(zend_refcounted *ref, gc_stack *stack)
993993
{
994-
HashTable *ht = NULL;
995994
Bucket *p, *end;
996995
zval *zv;
997996
GC_STACK_DCL(stack);
998997

999998
tail_call:
1000-
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
1001-
if (GC_REFCOUNT(ref) > 0) {
1002-
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
1003-
GC_REF_SET_BLACK(ref);
1004-
if (UNEXPECTED(!_stack->next)) {
1005-
gc_stack_next(_stack);
1006-
}
1007-
/* Split stack and reuse the tail */
1008-
_stack->next->prev = NULL;
1009-
gc_scan_black(ref, _stack->next);
1010-
_stack->next->prev = _stack;
999+
if (!GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
1000+
goto next;
1001+
}
1002+
1003+
if (GC_REFCOUNT(ref) > 0) {
1004+
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
1005+
GC_REF_SET_BLACK(ref);
1006+
if (UNEXPECTED(!_stack->next)) {
1007+
gc_stack_next(_stack);
10111008
}
1012-
} else {
1013-
if (GC_TYPE(ref) == IS_OBJECT) {
1014-
zend_object *obj = (zend_object*)ref;
1015-
1016-
if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED))) {
1017-
int n;
1018-
zval *zv, *end;
1019-
1020-
ht = obj->handlers->get_gc(obj, &zv, &n);
1021-
if (UNEXPECTED(ht)) {
1022-
if (GC_REF_CHECK_COLOR(ht, GC_GREY)) {
1023-
GC_REF_SET_COLOR(ht, GC_WHITE);
1024-
GC_STACK_PUSH((zend_refcounted *) ht);
1025-
}
1026-
ht = NULL;
1027-
}
1009+
/* Split stack and reuse the tail */
1010+
_stack->next->prev = NULL;
1011+
gc_scan_black(ref, _stack->next);
1012+
_stack->next->prev = _stack;
1013+
}
1014+
goto next;
1015+
}
10281016

1029-
if (!n) goto next;
1030-
end = zv + n;
1031-
while (!Z_REFCOUNTED_P(--end)) {
1032-
if (zv == end) goto next;
1033-
}
1034-
while (zv != end) {
1035-
if (Z_REFCOUNTED_P(zv)) {
1036-
ref = Z_COUNTED_P(zv);
1037-
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
1038-
GC_REF_SET_COLOR(ref, GC_WHITE);
1039-
GC_STACK_PUSH(ref);
1040-
}
1041-
}
1042-
zv++;
1043-
}
1044-
ref = Z_COUNTED_P(zv);
1045-
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
1046-
GC_REF_SET_COLOR(ref, GC_WHITE);
1047-
goto tail_call;
1048-
}
1049-
}
1050-
goto next;
1051-
} else if (GC_TYPE(ref) == IS_ARRAY) {
1052-
ZEND_ASSERT((zend_array*)ref != &EG(symbol_table));
1053-
ht = (zend_array*)ref;
1054-
} else if (GC_TYPE(ref) == IS_REFERENCE) {
1055-
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
1056-
ref = Z_COUNTED(((zend_reference*)ref)->val);
1057-
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
1058-
GC_REF_SET_COLOR(ref, GC_WHITE);
1059-
goto tail_call;
1060-
}
1017+
if (GC_TYPE(ref) == IS_OBJECT) {
1018+
zend_object *obj = (zend_object*)ref;
1019+
if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED))) {
1020+
int n;
1021+
zval *zv, *end;
1022+
HashTable *ht = obj->handlers->get_gc(obj, &zv, &n);
1023+
if (UNEXPECTED(ht)) {
1024+
if (GC_REF_CHECK_COLOR(ht, GC_GREY)) {
1025+
GC_REF_SET_COLOR(ht, GC_WHITE);
1026+
GC_STACK_PUSH((zend_refcounted *) ht);
10611027
}
1062-
goto next;
1063-
} else {
1064-
goto next;
10651028
}
10661029

1067-
if (!ht->nNumUsed) goto next;
1068-
p = ht->arData;
1069-
end = p + ht->nNumUsed;
1070-
while (1) {
1071-
end--;
1072-
zv = &end->val;
1073-
if (Z_TYPE_P(zv) == IS_INDIRECT) {
1074-
zv = Z_INDIRECT_P(zv);
1075-
}
1076-
if (Z_REFCOUNTED_P(zv)) {
1077-
break;
1078-
}
1079-
if (p == end) goto next;
1030+
if (!n) goto next;
1031+
end = zv + n;
1032+
while (!Z_REFCOUNTED_P(--end)) {
1033+
if (zv == end) goto next;
10801034
}
1081-
while (p != end) {
1082-
zv = &p->val;
1083-
if (Z_TYPE_P(zv) == IS_INDIRECT) {
1084-
zv = Z_INDIRECT_P(zv);
1085-
}
1035+
while (zv != end) {
10861036
if (Z_REFCOUNTED_P(zv)) {
10871037
ref = Z_COUNTED_P(zv);
10881038
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
10891039
GC_REF_SET_COLOR(ref, GC_WHITE);
10901040
GC_STACK_PUSH(ref);
10911041
}
10921042
}
1093-
p++;
1043+
zv++;
1044+
}
1045+
ref = Z_COUNTED_P(zv);
1046+
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
1047+
GC_REF_SET_COLOR(ref, GC_WHITE);
1048+
goto tail_call;
1049+
}
1050+
}
1051+
} else if (GC_TYPE(ref) == IS_ARRAY) {
1052+
HashTable *ht = (HashTable *)ref;
1053+
ZEND_ASSERT(ht != &EG(symbol_table));
1054+
if (!ht->nNumUsed) goto next;
1055+
p = ht->arData;
1056+
end = p + ht->nNumUsed;
1057+
while (1) {
1058+
end--;
1059+
zv = &end->val;
1060+
if (Z_TYPE_P(zv) == IS_INDIRECT) {
1061+
zv = Z_INDIRECT_P(zv);
1062+
}
1063+
if (Z_REFCOUNTED_P(zv)) {
1064+
break;
10941065
}
1066+
if (p == end) goto next;
1067+
}
1068+
while (p != end) {
10951069
zv = &p->val;
10961070
if (Z_TYPE_P(zv) == IS_INDIRECT) {
10971071
zv = Z_INDIRECT_P(zv);
10981072
}
1099-
ref = Z_COUNTED_P(zv);
1073+
if (Z_REFCOUNTED_P(zv)) {
1074+
ref = Z_COUNTED_P(zv);
1075+
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
1076+
GC_REF_SET_COLOR(ref, GC_WHITE);
1077+
GC_STACK_PUSH(ref);
1078+
}
1079+
}
1080+
p++;
1081+
}
1082+
zv = &p->val;
1083+
if (Z_TYPE_P(zv) == IS_INDIRECT) {
1084+
zv = Z_INDIRECT_P(zv);
1085+
}
1086+
ref = Z_COUNTED_P(zv);
1087+
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
1088+
GC_REF_SET_COLOR(ref, GC_WHITE);
1089+
goto tail_call;
1090+
}
1091+
} else if (GC_TYPE(ref) == IS_REFERENCE) {
1092+
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
1093+
ref = Z_COUNTED(((zend_reference*)ref)->val);
11001094
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
11011095
GC_REF_SET_COLOR(ref, GC_WHITE);
11021096
goto tail_call;

0 commit comments

Comments
 (0)