summaryrefslogtreecommitdiff
path: root/processor
diff options
context:
space:
mode:
authorXuefer <xuefer@gmail.com>2014-11-10 06:08:07 +0000
committerXuefer <xuefer@gmail.com>2014-11-10 06:08:07 +0000
commitde6840d14b68c991a1408b752962aef14047ff8c (patch)
treeb6c82775fb1d6072a3bdbe4c83613b1b637948f5 /processor
parentff9ba0d15ba2243dc69874242b61ca37065630c1 (diff)
downloadxcache-de6840d14b68c991a1408b752962aef14047ff8c.tar.gz
xcache-de6840d14b68c991a1408b752962aef14047ff8c.zip
closes #342: object caching
git-svn-id: svn://svn.lighttpd.net/xcache/trunk@1558 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
Diffstat (limited to 'processor')
-rw-r--r--processor/class-helper.h15
-rw-r--r--processor/class-helper.m42
-rw-r--r--processor/foot.m433
-rw-r--r--processor/head.m45
-rw-r--r--processor/process.m41
-rw-r--r--processor/processor-t.h1
-rw-r--r--processor/processor.m4129
-rw-r--r--processor/var-helper-t.h10
-rw-r--r--processor/var-helper.h72
-rw-r--r--processor/var-helper.m43
10 files changed, 259 insertions, 12 deletions
diff --git a/processor/class-helper.h b/processor/class-helper.h
new file mode 100644
index 0000000..db8a562
--- /dev/null
+++ b/processor/class-helper.h
@@ -0,0 +1,15 @@
+static zend_class_entry *xc_lookup_class(const char *class_name, int class_name_len TSRMLS_DC) /* {{{ */
+{
+ xc_cest_t *cest;
+#ifdef ZEND_ENGINE_2
+ if (zend_lookup_class_ex(class_name, class_name_len, NULL, 0, &cest TSRMLS_CC) != SUCCESS) {
+ return NULL;
+ }
+#else
+ if (zend_hash_find(EG(class_table), class_name, class_name_len, (void **) &cest) != SUCCESS) {
+ return NULL;
+ }
+#endif
+ return CestToCePtr(*cest);
+}
+/* }}} */
diff --git a/processor/class-helper.m4 b/processor/class-helper.m4
index 2e96c3e..95f0d35 100644
--- a/processor/class-helper.m4
+++ b/processor/class-helper.m4
@@ -112,3 +112,5 @@ static void xc_fix_method(xc_processor_t *processor, zend_op_array *dst TSRMLS_D
}
/* }}} */
#endif
+
+define(`xc_lookup_class', `IFRESTORE(``xc_lookup_class'($@)',``xc_lookup_class' can be use in restore only')')
diff --git a/processor/foot.m4 b/processor/foot.m4
index c22e97e..727b1b4 100644
--- a/processor/foot.m4
+++ b/processor/foot.m4
@@ -83,9 +83,9 @@ err_alloc:
}
dnl }}}
')
-DEFINE_STORE_API(`xc_entry_var_t')
DEFINE_STORE_API(`xc_entry_php_t')
DEFINE_STORE_API(`xc_entry_data_php_t')
+DEFINE_STORE_API(`xc_entry_var_t')
EXPORTED_FUNCTION(`xc_entry_php_t *xc_processor_restore_xc_entry_php_t(xc_entry_php_t *dst, const xc_entry_php_t *src TSRMLS_DC)') dnl {{{
{
xc_processor_t processor;
@@ -118,23 +118,46 @@ EXPORTED_FUNCTION(`xc_entry_data_php_t *xc_processor_restore_xc_entry_data_php_t
return dst;
}
dnl }}}
-EXPORTED_FUNCTION(`zval *xc_processor_restore_zval(zval *dst, const zval *src, zend_bool have_references TSRMLS_DC)') dnl {{{
+EXPORTED_FUNCTION(`zval *xc_processor_restore_var(zval *dst, const xc_entry_var_t *src TSRMLS_DC)') dnl {{{
{
xc_processor_t processor;
+ size_t i;
memset(&processor, 0, sizeof(processor));
- processor.handle_reference = have_references;
+ processor.handle_reference = src->have_references;
if (processor.handle_reference) {
zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
dnl fprintf(stderr, "mark[%p] = %p\n", src, dst);
- zend_hash_add(&processor.zvalptrs, (char *)src, sizeof(src), (void*)&dst, sizeof(dst), NULL);
+ zend_hash_add(&processor.zvalptrs, (char *)src->value, sizeof(src->value), (void *) &dst, sizeof(dst), NULL);
+ }
+ processor.entry_var_src = src;
+
+#ifdef ZEND_ENGINE_2
+ if (src->objects_count) {
+ processor.object_handles = emalloc(sizeof(*processor.object_handles) * src->objects_count);
+ xc_vector_init(zend_object_handle, &processor.objects, 0);
+ for (i = 0; i < src->objects_count; ++i) {
+ zend_object *object = emalloc(sizeof(*object));
+ xc_restore_zend_object(&processor, object, &src->objects[i] 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_zval(&processor, dst, src TSRMLS_CC);
+#endif
+ xc_restore_zval(&processor, dst, src->value TSRMLS_CC);
if (processor.handle_reference) {
zend_hash_destroy(&processor.zvalptrs);
}
+#ifdef ZEND_ENGINE_2
+ if (src->objects_count) {
+ for (i = 0; i < src->objects_count; ++i) {
+ zend_objects_store_del_ref_by_handle_ex(processor.object_handles[i], NULL TSRMLS_CC);
+ }
+ efree(processor.object_handles);
+ }
+#endif
+
return dst;
}
dnl }}}
diff --git a/processor/head.m4 b/processor/head.m4
index c727698..2e6656c 100644
--- a/processor/head.m4
+++ b/processor/head.m4
@@ -54,4 +54,9 @@ static void xc_zend_extension_op_array_ctor_handler(zend_extension *extension, z
#include "processor/string-helper.h"
include(__dir__`/string-helper.m4')
+
+#include "processor/class-helper.h"
include(__dir__`/class-helper.m4')
+
+#include "processor/var-helper.h"
+include(__dir__`/var-helper.m4')
diff --git a/processor/process.m4 b/processor/process.m4
index d7d7c40..86e5189 100644
--- a/processor/process.m4
+++ b/processor/process.m4
@@ -69,6 +69,7 @@ define(`PROCESS', `dnl PROCESS(1:type, 2:elm)
, `$1', `xc_entry_type_t', `PROCESS_SCALAR(`$2', `d', `$1')'
, `$1', `xc_hash_value_t', `PROCESS_SCALAR(`$2', `lu', `$1')'
, `$1', `last_brk_cont_t', `PROCESS_SCALAR(`$2', `d', `$1')'
+ , `$1', `zend_object_handle',`PROCESS_SCALAR(`$2', `d', `$1')'
, `$1', `xc_ztstring', `PROCESS_xc_ztstring(`$2')'
, `$1', `xc_zval_type_t', `PROCESS_xc_zval_type_t(`$2')'
diff --git a/processor/processor-t.h b/processor/processor-t.h
index ee0a0a4..0669fe8 100644
--- a/processor/processor-t.h
+++ b/processor/processor-t.h
@@ -24,6 +24,7 @@ typedef struct _xc_processor_t {
zend_bool readonly_protection; /* wheather it's present */
#include "processor/string-helper-t.h"
+ #include "processor/var-helper-t.h"
#ifdef HAVE_XCACHE_TEST
xc_vector_t allocsizes;
diff --git a/processor/processor.m4 b/processor/processor.m4
index e2645af..6be2952 100644
--- a/processor/processor.m4
+++ b/processor/processor.m4
@@ -118,6 +118,64 @@ DEF_STRUCT_P_FUNC(`zend_ast', , `dnl {{{
')
dnl }}}
#endif
+DEF_STRUCT_P_FUNC(`zend_object', , `dnl {{{
+ dnl handle ce
+ dnl IFCALCSTORE(`
+ dnl pushdef(`SRC', `ifelse(`$1', `ce', `src->ce->name', `')')
+ dnl pushdef(`DST', `ifelse(`$1', `ce', `(*(char **)&dst->ce)', `')')
+ dnl PROC_STRING(`ce')
+ dnl popdef(`SRC')
+ dnl popdef(`DST')
+ dnl ', `IFRESTORE(`
+ dnl if (!(DST(`ce') = xc_lookup_class((const char *) SRC(`ce') TSRMLS_CC))) {
+ dnl DST(`ce') = zend_standard_class_def;
+ dnl php_error_docref(NULL TSRMLS_CC, E_WARNING, "Class %s not found when restroing variable", (const char *) SRC(`ce'));
+ dnl }
+ dnl DONE(`ce')
+ dnl ', `
+ dnl PROCESS(zend_ulong, ce)
+ dnl ')')
+ IFCALC(`
+ xc_var_collect_class(processor, SRC(ce) TSRMLS_CC);
+ DONE(ce)
+ ', `IFSTORE(`
+ DST(ce) = (zend_class_entry *) xc_var_ce_to_index(processor, DST(ce) TSRMLS_CC);
+ DONE(ce)
+ ', `IFRESTORE(`
+ DST(ce) = xc_var_index_to_ec(processor, (size_t) DST(ce) TSRMLS_CC);
+ DONE(ce)
+ ', `
+ PROCESS_SCALAR(ce, %lu, unsigned long)
+ ')')')
+
+ STRUCT_P(HashTable, properties, HashTable_zval_ptr)
+#ifdef ZEND_ENGINE_2_4
+ dnl TODO: how to rebuild properties_table
+ STRUCT_ARRAY(int, ce->default_properties_count, zval_ptr, properties_table)
+#endif
+#ifdef ZEND_ENGINE_2
+ COPYNULL(`guards')
+#endif
+')
+dnl }}}
+#ifdef ZEND_ENGINE_2
+DEF_STRUCT_P_FUNC(`zend_object_value', , `dnl {{{
+ IFCALC(`
+ xc_var_collect_object(processor, SRC(handle) TSRMLS_CC);
+ DONE(handle)
+ ', `IFSTORE(`
+ DST(handle) = (zend_object_handle) xc_var_store_handle(processor, DST(handle) TSRMLS_CC);
+ DONE(handle)
+ ', `IFRESTORE(`
+ DST(handle) = xc_var_restore_handle(processor, (size_t) DST(handle) TSRMLS_CC);
+ DONE(handle)
+ ', `
+ PROCESS(zend_object_handle, handle)
+ ')')')
+ COPY(handlers)
+')
+dnl }}}
+#endif
DEF_STRUCT_P_FUNC(`zval', , `dnl {{{
IFDASM(`do {
zval_dtor(DST());
@@ -141,7 +199,6 @@ dnl {{{ zvalue_value
DISABLECHECK(`
switch ((Z_TYPE_P(SRC()) & IS_CONSTANT_TYPE_MASK)) {
case IS_LONG:
- case IS_RESOURCE:
case IS_BOOL:
PROCESS(long, value.lval)
break;
@@ -195,16 +252,18 @@ proc_unicode:
#endif
case IS_OBJECT:
- IFNOTMEMCPY(`IFCOPY(`memcpy(DST(), SRC(), sizeof(SRC()[0]));')')
- dnl STRUCT(value.obj)
-#ifndef ZEND_ENGINE_2
- STRUCT_P(zend_class_entry, value.obj.ce)
- STRUCT_P(HashTable, value.obj.properties, HashTable_zval_ptr)
+#ifdef ZEND_ENGINE_2
+ STRUCT(zend_object_value, value.obj)
+#else
+ STRUCT(zend_object, value.obj)
#endif
break;
default:
- assert(0);
+ /* IS_RESOURCE */
+ IFCOPY(`Z_TYPE_P(DST()) = IS_LONG;')
+ PROCESS(long, value.lval)
+ break;
}
')
dnl }}}
@@ -1339,6 +1398,9 @@ DEF_STRUCT_P_FUNC(`xc_entry_php_t', , `dnl {{{
')
dnl }}}
DEF_STRUCT_P_FUNC(`xc_entry_var_t', , `dnl {{{
+ IFCALCSTORE(`xc_entry_var_t *vsrc = /* const_cast */ (xc_entry_var_t *) src;')
+
+ dnl restore is done in foot.m4
STRUCT(xc_entry_t, entry)
#ifdef IS_UNICODE
@@ -1368,6 +1430,59 @@ DEF_STRUCT_P_FUNC(`xc_entry_var_t', , `dnl {{{
IFDPRINT(`INDENT()`'fprintf(stderr, "zval:value");')
STRUCT_P_EX(zval_ptr, DST(`value'), SRC(`value'), `value', `', `&')
+
+#ifdef ZEND_ENGINE_2
+ IFCALC(`
+ dnl objects = collect_from(value);
+ pushdef(`src', `vsrc')
+ SRC(objects_count) = xc_vector_size(&processor->objects);
+ SRC(objects) = xc_vector_detach(zend_object, &processor->objects);
+ popdef(`src')
+ xc_vector_destroy(&processor->objects);
+ if (SRC(`objects_count')) {
+ xc_vector_init(xc_constant_string_t, &processor->class_names, 0);
+ zend_hash_init(&processor->class_name_to_index, 0, NULL, NULL, 0);
+ }
+ ')
+ dnl must be after calc .value
+ PROCESS(zend_uint, objects_count)
+ STRUCT_ARRAY(zend_uint, objects_count, zend_object, objects)
+ IFSTORE(`{
+ /* no longer needed */
+ if (vsrc->objects_count) {
+ efree(vsrc->objects);
+ vsrc->objects_count = 0;
+ vsrc->objects = NULL;
+ zend_hash_destroy(&processor->handle_to_index);
+ }
+ }')
+#endif
+
+ dnl classe_
+ IFCALC(`
+ 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);
+ popdef(`src')
+ xc_vector_destroy(&processor->class_names);
+ ')
+ PROCESS(zend_uint, class_names_count)
+ STRUCT_ARRAY(zend_uint, class_names_count, xc_constant_string_t, class_names)
+ IFSTORE(`
+ /* no longer needed */
+ if (vsrc->class_names_count) {
+ dnl size_t i;
+ dnl for (i = 0; i < vsrc->class_names_count; ++i) {
+ dnl efree(vsrc->class_names[i]);
+ dnl }
+ efree(vsrc->class_names);
+ vsrc->class_names_count = 0;
+ vsrc->class_names = NULL;
+ zend_hash_destroy(&processor->class_name_to_index);
+ }
+ ')
+
PROCESS(zend_bool, have_references)
DONE(value)
')
diff --git a/processor/var-helper-t.h b/processor/var-helper-t.h
new file mode 100644
index 0000000..c9663af
--- /dev/null
+++ b/processor/var-helper-t.h
@@ -0,0 +1,10 @@
+/* {{{ var object helpers */
+zend_bool have_objects;
+xc_vector_t objects; /* in calc only */
+HashTable handle_to_index; /* in calc/store only */
+zend_object_handle *object_handles; /* in restore only */
+const xc_entry_var_t *entry_var_src; /* in restore */
+
+xc_vector_t class_names; /* in calc only */
+HashTable class_name_to_index; /* in calc/store only */
+/* }}} */
diff --git a/processor/var-helper.h b/processor/var-helper.h
new file mode 100644
index 0000000..35d5f48
--- /dev/null
+++ b/processor/var-helper.h
@@ -0,0 +1,72 @@
+#ifdef ZEND_ENGINE_2
+static void xc_var_collect_object(xc_processor_t *processor, zend_object_handle handle TSRMLS_DC) /* {{{ */
+{
+ size_t next_index = xc_vector_size(&processor->objects);
+
+ if (!xc_vector_initialized(&processor->objects)) {
+ xc_vector_init(zend_object, &processor->objects, 0);
+ zend_hash_init(&processor->handle_to_index, 0, NULL, NULL, 0);
+ }
+
+ 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->objects, object);
+ }
+}
+/* }}} */
+static size_t xc_var_store_handle(xc_processor_t *processor, zend_object_handle handle TSRMLS_DC) /* {{{ */
+{
+ size_t *index;
+
+ if (zend_hash_index_find(&processor->handle_to_index, handle, (void **) &index) != SUCCESS) {
+ php_error_docref(NULL TSRMLS_CC, E_CORE_ERROR, "Internal error: handle not found in objects");
+ return (size_t) -1;
+ }
+
+ return *index;
+}
+/* }}} */
+static zend_object_handle xc_var_restore_handle(xc_processor_t *processor, size_t index TSRMLS_DC) /* {{{ */
+{
+ zend_object_handle handle = processor->object_handles[index];
+ zend_objects_store_add_ref_by_handle(handle TSRMLS_CC);
+ return handle;
+}
+/* }}} */
+#endif
+static void xc_var_collect_class(xc_processor_t *processor, zend_class_entry *ce TSRMLS_DC) /* {{{ */
+{
+ size_t next_index = xc_vector_size(&processor->class_names);
+
+ if (zend_hash_add(&processor->class_name_to_index, ce->name, ce->name_length, (void *) &next_index, sizeof(next_index), NULL) == SUCCESS) {
+ xc_constant_string_t class_name = { ce->name, ce->name_length };
+ xc_vector_push_back(&processor->class_names, &class_name);
+ }
+}
+/* }}} */
+/* on store */
+static size_t xc_var_ce_to_index(xc_processor_t *processor, zend_class_entry *ce TSRMLS_DC) /* {{{ */
+{
+ size_t *index;
+
+ if (zend_hash_find(&processor->class_name_to_index, ce->name, ce->name_length, (void **) &index) != SUCCESS) {
+ php_error_docref(NULL TSRMLS_CC, E_CORE_ERROR, "Internal error: class name not found in class names");
+ return (size_t) -1;
+ }
+
+ return *index;
+}
+/* }}} */
+/* on restore */
+static zend_class_entry *xc_var_index_to_ec(xc_processor_t *processor, size_t index TSRMLS_DC) /* {{{ */
+{
+ xc_constant_string_t *name = &processor->entry_var_src->class_names[index];
+ zend_class_entry *ce;
+
+ if (!(ce = xc_lookup_class(name->str, name->len+1 TSRMLS_CC))) {
+ ce = zend_standard_class_def;
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Class %s not found when restroing variable", name->str);
+ }
+ return ce;
+}
+/* }}} */
diff --git a/processor/var-helper.m4 b/processor/var-helper.m4
new file mode 100644
index 0000000..6b48efc
--- /dev/null
+++ b/processor/var-helper.m4
@@ -0,0 +1,3 @@
+define(`xc_collect_object', `IFCALC(``xc_collect_object'($@)',``xc_collect_object' can be use in calc only')')
+define(`xc_var_store_handle', `IFSTORE(``xc_var_store_handle'($@)',``xc_var_store_handle' can be use in store only')')
+define(`xc_var_restore_handle', `IFRESTORE(``xc_var_restore_handle'($@)',``xc_var_restore_handle' can be use in restore only')')