summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend_opcode.c10
-rw-r--r--Zend/zend_types.h4
-rw-r--r--Zend/zend_vm_def.h28
-rw-r--r--Zend/zend_vm_execute.h28
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);
}
}