Browse Source

fixed #20, default: --enable-xcache-constant=yes

git-svn-id: svn://svn.lighttpd.net/xcache/trunk@95 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
1.1
Xuefer 15 years ago
parent
commit
99e6113755
  1. 6
      config.m4
  2. 7
      config.w32
  3. 38
      processor/processor.m4
  4. 58
      utils.c
  5. 7
      utils.h
  6. 148
      xcache.c
  7. 17
      xcache.h

6
config.m4

@ -17,6 +17,12 @@ PHP_ARG_ENABLE(xcache, for XCache support,
[ --enable-xcache Include XCache support.])
if test "$PHP_XCACHE" != "no"; then
PHP_ARG_ENABLE(xcache-constant, for XCache handle of compile time constant,
[ --enable-xcache-constant XCache: Handle new constants made by php compiler (e.g.: for __halt_compiler)], yes, no)
if test "$PHP_XCACHE_CONSTANT" != "no"; then
AC_DEFINE([HAVE_XCACHE_CONSTANT], 1, [Define to enable XCache handling of compile time constants])
fi
xcache_sources="processor.c \
xcache.c \
mmap.c \

7
config.w32

@ -4,6 +4,13 @@
ARG_ENABLE("xcache", "Include XCache support", "yes,shared");
if (PHP_XCACHE != "no") {
// {{{ check for xcache-constant
ARG_ENABLE("xcache-constant", "XCache: Handle new constants made by php compiler (e.g.: for __halt_compiler)", "yes");
if (PHP_XCACHE_CONSTANT != "no") {
AC_DEFINE("HAVE_XCACHE_CONSTANT", 1, "Define to enable XCache handling of compile time constants");
}
// }}}
var xcache_sources = "processor.c \
xcache.c \
mmap.c \

38
processor/processor.m4

@ -4,6 +4,9 @@ DECL_STRUCT_P_FUNC(`zval')
DECL_STRUCT_P_FUNC(`zval_ptr')
DECL_STRUCT_P_FUNC(`zend_op_array')
DECL_STRUCT_P_FUNC(`zend_class_entry')
#ifdef HAVE_XCACHE_CONSTANT
DECL_STRUCT_P_FUNC(`zend_constant')
#endif
DECL_STRUCT_P_FUNC(`zend_function')
DECL_STRUCT_P_FUNC(`xc_entry_t')
#ifdef ZEND_ENGINE_2
@ -58,6 +61,9 @@ DEF_STRUCT_P_FUNC(`zend_brk_cont_element', , `
')
dnl }}}
DEF_HASH_TABLE_FUNC(`HashTable_zval_ptr', `zval_ptr')
#ifdef HAVE_XCACHE_CONSTANT
DEF_HASH_TABLE_FUNC(`HashTable_zend_constant', `zend_constant')
#endif
DEF_HASH_TABLE_FUNC(`HashTable_zend_function', `zend_function')
#ifdef ZEND_ENGINE_2
DEF_HASH_TABLE_FUNC(`HashTable_zend_property_info', `zend_property_info')
@ -204,6 +210,17 @@ DEF_STRUCT_P_FUNC(`zend_arg_info', , `
')
#endif
dnl }}}
#ifdef HAVE_XCACHE_CONSTANT
DEF_STRUCT_P_FUNC(`zend_constant', , `dnl {{{
STRUCT(zval, value)
DISPATCH(int, flags)
DISPATCH(uint, name_len)
PROC_STRING_L(name, name_len)
zstr name;
DISPATCH(int, module_number)
')
dnl }}}
#endif
DEF_STRUCT_P_FUNC(`zend_function', , `dnl {{{
DISABLECHECK(`
switch (src->type) {
@ -598,8 +615,7 @@ DEF_STRUCT_P_FUNC(`zend_op_array', , `dnl {{{
STRUCT_P(HashTable, static_variables, HashTable_zval_ptr)
IFCOPY(`dst->start_op = src->start_op;')
DONE(start_op)
COPY(start_op)
DISPATCH(int, backpatch_count)
DISPATCH(zend_bool, done_pass_two)
@ -627,6 +643,19 @@ DEF_STRUCT_P_FUNC(`zend_op_array', , `dnl {{{
')
dnl }}}
#ifdef HAVE_XCACHE_CONSTANT
DEF_STRUCT_P_FUNC(`xc_constinfo_t', , `dnl {{{
DISPATCH(zend_uint, key_size)
#ifdef IS_UNICODE
DISPATCH(zend_uchar, type)
#endif
IFRESTORE(`COPY(key)', `
PROC_USTRING_N(type, key, key_size)
')
STRUCT(zend_constant, constant)
')
dnl }}}
#endif
DEF_STRUCT_P_FUNC(`xc_funcinfo_t', , `dnl {{{
DISPATCH(zend_uint, key_size)
#ifdef IS_UNICODE
@ -666,6 +695,11 @@ DEF_STRUCT_P_FUNC(`xc_entry_data_php_t', , `dnl {{{
STRUCT_P(zend_op_array, op_array)
#ifdef HAVE_XCACHE_CONSTANT
DISPATCH(zend_uint, constinfo_cnt)
STRUCT_ARRAY(constinfo_cnt, xc_constinfo_t, constinfos)
#endif
DISPATCH(zend_uint, funcinfo_cnt)
STRUCT_ARRAY(funcinfo_cnt, xc_funcinfo_t, funcinfos)

58
utils.c

@ -264,6 +264,25 @@ int xc_undo_fix_opcode(zend_op_array *op_array TSRMLS_DC) /* {{{ */
/* }}} */
#endif
#ifdef HAVE_XCACHE_CONSTANT
void xc_install_constant(char *filename, zend_constant *constant, zend_uchar type, void *key, uint len TSRMLS_DC) /* {{{ */
{
if (zend_u_hash_add(EG(zend_constants), type, key, len,
constant, sizeof(zend_constant),
NULL
) == FAILURE) {
CG(in_compilation) = 1;
CG(compiled_filename) = filename;
CG(zend_lineno) = 0;
zend_error(E_NOTICE, "Constant %s already defined", key);
free(constant->name);
if (!(constant->flags & CONST_PERSISTENT)) {
zval_dtor(&constant->value);
}
}
}
/* }}} */
#endif
void xc_install_function(char *filename, zend_function *func, zend_uchar type, void *key, uint len TSRMLS_DC) /* {{{ */
{
if (func->type == ZEND_USER_FUNCTION) {
@ -315,6 +334,16 @@ ZESW(xc_cest_t *, void) xc_install_class(char *filename, xc_cest_t *cest, zend_u
#define TG(x) (sandbox->tmp_##x)
#define OG(x) (sandbox->orig_##x)
/* }}} */
#ifdef HAVE_XCACHE_CONSTANT
static void xc_constant_copy_ctor(zend_constant *c) /* {{{ */
{
c->name = zend_strndup(c->name, c->name_len - 1);
if (!(c->flags & CONST_PERSISTENT)) {
zval_copy_ctor(&c->value);
}
}
/* }}} */
#endif
xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, char *filename TSRMLS_DC) /* {{{ */
{
if (sandbox) {
@ -324,9 +353,15 @@ xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, char *filename TSRMLS_DC) /
ECALLOC_ONE(sandbox);
sandbox->alloc = 1;
}
memcpy(&OG(included_files), &EG(included_files), sizeof(EG(included_files)));
memcpy(&OG(open_files), &CG(open_files), sizeof(CG(open_files)));
#ifdef HAVE_XCACHE_CONSTANT
OG(zend_constants) = EG(zend_constants);
EG(zend_constants) = &TG(zend_constants);
#endif
OG(function_table) = CG(function_table);
CG(function_table) = &TG(function_table);
@ -341,6 +376,9 @@ xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, char *filename TSRMLS_DC) /
zend_llist_init(TG(open_files), sizeof(zend_file_handle), (void (*)(void *)) zend_file_handle_dtor, 0);
zend_hash_init_ex(TG(included_files), 5, NULL, NULL, 0, 1);
#ifdef HAVE_XCACHE_CONSTANT
zend_hash_init_ex(&TG(zend_constants), 20, NULL, ZEND_CONSTANT_DTOR, 1, 0);
#endif
zend_hash_init_ex(&TG(function_table), 128, NULL, ZEND_FUNCTION_DTOR, 0, 0);
zend_hash_init_ex(&TG(class_table), 16, NULL, ZEND_CLASS_DTOR, 0, 0);
@ -356,6 +394,17 @@ static void xc_sandbox_install(xc_sandbox_t *sandbox TSRMLS_DC) /* {{{ */
zend_llist_position lpos;
zend_file_handle *handle;
#ifdef HAVE_XCACHE_CONSTANT
b = TG(zend_constants).pListHead;
/* install constants */
while (b != NULL) {
zend_constant *c = (zend_constant*) b->pData;
xc_install_constant(sandbox->filename, c,
BUCKET_KEY_TYPE(b), BUCKET_KEY(b), b->nKeyLength TSRMLS_CC);
b = b->pListNext;
}
#endif
b = TG(function_table).pListHead;
/* install function */
while (b != NULL) {
@ -385,6 +434,9 @@ static void xc_sandbox_install(xc_sandbox_t *sandbox TSRMLS_DC) /* {{{ */
void xc_sandbox_free(xc_sandbox_t *sandbox, int install TSRMLS_DC) /* {{{ */
{
/* restore first first install function/class */
#ifdef HAVE_XCACHE_CONSTANT
EG(zend_constants) = OG(zend_constants);
#endif
CG(function_table) = OG(function_table);
CG(class_table) = OG(class_table);
EG(class_table) = CG(class_table);
@ -393,12 +445,18 @@ void xc_sandbox_free(xc_sandbox_t *sandbox, int install TSRMLS_DC) /* {{{ */
xc_sandbox_install(sandbox TSRMLS_CC);
/* no free as it's installed */
#ifdef HAVE_XCACHE_CONSTANT
TG(zend_constants).pDestructor = NULL;
#endif
TG(function_table).pDestructor = NULL;
TG(class_table).pDestructor = NULL;
TG(open_files)->dtor = NULL;
}
/* destroy all the tmp */
#ifdef HAVE_XCACHE_CONSTANT
zend_hash_destroy(&TG(zend_constants));
#endif
zend_hash_destroy(&TG(function_table));
zend_hash_destroy(&TG(class_table));
zend_hash_destroy(TG(included_files));

7
utils.h

@ -25,6 +25,9 @@ int xc_undo_fix_opcode(zend_op_array *op_array TSRMLS_DC);
zend_uchar xc_get_fixed_opcode(zend_uchar opcode, int line);
/* installer */
#ifdef HAVE_XCACHE_CONSTANT
void xc_install_constant(char *filename, zend_constant *constant, zend_uchar type, void *key, uint len TSRMLS_DC);
#endif
void xc_install_function(char *filename, zend_function *func, zend_uchar type, void *key, uint len TSRMLS_DC);
ZESW(xc_cest_t *, void) xc_install_class(char *filename, xc_cest_t *cest, zend_uchar type, void *key, uint len TSRMLS_DC);
@ -38,6 +41,10 @@ typedef struct {
HashTable *tmp_included_files;
zend_llist *tmp_open_files;
#ifdef HAVE_XCACHE_CONSTANT
HashTable *orig_zend_constants;
HashTable tmp_zend_constants;
#endif
HashTable *orig_function_table;
HashTable *orig_class_table;
HashTable tmp_function_table;

148
xcache.c

@ -300,15 +300,18 @@ static void xc_fillentry_dmz(xc_entry_t *entry, int del, zval *list TSRMLS_DC) /
switch (entry->type) {
case XC_TYPE_PHP:
php = entry->data.php;
add_assoc_long_ex(ei, ZEND_STRS("sourcesize"), php->sourcesize);
add_assoc_long_ex(ei, ZEND_STRS("sourcesize"), php->sourcesize);
#ifdef HAVE_INODE
add_assoc_long_ex(ei, ZEND_STRS("device"), php->device);
add_assoc_long_ex(ei, ZEND_STRS("inode"), php->inode);
add_assoc_long_ex(ei, ZEND_STRS("device"), php->device);
add_assoc_long_ex(ei, ZEND_STRS("inode"), php->inode);
#endif
add_assoc_long_ex(ei, ZEND_STRS("mtime"), php->mtime);
add_assoc_long_ex(ei, ZEND_STRS("mtime"), php->mtime);
add_assoc_long_ex(ei, ZEND_STRS("function_cnt"), php->funcinfo_cnt);
add_assoc_long_ex(ei, ZEND_STRS("class_cnt"), php->classinfo_cnt);
#ifdef HAVE_XCACHE_CONSTANT
add_assoc_long_ex(ei, ZEND_STRS("constinfo_cnt"), php->constinfo_cnt);
#endif
add_assoc_long_ex(ei, ZEND_STRS("function_cnt"), php->funcinfo_cnt);
add_assoc_long_ex(ei, ZEND_STRS("class_cnt"), php->classinfo_cnt);
break;
case XC_TYPE_VAR:
var = entry->data.var;
@ -355,6 +358,15 @@ static zend_op_array *xc_entry_install(xc_entry_t *xce, zend_file_handle *h TSRM
xc_cest_t **new_cest_ptrs = (xc_cest_t **)do_alloca(sizeof(xc_cest_t*) * p->classinfo_cnt);
#endif
#ifdef HAVE_XCACHE_CONSTANT
/* install constant */
for (i = 0; i < p->constinfo_cnt; i ++) {
xc_constinfo_t *ci = &p->constinfos[i];
xc_install_constant(xce->name.str.val, &ci->constant,
UNISW(0, ci->type), ci->key, ci->key_size TSRMLS_CC);
}
#endif
/* install function */
for (i = 0; i < p->funcinfo_cnt; i ++) {
xc_funcinfo_t *fi = &p->funcinfos[i];
@ -593,6 +605,7 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
zend_bool clogged = 0;
zend_bool catched = 0;
char *filename;
int old_constinfo_cnt, old_funcinfo_cnt, old_classinfo_cnt;
if (!xc_initized) {
assert(0);
@ -674,6 +687,10 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
/* make compile inside sandbox */
xc_sandbox_init(&sandbox, filename TSRMLS_CC);
old_classinfo_cnt = zend_hash_num_elements(CG(class_table));
old_funcinfo_cnt = zend_hash_num_elements(CG(function_table));
old_constinfo_cnt = zend_hash_num_elements(EG(zend_constants));
zend_try {
op_array = origin_compile_file(h, type TSRMLS_CC);
} zend_catch {
@ -702,46 +719,60 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
php.op_array = op_array;
php.funcinfo_cnt = zend_hash_num_elements(CG(function_table));
php.classinfo_cnt = zend_hash_num_elements(CG(class_table));
#ifdef HAVE_XCACHE_CONSTANT
php.constinfo_cnt = zend_hash_num_elements(EG(zend_constants)) - old_constinfo_cnt;
#endif
php.funcinfo_cnt = zend_hash_num_elements(CG(function_table)) - old_funcinfo_cnt;
php.classinfo_cnt = zend_hash_num_elements(CG(class_table)) - old_classinfo_cnt;
#define X_ALLOC_N(var, cnt) do { \
if (php.cnt) { \
ECALLOC_N(php.var, php.cnt); \
if (!php.var) { \
goto err_##var; \
} \
} \
else { \
php.var = NULL; \
} \
} while (0)
php.funcinfos = ECALLOC_N(php.funcinfos, php.funcinfo_cnt);
if (!php.funcinfos) {
goto err_func;
}
php.classinfos = ECALLOC_N(php.classinfos, php.classinfo_cnt);
if (!php.classinfos) {
goto err_class;
}
#ifdef HAVE_XCACHE_CONSTANT
X_ALLOC_N(constinfos, constinfo_cnt);
#endif
X_ALLOC_N(funcinfos, funcinfo_cnt);
X_ALLOC_N(classinfos, classinfo_cnt);
#undef X_ALLOC
/* }}} */
/* {{{ shallow copy, pointers only */ {
Bucket *b;
unsigned int i;
b = CG(function_table)->pListHead;
for (i = 0; b; i ++, b = b->pListNext) {
xc_funcinfo_t *fi = &php.funcinfos[i];
#define COPY_H(vartype, var, cnt, name, datatype) do { \
for (i = 0; b; i ++, b = b->pListNext) { \
vartype *data = &php.var[i]; \
\
if (i < old_##cnt) { \
continue; \
} \
\
assert(i < old_##cnt + php.cnt); \
assert(b->pData); \
memcpy(&data->name, b->pData, sizeof(datatype)); \
UNISW(NOTHING, data->type = b->key.type;) \
data->key = BUCKET_KEY(b); \
data->key_size = b->nKeyLength; \
} \
} while(0)
assert(i < php.funcinfo_cnt);
assert(b->pData);
memcpy(&fi->func, b->pData, sizeof(zend_function));
UNISW(NOTHING, fi->type = b->key.type;)
fi->key = BUCKET_KEY(b);
fi->key_size = b->nKeyLength;
}
#ifdef HAVE_XCACHE_CONSTANT
b = EG(zend_constants)->pListHead; COPY_H(xc_constinfo_t, constinfos, constinfo_cnt, constant, zend_constant);
#endif
b = CG(function_table)->pListHead; COPY_H(xc_funcinfo_t, funcinfos, funcinfo_cnt, func, zend_function);
b = CG(class_table)->pListHead; COPY_H(xc_classinfo_t, classinfos, classinfo_cnt, cest, xc_cest_t);
b = CG(class_table)->pListHead;
for (i = 0; b; i ++, b = b->pListNext) {
xc_classinfo_t *ci = &php.classinfos[i];
assert(i < php.classinfo_cnt);
assert(b->pData);
memcpy(&ci->cest, b->pData, sizeof(xc_cest_t));
UNISW(NOTHING, ci->type = b->key.type;)
ci->key = BUCKET_KEY(b);
ci->key_size = b->nKeyLength;
/* need to fix inside store */
}
#undef COPY_H
/* for ZE1, cest need to fix inside store */
}
/* }}} */
xc_entry_gc(TSRMLS_C);
@ -753,10 +784,19 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
fprintf(stderr, "stored\n");
#endif
efree(xce.data.php->classinfos);
err_class:
efree(xce.data.php->funcinfos);
err_func:
#define X_FREE(var) \
if (xce.data.php->var) { \
efree(xce.data.php->var); \
} \
err_##var:
X_FREE(classinfos)
X_FREE(funcinfos)
#ifdef HAVE_XCACHE_CONSTANT
X_FREE(constinfos)
#endif
#undef X_FREE
err_oparray:
err_bailout:
@ -789,11 +829,29 @@ restore:
fprintf(stderr, "restoring\n");
#endif
xc_processor_restore_xc_entry_t(&xce, stored_xce, xc_readonly_protection TSRMLS_CC);
op_array = xc_entry_install(&xce, h TSRMLS_CC);
efree(xce.data.php->funcinfos);
efree(xce.data.php->classinfos);
catched = 0;
zend_try {
op_array = xc_entry_install(&xce, h TSRMLS_CC);
} zend_catch {
catched = 1;
} zend_end_try();
#define X_FREE(var) \
if (xce.data.php->var) { \
efree(xce.data.php->var); \
}
X_FREE(classinfos)
X_FREE(funcinfos)
#ifdef HAVE_XCACHE_CONSTANT
X_FREE(constinfos)
#endif
#undef X_FREE
efree(xce.data.php);
if (catched) {
zend_bailout();
}
#ifdef DEBUG
fprintf(stderr, "restored\n");
#endif

17
xcache.h

@ -153,6 +153,18 @@ typedef struct {
xc_cest_t cest;
} xc_classinfo_t;
/* }}} */
#ifdef HAVE_XCACHE_CONSTANT
/* {{{ xc_constinfo_t */
typedef struct {
#ifdef IS_UNICODE
zend_uchar type;
#endif
char *key;
zend_uint key_size;
zend_constant constant;
} xc_constinfo_t;
/* }}} */
#endif
/* {{{ xc_funcinfo_t */
typedef struct {
#ifdef IS_UNICODE
@ -175,6 +187,11 @@ typedef struct {
zend_op_array *op_array;
#ifdef HAVE_XCACHE_CONSTANT
zend_uint constinfo_cnt;
xc_constinfo_t *constinfos;
#endif
zend_uint funcinfo_cnt;
xc_funcinfo_t *funcinfos;

Loading…
Cancel
Save