summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_portability.h5
-rw-r--r--Zend/zend_vm_def.h12
-rw-r--r--Zend/zend_vm_execute.h24
3 files changed, 41 insertions, 0 deletions
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));