Browse Source

Use cache_slot offsets instead of indexes (simplify run-time instructions)

pull/1044/merge
Dmitry Stogov 11 years ago
parent
commit
5f278e4d3a
  1. 7
      Zend/zend_compile.c
  2. 2
      Zend/zend_compile.h
  3. 11
      Zend/zend_execute.c
  4. 16
      Zend/zend_execute.h
  5. 2
      Zend/zend_opcode.c
  6. 44
      Zend/zend_vm_def.h
  7. 450
      Zend/zend_vm_execute.h
  8. 10
      ext/opcache/Optimizer/compact_literals.c
  9. 20
      ext/opcache/Optimizer/zend_optimizer.c

7
Zend/zend_compile.c

@ -52,15 +52,16 @@
static inline void zend_alloc_cache_slot(uint32_t literal) {
zend_op_array *op_array = CG(active_op_array);
Z_CACHE_SLOT(op_array->literals[literal]) = op_array->last_cache_slot++;
Z_CACHE_SLOT(op_array->literals[literal]) = op_array->cache_size;
op_array->cache_size += sizeof(void*);
}
#define POLYMORPHIC_CACHE_SLOT_SIZE 2
static inline void zend_alloc_polymorphic_cache_slot(uint32_t literal) {
zend_op_array *op_array = CG(active_op_array);
Z_CACHE_SLOT(op_array->literals[literal]) = op_array->last_cache_slot;
op_array->last_cache_slot += POLYMORPHIC_CACHE_SLOT_SIZE;
Z_CACHE_SLOT(op_array->literals[literal]) = op_array->cache_size;
op_array->cache_size += POLYMORPHIC_CACHE_SLOT_SIZE * sizeof(void*);
}
ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type);

2
Zend/zend_compile.h

@ -352,7 +352,7 @@ struct _zend_op_array {
int last_literal;
zval *literals;
int last_cache_slot;
int cache_size;
void **run_time_cache;
void *reserved[ZEND_MAX_RESERVED_RESOURCES];

11
Zend/zend_execute.c

@ -1804,7 +1804,8 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu
}
if (UNEXPECTED(!op_array->run_time_cache)) {
op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
op_array->run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size);
memset(op_array->run_time_cache, 0, op_array->cache_size);
}
EX_LOAD_RUN_TIME_CACHE(op_array);
EX_LOAD_LITERALS(op_array);
@ -1829,7 +1830,8 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu
}
if (!op_array->run_time_cache) {
op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
op_array->run_time_cache = emalloc(op_array->cache_size);
memset(op_array->run_time_cache, 0, op_array->cache_size);
}
EX_LOAD_RUN_TIME_CACHE(op_array);
EX_LOAD_LITERALS(op_array);
@ -1906,10 +1908,11 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
if (!op_array->run_time_cache) {
if (op_array->function_name) {
op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
op_array->run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size);
} else {
op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
op_array->run_time_cache = emalloc(op_array->cache_size);
}
memset(op_array->run_time_cache, 0, op_array->cache_size);
}
EX_LOAD_RUN_TIME_CACHE(op_array);
EX_LOAD_LITERALS(op_array);

16
Zend/zend_execute.h

@ -256,21 +256,25 @@ ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS);
ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table);
void zend_free_compiled_variables(zend_execute_data *execute_data);
#define CACHE_ADDR(num) \
((void**)((char*)EX_RUN_TIME_CACHE() + (num)))
#define CACHED_PTR(num) \
EX_RUN_TIME_CACHE()[(num)]
((void**)((char*)EX_RUN_TIME_CACHE() + (num)))[0]
#define CACHE_PTR(num, ptr) do { \
EX_RUN_TIME_CACHE()[(num)] = (ptr); \
((void**)((char*)EX_RUN_TIME_CACHE() + (num)))[0] = (ptr); \
} while (0)
#define CACHED_POLYMORPHIC_PTR(num, ce) \
((EX_RUN_TIME_CACHE()[(num)] == (ce)) ? \
EX_RUN_TIME_CACHE()[(num) + 1] : \
((((void**)((char*)EX_RUN_TIME_CACHE() + (num)))[0] == (void*)(ce)) ? \
((void**)((char*)EX_RUN_TIME_CACHE() + (num)))[1] : \
NULL)
#define CACHE_POLYMORPHIC_PTR(num, ce, ptr) do { \
EX_RUN_TIME_CACHE()[(num)] = (ce); \
EX_RUN_TIME_CACHE()[(num) + 1] = (ptr); \
void **slot = (void**)((char*)EX_RUN_TIME_CACHE() + (num)); \
slot[0] = (ce); \
slot[1] = (ptr); \
} while (0)
#define CACHED_PTR_EX(slot) \

