summaryrefslogtreecommitdiff
path: root/processor
diff options
context:
space:
mode:
authorXuefer <xuefer@gmail.com>2014-11-11 18:27:44 +0000
committerXuefer <xuefer@gmail.com>2014-11-11 18:27:44 +0000
commite23a8984d25a262d542e16e89cddd861b739da56 (patch)
tree61b5817c58d64eecb127079f074fc4a1ff1b11e3 /processor
parent07183575efa06f2c59303739f45f7bb4c1791ca0 (diff)
downloadxcache-e23a8984d25a262d542e16e89cddd861b739da56.tar.gz
xcache-e23a8984d25a262d542e16e89cddd861b739da56.zip
handle nested object caching
git-svn-id: svn://svn.lighttpd.net/xcache/trunk@1568 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
Diffstat (limited to 'processor')
-rw-r--r--processor/foot.m416
-rw-r--r--processor/processor.m410
-rw-r--r--processor/var-helper-t.h3
-rw-r--r--processor/var-helper.h52
4 files changed, 63 insertions, 18 deletions
diff --git a/processor/foot.m4 b/processor/foot.m4
index ac2ade4..0fdc5e6 100644
--- a/processor/foot.m4
+++ b/processor/foot.m4
@@ -134,12 +134,14 @@ EXPORTED_FUNCTION(`zval *xc_processor_restore_var(zval *dst, const xc_entry_var_
#ifdef ZEND_ENGINE_2
if (src->objects_count) {
- zend_uint i;
- xc_vector_init(zend_object_handle, &processor.object_handles);
- xc_vector_reserve(&processor.object_handles, src->objects_count);
- for (i = 0; i < src->objects_count; ++i) {
+ int i;
+ size_t size = sizeof(processor.object_handles[0]) * src->objects_count;
+ processor.object_handles = emalloc(size);
+ IFAUTOCHECK(`xc_memsetptr(processor.object_handles, -1, size);')
+ /* other objects in $object->properties after $object, reverse order is necessary */
+ for (i = src->objects_count - 1; i >= 0; --i) {
zend_object *object = emalloc(sizeof(*object));
- xc_vector_data(zend_object_handle, &processor.object_handles)[i] = zend_objects_store_put(object, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) zend_objects_free_object_storage, NULL TSRMLS_CC);
+ processor.object_handles[i] = zend_objects_store_put(object, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) zend_objects_free_object_storage, NULL TSRMLS_CC);
xc_restore_zend_object(&processor, object, &src->objects[i] TSRMLS_CC);
}
}
@@ -153,9 +155,9 @@ EXPORTED_FUNCTION(`zval *xc_processor_restore_var(zval *dst, const xc_entry_var_
if (src->objects_count) {
zend_uint i;
for (i = 0; i < src->objects_count; ++i) {
- zend_objects_store_del_ref_by_handle(xc_vector_data(zend_object_handle, &processor.object_handles)[i] TSRMLS_CC);
+ zend_objects_store_del_ref_by_handle(processor.object_handles[i] TSRMLS_CC);
}
- xc_vector_destroy(&processor.object_handles);
+ efree(processor.object_handles);
}
#endif
diff --git a/processor/processor.m4 b/processor/processor.m4
index da4d689..d2e0ca5 100644
--- a/processor/processor.m4
+++ b/processor/processor.m4
@@ -1419,12 +1419,12 @@ DEF_STRUCT_P_FUNC(`xc_entry_var_t', , `dnl {{{
#ifdef ZEND_ENGINE_2
IFCALC(`
- dnl objects = collect_from(value);
+ dnl objects = collect_from(value + objects);
pushdef(`src', `vsrc')
- SRC(objects_count) = xc_vector_size(&processor->object_handles);
- SRC(objects) = xc_vector_detach(zend_object, &processor->object_handles);
+ SRC(objects_count) = xc_vector_size(&processor->objects);
+ SRC(objects) = xc_vector_detach(zend_object, &processor->objects);
popdef(`src')
- xc_vector_destroy(&processor->object_handles);
+ xc_vector_destroy(&processor->objects);
')
dnl must be after calc .value
PROCESS(zend_uint, objects_count)
@@ -1442,7 +1442,7 @@ DEF_STRUCT_P_FUNC(`xc_entry_var_t', , `dnl {{{
dnl classe_
IFCALC(`
- dnl class_names = collect_from(object_handles);
+ dnl class_names = collect_from(objects);
pushdef(`src', `vsrc')
SRC(class_names_count) = xc_vector_size(&processor->class_names);
SRC(class_names) = xc_vector_detach(xc_constant_string_t, &processor->class_names);
diff --git a/processor/var-helper-t.h b/processor/var-helper-t.h
index f8de297..ba459a5 100644
--- a/processor/var-helper-t.h
+++ b/processor/var-helper-t.h
@@ -1,7 +1,8 @@
/* {{{ var object helpers */
#ifdef ZEND_ENGINE_2
-xc_vector_t object_handles; /* in calc/restore only */
+xc_vector_t objects; /* in calc */
HashTable handle_to_index; /* in calc/store only */
+zend_object_handle *object_handles; /* in restore only */
#endif
const xc_entry_var_t *entry_var_src; /* in restore */
diff --git a/processor/var-helper.h b/processor/var-helper.h
index 957147d..a968978 100644
--- a/processor/var-helper.h
+++ b/processor/var-helper.h
@@ -1,17 +1,59 @@
#ifdef ZEND_ENGINE_2
+static void xc_var_collect_object(xc_processor_t *processor, zend_object_handle handle TSRMLS_DC);
+static void xc_var_collect_object_in_zval(xc_processor_t *processor, zval *zv TSRMLS_DC);
+static void xc_var_collect_object_in_hashtable(xc_processor_t *processor, HashTable *ht TSRMLS_DC);
+
+static void xc_var_collect_object_in_hashtable(xc_processor_t *processor, HashTable *ht TSRMLS_DC) /* {{{ */
+{
+ Bucket *bucket;
+ for (bucket = ht->pListHead; bucket; bucket = bucket->pListNext) {
+ xc_var_collect_object_in_zval(processor, *(zval **) bucket->pData TSRMLS_CC);
+ }
+}
+/* }}} */
+static void xc_var_collect_object_in_zval(xc_processor_t *processor, zval *zv TSRMLS_DC) /* {{{ */
+{
+ switch (Z_TYPE_P(zv)) {
+ case IS_OBJECT:
+ xc_var_collect_object(processor, Z_OBJ_HANDLE_P(zv) TSRMLS_CC);
+ break;
+
+ case IS_ARRAY:
+ xc_var_collect_object_in_hashtable(processor, Z_ARRVAL_P(zv) TSRMLS_CC);
+ break;
+ }
+}
+/* }}} */
static void xc_var_collect_object(xc_processor_t *processor, zend_object_handle handle TSRMLS_DC) /* {{{ */
{
size_t next_index;
- if (!xc_vector_initialized(&processor->object_handles)) {
- xc_vector_init(zend_object, &processor->object_handles);
+ if (!xc_vector_initialized(&processor->objects)) {
+ if (zend_hash_num_elements(&processor->handle_to_index)) {
+ /* collecting process is stopped, may reach here by xc_entry_src_t.objects.properties */
+ return;
+ }
+ xc_vector_init(zend_object, &processor->objects);
zend_hash_init(&processor->handle_to_index, 0, NULL, NULL, 0);
}
- next_index = xc_vector_size(&processor->object_handles);
+ next_index = xc_vector_size(&processor->objects);
if (_zend_hash_index_update_or_next_insert(&processor->handle_to_index, handle, (void *) &next_index, sizeof(next_index), NULL, HASH_ADD ZEND_FILE_LINE_CC) == SUCCESS) {
zend_object *object = zend_object_store_get_object_by_handle(handle TSRMLS_CC);
- xc_vector_push_back(&processor->object_handles, object);
+
+ xc_vector_push_back(&processor->objects, object);
+
+ if (object->properties) {
+ xc_var_collect_object_in_hashtable(processor, object->properties TSRMLS_CC);
+ }
+
+ /* TODO: is this necessary? */
+ if (object->properties_table) {
+ int i, count = zend_hash_num_elements(&object->ce->properties_info);
+ for (i = 0; i < count; ++i) {
+ xc_var_collect_object_in_zval(processor, object->properties_table[i] TSRMLS_CC);
+ }
+ }
}
}
/* }}} */
@@ -29,7 +71,7 @@ static size_t xc_var_store_handle(xc_processor_t *processor, zend_object_handle
/* }}} */
static zend_object_handle xc_var_restore_handle(xc_processor_t *processor, size_t index TSRMLS_DC) /* {{{ */
{
- zend_object_handle handle = xc_vector_data(zend_object_handle, &processor->object_handles)[index];
+ zend_object_handle handle = processor->object_handles[index];
zend_objects_store_add_ref_by_handle(handle TSRMLS_CC);
return handle;
}