From: Bob Weinand Date: Sun, 1 Dec 2013 18:05:30 +0000 (+0100) Subject: Separated opline address improvements from this branch X-Git-Tag: php-5.6.0alpha1~110^2~34 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=518519b8ed6f7f710252840e4630cc68db69bc26;p=php Separated opline address improvements from this branch --- diff --git a/phpdbg.c b/phpdbg.c index 52efd4338b..ce7a0b3184 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -142,7 +142,6 @@ static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */ zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], 8, NULL, php_phpdbg_destroy_bp_condition, 0); zend_hash_init(&PHPDBG_G(seek), 8, NULL, NULL, 0); zend_hash_init(&PHPDBG_G(registered), 8, NULL, php_phpdbg_destroy_registered, 0); - PHPDBG_G(opline_btree) = NULL; return SUCCESS; } /* }}} */ @@ -471,7 +470,6 @@ static sapi_module_struct phpdbg_sapi_module = { void phpdbg_op_array_handler(zend_op_array *op_array) { TSRMLS_FETCH(); - phpdbg_save_oplines(op_array TSRMLS_CC); phpdbg_resolve_op_array_breaks(op_array TSRMLS_CC); } diff --git a/phpdbg.h b/phpdbg.h index cd71cfd512..238caa8d4e 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -146,21 +146,8 @@ #define PHPDBG_IO_FDS 3 /* }}} */ /* {{{ structs */ -typedef union _phpdbg_btree phpdbg_btree; -union _phpdbg_btree { - phpdbg_btree *branches[2]; - struct { - char *func_name; - zend_uint func_len; - char *class_name; - zend_uint class_len; - zend_uint last; - } info; -}; - ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HashTable bp[PHPDBG_BREAK_TABLES]; /* break points */ - phpdbg_btree *opline_btree; /* opline root -> op_array */ HashTable registered; /* registered */ HashTable seek; /* seek oplines */ phpdbg_frame_t frame; /* frame */ diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 2e51abffec..0ecd796e5e 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -268,181 +268,22 @@ PHPDBG_API void phpdbg_set_breakpoint_method(const char* class_name, const char* efree(lcname); } /* }}} */ -PHPDBG_API void phpdbg_save_oplines(zend_op_array *op_array TSRMLS_DC) { - phpdbg_btree **branch = &PHPDBG_G(opline_btree); - int i = sizeof(void *) * 8 - 1; - - do { - if (*branch == NULL) { - break; - } - branch = &(*branch)->branches[((zend_ulong)op_array->opcodes >> i) % 2]; - } while (i--); - - if (*branch == NULL) { - phpdbg_btree *memory = *branch = emalloc((i + 2) * sizeof(phpdbg_btree)); - do { - (*branch)->branches[!(((zend_ulong)op_array->opcodes >> i) % 2)] = NULL; - branch = &(*branch)->branches[((zend_ulong)op_array->opcodes >> i) % 2]; - *branch = ++memory; - } while (i--); - } - - if (((*branch)->info.func_name = op_array->function_name)) { - (*branch)->info.func_len = strlen(op_array->function_name); - if (op_array->scope) { - (*branch)->info.class_name = op_array->scope->name; - (*branch)->info.class_len = op_array->scope->name_length; - } else { - (*branch)->info.class_name = NULL; - (*branch)->info.class_len = 0; - } - } else { - (*branch)->info.func_len = 0; - (*branch)->info.class_name = op_array->filename; - (*branch)->info.class_len = strlen(op_array->filename); - } - (*branch)->info.last = op_array->last; -} - PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{ */ { - if (PHPDBG_G(opline_btree) == NULL) { - phpdbg_error("No oplines initialized yet"); - return; - } - if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline)) { phpdbg_breakline_t new_break; - phpdbg_breakopline_t opline_break; - int i = sizeof(void *) * 8 - 1, last_superior_i = -1; - phpdbg_btree *branch = PHPDBG_G(opline_btree); - HashTable *insert = &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]; - HashTable func_breaks, *func_table = EG(function_table); - zend_ulong opcodes = 0; - - /* get highest opcodes root lower than or eqal to opline */ -#define CHOOSE_BRANCH(n) \ - opcodes = (opcodes << 1) + !!(n); \ - branch = branch->branches[!!(n)]; - - do { - /* an impossible branch was found if: */ - if ((opline >> i) % 2 == 0 && !branch->branches[0]) { - /* there's no lower branch than opline */ - if (last_superior_i == -1) { - phpdbg_error("No opline could be found at 0x%lx", opline); - return; - } - /* reset state */ - branch = PHPDBG_G(opline_btree); - opcodes = 0; - i = sizeof(void *) * 8 - 1; - /* follow branch according to bits in opline until the last lower branch before the impossible branch */ - do { - CHOOSE_BRANCH((opline >> i) % 2 == 1 && branch->branches[1]); - } while (--i > last_superior_i); - /* use now the lower branch of which we can be sure that it contains only branches lower than opline */ - CHOOSE_BRANCH(0); - /* and choose the highest possible branch in the branch containing only branches lower than opline */ - while (i--) { - CHOOSE_BRANCH(branch->branches[1]); - } - break; - } - /* follow branch according to bits in opline until having found an impossible branch */ - if ((opline >> i) % 2 == 1 && branch->branches[1]) { - if (branch->branches[0]) { - last_superior_i = i; - } - CHOOSE_BRANCH(1); - } else { - CHOOSE_BRANCH(0); - } - } while (i--); - - /* make sure that opline is an opcode address in the closest zend_op array */ - if (opcodes + branch->info.last * sizeof(zend_op) <= opline || - (opline - opcodes) % sizeof(zend_op) > 0) { - phpdbg_error("No opline could be found at 0x%lx; the closest opline is at 0x%lx (%s %s%s%s) with size %ld", - opline, - opcodes, - branch->info.func_name?(branch->info.class_name?"method":"function"):"file", - branch->info.func_name?branch->info.func_name:"", - branch->info.func_name&&branch->info.class_name?"::":"", - branch->info.class_name?branch->info.class_name:"", - branch->info.last); - return; - } - - opline_break.opline = (opline - opcodes) / sizeof(zend_op); PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP; - opline_break.func_len = branch->info.func_len; - opline_break.func_name = branch->info.func_name; - opline_break.id = PHPDBG_G(bp_count)++; - if (branch->info.func_name == NULL) { - opline_break.func_len = branch->info.class_len; - opline_break.func_name = branch->info.class_name; - - insert = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE]; - PHPDBG_G(flags) |= PHPDBG_HAS_FILE_OPLINE_BP; - new_break.type = PHPDBG_BREAK_FILE_OPLINE; - } else if (branch->info.class_name) { - HashTable class_breaks, *class_table; - - if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], - branch->info.class_name, - branch->info.class_len, - (void **)&class_table - ) == FAILURE) { - zend_hash_init(&class_breaks, 8, NULL, phpdbg_opline_class_breaks_dtor, 0); - zend_hash_update( - &PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], - branch->info.class_name, - branch->info.class_len, - (void **)&class_breaks, sizeof(HashTable), (void **)&class_table); - } - - opline_break.class_len = branch->info.class_len; - opline_break.class_name = branch->info.class_name; - - insert = class_table; - PHPDBG_G(flags) |= PHPDBG_HAS_METHOD_OPLINE_BP; - new_break.type = PHPDBG_BREAK_METHOD_OPLINE; - } else { - PHPDBG_G(flags) |= PHPDBG_HAS_FUNCTION_OPLINE_BP; - new_break.type = PHPDBG_BREAK_FUNCTION_OPLINE; - } - - if (zend_hash_find(insert, opline_break.func_name, opline_break.func_len, (void **)&func_table) == FAILURE) { - zend_hash_init(&func_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0); - zend_hash_update( - insert, - opline_break.func_name, - opline_break.func_len, - (void **)&func_breaks, sizeof(HashTable), (void **)&func_table); - } - - /* insert opline num breakpoint information */ - zend_hash_index_update(func_table, opline_break.opline, &opline_break, sizeof(phpdbg_breakopline_t), NULL); - - /* insert opline breakpoint */ new_break.name = NULL; new_break.opline = opline; - new_break.id = opline_break.id; /* use same id to identify */ + new_break.id = PHPDBG_G(bp_count)++; + zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline, &new_break, sizeof(phpdbg_breakline_t), NULL); - phpdbg_notice("Breakpoint #%d added at %#lx (opcode #%ld in %s %s%s%s)", - new_break.id, - new_break.opline, - (opline - opcodes) / sizeof(zend_op), - branch->info.func_name?(branch->info.class_name?"method":"function"):"file", - branch->info.func_name?branch->info.func_name:"", - branch->info.func_name&&branch->info.class_name?"::":"", - branch->info.class_name?branch->info.class_name:""); + phpdbg_notice("Breakpoint #%d added at %#lx", + new_break.id, new_break.opline); } else { phpdbg_notice("Breakpoint exists at %#lx", opline); } diff --git a/phpdbg_bp.h b/phpdbg_bp.h index 5f8ed6622a..1aec77b545 100644 --- a/phpdbg_bp.h +++ b/phpdbg_bp.h @@ -92,8 +92,6 @@ typedef struct _phpdbg_breakcond_t { int id; } phpdbg_breakcond_t; -PHPDBG_API void phpdbg_save_oplines(zend_op_array *op_array TSRMLS_DC); - PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC); PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_op_array *op_array TSRMLS_DC); PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRMLS_DC);