diff options
author | Austin Seipp <austin@well-typed.com> | 2013-11-26 03:31:30 -0600 |
---|---|---|
committer | Austin Seipp <austin@well-typed.com> | 2013-11-26 19:29:57 -0600 |
commit | 9fbb8c788d4bdf091709778b42a1294bbdabef95 (patch) | |
tree | f5c3db21adb0f0003809c64afee1438421fbdc16 /rts | |
parent | 6279a01173152753e792674bfb30ef2f7474ef09 (diff) | |
download | haskell-9fbb8c788d4bdf091709778b42a1294bbdabef95.tar.gz |
Rejigger flushExec implementation (#8562, #8561)
Instead, just don't do anything on x86/amd64, and on !x86, use either A)
__clear_cache from libgcc, or B) sys_icache_invalidate for OS X (and
iOS.)
Signed-off-by: Austin Seipp <austin@well-typed.com>
Diffstat (limited to 'rts')
-rw-r--r-- | rts/sm/Storage.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c index c1a1a5a248..b5f3202887 100644 --- a/rts/sm/Storage.c +++ b/rts/sm/Storage.c @@ -1152,13 +1152,29 @@ AdjustorWritable allocateExec (W_ bytes, AdjustorExecutable *exec_ret) return (ret + 1); } +#if defined(arm_HOST_ARCH) && defined(ios_HOST_OS) +void sys_icache_invalidate(void *start, size_t len); +#endif + +/* On ARM and other platforms, we need to flush the cache after + writing code into memory, so the processor reliably sees it. */ void flushExec (W_ len, AdjustorExecutable exec_addr) { - /* On ARM and other platforms, we need to flush the cache after - writing code into memory, so the processor reliably sees it. */ +#if defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH) + /* x86 doesn't need to do anything, so just suppress some warnings. */ + (void)len; + (void)exec_addr; +#elif defined(arm_HOST_ARCH) && defined(ios_HOST_OS) + /* On iOS we need to use the special 'sys_icache_invalidate' call. */ + sys_icache_invalidate(exec_addr, ((unsigned char*)exec_addr)+len); +#elif defined(__GNUC__) + /* For all other platforms, fall back to a libgcc builtin. */ unsigned char* begin = (unsigned char*)exec_addr; unsigned char* end = begin + len; - __builtin___clear_cache(begin, end); + __clear_cache((void*)begin, (void*)end); +#else +#error Missing support to flush the instruction cache +#endif } // freeExec gets passed the executable address, not the writable address. |