|
|
|
@ -10,9 +10,9 @@ |
|
|
|
|
|
|
|
|
|
#include "stack.h" |
|
|
|
|
#include "xcache_globals.h" |
|
|
|
|
#include "coverage.h" |
|
|
|
|
#include "coverager.h" |
|
|
|
|
#include "utils.h" |
|
|
|
|
typedef HashTable *coverage_t; |
|
|
|
|
typedef HashTable *coverager_t; |
|
|
|
|
#define PCOV_HEADER_MAGIC 0x564f4350 |
|
|
|
|
|
|
|
|
|
char *xc_coveragedump_dir = NULL; |
|
|
|
@ -22,7 +22,7 @@ static zend_compile_file_t *origin_compile_file; |
|
|
|
|
/* dumper */ |
|
|
|
|
static void xc_destroy_coverage(void *pDest) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
coverage_t cov = *(coverage_t*) pDest; |
|
|
|
|
coverager_t cov = *(coverager_t*) pDest; |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
fprintf(stderr, "destroy %p\n", cov); |
|
|
|
|
#endif |
|
|
|
@ -64,7 +64,7 @@ void xcache_mkdirs_ex(char *root, int rootlen, char *path, int pathlen TSRMLS_DC |
|
|
|
|
free_alloca(fullpath); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static void xc_coverage_save_cov(char *srcfile, char *outfilename, coverage_t cov TSRMLS_DC) /* {{{ */ |
|
|
|
|
static void xc_coverager_save_cov(char *srcfile, char *outfilename, coverager_t cov TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
long *buf = NULL, *p; |
|
|
|
|
long covlines, *phits; |
|
|
|
@ -192,7 +192,7 @@ bailout: |
|
|
|
|
if (buf) efree(buf); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
void xc_coverage_request_init(TSRMLS_D) /* {{{ */ |
|
|
|
|
void xc_coverager_request_init(TSRMLS_D) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
if (XG(coveragedumper)) { |
|
|
|
|
XG(coverages) = emalloc(sizeof(HashTable)); |
|
|
|
@ -200,9 +200,9 @@ void xc_coverage_request_init(TSRMLS_D) /* {{{ */ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
void xc_coverage_request_shutdown(TSRMLS_D) /* {{{ */ |
|
|
|
|
void xc_coverager_request_shutdown(TSRMLS_D) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
coverage_t *pcov; |
|
|
|
|
coverager_t *pcov; |
|
|
|
|
zstr s; |
|
|
|
|
char *outfilename; |
|
|
|
|
int dumpdir_len, outfilelen, size, alloc_len = 0; |
|
|
|
@ -230,7 +230,7 @@ void xc_coverage_request_shutdown(TSRMLS_D) /* {{{ */ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
fprintf(stderr, "outfilename %s\n", outfilename); |
|
|
|
|
#endif |
|
|
|
|
xc_coverage_save_cov(ZSTR_S(s), outfilename, *pcov TSRMLS_CC); |
|
|
|
|
xc_coverager_save_cov(ZSTR_S(s), outfilename, *pcov TSRMLS_CC); |
|
|
|
|
zend_hash_move_forward(XG(coverages)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -242,10 +242,10 @@ void xc_coverage_request_shutdown(TSRMLS_D) /* {{{ */ |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
/* helper func to store hits into coverages */ |
|
|
|
|
static coverage_t xc_coverage_get(char *filename TSRMLS_DC) /* {{{ */ |
|
|
|
|
static coverager_t xc_coverager_get(char *filename TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
int len = strlen(filename) + 1; |
|
|
|
|
coverage_t cov, *pcov; |
|
|
|
|
coverager_t cov, *pcov; |
|
|
|
|
|
|
|
|
|
if (zend_hash_find(XG(coverages), filename, len, (void **) &pcov) == SUCCESS) { |
|
|
|
|
#ifdef DEBUG |
|
|
|
@ -264,7 +264,7 @@ static coverage_t xc_coverage_get(char *filename TSRMLS_DC) /* {{{ */ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static void xc_coverage_add_hits(HashTable *cov, long line, long hits TSRMLS_DC) /* {{{ */ |
|
|
|
|
static void xc_coverager_add_hits(HashTable *cov, long line, long hits TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
long *poldhits; |
|
|
|
|
|
|
|
|
@ -284,7 +284,7 @@ static void xc_coverage_add_hits(HashTable *cov, long line, long hits TSRMLS_DC) |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
static int xc_coverage_get_op_array_size_no_tail(zend_op_array *op_array) /* {{{ */ |
|
|
|
|
static int xc_coverager_get_op_array_size_no_tail(zend_op_array *op_array) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
zend_uint size; |
|
|
|
|
|
|
|
|
@ -308,18 +308,18 @@ static int xc_coverage_get_op_array_size_no_tail(zend_op_array *op_array) /* {{{ |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
/* prefill */ |
|
|
|
|
static int xc_coverage_init_op_array(zend_op_array *op_array TSRMLS_DC) /* {{{ */ |
|
|
|
|
static int xc_coverager_init_op_array(zend_op_array *op_array TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
zend_uint size; |
|
|
|
|
coverage_t cov; |
|
|
|
|
coverager_t cov; |
|
|
|
|
zend_uint i; |
|
|
|
|
|
|
|
|
|
if (op_array->type != ZEND_USER_FUNCTION) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
size = xc_coverage_get_op_array_size_no_tail(op_array); |
|
|
|
|
cov = xc_coverage_get(op_array->filename TSRMLS_CC); |
|
|
|
|
size = xc_coverager_get_op_array_size_no_tail(op_array); |
|
|
|
|
cov = xc_coverager_get(op_array->filename TSRMLS_CC); |
|
|
|
|
for (i = 0; i < size; i ++) { |
|
|
|
|
switch (op_array->opcodes[i].opcode) { |
|
|
|
|
case ZEND_EXT_STMT: |
|
|
|
@ -327,19 +327,19 @@ static int xc_coverage_init_op_array(zend_op_array *op_array TSRMLS_DC) /* {{{ * |
|
|
|
|
case ZEND_EXT_FCALL_BEGIN: |
|
|
|
|
case ZEND_EXT_FCALL_END: |
|
|
|
|
#endif |
|
|
|
|
xc_coverage_add_hits(cov, op_array->opcodes[i].lineno, -1 TSRMLS_CC); |
|
|
|
|
xc_coverager_add_hits(cov, op_array->opcodes[i].lineno, -1 TSRMLS_CC); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static void xc_coverage_init_compile_result(zend_op_array *op_array TSRMLS_DC) /* {{{ */ |
|
|
|
|
static void xc_coverager_init_compile_result(zend_op_array *op_array TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
xc_compile_result_t cr; |
|
|
|
|
|
|
|
|
|
xc_compile_result_init_cur(&cr, op_array TSRMLS_CC); |
|
|
|
|
xc_apply_op_array(&cr, (apply_func_t) xc_coverage_init_op_array TSRMLS_CC); |
|
|
|
|
xc_apply_op_array(&cr, (apply_func_t) xc_coverager_init_op_array TSRMLS_CC); |
|
|
|
|
xc_compile_result_free(&cr); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
@ -349,29 +349,29 @@ static zend_op_array *xc_compile_file_for_coverage(zend_file_handle *h, int type |
|
|
|
|
|
|
|
|
|
op_array = origin_compile_file(h, type TSRMLS_CC); |
|
|
|
|
if (XG(coveragedumper) && XG(coverages)) { |
|
|
|
|
xc_coverage_init_compile_result(op_array TSRMLS_CC); |
|
|
|
|
xc_coverager_init_compile_result(op_array TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
return op_array; |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
/* hits */ |
|
|
|
|
void xc_coverage_handle_ext_stmt(zend_op_array *op_array, zend_uchar op) /* {{{ */ |
|
|
|
|
void xc_coverager_handle_ext_stmt(zend_op_array *op_array, zend_uchar op) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
TSRMLS_FETCH(); |
|
|
|
|
|
|
|
|
|
if (XG(coveragedumper) && XG(coverages)) { |
|
|
|
|
int size = xc_coverage_get_op_array_size_no_tail(op_array); |
|
|
|
|
int size = xc_coverager_get_op_array_size_no_tail(op_array); |
|
|
|
|
int oplineno = (*EG(opline_ptr)) - op_array->opcodes; |
|
|
|
|
if (oplineno < size) { |
|
|
|
|
xc_coverage_add_hits(xc_coverage_get(op_array->filename TSRMLS_CC), (*EG(opline_ptr))->lineno, 1 TSRMLS_CC); |
|
|
|
|
xc_coverager_add_hits(xc_coverager_get(op_array->filename TSRMLS_CC), (*EG(opline_ptr))->lineno, 1 TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
/* init/destroy */ |
|
|
|
|
int xc_coverage_init(int module_number TSRMLS_DC) /* {{{ */ |
|
|
|
|
int xc_coverager_init(int module_number TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
if (xc_coveragedump_dir) { |
|
|
|
|
int len = strlen(xc_coveragedump_dir); |
|
|
|
@ -389,7 +389,7 @@ int xc_coverage_init(int module_number TSRMLS_DC) /* {{{ */ |
|
|
|
|
return SUCCESS; |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
void xc_coverage_destroy() /* {{{ */ |
|
|
|
|
void xc_coverager_destroy() /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
if (origin_compile_file == xc_compile_file_for_coverage) { |
|
|
|
|
zend_compile_file = origin_compile_file; |
|
|
|
@ -402,7 +402,7 @@ void xc_coverage_destroy() /* {{{ */ |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
/* user api */ |
|
|
|
|
PHP_FUNCTION(xcache_coverage_decode) /* {{{ */ |
|
|
|
|
PHP_FUNCTION(xcache_coverager_decode) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
char *str; |
|
|
|
|
int len; |
|
|
|
@ -421,7 +421,7 @@ PHP_FUNCTION(xcache_coverage_decode) /* {{{ */ |
|
|
|
|
} |
|
|
|
|
if (*p++ != PCOV_HEADER_MAGIC) { |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
fprintf(stderr, "wrong magic in xcache_coverage_decode"); |
|
|
|
|
fprintf(stderr, "wrong magic in xcache_coverager_decode"); |
|
|
|
|
#endif |
|
|
|
|
return; |
|
|
|
|
} |