Keep extra args in the same VM stack segment (after all CV and TMP vars)

This commit is contained in:
Dmitry Stogov 2014-06-27 12:25:36 +04:00
parent 04c87b9961
commit 032f33591a
7 changed files with 24 additions and 39 deletions

View file

@ -436,8 +436,8 @@ ZEND_FUNCTION(func_get_arg)
RETURN_FALSE;
}
if (ex->extra_args && requested_offset >= ex->func->op_array.num_args) {
arg = ex->extra_args + (requested_offset - ex->func->op_array.num_args);
if (requested_offset >= ex->func->op_array.num_args && (ex->num_args > ex->func->op_array.num_args)) {
arg = EX_VAR_NUM_2(ex, ex->func->op_array.last_var + ex->func->op_array.T) + (requested_offset - ex->func->op_array.num_args);
} else {
arg = ZEND_CALL_ARG(ex, requested_offset + 1);
}
@ -469,7 +469,7 @@ ZEND_FUNCTION(func_get_args)
i = 0;
q = Z_ARRVAL_P(return_value)->arData;
p = ZEND_CALL_ARG(ex, 1);
if (ex->extra_args) {
if (ex->num_args > ex->func->op_array.num_args) {
while (i < ex->func->op_array.num_args) {
q->h = i;
q->key = NULL;
@ -482,7 +482,7 @@ ZEND_FUNCTION(func_get_args)
q++;
i++;
}
p = ex->extra_args;
p = EX_VAR_NUM_2(ex, ex->func->op_array.last_var + ex->func->op_array.T);
}
while (i < arg_count) {
q->h = i;
@ -1985,14 +1985,14 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array TS
int i = 0;
zval *p = ZEND_CALL_ARG(call, 1);
if (call->extra_args) {
if (call->func->type == ZEND_USER_FUNCTION && (call->num_args > call->func->op_array.num_args)) {
while (i < call->func->op_array.num_args) {
if (Z_REFCOUNTED_P(p)) Z_ADDREF_P(p);
zend_hash_next_index_insert_new(Z_ARRVAL_P(arg_array), p);
p++;
i++;
}
p = call->extra_args;
p = EX_VAR_NUM_2(call, call->func->op_array.last_var + call->func->op_array.T);
}
while (i < num_args) {

View file

@ -372,7 +372,6 @@ struct _zend_execute_data {
void **run_time_cache;
zend_execute_data *prev_execute_data;
zval *return_value;
zval *extra_args;
vm_frame_kind frame_kind;
zval old_error_reporting;
struct _zend_op *fast_ret; /* used by FAST_CALL/FAST_RET (finally keyword) */

View file

@ -1531,10 +1531,14 @@ void zend_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC) /*
* +----------------------------------------+
* EX_CV_NUM(0) ---------> | VAR[0] = ARG[1] |
* | ... |
* | VAR[op_array->num_args-1] = ARG[N] |
* | ... |
* | VAR[op_array->last_var-1] |
* | VAR[op_array->last_var] |
* | VAR[op_array->last_var] = TMP[0] |
* | ... |
* | VAR[op_array->last_var+op_array->T-1] |
* | ARG[N+1] (extra_args) |
* | ... |
* +----------------------------------------+
*/
@ -1561,9 +1565,9 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
} else {
if (UNEXPECTED(EX(num_args) > op_array->num_args)) {
/* move extra args into separate array */
EX(extra_args) = safe_emalloc(EX(num_args) - op_array->num_args, sizeof(zval), 0);
memcpy(EX(extra_args), EX_VAR_NUM(op_array->num_args), sizeof(zval) * (EX(num_args) - op_array->num_args));
/* move extra args into separate array after all CV and TMP vars */
zval *extra_args = EX_VAR_NUM(op_array->last_var + op_array->T);
memmove(extra_args, EX_VAR_NUM(op_array->num_args), sizeof(zval) * (EX(num_args) - op_array->num_args));
}
do {

View file

@ -210,13 +210,11 @@ static zend_always_inline void zend_vm_stack_extend(int count TSRMLS_DC)
static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(zend_function *func, zend_uint num_args, zend_uint flags, zend_class_entry *called_scope, zend_object *object, zend_execute_data *prev TSRMLS_DC)
{
int used_stack = ZEND_CALL_FRAME_SLOT;
int used_stack = ZEND_CALL_FRAME_SLOT + num_args;
zend_execute_data *call;
if (func && (func->type == ZEND_USER_FUNCTION || func->type == ZEND_EVAL_CODE)) {
used_stack += MAX(func->op_array.last_var + func->op_array.T, num_args);
} else {
used_stack += num_args;
if (func->type == ZEND_USER_FUNCTION || func->type == ZEND_EVAL_CODE) {
used_stack += func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args);
}
ZEND_VM_STACK_GROW_IF_NEEDED(used_stack);
call = (zend_execute_data*)EG(argument_stack)->top;
@ -226,21 +224,19 @@ static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(zend_
call->called_scope = called_scope;
call->object = object;
call->prev_nested_call = prev;
call->extra_args = NULL;
EG(argument_stack)->top += used_stack;
return call;
}
static zend_always_inline void zend_vm_stack_free_extra_args(zend_execute_data *call TSRMLS_DC)
{
if (UNEXPECTED(call->extra_args != NULL)) {
zval *p = call->extra_args + (call->num_args - call->func->op_array.num_args);
zval *end = call->extra_args;
if (UNEXPECTED(call->num_args > call->func->op_array.num_args)) {
zval *end = EX_VAR_NUM_2(call, call->func->op_array.last_var + call->func->op_array.T);
zval *p = end + (call->num_args - call->func->op_array.num_args);
do {
p--;
i_zval_ptr_dtor_nogc(p ZEND_FILE_LINE_CC TSRMLS_CC);
} while (p != end);
efree(end);
}
}
@ -249,22 +245,9 @@ static zend_always_inline void zend_vm_stack_free_args(zend_execute_data *call T
zend_uint num_args = call->num_args;
if (num_args > 0) {
zval *p;
zval *end;
zval *p = ZEND_CALL_ARG(call, num_args + 1);
zval *end = p - num_args;;
if (UNEXPECTED(call->extra_args != NULL)) {
p = call->extra_args + (num_args - call->func->op_array.num_args);
end = call->extra_args;
do {
p--;
i_zval_ptr_dtor_nogc(p ZEND_FILE_LINE_CC TSRMLS_CC);
} while (p != end);
efree(end);
num_args = call->func->op_array.num_args;
}
p = ZEND_CALL_ARG(call, num_args + 1);
end = p - num_args;
do {
p--;
i_zval_ptr_dtor_nogc(p ZEND_FILE_LINE_CC TSRMLS_CC);

View file

@ -911,7 +911,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
ZVAL_UNDEF(fci->retval);
}
}
//??? zend_vm_stack_free_call_frame(EX(call), 0 TSRMLS_CC);
if (Z_OBJ(EG(This))) {
zval_ptr_dtor(&EG(This));

View file

@ -3358,7 +3358,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY)
ZVAL_COPY_VALUE(&tmp, params);
array_init_size(params, arg_count - arg_num + 1);
param = EX(extra_args);
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
zend_verify_arg_type(EX(func), arg_num, &tmp, opline->extended_value TSRMLS_CC);
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), &tmp);

View file

@ -949,7 +949,7 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
ZVAL_COPY_VALUE(&tmp, params);
array_init_size(params, arg_count - arg_num + 1);
param = EX(extra_args);
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
zend_verify_arg_type(EX(func), arg_num, &tmp, opline->extended_value TSRMLS_CC);
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), &tmp);