2
Zend/zend_opcode.c

@ -91,7 +91,7 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
op_array->literals = NULL;
op_array->run_time_cache = NULL;
op_array->last_cache_slot = 0;
op_array->cache_size = 0;
memset(op_array->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*));

44
Zend/zend_vm_def.h

@ -377,7 +377,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
/* here we are sure we are dealing with an object */
if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
ZVAL_DEREF(zptr);
SEPARATE_ZVAL_NOREF(zptr);
@ -391,7 +391,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
zval rv;
if (Z_OBJ_HT_P(object)->read_property &&
(z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
(z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
zval rv;
zval *value = Z_OBJ_HT_P(z)->get(z, &rv);
@ -404,7 +404,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
ZVAL_DEREF(z);
SEPARATE_ZVAL_NOREF(z);
binary_op(z, z, value);
Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL));
Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(EX_VAR(opline->result.var), z);
}
@ -777,7 +777,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
/* here we are sure we are dealing with an object */
if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
ZVAL_DEREF(zptr);
SEPARATE_ZVAL_NOREF(zptr);
@ -790,7 +790,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv);
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
zval rv;
@ -807,7 +807,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(retval, z);
}
Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL));
Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
zval_ptr_dtor(z);
} else {
zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
@ -864,7 +864,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|
/* here we are sure we are dealing with an object */
if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
ZVAL_DEREF(zptr);
ZVAL_COPY_VALUE(retval, zptr);
@ -874,7 +874,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|
} else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv);
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
zval z_copy;
if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
@ -890,7 +890,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|
ZVAL_DUP(&z_copy, z);
incdec_op(&z_copy);
if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL));
Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
zval_ptr_dtor(&z_copy);
zval_ptr_dtor(z);
} else {
@ -1131,7 +1131,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V
if (OP1_TYPE == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1);
retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*));
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
@ -1438,7 +1438,7 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|CV)
if (OP2_TYPE == IS_CONST &&
EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*));
if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
retval = OBJ_PROP(zobj, prop_offset);
@ -1460,7 +1460,7 @@ ZEND_VM_C_LABEL(fetch_obj_r_no_object):
zend_error(E_NOTICE, "Trying to get property of non-object");
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
if (retval != EX_VAR(opline->result.var)) {
ZVAL_COPY(EX_VAR(opline->result.var), retval);
@ -1489,7 +1489,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMPVAR|CV)
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W);
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@ -1513,7 +1513,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMPVAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW);
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@ -1553,7 +1553,7 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV)
if (OP2_TYPE == IS_CONST &&
EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*));
if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
retval = OBJ_PROP(zobj, prop_offset);
@ -1575,7 +1575,7 @@ ZEND_VM_C_LABEL(fetch_obj_is_no_object):
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
if (retval != EX_VAR(opline->result.var)) {
ZVAL_COPY(EX_VAR(opline->result.var), retval);
@ -1609,7 +1609,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMPV
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W);
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@ -1635,7 +1635,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMPVAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET);
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@ -1696,7 +1696,7 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, OP1_TYPE, property_name, OP2_TYPE, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property_name)) : NULL));
zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, OP1_TYPE, property_name, OP2_TYPE, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL));
FREE_OP2();
FREE_OP1_VAR_PTR();
/* assign_obj has two opcodes! */
@ -4659,7 +4659,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
}
}
if (Z_OBJ_HT_P(container)->unset_property) {
Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL));
Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
} else {
zend_error(E_NOTICE, "Trying to unset property of non-object");
}
@ -5321,7 +5321,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
if (OP1_TYPE == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1);
value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*));
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
@ -5528,7 +5528,7 @@ ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|
ZEND_VM_C_LABEL(isset_no_object):
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL));
result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
if ((opline->extended_value & ZEND_ISSET) == 0) {
result = !result;
}

