diff options
author | Alan Wu <XrXr@users.noreply.github.com> | 2022-08-26 14:02:51 -0400 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2022-08-29 09:09:41 -0700 |
commit | 46007b88af82d6ff22fc01edb7c74922dfa5c68a (patch) | |
tree | 342e6182f62573a1b6ee8b89017559cea7432dd3 /yjit.c | |
parent | 29e0713a1272cb63f1e3cebfab85dec2424ead0f (diff) |
A64: Only clear icache when writing out new code (https://github.com/Shopify/ruby/pull/442)
Previously we cleared the cache for all the code in the system when we
flip memory protection, which was prohibitively expensive since the
operation is not constant time. Instead, only clear the cache for the
memory region of newly written code when we write out new code.
This brings the runtime for the 30k_if_else test down to about 6 seconds
from the previous 45 seconds on my laptop.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/6289
Diffstat (limited to 'yjit.c')
-rw-r--r-- | yjit.c | 10 |
1 files changed, 8 insertions, 2 deletions
@@ -78,11 +78,17 @@ rb_yjit_mark_executable(void *mem_block, uint32_t mem_size) rb_bug("Couldn't make JIT page (%p, %lu bytes) executable, errno: %s\n", mem_block, (unsigned long)mem_size, strerror(errno)); } +} +// `start` is inclusive and `end` is exclusive. +void +rb_yjit_icache_invalidate(void *start, void *end) +{ // Clear/invalidate the instruction cache. Compiles to nothing on x86_64 - // but required on ARM. On Darwin it's the same as calling sys_icache_invalidate(). + // but required on ARM before running freshly written code. + // On Darwin it's the same as calling sys_icache_invalidate(). #ifdef __GNUC__ - __builtin___clear_cache(mem_block, (char *)mem_block + mem_size); + __builtin___clear_cache(start, end); #endif } |