[commit: ghc] master: Rejigger flushExec implementation (#8562, #8561) (9fbb8c7)
git at git.haskell.org
git at git.haskell.org
Wed Nov 27 01:30:20 UTC 2013
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/9fbb8c788d4bdf091709778b42a1294bbdabef95/ghc
>---------------------------------------------------------------
commit 9fbb8c788d4bdf091709778b42a1294bbdabef95
Author: Austin Seipp <austin at well-typed.com>
Date: Tue Nov 26 03:31:30 2013 -0600
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 at well-typed.com>
>---------------------------------------------------------------
9fbb8c788d4bdf091709778b42a1294bbdabef95
rts/sm/Storage.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index c1a1a5a..b5f3202 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.
More information about the ghc-commits
mailing list