450
Zend/zend_vm_execute.h
File diff suppressed because it is too large
View File

10
ext/opcache/Optimizer/compact_literals.c

@ -117,7 +117,7 @@ static void optimizer_literal_class_info(literal_info *info,
void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx)
{
zend_op *opline, *end;
int i, j, n, *map, cache_slots;
int i, j, n, *map, cache_size;
zval zv, *pos;
literal_info *info;
int l_null = -1;
@ -318,7 +318,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
#endif
/* Merge equal constants */
j = 0; cache_slots = 0;
j = 0; cache_size = 0;
zend_hash_init(&hash, op_array->last_literal, NULL, NULL, 0);
map = (int*)zend_arena_alloc(&ctx->arena, op_array->last_literal * sizeof(int));
memset(map, 0, op_array->last_literal * sizeof(int));
@ -439,8 +439,8 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
info[j] = info[i];
}
if (LITERAL_NUM_SLOTS(info[i].flags)) {
Z_CACHE_SLOT(op_array->literals[j]) = cache_slots;
cache_slots += LITERAL_NUM_SLOTS(info[i].flags);
Z_CACHE_SLOT(op_array->literals[j]) = cache_size;
cache_size += LITERAL_NUM_SLOTS(info[i].flags) * sizeof(void*);
}
j++;
n = LITERAL_NUM_RELATED(info[i].flags);
@ -465,7 +465,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
}
zend_hash_destroy(&hash);
op_array->last_literal = j;
op_array->last_cache_slot = cache_slots;
op_array->cache_size = cache_size;
/* Update opcodes to use new literals table */
opline = op_array->opcodes;

20
ext/opcache/Optimizer/zend_optimizer.c

@ -129,7 +129,8 @@ void zend_optimizer_update_op1_const(zend_op_array *op_array,
case ZEND_NEW:
opline->op1.constant = zend_optimizer_add_literal(op_array, val);
zend_string_hash_val(Z_STR(ZEND_OP1_LITERAL(opline)));
Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->last_cache_slot++;
Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->cache_size;
op_array->cache_size += sizeof(void*);
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
zend_optimizer_add_literal(op_array, val);
zend_string_hash_val(Z_STR(op_array->literals[opline->op1.constant+1]));
@ -154,7 +155,8 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array,
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
zend_string_hash_val(Z_STR(ZEND_OP2_LITERAL(opline)));
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot++;
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
op_array->cache_size += sizeof(void*);
return;
}
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
@ -175,14 +177,16 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array,
case ZEND_ADD_INTERFACE:
case ZEND_ADD_TRAIT:
case ZEND_INSTANCEOF:
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot++;
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
op_array->cache_size += sizeof(void*);
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
zend_optimizer_add_literal(op_array, val);
zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1]));
break;
case ZEND_INIT_DYNAMIC_CALL:
opline->opcode = ZEND_INIT_FCALL_BY_NAME;
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot++;
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
op_array->cache_size += sizeof(void*);
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
zend_optimizer_add_literal(op_array, val);
zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1]));
@ -207,8 +211,8 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array,
case ZEND_POST_INC_OBJ:
case ZEND_POST_DEC_OBJ:
case ZEND_ISSET_ISEMPTY_PROP_OBJ:
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot;
op_array->last_cache_slot += 2;
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
op_array->cache_size += 2 * sizeof(void*);
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
@ -222,8 +226,8 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array,
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
if (opline->extended_value == ZEND_ASSIGN_OBJ) {
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot;
op_array->last_cache_slot += 2;
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
op_array->cache_size += 2 * sizeof(void*);
}
break;
case ZEND_OP_DATA:

Loading…
Cancel
Save