mirror of
https://github.com/php/php-src.git
synced 2024-09-22 10:27:25 +00:00
Implemented Request #76178 (Class constants are slow: they should be inlined at runtime)
Run-time cache is used to eliminate recalculation of constant expression in RECV_INIT opcode (only non reference countable values are cached).
This commit is contained in:
parent
5a31e14beb
commit
1a63fa6ec9
@ -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);
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -740,6 +740,25 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
||||
zend_hash_destroy(&hash);
|
||||
zend_arena_release(&ctx->arena, checkpoint);
|
||||
|
||||
if (1) {
|
||||
opline = op_array->opcodes;
|
||||
while (1) {
|
||||
if (opline->opcode == ZEND_RECV_INIT) {
|
||||
zval *val = &op_array->literals[opline->op2.constant];
|
||||
|
||||
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);
|
||||
}
|
||||
} else if (opline->opcode != ZEND_RECV) {
|
||||
break;
|
||||
}
|
||||
opline++;
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG_COMPACT_LITERALS
|
||||
{
|
||||
int i, use_copy;
|
||||
|
Loading…
Reference in New Issue
Block a user