diff options
Diffstat (limited to 'Zend')
| -rw-r--r-- | Zend/zend_opcode.c | 10 | ||||
| -rw-r--r-- | Zend/zend_types.h | 4 | ||||
| -rw-r--r-- | Zend/zend_vm_def.h | 28 | ||||
| -rw-r--r-- | Zend/zend_vm_execute.h | 28 |
4 files changed, 56 insertions, 14 deletions
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index f534808321..869baae020 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -579,6 +579,16 @@ ZEND_API int pass_two(zend_op_array *op_array) end = opline + op_array->last; while (opline < end) { switch (opline->opcode) { + case ZEND_RECV_INIT: + { + zval *val = CT_CONSTANT(opline->op2); + if (Z_TYPE_P(val) == IS_CONSTANT_AST) { + uint32_t slot = ZEND_MM_ALIGNED_SIZE_EX(op_array->cache_size, 8); + Z_CACHE_SLOT_P(val) = slot; + op_array->cache_size += sizeof(zval); + } + } + break; case ZEND_FAST_CALL: opline->op1.opline_num = op_array->try_catch_array[opline->op1.num].finally_op; ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1); diff --git a/Zend/zend_types.h b/Zend/zend_types.h index b0a1ce589d..a57f5ae8fe 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -192,6 +192,7 @@ struct _zval_struct { } u1; union { uint32_t next; /* hash collision chain */ + uint32_t cache_slot; /* cache slot (for RECV_INIT) */ uint32_t opline_num; /* opline number (for FAST_CALL) */ uint32_t lineno; /* line number (for ast nodes) */ uint32_t num_args; /* arguments number for EX(This) */ @@ -404,6 +405,9 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_NEXT(zval) (zval).u2.next #define Z_NEXT_P(zval_p) Z_NEXT(*(zval_p)) +#define Z_CACHE_SLOT(zval) (zval).u2.cache_slot +#define Z_CACHE_SLOT_P(zval_p) Z_CACHE_SLOT(*(zval_p)) + #define Z_LINENO(zval) (zval).u2.lineno #define Z_LINENO_P(zval_p) Z_LINENO(*(zval_p)) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index cad1ca2ebc..d756e97bc9 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4724,14 +4724,28 @@ ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST, CACHE_SLOT) arg_num = opline->op1.num; param = _get_zval_ptr_cv_undef_BP_VAR_W(opline->result.var EXECUTE_DATA_CC); if (arg_num > EX_NUM_ARGS()) { - ZVAL_COPY(param, RT_CONSTANT(opline, opline->op2)); - if (Z_OPT_TYPE_P(param) == IS_CONSTANT_AST) { - SAVE_OPLINE(); - if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) { - zval_ptr_dtor_nogc(param); - ZVAL_UNDEF(param); - HANDLE_EXCEPTION(); + zval *default_value = RT_CONSTANT(opline, opline->op2); + + if (Z_OPT_TYPE_P(default_value) == IS_CONSTANT_AST) { + zval *cache_val = (zval*)CACHE_ADDR(Z_CACHE_SLOT_P(default_value)); + + /* we keep in cache only not refcounted values */ + if (Z_TYPE_P(cache_val) != IS_UNDEF) { + ZVAL_COPY_VALUE(param, cache_val); + } else { + SAVE_OPLINE(); + ZVAL_COPY(param, default_value); + if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) { + zval_ptr_dtor_nogc(param); + ZVAL_UNDEF(param); + HANDLE_EXCEPTION(); + } + if (!Z_REFCOUNTED_P(param)) { + ZVAL_COPY_VALUE(cache_val, param); + } } + } else { + ZVAL_COPY(param, default_value); } } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 2fbbf0fb21..c72ebebc72 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2237,14 +2237,28 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CON arg_num = opline->op1.num; param = _get_zval_ptr_cv_undef_BP_VAR_W(opline->result.var EXECUTE_DATA_CC); if (arg_num > EX_NUM_ARGS()) { - ZVAL_COPY(param, RT_CONSTANT(opline, opline->op2)); - if (Z_OPT_TYPE_P(param) == IS_CONSTANT_AST) { - SAVE_OPLINE(); - if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) { - zval_ptr_dtor_nogc(param); - ZVAL_UNDEF(param); - HANDLE_EXCEPTION(); + zval *default_value = RT_CONSTANT(opline, opline->op2); + + if (Z_OPT_TYPE_P(default_value) == IS_CONSTANT_AST) { + zval *cache_val = (zval*)CACHE_ADDR(Z_CACHE_SLOT_P(default_value)); + + /* we keep in cache only not refcounted values */ + if (Z_TYPE_P(cache_val) != IS_UNDEF) { + ZVAL_COPY_VALUE(param, cache_val); + } else { + SAVE_OPLINE(); + ZVAL_COPY(param, default_value); + if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) { + zval_ptr_dtor_nogc(param); + ZVAL_UNDEF(param); + HANDLE_EXCEPTION(); + } + if (!Z_REFCOUNTED_P(param)) { + ZVAL_COPY_VALUE(cache_val, param); + } } + } else { + ZVAL_COPY(param, default_value); } } |
