Micro optimizations

This commit is contained in:
Dmitry Stogov 2015-04-28 19:11:45 +03:00
parent 612de5214f
commit 388c2cbdbc
6 changed files with 116 additions and 79 deletions

View File

@ -1223,16 +1223,20 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */
ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type) /* {{{ */
{
int i;
if (class_type->default_properties_count) {
for (i = 0; i < class_type->default_properties_count; i++) {
zval *src = class_type->default_properties_table;
zval *dst = object->properties_table;
zval *end = src + class_type->default_properties_count;
do {
#if ZTS
ZVAL_DUP(&object->properties_table[i], &class_type->default_properties_table[i]);
ZVAL_DUP(dst, src);
#else
ZVAL_COPY(&object->properties_table[i], &class_type->default_properties_table[i]);
ZVAL_COPY(dst, src);
#endif
}
src++;
dst++;
} while (src != end);
object->properties = NULL;
}
}
@ -3451,10 +3455,12 @@ ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, zend_fcall_i
ZEND_API void zend_fcall_info_args_clear(zend_fcall_info *fci, int free_mem) /* {{{ */
{
if (fci->params) {
uint32_t i;
zval *p = fci->params;
zval *end = p + fci->param_count;
for (i = 0; i < fci->param_count; i++) {
zval_ptr_dtor(&fci->params[i]);
while (p != end) {
i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
p++;
}
if (free_mem) {
efree(fci->params);

View File

@ -2083,11 +2083,13 @@ ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data
if (num_args > 0) {
zval *arg_src = ZEND_CALL_ARG(call, 1);
zval *arg_dst = ZEND_CALL_ARG(execute_data, 1);
uint32_t i;
zval *end = arg_src + num_args;
for (i = 0; i < num_args; i++) {
ZVAL_COPY_VALUE(arg_dst + i, arg_src + i);
}
do {
ZVAL_COPY_VALUE(arg_dst, arg_src);
arg_src++;
arg_dst++;
} while (arg_src != end);
}
EX(symbol_table) = NULL;

View File

@ -1326,16 +1326,20 @@ static int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
return 1; /* different classes */
}
if (!zobj1->properties && !zobj2->properties) {
int i;
zval *p1, *p2, *end;
if (!zobj1->ce->default_properties_count) {
return 0;
}
p1 = zobj1->properties_table;
p2 = zobj2->properties_table;
end = p1 + zobj1->ce->default_properties_count;
Z_OBJ_PROTECT_RECURSION(o1);
Z_OBJ_PROTECT_RECURSION(o2);
for (i = 0; i < zobj1->ce->default_properties_count; i++) {
if (Z_TYPE(zobj1->properties_table[i]) != IS_UNDEF) {
if (Z_TYPE(zobj2->properties_table[i]) != IS_UNDEF) {
do {
if (Z_TYPE_P(p1) != IS_UNDEF) {
if (Z_TYPE_P(p2) != IS_UNDEF) {
zval result;
zval *p1 = &zobj1->properties_table[i];
zval *p2 = &zobj2->properties_table[i];
if (compare_function(&result, p1, p2)==FAILURE) {
Z_OBJ_UNPROTECT_RECURSION(o1);
@ -1353,13 +1357,15 @@ static int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
return 1;
}
} else {
if (Z_TYPE(zobj2->properties_table[i]) != IS_UNDEF) {
if (Z_TYPE_P(p2) != IS_UNDEF) {
Z_OBJ_UNPROTECT_RECURSION(o1);
Z_OBJ_UNPROTECT_RECURSION(o2);
return 1;
}
}
}
p1++;
p2++;
} while (p1 != end);
Z_OBJ_UNPROTECT_RECURSION(o1);
Z_OBJ_UNPROTECT_RECURSION(o2);
return 0;

View File

@ -151,14 +151,18 @@ ZEND_API zend_object *zend_objects_new(zend_class_entry *ce)
ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *old_object)
{
int i;
if (old_object->ce->default_properties_count) {
for (i = 0; i < old_object->ce->default_properties_count; i++) {
zval_ptr_dtor(&new_object->properties_table[i]);
ZVAL_COPY_VALUE(&new_object->properties_table[i], &old_object->properties_table[i]);
zval_add_ref(&new_object->properties_table[i]);
}
zval *src = old_object->properties_table;
zval *dst = new_object->properties_table;
zval *end = src + old_object->ce->default_properties_count;
do {
i_zval_ptr_dtor(dst ZEND_FILE_LINE_CC);
ZVAL_COPY_VALUE(dst, src);
zval_add_ref(dst);
src++;
dst++;
} while (src != end);
}
if (old_object->properties) {
zval *prop, new_prop;

View File

@ -42,46 +42,58 @@ ZEND_API void zend_objects_store_destroy(zend_objects_store *objects)
ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects)
{
uint32_t i;
if (objects->top > 1) {
zend_object **obj_ptr = objects->object_buckets + 1;
zend_object **end = objects->object_buckets + objects->top;
for (i = 1; i < objects->top ; i++) {
zend_object *obj = objects->object_buckets[i];
do {
zend_object *obj = *obj_ptr;
if (IS_OBJ_VALID(obj)) {
if (!(GC_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) {
GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED;
GC_REFCOUNT(obj)++;
obj->handlers->dtor_obj(obj);
GC_REFCOUNT(obj)--;
if (IS_OBJ_VALID(obj)) {
if (!(GC_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) {
GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED;
GC_REFCOUNT(obj)++;
obj->handlers->dtor_obj(obj);
GC_REFCOUNT(obj)--;
}
}
}
obj_ptr++;
} while (obj_ptr != end);
}
}
ZEND_API void zend_objects_store_mark_destructed(zend_objects_store *objects)
{
uint32_t i;
if (objects->object_buckets && objects->top > 1) {
zend_object **obj_ptr = objects->object_buckets + 1;
zend_object **end = objects->object_buckets + objects->top;
if (!objects->object_buckets) {
return;
}
for (i = 1; i < objects->top ; i++) {
zend_object *obj = objects->object_buckets[i];
do {
zend_object *obj = *obj_ptr;
if (IS_OBJ_VALID(obj)) {
GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED;
}
if (IS_OBJ_VALID(obj)) {
GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED;
}
obj_ptr++;
} while (obj_ptr != end);
}
}
ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects)
{
uint32_t i;
zend_object **obj_ptr, **end, *obj;
if (objects->top <= 1) {
return;
}
/* Free object contents, but don't free objects themselves */
for (i = objects->top - 1; i > 0 ; i--) {
zend_object *obj = objects->object_buckets[i];
end = objects->object_buckets + 1;
obj_ptr = objects->object_buckets + objects->top;
do {
obj_ptr--;
obj = *obj_ptr;
if (IS_OBJ_VALID(obj)) {
if (!(GC_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
GC_FLAGS(obj) |= IS_OBJ_FREE_CALLED;
@ -92,20 +104,21 @@ ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects
}
}
}
}
} while (obj_ptr != end);
/* Free objects themselves if they now have a refcount of 0, which means that
* they were previously part of a cycle. Everything else will report as a leak.
* Cycles are allowed because not all internal objects currently support GC. */
for (i = 1; i < objects->top ; i++) {
zend_object *obj = objects->object_buckets[i];
end = objects->object_buckets + objects->top;
while (obj_ptr != end) {
obj = *obj_ptr;
if (IS_OBJ_VALID(obj) && GC_REFCOUNT(obj) == 0) {
/* Not adding to free list as we are shutting down anyway */
void *ptr = ((char*)obj) - obj->handlers->offset;
GC_REMOVE_FROM_BUFFER(obj);
efree(ptr);
}
obj_ptr++;
}
}

View File

@ -154,13 +154,15 @@ ZEND_API void zend_cleanup_user_class_data(zend_class_entry *ce)
}
if (ce->static_members_table) {
zval *static_members = ce->static_members_table;
int count = ce->default_static_members_count;
int i;
zval *p = static_members;
zval *end = p + ce->default_static_members_count;
ce->default_static_members_count = 0;
ce->default_static_members_table = ce->static_members_table = NULL;
for (i = 0; i < count; i++) {
zval_ptr_dtor(&static_members[i]);
while (p != end) {
i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
p++;
}
efree(static_members);
}
@ -170,15 +172,17 @@ 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;
zval *p = static_members;
zval *end = p + ce->default_static_members_count;
#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]);
while (p != end) {
i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
p++;
}
efree(static_members);
}
@ -249,22 +253,22 @@ ZEND_API void destroy_zend_class(zval *zv)
switch (ce->type) {
case ZEND_USER_CLASS:
if (ce->default_properties_table) {
int i;
zval *p = ce->default_properties_table;
zval *end = p + ce->default_properties_count;
for (i = 0; i < ce->default_properties_count; i++) {
if (Z_TYPE(ce->default_properties_table[i]) != IS_UNDEF) {
zval_ptr_dtor(&ce->default_properties_table[i]);
}
while (p != end) {
i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
p++;
}
efree(ce->default_properties_table);
}
if (ce->default_static_members_table) {
int i;
zval *p = ce->default_static_members_table;
zval *end = p + ce->default_static_members_count;
for (i = 0; i < ce->default_static_members_count; i++) {
if (Z_TYPE(ce->default_static_members_table[i]) != IS_UNDEF) {
zval_ptr_dtor(&ce->default_static_members_table[i]);
}
while (p != end) {
i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
p++;
}
efree(ce->default_static_members_table);
}
@ -292,20 +296,22 @@ ZEND_API void destroy_zend_class(zval *zv)
break;
case ZEND_INTERNAL_CLASS:
if (ce->default_properties_table) {
int i;
zval *p = ce->default_properties_table;
zval *end = p + ce->default_properties_count;
for (i = 0; i < ce->default_properties_count; i++) {
if (Z_TYPE(ce->default_properties_table[i]) != IS_UNDEF) {
zval_internal_ptr_dtor(&ce->default_properties_table[i]);
}
while (p != end) {
zval_internal_ptr_dtor(p);
p++;
}
free(ce->default_properties_table);
}
if (ce->default_static_members_table) {
int i;
zval *p = ce->default_static_members_table;
zval *end = p + ce->default_static_members_count;
for (i = 0; i < ce->default_static_members_count; i++) {
zval_internal_ptr_dtor(&ce->default_static_members_table[i]);
while (p != end) {
zval_internal_ptr_dtor(p);
p++;
}
free(ce->default_static_members_table);
}