Skip to content

Instantly share code, notes, and snippets.

@dstogov
Created May 5, 2015 23:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dstogov/b53dda976a0b07361b56 to your computer and use it in GitHub Desktop.
Save dstogov/b53dda976a0b07361b56 to your computer and use it in GitHub Desktop.
diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c
index 30d75c2..dc5a458 100644
--- a/Zend/zend_gc.c
+++ b/Zend/zend_gc.c
@@ -295,6 +295,7 @@ static void gc_scan_black(zend_refcounted *ref)
{
HashTable *ht;
Bucket *p, *end;
+ zval *zv;
tail_call:
ht = NULL;
@@ -362,12 +363,24 @@ tail_call:
if (!ht->nNumUsed) return;
p = ht->arData;
end = p + ht->nNumUsed;
- while (!Z_REFCOUNTED((--end)->val)) {
+ while (1) {
+ end--;
+ zv = &end->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ if (Z_REFCOUNTED_P(zv)) {
+ break;
+ }
if (p == end) return;
}
while (p != end) {
- if (Z_REFCOUNTED(p->val)) {
- ref = Z_COUNTED(p->val);
+ zv = &p->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ if (Z_REFCOUNTED_P(zv)) {
+ ref = Z_COUNTED_P(zv);
GC_REFCOUNT(ref)++;
if (GC_REF_GET_COLOR(ref) != GC_BLACK) {
gc_scan_black(ref);
@@ -375,7 +388,11 @@ tail_call:
}
p++;
}
- ref = Z_COUNTED(p->val);
+ zv = &p->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ ref = Z_COUNTED_P(zv);
GC_REFCOUNT(ref)++;
if (GC_REF_GET_COLOR(ref) != GC_BLACK) {
goto tail_call;
@@ -386,6 +403,7 @@ static void gc_mark_grey(zend_refcounted *ref)
{
HashTable *ht;
Bucket *p, *end;
+ zval *zv;
tail_call:
if (GC_REF_GET_COLOR(ref) != GC_GREY) {
@@ -454,27 +472,43 @@ tail_call:
if (!ht->nNumUsed) return;
p = ht->arData;
end = p + ht->nNumUsed;
- while (!Z_REFCOUNTED((--end)->val)) {
+ while (1) {
+ end--;
+ zv = &end->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ if (Z_REFCOUNTED_P(zv)) {
+ break;
+ }
if (p == end) return;
}
while (p != end) {
- if (Z_REFCOUNTED(p->val)) {
- if (Z_TYPE(p->val) == IS_OBJECT &&
+ zv = &p->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ if (Z_REFCOUNTED_P(zv)) {
+ if (Z_TYPE_P(zv) == IS_OBJECT &&
UNEXPECTED(!EG(objects_store).object_buckets)) {
- Z_TYPE_INFO(p->val) = IS_NULL;
+ Z_TYPE_INFO_P(zv) = IS_NULL;
} else {
- ref = Z_COUNTED(p->val);
+ ref = Z_COUNTED_P(zv);
GC_REFCOUNT(ref)--;
gc_mark_grey(ref);
}
}
p++;
}
- if (Z_TYPE(p->val) == IS_OBJECT &&
+ zv = &p->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ if (Z_TYPE_P(zv) == IS_OBJECT &&
UNEXPECTED(!EG(objects_store).object_buckets)) {
- Z_TYPE_INFO(p->val) = IS_NULL;
+ Z_TYPE_INFO_P(zv) = IS_NULL;
} else {
- ref = Z_COUNTED(p->val);
+ ref = Z_COUNTED_P(zv);
GC_REFCOUNT(ref)--;
goto tail_call;
}
@@ -497,6 +531,7 @@ static void gc_scan(zend_refcounted *ref)
{
HashTable *ht;
Bucket *p, *end;
+ zval *zv;
tail_call:
if (GC_REF_GET_COLOR(ref) == GC_GREY) {
@@ -557,17 +592,33 @@ tail_call:
if (!ht->nNumUsed) return;
p = ht->arData;
end = p + ht->nNumUsed;
- while (!Z_REFCOUNTED((--end)->val)) {
+ while (1) {
+ end--;
+ zv = &end->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ if (Z_REFCOUNTED_P(zv)) {
+ break;
+ }
if (p == end) return;
}
while (p != end) {
- if (Z_REFCOUNTED(p->val)) {
- ref = Z_COUNTED(p->val);
+ zv = &p->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ if (Z_REFCOUNTED_P(zv)) {
+ ref = Z_COUNTED_P(zv);
gc_scan(ref);
}
p++;
}
- ref = Z_COUNTED(p->val);
+ zv = &p->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ ref = Z_COUNTED_P(zv);
goto tail_call;
}
}
@@ -641,6 +692,7 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_additional
int count = 0;
HashTable *ht;
Bucket *p, *end;
+ zval *zv;
tail_call:
if (GC_REF_GET_COLOR(ref) == GC_WHITE) {
@@ -731,25 +783,41 @@ tail_call:
if (!ht->nNumUsed) return count;
p = ht->arData;
end = p + ht->nNumUsed;
- while (!Z_REFCOUNTED((--end)->val)) {
+ while (1) {
+ end--;
+ zv = &end->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ if (Z_REFCOUNTED_P(zv)) {
+ break;
+ }
/* count non-refcounted for compatibility ??? */
- if (Z_TYPE(end->val) != IS_UNDEF && Z_TYPE(end->val) != IS_INDIRECT) {
+ if (Z_TYPE_P(zv) != IS_UNDEF) {
count++;
}
- if (p == end) return count;
+ if (p == end) return;
}
while (p != end) {
- if (Z_REFCOUNTED(p->val)) {
- ref = Z_COUNTED(p->val);
+ zv = &p->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ if (Z_REFCOUNTED_P(zv)) {
+ ref = Z_COUNTED_P(zv);
GC_REFCOUNT(ref)++;
count += gc_collect_white(ref, flags, additional_buffer);
/* count non-refcounted for compatibility ??? */
- } else if (Z_TYPE(p->val) != IS_UNDEF && Z_TYPE(p->val) != IS_INDIRECT) {
- count++;
+ } else if (Z_TYPE_P(zv) != IS_UNDEF) {
+ count++;
}
p++;
}
- ref = Z_COUNTED(p->val);
+ zv = &p->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ ref = Z_COUNTED_P(zv);
GC_REFCOUNT(ref)++;
goto tail_call;
}
@@ -806,6 +874,7 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
{
HashTable *ht = NULL;
Bucket *p, *end;
+ zval *zv;
tail_call:
if (root ||
@@ -870,17 +939,33 @@ tail_call:
if (!ht->nNumUsed) return;
p = ht->arData;
end = p + ht->nNumUsed;
- while (!Z_REFCOUNTED((--end)->val)) {
+ while (1) {
+ end--;
+ zv = &end->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ if (Z_REFCOUNTED_P(zv)) {
+ break;
+ }
if (p == end) return;
}
while (p != end) {
- if (Z_REFCOUNTED(p->val)) {
- ref = Z_COUNTED(p->val);
+ zv = &p->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ if (Z_REFCOUNTED_P(zv)) {
+ ref = Z_COUNTED_P(zv);
gc_remove_nested_data_from_buffer(ref, NULL);
}
p++;
}
- ref = Z_COUNTED(p->val);
+ zv = &p->val;
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ ref = Z_COUNTED_P(zv);
goto tail_call;
}
}
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index b85dd84..363ea13 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -127,9 +127,15 @@ ZEND_API HashTable *zend_std_get_gc(zval *object, zval **table, int *n) /* {{{ *
} else {
zend_object *zobj = Z_OBJ_P(object);
- *table = zobj->properties_table;
- *n = zobj->ce->default_properties_count;
- return zobj->properties;
+ if (zobj->properties) {
+ *table = NULL;
+ *n = 0;
+ return zobj->properties;
+ } else {
+ *table = zobj->properties_table;
+ *n = zobj->ce->default_properties_count;
+ return NULL;
+ }
}
}
/* }}} */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment