From cf388033d553d88d84c1d03eda0e064bbb082c5f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 31 May 2019 00:14:10 +0300 Subject: [PATCH] Reduce register pressure by reloading values on CPUs with few general purpose registers --- Zend/zend_portability.h | 5 +++++ Zend/zend_vm_def.h | 12 ++++++++++++ Zend/zend_vm_execute.h | 24 ++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index b0eb20bf40..009be97d96 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -636,4 +636,9 @@ static zend_always_inline double _zend_get_nan(void) /* {{{ */ # define ZEND_EXPAND_VA(code) code #endif +/* On CPU with few registers, it's cheaper to reload value then use spill slot */ +#if defined(__i386__) || (defined(_WIN32) && !defined(_WIN64)) +# define ZEND_PREFER_RELOAD +#endif + #endif /* ZEND_PORTABILITY_H */ diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 6a57beccb1..9b7e1b1e9b 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2738,6 +2738,9 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY) if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) { i_free_compiled_variables(execute_data); +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { OBJ_RELEASE(Z_OBJ(execute_data->This)); @@ -2757,6 +2760,9 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY) } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) { i_free_compiled_variables(execute_data); +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { zend_clean_and_cache_symbol_table(EX(symbol_table)); } @@ -2783,6 +2789,9 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY) zend_detach_symbol_table(execute_data); destroy_op_array(&EX(func)->op_array); efree_size(EX(func), sizeof(zend_op_array)); +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif old_execute_data = execute_data; execute_data = EG(current_execute_data) = EX(prev_execute_data); zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); @@ -2798,6 +2807,9 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY) } else { if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) { i_free_compiled_variables(execute_data); +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) { if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { zend_clean_and_cache_symbol_table(EX(symbol_table)); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 210f488de2..17622c00d2 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -794,6 +794,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) { i_free_compiled_variables(execute_data); +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { OBJ_RELEASE(Z_OBJ(execute_data->This)); @@ -813,6 +816,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) { i_free_compiled_variables(execute_data); +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { zend_clean_and_cache_symbol_table(EX(symbol_table)); } @@ -839,6 +845,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ zend_detach_symbol_table(execute_data); destroy_op_array(&EX(func)->op_array); efree_size(EX(func), sizeof(zend_op_array)); +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif old_execute_data = execute_data; execute_data = EG(current_execute_data) = EX(prev_execute_data); zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); @@ -854,6 +863,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ } else { if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) { i_free_compiled_variables(execute_data); +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) { if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { zend_clean_and_cache_symbol_table(EX(symbol_table)); @@ -59382,6 +59394,9 @@ zend_leave_helper_SPEC_LABEL: if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) { i_free_compiled_variables(execute_data); +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { OBJ_RELEASE(Z_OBJ(execute_data->This)); @@ -59401,6 +59416,9 @@ zend_leave_helper_SPEC_LABEL: } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) { i_free_compiled_variables(execute_data); +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { zend_clean_and_cache_symbol_table(EX(symbol_table)); } @@ -59427,6 +59445,9 @@ zend_leave_helper_SPEC_LABEL: zend_detach_symbol_table(execute_data); destroy_op_array(&EX(func)->op_array); efree_size(EX(func), sizeof(zend_op_array)); +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif old_execute_data = execute_data; execute_data = EG(current_execute_data) = EX(prev_execute_data); zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); @@ -59442,6 +59463,9 @@ zend_leave_helper_SPEC_LABEL: } else { if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) { i_free_compiled_variables(execute_data); +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) { if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { zend_clean_and_cache_symbol_table(EX(symbol_table)); -- 2.50.1