From 0b6b8169e5105ce1c52c1c586a7384efbb8523bb Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Mon, 26 Feb 2024 14:19:39 -0500 Subject: [PATCH] Skip isolating cover instructions when native coverage is available If OTP is compiled with native coverage support (OTP 27+ plus JIT), `cover` does not attempt to inject counters into the code, so isolating the cover instructions fails. We can skip that step when we detect native coverage support. --- src/horus.erl | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/horus.erl b/src/horus.erl index b074466..88b814e 100644 --- a/src/horus.erl +++ b/src/horus.erl @@ -324,6 +324,19 @@ fun((#{calls := #{Call :: mfa() => true}, -define(SF_ENTRYPOINT, run). +-if(?OTP_RELEASE >= 27). +-define(IF_NATIVE_COVERAGE_IS_SUPPORTED(IfSupportedBlock, ElseBlock), + (case code:coverage_support() of + true -> + IfSupportedBlock; + false -> + ElseBlock + end)). +-else. +-define(IF_NATIVE_COVERAGE_IS_SUPPORTED(_IfSupportedBlock, ElseBlock), + (ElseBlock)). +-endif. + -spec to_standalone_fun(Fun) -> StandaloneFun when Fun :: fun(), StandaloneFun :: horus_fun(). @@ -1218,8 +1231,17 @@ pass1_process_instructions( Instructions, #state{mfa_in_progress = MFA, asm_in_progress_from = cover} = State) -> - Instructions1 = horus_cover:isolate_cover_instructions(MFA, Instructions), - pass1_process_instructions(Instructions1, State, []); + ?IF_NATIVE_COVERAGE_IS_SUPPORTED( + begin + %% In Erlang/OTP 27+ with JIT, cover does not inject counters, so + %% there are no significant cover instructions to isolate. + pass1_process_instructions(Instructions, State, []); + end, + begin + Instructions1 = horus_cover:isolate_cover_instructions( + MFA, Instructions), + pass1_process_instructions(Instructions1, State, []) + end); pass1_process_instructions(Instructions, State) -> pass1_process_instructions(Instructions, State, []).