Doesn't mapping the same physical memory into two places actually end up defeating the W^X bit entirely? Since you can write to the RW mapped page and have it change the RX page?
Those pages would be mapped at a different, random address while the executing code has an instruction pointer pointing right at the RX page.
It's much more difficult getting access to the JIT's internal data structures, traversing them to find the correct RW page, then modify it, then jump to the same place in the RX page. If you already have that much control you're probably not far from getting the JIT to emit arbitrary code anyway.
Note that writing to ICs can happen from a different thread, so the current thread stack does not need to know much of the JIT's internal data.