Hi:
Attached is a patch that adds an optional 'limit' parameter to
debug_backtrace, which limits the size of the returned array. In cases
where a script wants debug information only for the current function, or
for the function <n> levels above that, we can save a lot of unnecessary
call-stack traversal and zval allocation by bailing out early. For a
sufficiently large call depth and a small <n>, I'd expect this to
improve performance quite a bit.
The patch adds a total of six lines to the function, and one test in the
main loop for the zero-argument case. Should apply cleanly to both PHP_4_3
and HEAD.
Is there any chance this could be applied? :)
Thanks in advance,
- Dave
dave@codewhore.org
--- Zend/zend_builtin_functions.c~ 2003-05-20 11:33:36.000000000 -0400
+++ Zend/zend_builtin_functions.c 2003-05-20 13:34:40.000000000 -0400
@@ -1173,7 +1173,7 @@
return arg_array;
}
-/* {{{ proto void debug_backtrace(void)
+/* {{{ proto void debug_backtrace([int limit])
Prints out a backtrace */
ZEND_FUNCTION(debug_backtrace)
{
@@ -1189,11 +1189,18 @@
void **args = cur_arg_pos;
int arg_stack_consistent = 0;
int frames_on_stack = 0;
- zval **limit_zval = NULL;
- long limit;
- if (ZEND_NUM_ARGS()) {
-
if (ZEND_NUM_ARGS() > 1) {
ZEND_WRONG_PARAM_COUNT();
} -
if (ZEND_NUM_ARGS() == 1 && zend_get_parameters_ex(1, &limit_zval) == SUCCESS) {
-
convert_to_long_ex(limit_zval); -
limit = (*limit_zval)->value.lval; -
}
-
while (--args >= EG(argument_stack).elements) {
if (*args--) {
break;
@@ -1217,6 +1224,9 @@
array_init(return_value);while (ptr) {
-
if (limit_zval && --limit < 0) -
break; -
MAKE_STD_ZVAL(stack_frame); array_init(stack_frame);
| Hi:
| <patch>
Or, so as to not turn this into the Integer Overflow and Crappy C
Competition (IOCCC <grin>), perhaps this instead:
--- Zend/zend_builtin_functions.c~ 2003-05-20 11:33:36.000000000 -0400
+++ Zend/zend_builtin_functions.c 2003-05-20 15:31:09.000000000 -0400
@@ -1173,7 +1173,7 @@
return arg_array;
}
-/* {{{ proto void debug_backtrace(void)
+/* {{{ proto void debug_backtrace([int limit])
Prints out a backtrace */
ZEND_FUNCTION(debug_backtrace)
{
@@ -1189,11 +1189,21 @@
void **args = cur_arg_pos;
int arg_stack_consistent = 0;
int frames_on_stack = 0;
- zval **limit_zval = NULL;
- long limit;
- if (ZEND_NUM_ARGS()) {
-
if (ZEND_NUM_ARGS() > 1) {
ZEND_WRONG_PARAM_COUNT();
} -
if (ZEND_NUM_ARGS() == 1 && zend_get_parameters_ex(1, &limit_zval) == SUCCESS) {
-
convert_to_long_ex(limit_zval); -
if ((limit = (*limit_zval)->value.lval) <= 0) { -
zend_error(E_WARNING, "Limit must be a non-zero positive integer"); -
return; -
} -
}
-
while (--args >= EG(argument_stack).elements) {
if (*args--) {
break;
@@ -1217,6 +1227,9 @@
array_init(return_value);while (ptr) {
-
if (limit_zval && --limit < 0) -
break; -
MAKE_STD_ZVAL(stack_frame); array_init(stack_frame);
Thanks,
- Dave
dave@codewhore.org