GC_ZVAL_SET_BLACK(pz);
if (Z_TYPE_P(pz) == IS_OBJECT && EG(objects_store).object_buckets) {
+ zend_object_get_properties_t get_props;
struct _store_object *obj = &EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj;
obj->refcount++;
if (GC_GET_COLOR(obj->buffered) != GC_BLACK) {
GC_SET_BLACK(obj->buffered);
if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
- Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
- HashTable *props = Z_OBJPROP_P(pz);
- if(!props) {
- return;
+ (get_props = Z_OBJ_HANDLER_P(pz, get_properties)) != NULL)) {
+ if (get_props == zend_std_get_properties) {
+ zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object));
+
+ if (!zobj->properties) {
+ int i;
+ int n = zobj->ce->default_properties_count;
+
+ while (n > 0 && !zobj->properties_table[n-1]) n--;
+ for (i = 0; i < n; i++) {
+ if (zobj->properties_table[i]) {
+ pz = zobj->properties_table[i];
+ if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+ pz->refcount__gc++;
+ }
+ if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) {
+ if (i == n - 1) {
+ goto tail_call;
+ } else {
+ zval_scan_black(pz TSRMLS_CC);
+ }
+ }
+ }
+ }
+ return;
+ } else {
+ p = zobj->properties->pListHead;
+ }
+ } else {
+ HashTable *props = get_props(pz);
+ if(!props) {
+ return;
+ }
+ p = props->pListHead;
}
- p = props->pListHead;
}
}
} else if (Z_TYPE_P(pz) == IS_ARRAY) {
static void zobj_scan_black(struct _store_object *obj, zval *pz TSRMLS_DC)
{
Bucket *p;
+ zend_object_get_properties_t get_props;
GC_SET_BLACK(obj->buffered);
if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
- Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
- HashTable *props = Z_OBJPROP_P(pz);
- if(!props) {
- return;
+ (get_props = Z_OBJ_HANDLER_P(pz, get_properties)) != NULL)) {
+ if (get_props == zend_std_get_properties) {
+ zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object));
+
+ if (!zobj->properties) {
+ int i;
+
+ for (i = 0; i < zobj->ce->default_properties_count; i++) {
+ if (zobj->properties_table[i]) {
+ pz = zobj->properties_table[i];
+ if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+ pz->refcount__gc++;
+ }
+ if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) {
+ zval_scan_black(pz TSRMLS_CC);
+ }
+ }
+ }
+ return;
+ } else {
+ p = zobj->properties->pListHead;
+ }
+ } else {
+ HashTable *props = get_props(pz);
+ if(!props) {
+ return;
+ }
+ p = props->pListHead;
}
- p = props->pListHead;
while (p != NULL) {
pz = *(zval**)p->pData;
if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
GC_ZVAL_SET_COLOR(pz, GC_GREY);
if (Z_TYPE_P(pz) == IS_OBJECT && EG(objects_store).object_buckets) {
+ zend_object_get_properties_t get_props;
struct _store_object *obj = &EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj;
obj->refcount--;
GC_BENCH_INC(zobj_marked_grey);
GC_SET_COLOR(obj->buffered, GC_GREY);
if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
- Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
- HashTable *props = Z_OBJPROP_P(pz);
- if(!props) {
- return;
+ (get_props = Z_OBJ_HANDLER_P(pz, get_properties)) != NULL)) {
+ if (get_props == zend_std_get_properties) {
+ zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object));
+
+ if (!zobj->properties) {
+ int i;
+ int n = zobj->ce->default_properties_count;
+
+ while (n > 0 && !zobj->properties_table[n-1]) n--;
+ for (i = 0; i < n; i++) {
+ if (zobj->properties_table[i]) {
+ pz = zobj->properties_table[i];
+ if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+ pz->refcount__gc--;
+ }
+ if (i == n - 1) {
+ goto tail_call;
+ } else {
+ zval_mark_grey(pz TSRMLS_CC);
+ }
+ }
+ }
+ return;
+ } else {
+ p = zobj->properties->pListHead;
+ }
+ } else {
+ HashTable *props = get_props(pz);
+ if(!props) {
+ return;
+ }
+ p = props->pListHead;
}
- p = props->pListHead;
}
}
} else if (Z_TYPE_P(pz) == IS_ARRAY) {
static void zobj_mark_grey(struct _store_object *obj, zval *pz TSRMLS_DC)
{
Bucket *p;
+ zend_object_get_properties_t get_props;
if (GC_GET_COLOR(obj->buffered) != GC_GREY) {
GC_BENCH_INC(zobj_marked_grey);
GC_SET_COLOR(obj->buffered, GC_GREY);
if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
- Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
- HashTable *props = Z_OBJPROP_P(pz);
- if(!props) {
- return;
+ (get_props = Z_OBJ_HANDLER_P(pz, get_properties)) != NULL)) {
+ if (get_props == zend_std_get_properties) {
+ zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object));
+
+ if (!zobj->properties) {
+ int i;
+
+ for (i = 0; i < zobj->ce->default_properties_count; i++) {
+ if (zobj->properties_table[i]) {
+ pz = zobj->properties_table[i];
+ if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+ pz->refcount__gc--;
+ }
+ zval_mark_grey(pz TSRMLS_CC);
+ }
+ }
+ return;
+ } else {
+ p = zobj->properties->pListHead;
+ }
+ } else {
+ HashTable *props = get_props(pz);
+ if(!props) {
+ return;
+ }
+ p = props->pListHead;
}
- p = props->pListHead;
while (p != NULL) {
pz = *(zval**)p->pData;
if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
}
}
-static int zval_scan(zval *pz TSRMLS_DC)
+static void zval_scan(zval *pz TSRMLS_DC)
{
Bucket *p;
} else {
GC_ZVAL_SET_COLOR(pz, GC_WHITE);
if (Z_TYPE_P(pz) == IS_OBJECT && EG(objects_store).object_buckets) {
+ zend_object_get_properties_t get_props;
struct _store_object *obj = &EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj;
if (GC_GET_COLOR(obj->buffered) == GC_GREY) {
} else {
GC_SET_COLOR(obj->buffered, GC_WHITE);
if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
- Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
- HashTable *props = Z_OBJPROP_P(pz);
- if(!props) {
- return 0;
+ (get_props = Z_OBJ_HANDLER_P(pz, get_properties)) != NULL)) {
+ if (get_props == zend_std_get_properties) {
+ zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object));
+
+ if (!zobj->properties) {
+ int i;
+ int n = zobj->ce->default_properties_count;
+
+ while (n > 0 && !zobj->properties_table[n-1]) n--;
+ for (i = 0; i < n; i++) {
+ if (zobj->properties_table[i]) {
+ pz = zobj->properties_table[i];
+ if (i == n - 1) {
+ goto tail_call;
+ } else {
+ zval_scan(pz TSRMLS_CC);
+ }
+ }
+ }
+ return;
+ } else {
+ p = zobj->properties->pListHead;
+ }
+ } else {
+ HashTable *props = get_props(pz);
+ if(!props) {
+ return;
+ }
+ p = props->pListHead;
}
- p = props->pListHead;
}
}
}
p = p->pListNext;
}
}
- return 0;
}
static void zobj_scan(zval *pz TSRMLS_DC)
{
Bucket *p;
+ zend_object_get_properties_t get_props;
if (EG(objects_store).object_buckets) {
struct _store_object *obj = &EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj;
} else {
GC_SET_COLOR(obj->buffered, GC_WHITE);
if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
- Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
- HashTable *props = Z_OBJPROP_P(pz);
- if(!props) {
- return;
+ (get_props = Z_OBJ_HANDLER_P(pz, get_properties)) != NULL)) {
+ if (get_props == zend_std_get_properties) {
+ zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object));
+
+ if (!zobj->properties) {
+ int i;
+
+ for (i = 0; i < zobj->ce->default_properties_count; i++) {
+ if (zobj->properties_table[i]) {
+ pz = zobj->properties_table[i];
+ zval_scan(pz TSRMLS_CC);
+ }
+ }
+ return;
+ } else {
+ p = zobj->properties->pListHead;
+ }
+ } else {
+ HashTable *props = get_props(pz);
+ if(!props) {
+ return;
+ }
+ p = props->pListHead;
}
- p = props->pListHead;
while (p != NULL) {
zval_scan(*(zval**)p->pData TSRMLS_CC);
p = p->pListNext;
GC_ZVAL_SET_BLACK(pz);
if (Z_TYPE_P(pz) == IS_OBJECT && EG(objects_store).object_buckets) {
+ zend_object_get_properties_t get_props;
struct _store_object *obj = &EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj;
if (obj->buffered == (gc_root_buffer*)GC_WHITE) {
GC_SET_BLACK(obj->buffered);
if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
- Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
- HashTable *props = Z_OBJPROP_P(pz);
- if(!props) {
- return;
+ (get_props = Z_OBJ_HANDLER_P(pz, get_properties)) != NULL)) {
+ if (get_props == zend_std_get_properties) {
+ zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object));
+
+ if (!zobj->properties) {
+ int i;
+ int n = zobj->ce->default_properties_count;
+
+ while (n > 0 && !zobj->properties_table[n-1]) n--;
+
+ /* restore refcount and put into list to free */
+ pz->refcount__gc++;
+ ((zval_gc_info*)pz)->u.next = GC_G(zval_to_free);
+ GC_G(zval_to_free) = (zval_gc_info*)pz;
+
+ for (i = 0; i < n; i++) {
+ if (zobj->properties_table[i]) {
+ pz = zobj->properties_table[i];
+ if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+ pz->refcount__gc++;
+ }
+ if (i == n - 1) {
+ goto tail_call;
+ } else {
+ zval_collect_white(pz TSRMLS_CC);
+ }
+ }
+ }
+ return;
+ } else {
+ p = zobj->properties->pListHead;
+ }
+ } else {
+ HashTable *props = get_props(pz);
+ if(!props) {
+ return;
+ }
+ p = props->pListHead;
}
- p = props->pListHead;
}
}
} else {
Bucket *p;
if (EG(objects_store).object_buckets) {
+ zend_object_get_properties_t get_props;
struct _store_object *obj = &EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj;
if (obj->buffered == (gc_root_buffer*)GC_WHITE) {
GC_SET_BLACK(obj->buffered);
if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid &&
- Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) {
- HashTable *props = Z_OBJPROP_P(pz);
- if(!props) {
- return;
+ (get_props = Z_OBJ_HANDLER_P(pz, get_properties)) != NULL)) {
+ if (get_props == zend_std_get_properties) {
+ zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object));
+
+ if (!zobj->properties) {
+ int i;
+
+ for (i = 0; i < zobj->ce->default_properties_count; i++) {
+ if (zobj->properties_table[i]) {
+ pz = zobj->properties_table[i];
+ if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+ pz->refcount__gc++;
+ }
+ zval_collect_white(pz TSRMLS_CC);
+ }
+ }
+ return;
+ } else {
+ p = zobj->properties->pListHead;
+ }
+ } else {
+ HashTable *props = get_props(pz);
+ if(!props) {
+ return;
+ }
+ p = props->pListHead;
}
- p = props->pListHead;
while (p != NULL) {
pz = *(zval**)p->pData;
if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {