Skip to content

Commit 8fa433a

Browse files
committed
Split atomic exchange into load + store
It is difficult to determine performance of atomics sometimes. In this case, the separate load+store is still correct, and a load does not cause a modification, and might be faster for some platforms than an exchange. A load+store is slower than an exchange, but we're fine trading the penalty to the slow path and keeping the happy path faster.
1 parent 1255c71 commit 8fa433a

File tree

4 files changed

+9
-14
lines changed

4 files changed

+9
-14
lines changed

Zend/zend_execute.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -4054,8 +4054,9 @@ ZEND_API void ZEND_FASTCALL zend_free_compiled_variables(zend_execute_data *exec
40544054
}
40554055
/* }}} */
40564056

4057-
ZEND_API ZEND_COLD void zend_fcall_interrupt(zend_execute_data *call)
4057+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_fcall_interrupt(zend_execute_data *call)
40584058
{
4059+
zend_atomic_bool_store_ex(&EG(vm_interrupt), false);
40594060
if (zend_atomic_bool_load_ex(&EG(timed_out))) {
40604061
zend_timeout();
40614062
} else if (zend_interrupt_function) {
@@ -4076,7 +4077,7 @@ ZEND_API ZEND_COLD void zend_fcall_interrupt(zend_execute_data *call)
40764077
} while (0)
40774078

40784079
#define ZEND_VM_FCALL_INTERRUPT_CHECK(call) do { \
4079-
if (UNEXPECTED(zend_atomic_bool_exchange_ex(&EG(vm_interrupt), false))) { \
4080+
if (UNEXPECTED(zend_atomic_bool_load_ex(&EG(vm_interrupt)))) { \
40804081
zend_fcall_interrupt(call); \
40814082
} \
40824083
} while (0)

Zend/zend_execute.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -539,10 +539,10 @@ ZEND_COLD void zend_magic_get_property_type_inconsistency_error(const zend_prope
539539

540540
ZEND_COLD void zend_match_unhandled_error(const zval *value);
541541

542-
/* Call this to handle the timeout or the interrupt function. It will not clear
543-
* the EG(vm_interrupt); this is done by the fcall/jit handler.
542+
/* Call this to handle the timeout or the interrupt function. It will set
543+
* EG(vm_interrupt) to false.
544544
*/
545-
ZEND_API ZEND_COLD void zend_fcall_interrupt(zend_execute_data *call);
545+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_fcall_interrupt(zend_execute_data *call);
546546

547547
static zend_always_inline void *zend_get_bad_ptr(void)
548548
{

ext/opcache/jit/zend_jit_helpers.c

-6
Original file line numberDiff line numberDiff line change
@@ -3272,9 +3272,3 @@ static zend_string* ZEND_FASTCALL zend_jit_rope_end(zend_string **rope, uint32_t
32723272
*target = '\0';
32733273
return ret;
32743274
}
3275-
3276-
ZEND_COLD static void ZEND_FASTCALL zend_jit_fcall_interrupt(zend_execute_data *call)
3277-
{
3278-
zend_atomic_bool_store_ex(&EG(vm_interrupt), false);
3279-
zend_fcall_interrupt(call);
3280-
}

ext/opcache/jit/zend_jit_ir.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -3075,7 +3075,7 @@ static void zend_jit_setup_disasm(void)
30753075
REGISTER_HELPER(zend_jit_pre_dec_obj_helper);
30763076
REGISTER_HELPER(zend_jit_post_dec_obj_helper);
30773077
REGISTER_HELPER(zend_jit_rope_end);
3078-
REGISTER_HELPER(zend_jit_fcall_interrupt);
3078+
REGISTER_HELPER(zend_fcall_interrupt);
30793079

30803080
#ifndef ZTS
30813081
REGISTER_DATA(EG(current_execute_data));
@@ -10203,10 +10203,10 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen
1020310203
* down that handles when there isn't an interrupt function.
1020410204
*/
1020510205
if (zend_interrupt_function) {
10206-
// JIT: if (EG(vm_interrupt)) zend_jit_fcall_interrupt(execute_data);
10206+
// JIT: if (EG(vm_interrupt)) zend_fcall_interrupt(execute_data);
1020710207
ir_ref if_interrupt = ir_IF(ir_LOAD_U8(jit_EG(vm_interrupt)));
1020810208
ir_IF_TRUE_cold(if_interrupt);
10209-
ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_fcall_interrupt), rx);
10209+
ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_fcall_interrupt), rx);
1021010210
ir_MERGE_WITH_EMPTY_FALSE(if_interrupt);
1021110211
}
1021210212

0 commit comments

Comments
 (0)