[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