summaryrefslogtreecommitdiff
path: root/Zend/zend_execute.h
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-12-12 09:01:42 +0300
committerDmitry Stogov <dmitry@zend.com>2014-12-12 09:01:42 +0300
commit9ea35a37b9425fc0dc392a754dac7e53791f5521 (patch)
tree5b7a2e6b6dc1e49be998d815738dfad6ce36be7c /Zend/zend_execute.h
parent2ea5f7aea4fe0ab7fe7f931040aebb52d3112999 (diff)
downloadphp-git-9ea35a37b9425fc0dc392a754dac7e53791f5521.tar.gz
Make ZEND_INIT_FCALL keep predcalculted size of necessary stack space in opline->op1.num to avoid its recalculation on each execution.
Diffstat (limited to 'Zend/zend_execute.h')
-rw-r--r--Zend/zend_execute.h29
1 files changed, 21 insertions, 8 deletions
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h
index f13624be47..5ab083e9f2 100644
--- a/Zend/zend_execute.h
+++ b/Zend/zend_execute.h
@@ -143,15 +143,10 @@ static zend_always_inline zval* zend_vm_stack_alloc(size_t size TSRMLS_DC)
return (zval*)top;
}
-static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(uint32_t call_info, zend_function *func, uint32_t num_args, zend_class_entry *called_scope, zend_object *object, zend_execute_data *prev TSRMLS_DC)
+static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame_ex(uint32_t call_info, zend_function *func, uint32_t used_stack, zend_class_entry *called_scope, zend_object *object, zend_execute_data *prev TSRMLS_DC)
{
- uint32_t used_stack = ZEND_CALL_FRAME_SLOT + num_args;
- zend_execute_data *call;
-
- if (ZEND_USER_CODE(func->type)) {
- used_stack += func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args);
- }
- call = (zend_execute_data*)zend_vm_stack_alloc(used_stack * sizeof(zval) TSRMLS_CC);
+ zend_execute_data *call = (zend_execute_data*)zend_vm_stack_alloc(used_stack TSRMLS_CC);
+
call->func = func;
Z_OBJ(call->This) = object;
ZEND_SET_CALL_INFO(call, call_info);
@@ -161,6 +156,24 @@ static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(uint3
return call;
}
+static zend_always_inline uint32_t zend_vm_calc_used_stack(uint32_t num_args, zend_function *func)
+{
+ uint32_t used_stack = ZEND_CALL_FRAME_SLOT + num_args;
+
+ if (ZEND_USER_CODE(func->type)) {
+ used_stack += func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args);
+ }
+ return used_stack * sizeof(zval);
+}
+
+static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(uint32_t call_info, zend_function *func, uint32_t num_args, zend_class_entry *called_scope, zend_object *object, zend_execute_data *prev TSRMLS_DC)
+{
+ uint32_t used_stack = zend_vm_calc_used_stack(num_args, func);
+
+ return zend_vm_stack_push_call_frame_ex(call_info,
+ func, used_stack, called_scope, object, prev TSRMLS_CC);
+}
+
static zend_always_inline void zend_vm_stack_free_extra_args(zend_execute_data *call TSRMLS_DC)
{
uint32_t first_extra_arg = call->func->op_array.num_args - ((call->func->common.fn_flags & ZEND_ACC_VARIADIC) != 0);