Improved access to static property. Now we cache pointers to zval instead of pointers to property_info.

This commit is contained in:
Dmitry Stogov 2015-01-13 03:32:51 +03:00
parent 0445974cb1
commit dbe66fb2cf
4 changed files with 231 additions and 43 deletions

View File

@ -1198,15 +1198,13 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *property_name, zend_bool silent, void **cache_slot) /* {{{ */
{
zend_property_info *property_info;
zval *ret;
if (UNEXPECTED(cache_slot == NULL) ||
(property_info = CACHED_POLYMORPHIC_PTR_EX(cache_slot, ce)) == NULL) {
if (cache_slot == NULL ||
(ret = CACHED_POLYMORPHIC_PTR_EX(cache_slot, ce)) == NULL) {
if (UNEXPECTED((property_info = zend_hash_find_ptr(&ce->properties_info, property_name)) == NULL)) {
if (!silent) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, property_name->val);
}
return NULL;
goto undeclared_property;
}
if (UNEXPECTED(!zend_verify_property_access(property_info, ce))) {
@ -1217,28 +1215,32 @@ ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *p
}
if (UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) {
if (!silent) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, property_name->val);
}
return NULL;
goto undeclared_property;
}
zend_update_class_constants(ce);
ret = CE_STATIC_MEMBERS(ce) + property_info->offset;
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
goto undeclared_property;
}
if (EXPECTED(cache_slot != NULL)) {
CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, property_info);
CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, ret);
}
} else {
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
undeclared_property:
if (!silent) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, property_name->val);
}
ret = NULL;
}
}
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL) ||
UNEXPECTED(Z_TYPE(CE_STATIC_MEMBERS(ce)[property_info->offset]) == IS_UNDEF)) {
if (!silent) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, property_name->val);
}
return NULL;
}
return &CE_STATIC_MEMBERS(ce)[property_info->offset];
return ret;
}
/* }}} */

View File

@ -150,35 +150,31 @@ ZEND_API void zend_cleanup_user_class_data(zend_class_entry *ce)
} ZEND_HASH_FOREACH_END();
}
if (ce->static_members_table) {
zval *static_members = ce->static_members_table;
int i;
for (i = 0; i < ce->default_static_members_count; i++) {
if (Z_TYPE(ce->static_members_table[i]) != IS_UNDEF) {
zval tmp;
ZVAL_COPY_VALUE(&tmp, &ce->static_members_table[i]);
ZVAL_UNDEF(&ce->static_members_table[i]);
zval_ptr_dtor(&tmp);
}
}
ce->static_members_table = NULL;
for (i = 0; i < ce->default_static_members_count; i++) {
zval_ptr_dtor(&static_members[i]);
}
}
}
ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce)
{
if (CE_STATIC_MEMBERS(ce)) {
zval *static_members = CE_STATIC_MEMBERS(ce);
int i;
for (i = 0; i < ce->default_static_members_count; i++) {
zval_ptr_dtor(&CE_STATIC_MEMBERS(ce)[i]);
}
efree(CE_STATIC_MEMBERS(ce));
#ifdef ZTS
CG(static_members_table)[(zend_intptr_t)(ce->static_members_table)] = NULL;
#else
ce->static_members_table = NULL;
#endif
for (i = 0; i < ce->default_static_members_count; i++) {
zval_ptr_dtor(&static_members[i]);
}
efree(static_members);
}
}

View File

@ -1112,7 +1112,26 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V
zend_class_entry *ce;
if (OP2_TYPE == IS_CONST) {
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
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);
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, name->val);
}
if (type == BP_VAR_R || type == BP_VAR_IS) {
if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) {
ZVAL_UNREF(retval);
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
ZEND_VM_NEXT_OPCODE();
} else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
} else {
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0);

View File

@ -3759,7 +3759,26 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type
zend_class_entry *ce;
if (IS_CONST == IS_CONST) {
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
if (IS_CONST == 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);
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, name->val);
}
if (type == BP_VAR_R || type == BP_VAR_IS) {
if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) {
ZVAL_UNREF(retval);
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
ZEND_VM_NEXT_OPCODE();
} else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
} else {
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0);
@ -5252,7 +5271,26 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type,
zend_class_entry *ce;
if (IS_VAR == IS_CONST) {
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
if (IS_CONST == 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);
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, name->val);
}
if (type == BP_VAR_R || type == BP_VAR_IS) {
if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) {
ZVAL_UNREF(retval);
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
ZEND_VM_NEXT_OPCODE();
} else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
} else {
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0);
@ -5677,7 +5715,26 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ
zend_class_entry *ce;
if (IS_UNUSED == IS_CONST) {
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
if (IS_CONST == 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);
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, name->val);
}
if (type == BP_VAR_R || type == BP_VAR_IS) {
if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) {
ZVAL_UNREF(retval);
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
ZEND_VM_NEXT_OPCODE();
} else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
} else {
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0);
@ -25092,7 +25149,26 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z
zend_class_entry *ce;
if (IS_CONST == IS_CONST) {
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
if (IS_CV == 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);
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, name->val);
}
if (type == BP_VAR_R || type == BP_VAR_IS) {
if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) {
ZVAL_UNREF(retval);
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
ZEND_VM_NEXT_OPCODE();
} else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
} else {
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0);
@ -26916,7 +26992,26 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN
zend_class_entry *ce;
if (IS_VAR == IS_CONST) {
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
if (IS_CV == 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);
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, name->val);
}
if (type == BP_VAR_R || type == BP_VAR_IS) {
if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) {
ZVAL_UNREF(retval);
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
ZEND_VM_NEXT_OPCODE();
} else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
} else {
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0);
@ -27762,7 +27857,26 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type,
zend_class_entry *ce;
if (IS_UNUSED == IS_CONST) {
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
if (IS_CV == 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);
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, name->val);
}
if (type == BP_VAR_R || type == BP_VAR_IS) {
if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) {
ZVAL_UNREF(retval);
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
ZEND_VM_NEXT_OPCODE();
} else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
} else {
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0);
@ -33125,7 +33239,26 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMPVAR_CONST(int typ
zend_class_entry *ce;
if (IS_CONST == IS_CONST) {
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
if ((IS_TMP_VAR|IS_VAR) == 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);
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, name->val);
}
if (type == BP_VAR_R || type == BP_VAR_IS) {
if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) {
ZVAL_UNREF(retval);
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
ZEND_VM_NEXT_OPCODE();
} else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
} else {
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0);
@ -33896,7 +34029,26 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMPVAR_VAR(int type,
zend_class_entry *ce;
if (IS_VAR == IS_CONST) {
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
if ((IS_TMP_VAR|IS_VAR) == 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);
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, name->val);
}
if (type == BP_VAR_R || type == BP_VAR_IS) {
if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) {
ZVAL_UNREF(retval);
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
ZEND_VM_NEXT_OPCODE();
} else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
} else {
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0);
@ -34234,7 +34386,26 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(int ty
zend_class_entry *ce;
if (IS_UNUSED == IS_CONST) {
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
if ((IS_TMP_VAR|IS_VAR) == 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);
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name->val, name->val);
}
if (type == BP_VAR_R || type == BP_VAR_IS) {
if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) {
ZVAL_UNREF(retval);
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
ZEND_VM_NEXT_OPCODE();
} else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
} else {
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0);