Browse Source

back patch !__FILE__ and !__DIR__ on cache restore

git-svn-id: svn://svn.lighttpd.net/xcache/trunk@662 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
3.0
Xuefer 12 years ago
parent
commit
38569c559e
  1. 29
      processor/dispatch.m4
  2. 14
      processor/head.m4
  3. 20
      processor/main.m4
  4. 86
      processor/processor.m4
  5. 7
      processor/string.m4
  6. 22
      processor/struct.m4
  7. 52
      utils.h
  8. 289
      xcache.c
  9. 38
      xcache.h
  10. 2
      xcache_globals.h

29
processor/dispatch.m4

@ -27,3 +27,32 @@ define(`DISPATCH', `
, `', `', `m4_errprint(`Unknown type "$1"')'
)
')
dnl {{{ DISPATCH_ARRAY(1:count, 2:type, 3:elm)
define(`DISPATCH_ARRAY', `
if (src->$3) {
int i;
IFDASM(`
zval *arr;
ALLOC_INIT_ZVAL(arr);
array_init(arr);
for (i = 0; i < src->$1; i ++) {
ifelse(
`$2', `zend_bool', `add_assoc_bool_ex(arr, ZEND_STRS("$3"), src->$3[i] ? 1 : 0);'
, `', `', `add_assoc_long_ex(arr, ZEND_STRS("$3"), src->$3[i]);')
}
add_assoc_zval_ex(dst, ZEND_STRS("$3"), arr);
', `
COPY_N_EX($@)
for (i = 0; i < src->$1; i ++) {
DISABLECHECK(`
DISPATCH(`$2', `$3[i]', `$4')
')
}
')dnl IFDASM
DONE(`$3')
}
else {
COPYNULL(`$3')
}
')
dnl }}}

14
processor/head.m4

@ -68,13 +68,15 @@ struct _xc_processor_t {
const xc_entry_data_php_t *php_dst;
const xc_cache_t *cache;
const zend_class_entry *cache_ce;
zend_uint cache_class_num;
zend_uint cache_class_index;
const zend_op *active_opcodes_src;
zend_op *active_opcodes_dst;
const zend_class_entry *active_class_entry_src;
zend_class_entry *active_class_entry_dst;
zend_uint active_class_num;
zend_uint active_class_index;
zend_uint active_op_array_index;
const xc_op_array_info_t *active_op_array_infos_src;
zend_bool readonly_protection; /* wheather it's present */
IFASSERT(xc_stack_t allocsizes;)
@ -185,28 +187,30 @@ static zend_ulong xc_get_class_num(xc_processor_t *processor, zend_class_entry *
zend_class_entry *ceptr;
if (processor->cache_ce == ce) {
return processor->cache_class_num;
return processor->cache_class_index + 1;
}
for (i = 0; i < php->classinfo_cnt; i ++) {
ceptr = CestToCePtr(php->classinfos[i].cest);
if (ZCEP_REFCOUNT_PTR(ceptr) == ZCEP_REFCOUNT_PTR(ce)) {
processor->cache_ce = ceptr;
processor->cache_class_num = i + 1;
processor->cache_class_index = i + 1;
return i + 1;
}
}
assert(0);
return (zend_ulong) -1;
}
define(`xc_get_class_num', `xc_get_class_numNOTDEFINED')
/* }}} */
/* {{{ xc_get_class */
#ifdef ZEND_ENGINE_2
static zend_class_entry *xc_get_class(xc_processor_t *processor, zend_ulong class_num) {
/* must be parent or currrent class */
assert(class_num <= processor->active_class_num);
assert(class_num <= processor->active_class_index + 1);
return CestToCePtr(processor->php_dst->classinfos[class_num - 1].cest);
}
#endif
define(`xc_get_class', `xc_get_classNOTDEFINED')
/* }}} */
#ifdef ZEND_ENGINE_2
/* fix method on store */

20
processor/main.m4

@ -149,11 +149,25 @@ dnl }}}
dnl {{{ COPY
define(`COPY', `IFNOTMEMCPY(`IFCOPY(`dst->$1 = src->$1;')')DONE(`$1')')
dnl }}}
dnl {{{ COPY_N_EX
define(`COPY_N_EX', `
ALLOC(`dst->$3', `$2', `src->$1')
IFCOPY(`
memcpy(dst->$3, src->$3, sizeof(dst->$3[0]) * src->$1);
')
')
dnl }}}
dnl {{{ COPY_N
define(`COPY_N', `COPY_N_EX(`$1',`$2')DONE(`$1')')
dnl }}}
dnl {{{ COPYPOINTER
define(`COPYPOINTER', `COPY(`$1')')
dnl }}}
dnl {{{ COPYARRAY_EX
define(`COPYARRAY_EX', `IFNOTMEMCPY(`IFCOPY(`memcpy(dst->$1, src->$1, sizeof(dst->$1));')')')
dnl }}}
dnl {{{ COPYARRAY
define(`COPYARRAY', `IFNOTMEMCPY(`IFCOPY(`memcpy(dst->$1, src->$1, sizeof(dst->$1));')')DONE(`$1')')
define(`COPYARRAY', `COPYARRAY_EX(`$1',`$2')DONE(`$1')')
dnl }}}
dnl {{{ SETNULL_EX
define(`SETNULL_EX', `IFCOPY(`$1 = NULL;')')
@ -243,8 +257,12 @@ include(srcdir`/processor/head.m4')
define(`IFNOTMEMCPY', `ifdef(`USEMEMCPY', `', `$1')')
REDEF(`KIND', `calc') include(srcdir`/processor/processor.m4')
pushdef(`xc_get_class_num', ``xc_get_class_num'($@)')
REDEF(`KIND', `store') include(srcdir`/processor/processor.m4')
popdef(`xc_get_class_num')
pushdef(`xc_get_class', ``xc_get_class'($@)')
REDEF(`KIND', `restore') include(srcdir`/processor/processor.m4')
popdef(`xc_get_class')
REDEF(`IFNOTMEMCPY', `$1')
#ifdef HAVE_XCACHE_DPRINT

86
processor/processor.m4

@ -338,6 +338,7 @@ DEF_STRUCT_P_FUNC(`zend_class_entry', , `dnl {{{
IFDASM(`
if (src->num_interfaces) {
/*
int i;
zval *arr;
ALLOC_INIT_ZVAL(arr);
array_init(arr);
@ -498,40 +499,55 @@ DEF_STRUCT_P_FUNC(`zend_op', , `dnl {{{
dnl }}}
DEF_STRUCT_P_FUNC(`zend_op_array', , `dnl {{{
IFRESTORE(`
const xc_op_array_info_t *op_array_info = &processor->active_op_array_infos_src[processor->active_op_array_index];
dnl shadow copy must NOT meet:
dnl readonly_protection=on
dnl main op_array && have early binding
zend_uint ii;
#ifdef ZEND_COMPILE_DELAYED_BINDING
zend_bool need_early_binding = 0;
#else
zend_bool need_early_binding = processor->php_src->have_early_binding;
#endif
if (!processor->readonly_protection && !(src == processor->php_src->op_array && need_early_binding)) {
zend_bool shallow_copy = !processor->readonly_protection && !(src == processor->php_src->op_array && need_early_binding);
if (shallow_copy) {
zend_bool gc_arg_info = 0;
int gc_opcodes = 0;
/* really fast shallow copy */
memcpy(dst, src, sizeof(src[0]));
dst->refcount[0] = 1000;
/* deep */
STRUCT_P(HashTable, static_variables, HashTable_zval_ptr)
#ifdef ZEND_ENGINE_2
STRUCT_ARRAY_I(num_args, zend_arg_info, arg_info)
xc_gc_add_op_array(dst TSRMLS_CC);
STRUCT_ARRAY(num_args, zend_arg_info, arg_info)
gc_arg_info = 1;
#endif
if (op_array_info->oplineinfo_cnt) {
gc_opcodes = 1;
COPY_N_EX(last, zend_op, opcodes)
}
if (gc_arg_info || gc_opcodes) {
xc_gc_op_array_t gc_op_array;
#ifdef ZEND_ENGINE_2
gc_op_array.num_args = gc_arg_info ? dst->num_args : 0;
gc_op_array.arg_info = gc_arg_info ? dst->arg_info : NULL;
#endif
gc_op_array.last = gc_opcodes > 1 ? dst->last : 0;
gc_op_array.opcodes = gc_opcodes ? dst->opcodes : NULL;
xc_gc_add_op_array(&gc_op_array TSRMLS_CC);
}
define(`SKIPASSERT_ONCE')
}
else
')
do {
dnl RESTORE is done above!
zend_uint ii;
int i;
/* Common elements */
DISPATCH(zend_uchar, type)
PROC_ZSTRING(, function_name)
#ifdef ZEND_ENGINE_2
DISPATCH(zend_uint, fn_flags)
STRUCT_ARRAY_I(num_args, zend_arg_info, arg_info)
STRUCT_ARRAY(num_args, zend_arg_info, arg_info)
DISPATCH(zend_uint, num_args)
DISPATCH(zend_uint, required_num_args)
DISPATCH(zend_bool, pass_rest_by_reference)
@ -540,7 +556,6 @@ DEF_STRUCT_P_FUNC(`zend_op_array', , `dnl {{{
ALLOC(dst->arg_types, zend_uchar, src->arg_types[0] + 1)
IFCOPY(`memcpy(dst->arg_types, src->arg_types, sizeof(src->arg_types[0]) * (src->arg_types[0]+1));')
IFDASM(`do {
zend_uint ii;
int i;
zval *zv;
ALLOC_INIT_ZVAL(zv);
@ -580,7 +595,7 @@ DEF_STRUCT_P_FUNC(`zend_op_array', , `dnl {{{
processor->active_opcodes_dst = dst->opcodes;
processor->active_opcodes_src = src->opcodes;
')')
STRUCT_ARRAY_I(last, zend_op, opcodes)
STRUCT_ARRAY(last, zend_op, opcodes)
popdef(`AFTER_ALLOC')
DISPATCH(zend_uint, last)
IFCOPY(`dst->size = src->last;DONE(size)', `DISPATCH(zend_uint, size)')
@ -598,7 +613,7 @@ DEF_STRUCT_P_FUNC(`zend_op_array', , `dnl {{{
DISPATCH(zend_uint, T)
STRUCT_ARRAY_I(last_brk_cont, zend_brk_cont_element, brk_cont_array)
STRUCT_ARRAY(last_brk_cont, zend_brk_cont_element, brk_cont_array)
DISPATCH(zend_uint, last_brk_cont)
DISPATCH(zend_uint, current_brk_cont)
#ifndef ZEND_ENGINE_2
@ -648,6 +663,7 @@ DEF_STRUCT_P_FUNC(`zend_op_array', , `dnl {{{
DISPATCH(zend_bool, created_by_eval)
#endif
} while (0);
IFRESTORE(`xc_fix_op_array_info(processor->php_src, dst, !shallow_copy, op_array_info TSRMLS_CC);')
#ifdef ZEND_ENGINE_2
dnl mark it as -1 on store, and lookup parent on restore
@ -712,6 +728,11 @@ DEF_STRUCT_P_FUNC(`xc_constinfo_t', , `dnl {{{
')
dnl }}}
#endif
DEF_STRUCT_P_FUNC(`xc_op_array_info_t', , `dnl {{{
DISPATCH(zend_uint, oplineinfo_cnt)
DISPATCH_ARRAY(oplineinfo_cnt, int, oplineinfos)
')
dnl }}}
DEF_STRUCT_P_FUNC(`xc_funcinfo_t', , `dnl {{{
DISPATCH(zend_uint, key_size)
#ifdef IS_UNICODE
@ -721,6 +742,13 @@ DEF_STRUCT_P_FUNC(`xc_funcinfo_t', , `dnl {{{
PROC_ZSTRING_N(type, key, key_size)
')
DISPATCH(ulong, h)
IFRESTORE(`COPY(op_array_info)', `
STRUCT(xc_op_array_info_t, op_array_info)
')
IFRESTORE(`
processor->active_op_array_infos_src = &dst->op_array_info;
processor->active_op_array_index = 0;
')
STRUCT(zend_function, func)
')
dnl }}}
@ -733,6 +761,14 @@ DEF_STRUCT_P_FUNC(`xc_classinfo_t', , `dnl {{{
PROC_ZSTRING_N(type, key, key_size)
')
DISPATCH(ulong, h)
DISPATCH(zend_uint, methodinfo_cnt)
IFRESTORE(`COPY(methodinfos)', `
STRUCT_ARRAY(methodinfo_cnt, xc_op_array_info_t, methodinfos)
')
IFRESTORE(`
processor->active_op_array_infos_src = dst->methodinfos;
processor->active_op_array_index = 0;
')
#ifdef ZEND_ENGINE_2
STRUCT_P(zend_class_entry, cest)
#else
@ -766,8 +802,6 @@ DEF_STRUCT_P_FUNC(`xc_compilererror_t', , `dnl {{{
dnl }}}
#endif
DEF_STRUCT_P_FUNC(`xc_entry_data_php_t', , `dnl {{{
zend_uint i;
IFCOPY(`
processor->php_dst = dst;
processor->php_src = src;
@ -784,6 +818,24 @@ DEF_STRUCT_P_FUNC(`xc_entry_data_php_t', , `dnl {{{
DISPATCH(zend_ulong, hits)
DISPATCH(size_t, size)
DISPATCH(int, filepath_len)
IFRESTORE(`COPY(filepath)', `PROC_STRING_L(filepath, filepath_len)')
DISPATCH(int, dirpath_len)
IFRESTORE(`COPY(dirpath)', `PROC_STRING_L(dirpath, dirpath_len)')
#ifdef IS_UNICODE
DISPATCH(int, ufilepath_len)
IFRESTORE(`COPY(ufilepath)', `PROC_USTRING_L(ufilepath, ufilepath_len)')
DISPATCH(int, udirpath_len)
IFRESTORE(`COPY(udirpath)', `PROC_USTRING_L(udirpath, udirpath_len)')
#endif
IFRESTORE(`COPY(op_array_info)', `
STRUCT(xc_op_array_info_t, op_array_info)
')
IFRESTORE(`
processor->active_op_array_infos_src = &dst->op_array_info;
processor->active_op_array_index = 0;
')
STRUCT_P(zend_op_array, op_array)
#ifdef HAVE_XCACHE_CONSTANT
@ -795,13 +847,7 @@ DEF_STRUCT_P_FUNC(`xc_entry_data_php_t', , `dnl {{{
STRUCT_ARRAY(funcinfo_cnt, xc_funcinfo_t, funcinfos)
DISPATCH(zend_uint, classinfo_cnt)
pushdef(`BEFORE_LOOP', `
IFCOPY(`
processor->active_class_num = i + 1;
')
')
STRUCT_ARRAY(classinfo_cnt, xc_classinfo_t, classinfos)
popdef(`BEFORE_LOOP')
STRUCT_ARRAY(classinfo_cnt, xc_classinfo_t, classinfos, , IFRESTORE(`processor->active_class_index'))
#ifdef ZEND_ENGINE_2_1
DISPATCH(zend_uint, autoglobal_cnt)
IFRESTORE(`
@ -878,7 +924,7 @@ DEF_STRUCT_P_FUNC(`xc_entry_t', , `
DISABLECHECK(`
switch (src->type) {
case XC_TYPE_PHP:
IFCALCCOPY(`DONE(data.php)', `STRUCT_P(xc_entry_data_php_t, data.php)')
IFCALCCOPY(`COPY(data.php)', `STRUCT_P(xc_entry_data_php_t, data.php)')
break;
case XC_TYPE_VAR:

7
processor/string.m4

@ -6,12 +6,12 @@ define(`PROC_STRING_N_EX', `
STRTYPE, `char', `char',
STRTYPE, `zstr_char', `char',
`', `', `UChar'))
pushdef(`ISTYPE', ifelse(STRTYPE,`zstr_uchar',IS_UNICODE,IS_STRING))
pushdef(`ISTYPE', ifelse(PTRTYPE,`UChar',IS_UNICODE,IS_STRING))
pushdef(`UNI_STRLEN', ifelse(
STRTYPE, `zstr_uchar', `xc_zstrlen_uchar',
STRTYPE, `zstr_char', `xc_zstrlen_char',
`', `', `strlen'))
pushdef(`SRCSTR', ifelse(STRTYPE,`char',`ZSTR($2)',`$2'))
pushdef(`SRCSTR', ifelse(STRTYPE,`char',`ZSTR($2)',STRTYPE,`UChar',`ZSTR($2)',`$2'))
pushdef(`SRCPTR', ifelse(
STRTYPE, `zstr_uchar', `ZSTR_U($2)',
STRTYPE, `zstr_char', `ZSTR_S($2)',
@ -87,9 +87,12 @@ define(`PROC_STRING_N_EX', `
dnl }}}
dnl PROC_STRING_N(1:name, 2:size, 3:type)
define(`PROC_STRING_N', `DBG(`$0($*)') DONE(`$1')`'PROC_STRING_N_EX(`dst->$1', `src->$1', `src->$2', `$1', `char')')
define(`PROC_USTRING_N', `DBG(`$0($*)') DONE(`$1')`'PROC_STRING_N_EX(`dst->$1', `src->$1', `src->$2', `$1', `UChar')')
define(`PROC_STRING_L', `DBG(`$0($*)') PROC_STRING_N(`$1', `$2 + 1')')
define(`PROC_USTRING_L', `DBG(`$0($*)') PROC_USTRING_N(`$1', `$2 + 1')')
define(`PROC_STRING', `DBG(`$0($*)') DONE(`$1')`'PROC_STRING_N_EX(`dst->$1', `src->$1', `strlen(src->$1) + 1', `$1', `char')')
define(`PROC_USTRING', `DBG(`$0($*)') DONE(`$1')`'PROC_STRING_N_EX(`dst->$1', `src->$1', `strlen(src->$1) + 1', `$1', `UChar')')
dnl {{{ PROC_ZSTRING_N(1:type, 2:name, 3:size, 4:size_type)
define(`PROC_ZSTRING_N', `

22
processor/struct.m4

@ -164,42 +164,38 @@ define(`STRUCT', `
DONE(`$2')
')
dnl }}}
dnl {{{ STRUCT_ARRAY_I(1:count, 2:type, 3:elm, 4:name=type)
define(`STRUCT_ARRAY_I', `
pushdef(`i', `ii')
STRUCT_ARRAY(`$1', `$2', `$3', `$4')
popdef(`i')
')
dnl }}}
dnl {{{ STRUCT_ARRAY(1:count, 2:type, 3:elm, 4:name=type)
dnl {{{ STRUCT_ARRAY(1:count, 2:type, 3:elm, 4:name=type, 5:loopcounter)
define(`STRUCT_ARRAY', `
if (src->$3) {
ifelse(
`$5', `', `int i; pushdef(`LOOPCOUNTER', `i')',
`', `', `pushdef(`LOOPCOUNTER', `$5')')
pushdefFUNC_NAME(`$2', `$4')
IFDASM(`
zval *arr;
ALLOC_INIT_ZVAL(arr);
array_init(arr);
for (i = 0; i < src->$1; i ++) {
for (LOOPCOUNTER = 0; LOOPCOUNTER < src->$1; LOOPCOUNTER ++) {
zval *zv;
ALLOC_INIT_ZVAL(zv);
array_init(zv);
FUNC_NAME (zv, &(src->$3[i]) TSRMLS_CC);
FUNC_NAME (zv, &(src->$3[LOOPCOUNTER]) TSRMLS_CC);
add_next_index_zval(arr, zv);
}
add_assoc_zval_ex(dst, ZEND_STRS("$3"), arr);
', `
ALLOC(`dst->$3', `$2', `src->$1')
ifdef(`AFTER_ALLOC', AFTER_ALLOC)
for (i = 0; i < src->$1; i ++) {
for (LOOPCOUNTER = 0; LOOPCOUNTER < src->$1; LOOPCOUNTER ++) {
DISABLECHECK(`
ifdef(`BEFORE_LOOP', `BEFORE_LOOP')
STRUCT(`$2', `$3[i]', `$4')
STRUCT(`$2', `$3[LOOPCOUNTER]', `$4')
')
}
')dnl IFDASM
DONE(`$3')
popdef(`FUNC_NAME')
popdef(`LOOPCOUNTER')
}
else {
COPYNULL(`$3')

52
utils.h

@ -37,9 +37,6 @@ static inline int TRACE_DUMMY(const char *fmt, ...)
# endif /* ZEND_WIN32 */
# define IFDEBUG(x) do { } while (0)
# ifndef NDEBUG
# define NDEBUG
# endif
#endif /* XCACHE_DEBUG */
#include <assert.h>
@ -131,3 +128,52 @@ void xc_zend_constant_ctor(zend_constant *c);
void xc_zend_constant_dtor(zend_constant *c);
void xc_copy_internal_zend_constants(HashTable *target, HashTable *source);
#endif
typedef struct {
zend_uint size;
zend_uint cnt;
void *data;
} xc_vector_t;
#define xc_vector_init(type, vector) do { \
(vector)->cnt = 0; \
(vector)->size = 0; \
(vector)->data = NULL; \
} while (0)
#define xc_vector_add(type, vector, value) do { \
if ((vector)->cnt == (vector)->size) { \
if ((vector)->size) { \
(vector)->size <<= 1; \
(vector)->data = erealloc((vector)->data, sizeof(type) * (vector)->size); \
} \
else { \
(vector)->size = 8; \
(vector)->data = emalloc(sizeof(type) * (vector)->size); \
} \
} \
((type *) (vector)->data)[(vector)->cnt++] = value; \
} while (0)
static inline void *xc_vector_detach_impl(xc_vector_t *vector)
{
void *data = vector->data;
vector->data = NULL;
vector->size = 0;
vector->cnt = 0;
return data;
}
#define xc_vector_detach(type, vector) ((type *) xc_vector_detach_impl(vector))
static inline void xc_vector_free_impl(xc_vector_t *vector TSRMLS_DC)
{
if (vector->data) {
efree(vector->data);
}
vector->size = 0;
vector->cnt = 0;
}
#define xc_vector_free(type, vector) xc_vector_free_impl(vector TSRMLS_CC)

289
xcache.c

@ -37,6 +37,14 @@
#include "opcode_spec.h"
#include "utils.h"
#ifndef ZEND_ENGINE_2_3
ZEND_API size_t zend_dirname(char *path, size_t len)
{
php_dirname(path, len);
return strlen(path);
}
#endif
#define VAR_ENTRY_EXPIRED(pentry) ((pentry)->ttl && XG(request_time) > pentry->ctime + (pentry)->ttl)
#define CHECK(x, e) do { if ((x) == NULL) { zend_error(E_ERROR, "XCache: " e); goto err; } } while (0)
#define LOCK(x) xc_lock(x->lck)
@ -1004,6 +1012,7 @@ stat_done:
#endif
{
/* hash on filename, let's expand it to real path */
/* FIXME */
filename = expand_filepath(filename, opened_path_buffer TSRMLS_CC);
if (filename == NULL) {
return FAILURE;
@ -1107,14 +1116,211 @@ static void xc_cache_early_binding_class_cb(zend_op *opline, int oplineno, void
}
/* }}} */
#endif
/* {{{ Constant Usage */
#define xcache_op1_is_file 1
#define xcache_op1_is_dir 2
#define xcache_op2_is_file 4
#define xcache_op2_is_dir 8
typedef struct {
zend_bool filepath_used;
zend_bool dirpath_used;
zend_bool ufilepath_used;
zend_bool udirpath_used;
} xc_const_usage_t;
/* }}} */
static void xc_collect_op_array_info(xc_entry_data_php_t *php, xc_const_usage_t *usage, xc_op_array_info_t *op_array_info, zend_op_array *op_array TSRMLS_DC) /* {{{ */
{
int oplineno;
xc_vector_t vector_int;
xc_vector_init(int, &vector_int);
#define XCACHE_CHECK_OP(type, op) \
if (zend_binary_strcmp(Z_STRVAL(opline->op.u.constant), Z_STRLEN(opline->op.u.constant), php->type##path, php->type##path_len) == 0) { \
usage->type##path_used = 1; \
oplineinfo |= xcache_##op##_is_##type; \
}
#define XCACHE_U_CHECK_OP(type, op) \
if (zend_u_##binary_strcmp(Z_USTRVAL(opline->op.u.constant), Z_USTRLEN(opline->op.u.constant), php->u##type##path, php->u##type##path_len) == 0) { \
usage->u##type##path_used = 1; \
oplineinfo |= xcache_##op##_is_##type; \
}
for (oplineno = 0; oplineno < op_array->last; oplineno++) {
zend_op *opline = &op_array->opcodes[oplineno];
int oplineinfo = 0;
if (opline->op1.op_type == IS_CONST) {
if (Z_TYPE(opline->op1.u.constant) == IS_STRING) {
XCACHE_CHECK_OP(file, op1)
else XCACHE_CHECK_OP(dir, op1)
}
#ifdef IS_UNICODE
else if (Z_TYPE(opline->op1.u.constant) == IS_UNICODE) {
XCACHE_U_CHECK_OP(file, op1)
else XCACHE_U_CHECK_OP(dir, op1)
}
#endif
}
if (opline->op2.op_type == IS_CONST) {
if (Z_TYPE(opline->op2.u.constant) == IS_STRING) {
XCACHE_CHECK_OP(file, op2)
else XCACHE_CHECK_OP(dir, op2)
}
#ifdef IS_UNICODE
else if (Z_TYPE(opline->op2.u.constant) == IS_UNICODE) {
XCACHE_U_CHECK_OP(file, op2)
else XCACHE_U_CHECK_OP(dir, op2)
}
#endif
}
if (oplineinfo) {
xc_vector_add(int, &vector_int, oplineno);
xc_vector_add(int, &vector_int, oplineinfo);
}
}
op_array_info->oplineinfo_cnt = vector_int.cnt;
op_array_info->oplineinfos = xc_vector_detach(int, &vector_int);
xc_vector_free(int, &vector_int);
}
/* }}} */
void xc_fix_op_array_info(const xc_entry_data_php_t *php, zend_op_array *op_array, int copy, const xc_op_array_info_t *op_array_info TSRMLS_DC) /* {{{ */
{
int i;
if (!op_array_info->oplineinfo_cnt) {
return;
}
for (i = 0; i < op_array_info->oplineinfo_cnt; i += 2) {
int oplineno = op_array_info->oplineinfos[i];
int oplineinfo = op_array_info->oplineinfos[i + 1];
zend_op *opline = &op_array->opcodes[oplineno];
if ((oplineinfo & xcache_op1_is_file)) {
assert(opline->op1.op_type == IS_CONST);
if (copy) {
efree(Z_STRVAL(opline->op1.u.constant));
}
if (Z_TYPE(opline->op1.u.constant) == IS_STRING) {
assert(php->filepath);
ZVAL_STRINGL(&opline->op1.u.constant, php->filepath, php->filepath_len, copy);
}
#ifdef IS_UNICODE
else if (Z_TYPE(opline->op1.u.constant) == IS_UNICODE) {
assert(php->ufilepath);
ZVAL_UNICODEL(&opline->op1.u.constant, php->ufilepath, php->ufilepath_len, copy);
}
#endif
else {
assert(0);
}
}
else if ((oplineinfo & xcache_op1_is_dir)) {
assert(opline->op1.op_type == IS_CONST);
if (copy) {
efree(Z_STRVAL(opline->op1.u.constant));
}
if (Z_TYPE(opline->op1.u.constant) == IS_STRING) {
assert(php->dirpath);
ZVAL_STRINGL(&opline->op1.u.constant, php->dirpath, php->dirpath_len, copy);
}
#ifdef IS_UNICODE
else if (Z_TYPE(opline->op1.u.constant) == IS_UNICODE) {
assert(!php->udirpath);
ZVAL_UNICODEL(&opline->op1.u.constant, php->udirpath, php->udirpath_len, copy);
}
#endif
else {
assert(0);
}
}
if ((oplineinfo & xcache_op2_is_file)) {
assert(opline->op2.op_type == IS_CONST);
if (copy) {
efree(Z_STRVAL(opline->op2.u.constant));
}
if (Z_TYPE(opline->op2.u.constant) == IS_STRING) {
assert(php->filepath);
ZVAL_STRINGL(&opline->op2.u.constant, php->filepath, php->filepath_len, copy);
}
#ifdef IS_UNICODE
else if (Z_TYPE(opline->op2.u.constant) == IS_UNICODE) {
assert(php->ufilepath);
ZVAL_UNICODEL(&opline->op2.u.constant, php->ufilepath, php->ufilepath_len, copy);
}
#endif
else {
assert(0);
}
}
else if ((oplineinfo & xcache_op2_is_dir)) {
assert(opline->op2.op_type == IS_CONST);
if (copy) {
efree(Z_STRVAL(opline->op2.u.constant));
}
if (Z_TYPE(opline->op2.u.constant) == IS_STRING) {
assert(!php->dirpath);
ZVAL_STRINGL(&opline->op2.u.constant, php->dirpath, php->dirpath_len, copy);
}
#ifdef IS_UNICODE
else if (Z_TYPE(opline->op2.u.constant) == IS_UNICODE) {
assert(!php->udirpath);
ZVAL_UNICODEL(&opline->op2.u.constant, php->udirpath, php->udirpath_len, copy);
}
#endif
else {
assert(0);
}
}
}
}
/* }}} */
static void xc_free_op_array_info(xc_op_array_info_t *op_array_info TSRMLS_DC) /* {{{ */
{
if (op_array_info->oplineinfos) {
efree(op_array_info->oplineinfos);
}
}
/* }}} */
static void xc_free_php(xc_entry_data_php_t *php TSRMLS_DC) /* {{{ */
{
int i;
if (php->classinfos) {
for (i = 0; i < php->classinfo_cnt; i ++) {
xc_classinfo_t *classinfo = &php->classinfos[i];
int j;
for (j = 0; j < classinfo->methodinfo_cnt; j ++) {
xc_free_op_array_info(&classinfo->methodinfos[j] TSRMLS_CC);
}
if (classinfo->methodinfos) {
efree(classinfo->methodinfos);
}
}
}
if (php->funcinfos) {
for (i = 0; i < php->funcinfo_cnt; i ++) {
xc_free_op_array_info(&php->funcinfos[i].op_array_info TSRMLS_CC);
}
}
xc_free_op_array_info(&php->op_array_info TSRMLS_CC);
#define X_FREE(var) do {\
if (php->var) { \
efree(php->var); \
} \
} while (0)
X_FREE(dirpath);
#ifdef IS_UNICODE
X_FREE(ufilepath);
X_FREE(udirpath);
#endif
#ifdef ZEND_ENGINE_2_1
X_FREE(autoglobals);
#endif
@ -1131,6 +1337,7 @@ static zend_op_array *xc_compile_php(xc_entry_data_php_t *php, zend_file_handle
zend_op_array *op_array;
int old_constinfo_cnt, old_funcinfo_cnt, old_classinfo_cnt;
zend_bool catched = 0;
xc_const_usage_t const_usage;
/* {{{ compile */
TRACE("compiling %s", h->opened_path ? h->opened_path : h->filename);
@ -1161,6 +1368,7 @@ static zend_op_array *xc_compile_php(xc_entry_data_php_t *php, zend_file_handle
/* }}} */
/* {{{ prepare */
zend_restore_compiled_filename(h->opened_path ? h->opened_path : h->filename TSRMLS_CC);
php->op_array = op_array;
#ifdef HAVE_XCACHE_CONSTANT
@ -1206,6 +1414,18 @@ static zend_op_array *xc_compile_php(xc_entry_data_php_t *php, zend_file_handle
#endif
#undef X_ALLOC
/* }}} */
/* {{{ file/dir path init */
memset(&const_usage, 0, sizeof(const_usage));
php->filepath = zend_get_compiled_filename(TSRMLS_C);
php->filepath_len = strlen(php->filepath);
php->dirpath = estrndup(php->filepath, php->filepath_len);
php->dirpath_len = zend_dirname(php->dirpath, php->filepath_len);
#ifdef IS_UNICODE
zend_string_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &php->ufilepath, &php->ufilepath_len, php->filepath, php->filepath_len TSRMLS_CC);
zend_string_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &php->udirpath, &php->udirpath_len, php->dirpath, php->dirpath_len TSRMLS_CC);
#endif
/* }}} */
/* {{{ shallow copy, pointers only */ {
Bucket *b;
unsigned int i;
@ -1241,6 +1461,33 @@ static zend_op_array *xc_compile_php(xc_entry_data_php_t *php, zend_file_handle
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);
for (i = 0; i < php->classinfo_cnt; i ++) {
xc_classinfo_t *classinfo = &php->classinfos[i];
zend_class_entry *ce = CestToCePtr(classinfo->cest);
classinfo->methodinfo_cnt = ce->function_table.nTableSize;
if (classinfo->methodinfo_cnt) {
int j;
ECALLOC_N(classinfo->methodinfos, classinfo->methodinfo_cnt);
if (!classinfo->methodinfos) {
goto err_alloc;
}
for (j = 0, b = ce->function_table.pListHead; b; j ++, b = b->pListNext) {
xc_collect_op_array_info(php, &const_usage, &classinfo->methodinfos[j], (zend_op_array *) b->pData TSRMLS_CC);
}
}
else {
classinfo->methodinfos = NULL;
}
}
for (i = 0; i < php->funcinfo_cnt; i ++) {
xc_collect_op_array_info(php, &const_usage, &php->funcinfos[i].op_array_info, (zend_op_array *) &php->funcinfos[i].func TSRMLS_CC);
}
xc_collect_op_array_info(php, &const_usage, &php->op_array_info, php->op_array TSRMLS_CC);
#undef COPY_H
/* for ZE1, cest need to be fixed inside store */
@ -1270,6 +1517,24 @@ static zend_op_array *xc_compile_php(xc_entry_data_php_t *php, zend_file_handle
#endif
}
/* }}} */
/* {{{ file/dir path free unused */
#define X_FREE_UNUSED(var) \
if (!const_usage.var##path_used) { \
efree(php->var##path); \
php->var##path = NULL; \
php->var##path_len = 0; \
}
if (!const_usage.filepath_used) {
php->filepath = NULL;
php->filepath_len = 0;
}
X_FREE_UNUSED(dir)
#ifdef IS_UNICODE
X_FREE_UNUSED(ufile)
X_FREE_UNUSED(udir)
#endif
#undef X_FREE_UNUSED
/* }}} */
#ifdef E_STRICT
php->compilererrors = ((xc_sandbox_t *) XG(sandbox))->compilererrors;
php->compilererror_cnt = ((xc_sandbox_t *) XG(sandbox))->compilererror_cnt;
@ -1466,6 +1731,8 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
#ifdef ZEND_ENGINE_2_1
php.autoglobals = NULL;
#endif
memset(&php.op_array_info, 0, sizeof(php.op_array_info));
zend_try {
op_array = xc_compile_php(&php, h, type TSRMLS_CC);
} zend_catch {
@ -1637,27 +1904,16 @@ int xc_is_shm(const void *p) /* {{{ */
}
/* }}} */
#ifdef ZEND_ENGINE_2
/* {{{ xc_gc_op_array_t */
typedef struct {
zend_uint num_args;
zend_arg_info *arg_info;
} xc_gc_op_array_t;
/* }}} */
void xc_gc_add_op_array(zend_op_array *op_array TSRMLS_DC) /* {{{ */
void xc_gc_add_op_array(xc_gc_op_array_t *gc_op_array TSRMLS_DC) /* {{{ */
{
xc_gc_op_array_t gc_op_array;
gc_op_array.num_args = op_array->num_args;
gc_op_array.arg_info = op_array->arg_info;
#ifdef ZEND_ENGINE_2
zend_llist_add_element(&XG(gc_op_arrays), (void *) &gc_op_array);
#endif
zend_llist_add_element(&XG(gc_op_arrays), (void *) gc_op_array);
}
/* }}} */
static void xc_gc_op_array(void *pDest) /* {{{ */
{
xc_gc_op_array_t *op_array = (xc_gc_op_array_t *) pDest;
zend_uint i;
#ifdef ZEND_ENGINE_2
if (op_array->arg_info) {
for (i = 0; i < op_array->num_args; i++) {
efree((char *) ZSTR_V(op_array->arg_info[i].name));
@ -1667,9 +1923,12 @@ static void xc_gc_op_array(void *pDest) /* {{{ */
}
efree(op_array->arg_info);
}
#endif
if (op_array->opcodes) {
efree(op_array->opcodes);
}
}
/* }}} */
#endif
/* module helper function */
static int xc_init_constant(int module_number TSRMLS_DC) /* {{{ */

38
xcache.h

@ -63,6 +63,10 @@
# define IS_CONSTANT_TYPE_MASK (~IS_CONSTANT_INDEX)
#endif
#ifndef ZEND_ENGINE_2_3
#define zend_dirname(path, len) xc_dirname(path, len)
#endif
/* {{{ dirty fix for PHP 6 */
#ifdef add_assoc_long_ex
static inline void my_add_assoc_long_ex(zval *arg, char *key, uint key_len, long value)
@ -237,6 +241,12 @@ typedef struct {
zend_ulong hits_by_second[5];
} xc_cache_t;
/* }}} */
/* {{{ xc_op_array_info_t */
typedef struct {
zend_uint oplineinfo_cnt;
int *oplineinfos;
} xc_op_array_info_t;
/* }}} */
/* {{{ xc_classinfo_t */
typedef struct {
#ifdef IS_UNICODE
@ -245,6 +255,8 @@ typedef struct {
zstr key;
zend_uint key_size;
ulong h;
zend_uint methodinfo_cnt;
xc_op_array_info_t *methodinfos;
xc_cest_t cest;
#ifndef ZEND_COMPILE_DELAYED_BINDING
int oplineno;
@ -272,6 +284,7 @@ typedef struct {
zstr key;
zend_uint key_size;
ulong h;
xc_op_array_info_t op_array_info;
zend_function func;
} xc_funcinfo_t;
/* }}} */
@ -310,6 +323,18 @@ struct _xc_entry_data_php_t {
zend_ulong hits; /* hits of this php */
size_t size;
int filepath_len;
char *filepath;
int dirpath_len;
char *dirpath;
#ifdef IS_UNICODE
UChar *ufilepath;
int ufilepath_len;
UChar *udirpath;
int udirpath_len;
#endif
xc_op_array_info_t op_array_info;
zend_op_array *op_array;
#ifdef HAVE_XCACHE_CONSTANT
@ -386,6 +411,17 @@ extern zend_module_entry xcache_module_entry;
int xc_is_rw(const void *p);
int xc_is_ro(const void *p);
int xc_is_shm(const void *p);
void xc_gc_add_op_array(zend_op_array *op_array TSRMLS_DC);
/* {{{ xc_gc_op_array_t */
typedef struct {
#ifdef ZEND_ENGINE_2
zend_uint num_args;
zend_arg_info *arg_info;
#endif
zend_uint last;
zend_op *opcodes;
} xc_gc_op_array_t;
/* }}} */
void xc_gc_add_op_array(xc_gc_op_array_t *gc_op_array TSRMLS_DC);
void xc_fix_op_array_info(const xc_entry_data_php_t *php, zend_op_array *op_array, int shallow_copied, const xc_op_array_info_t *op_array_info TSRMLS_DC);
#endif /* __XCACHE_H */

2
xcache_globals.h

@ -17,9 +17,7 @@ ZEND_BEGIN_MODULE_GLOBALS(xcache)
time_t request_time;
long var_ttl;
#ifdef ZEND_ENGINE_2
zend_llist gc_op_arrays;
#endif
#ifdef HAVE_XCACHE_CONSTANT
HashTable internal_constant_table;

Loading…
Cancel
Save