From efccb81f065b213740955d12e524d197a45d4bf1 Mon Sep 17 00:00:00 2001 From: Xuefer Date: Wed, 10 Jul 2013 06:59:45 +0000 Subject: [PATCH] PHP_5_5: optimizer: support for finally git-svn-id: svn://svn.lighttpd.net/xcache/trunk@1284 c26eb9a1-5813-0410-bd6c-c2e55f420ca7 --- mod_optimizer/xc_optimizer.c | 101 +++++++++++++++++++++++++---------- xcache.c | 3 +- 2 files changed, 73 insertions(+), 31 deletions(-) diff --git a/mod_optimizer/xc_optimizer.c b/mod_optimizer/xc_optimizer.c index e909aae..ee4b517 100644 --- a/mod_optimizer/xc_optimizer.c +++ b/mod_optimizer/xc_optimizer.c @@ -15,6 +15,7 @@ #ifdef XCACHE_DEBUG # include "xc_processor.h" # include "xcache/xc_const_string.h" +# include "xcache/xc_opcode_spec.h" # include "ext/standard/php_var.h" #endif @@ -226,9 +227,9 @@ static int op_get_flowinfo(op_flowinfo_t *fi, zend_op *opline) /* {{{ */ } /* }}} */ #ifdef XCACHE_DEBUG -static void op_snprint(zend_op_array *op_array, char *buf, int size, zend_uchar op_type, znode_op *op) /* {{{ */ +static void op_snprint(zend_op_array *op_array, char *buf, int size, zend_uchar op_type, znode_op *op, xc_op_spec_t op_spec) /* {{{ */ { - switch (op_type) { + switch ((op_spec & OPSPEC_UNUSED) ? IS_UNUSED : op_type) { case IS_CONST: { zval result; @@ -275,17 +276,31 @@ static void op_print(zend_op_array *op_array, int line, zend_op *first, zend_op char buf_r[20]; char buf_1[20]; char buf_2[20]; - op_snprint(op_array, buf_r, sizeof(buf_r), Z_OP_TYPE(opline->result), &opline->result); - op_snprint(op_array, buf_1, sizeof(buf_1), Z_OP_TYPE(opline->op1), &opline->op1); - op_snprint(op_array, buf_2, sizeof(buf_2), Z_OP_TYPE(opline->op2), &opline->op2); + const xc_opcode_spec_t *opcode_spec = xc_get_opcode_spec(opline->opcode); + op_snprint(op_array, buf_r, sizeof(buf_r), Z_OP_TYPE(opline->result), &opline->result, opcode_spec->res); + op_snprint(op_array, buf_1, sizeof(buf_1), Z_OP_TYPE(opline->op1), &opline->op1, opcode_spec->op1); + op_snprint(op_array, buf_2, sizeof(buf_2), Z_OP_TYPE(opline->op2), &opline->op2, opcode_spec->op2); fprintf(stderr, "%3d %3lu" - " %-25s%-5s%-20s%-20s%5lu\r\n" + " %-25s%-8s%-20s%-20s%5lu\n" , opline->lineno, (long) (opline - first + line) , xc_get_opcode(opline->opcode), buf_r, buf_1, buf_2, opline->extended_value); } } /* }}} */ +static void op_array_print_try_catch(zend_op_array *op_array TSRMLS_DC) /* {{{ */ +{ + int i; + for (i = 0; i < op_array->last_try_catch; i ++) { + zend_try_catch_element *element = &op_array->try_catch_array[i]; +# ifdef ZEND_ENGINE_2_5 + fprintf(stderr, "try_catch[%d] = %u, %u, %u, %u\n", i, element->try_op, element->catch_op, element->finally_op, element->finally_end); +# else + fprintf(stderr, "try_catch[%d] = %u, %u\n", i, element->try_op, element->catch_op); +# endif + } +} +/* }}} */ #endif /* @@ -342,9 +357,9 @@ static void bb_print(bb_t *bb, zend_op_array *op_array) /* {{{ */ op_get_flowinfo(&fi, last); fprintf(stderr, - "\r\n==== #%-3d cnt:%-3d lno:%-3d" + "\n==== #%-3d cnt:%-3d lno:%-3d" " %c%c" - " op1:%-3d op2:%-3d ext:%-3d fal:%-3d cat:%-3d fnl:%-3d %s ====\r\n" + " op1:%-3d op2:%-3d ext:%-3d fal:%-3d cat:%-3d fnl:%-3d %s ====\n" , bb->id, bb->count, bb->alloc ? -1 : line , bb->used ? 'U' : ' ', bb->alloc ? 'A' : ' ' , fi.jmpout_op1, fi.jmpout_op2, fi.jmpout_ext, bb->fall, catchbbid, finallybbid, xc_get_opcode(last->opcode) @@ -467,12 +482,10 @@ static int bbs_build_from(bbs_t *bbs, zend_op_array *op_array, int count) /* {{{ zend_try_catch_element *e = &op_array->try_catch_array[i]; for (j = e->try_op; j < e->catch_op; j ++) { oplineinfos[j].catchbbid = oplineinfos[e->catch_op].bbid; - } # ifdef ZEND_ENGINE_2_5 - for (j = e->finally_op; j < e->finally_end; j ++) { oplineinfos[j].finallybbid = oplineinfos[e->finally_op].bbid; - } # endif + } } #ifdef XCACHE_DEBUG for (i = 0; i < count; i ++) { @@ -535,16 +548,16 @@ static int bbs_build_from(bbs_t *bbs, zend_op_array *op_array, int count) /* {{{ /* }}} */ static void bbs_restore_opnum(bbs_t *bbs, zend_op_array *op_array) /* {{{ */ { - int i; + int bbid; bbid_t lasttrybbid; bbid_t lastcatchbbid; #ifdef ZEND_ENGINE_2_5 bbid_t lastfinallybbid; #endif - for (i = 0; i < bbs_count(bbs); i ++) { + for (bbid = 0; bbid < bbs_count(bbs); bbid ++) { op_flowinfo_t fi; - bb_t *bb = bbs_get(bbs, i); + bb_t *bb = bbs_get(bbs, bbid); zend_op *last = bb->opcodes + bb->count - 1; if (op_get_flowinfo(&fi, last) == SUCCESS) { @@ -569,22 +582,52 @@ static void bbs_restore_opnum(bbs_t *bbs, zend_op_array *op_array) /* {{{ */ lastfinallybbid = BBID_INVALID; #endif op_array->last_try_catch = 0; - for (i = 0; i < bbs_count(bbs); i ++) { - bb_t *bb = bbs_get(bbs, i); + for (bbid = 0; bbid < bbs_count(bbs); bbid ++) { + bb_t *bb = bbs_get(bbs, bbid); - if (lastcatchbbid != bb->catch) { - if (lasttrybbid != BBID_INVALID) { - int try_catch_offset = op_array->last_try_catch ++; + if (lastcatchbbid != bb->catch +#ifdef ZEND_ENGINE_2_5 + || lastfinallybbid != bb->finally +#endif + ) { + if (bb->catch != BBID_INVALID +#ifdef ZEND_ENGINE_2_5 + && bb->finally != BBID_INVALID +#endif + ) { + int try_op = bbs_get(bbs, bbid)->opnum; + int catch_op = bbs_get(bbs, bb->catch)->opnum; +#ifdef ZEND_ENGINE_2_5 + int finally_op = bbs_get(bbs, bb->finally)->opnum; +#endif + + zend_bool already_in_try_catch = 0; + zend_uint j; + + for (j = 0; j < op_array->last_try_catch; ++j) { + zend_try_catch_element *element = &op_array->try_catch_array[j]; + if (try_op >= element->try_op && try_op < element->catch_op + && catch_op == element->catch_op +#ifdef ZEND_ENGINE_2_5 + && finally_op == element->finally_op +#endif + ) { + already_in_try_catch = 1; + break; + } + } + if (!already_in_try_catch) { + int try_catch_offset = op_array->last_try_catch ++; - op_array->try_catch_array = erealloc(op_array->try_catch_array, sizeof(zend_try_catch_element) * op_array->last_try_catch); - op_array->try_catch_array[try_catch_offset].try_op = bbs_get(bbs, lasttrybbid)->opnum; - op_array->try_catch_array[try_catch_offset].catch_op = lastcatchbbid != BBID_INVALID ? bbs_get(bbs, lastcatchbbid)->opnum : 0; - assert(lastcatchbbid != BBID_INVALID); + op_array->try_catch_array = erealloc(op_array->try_catch_array, sizeof(zend_try_catch_element) * op_array->last_try_catch); + op_array->try_catch_array[try_catch_offset].try_op = try_op; + op_array->try_catch_array[try_catch_offset].catch_op = catch_op; #ifdef ZEND_ENGINE_2_5 - op_array->try_catch_array[try_catch_offset].finally_op = lastfinallybbid != BBID_INVALID ? bbs_get(bbs, lastfinallybbid)->opnum : 0; + op_array->try_catch_array[try_catch_offset].finally_op = finally_op; #endif + } } - lasttrybbid = i; + lasttrybbid = bbid; lastcatchbbid = bb->catch; #ifdef ZEND_ENGINE_2_5 lastfinallybbid = bb->finally; @@ -607,11 +650,11 @@ static int xc_optimize_op_array(zend_op_array *op_array TSRMLS_DC) /* {{{ */ } #ifdef XCACHE_DEBUG - xc_fix_opcode(op_array TSRMLS_CC); -# if 0 TRACE("optimize file: %s", op_array->filename); +# if 0 && HAVE_XCACHE_DPRINT xc_dprint_zend_op_array(op_array, 0 TSRMLS_CC); # endif + op_array_print_try_catch(op_array TSRMLS_CC); op_print(op_array, 0, op_array->opcodes, op_array->opcodes + op_array->last); #endif @@ -633,12 +676,12 @@ static int xc_optimize_op_array(zend_op_array *op_array TSRMLS_DC) /* {{{ */ } #ifdef XCACHE_DEBUG -# if 0 TRACE("%s", "after compiles"); +# if 0 xc_dprint_zend_op_array(op_array, 0 TSRMLS_CC); # endif + op_array_print_try_catch(op_array TSRMLS_CC); op_print(op_array, 0, op_array->opcodes, op_array->opcodes + op_array->last); - xc_undo_fix_opcode(op_array TSRMLS_CC); #endif return 0; } diff --git a/xcache.c b/xcache.c index 5528998..d5ff9f5 100644 --- a/xcache.c +++ b/xcache.c @@ -206,6 +206,7 @@ PHP_FUNCTION(xcache_get_isref) #ifdef HAVE_XCACHE_DPRINT /* {{{ proto bool xcache_dprint(mixed value) Prints variable (or value) internal struct (debug only) */ +#include "xc_processor.h" PHP_FUNCTION(xcache_dprint) { zval *value; @@ -808,9 +809,7 @@ static PHP_MINIT_FUNCTION(xcache) /* {{{ */ /* must be the first */ xcache_zend_extension_add(&xc_zend_extension_entry, 1); #ifdef HAVE_XCACHE_OPTIMIZER -# ifndef ZEND_ENGINE_2_5 xc_optimizer_startup_module(); -# endif #endif #ifdef HAVE_XCACHE_CACHER xc_cacher_startup_module();