[commit: ghc] master: use libffi for iOS adjustors; fixes #7718 (972c044)

Ian Lynagh igloo at earth.li
Sat Jun 8 16:33:01 CEST 2013


Repository : http://darcs.haskell.org/ghc.git/

On branch  : master

https://github.com/ghc/ghc/commit/972c044d5da72cee3a43209ccb41e2229914211c

>---------------------------------------------------------------

commit 972c044d5da72cee3a43209ccb41e2229914211c
Author: Ian Lynagh <ian at well-typed.com>
Date:   Sat Jun 8 15:22:24 2013 +0100

    use libffi for iOS adjustors; fixes #7718
    
    Based on a patch from Stephen Blackheath.

>---------------------------------------------------------------

 includes/rts/storage/GC.h |  7 ++++--
 rts/sm/Storage.c          | 58 +++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/includes/rts/storage/GC.h b/includes/rts/storage/GC.h
index 80f11d3..6ddd301 100644
--- a/includes/rts/storage/GC.h
+++ b/includes/rts/storage/GC.h
@@ -154,8 +154,11 @@ StgPtr  allocate        ( Capability *cap, W_ n );
 StgPtr  allocatePinned  ( Capability *cap, W_ n );
 
 /* memory allocator for executable memory */
-void * allocateExec(W_ len, void **exec_addr);
-void   freeExec (void *p);
+typedef void* AdjustorWritable;
+typedef void* AdjustorExecutable;
+
+AdjustorWritable allocateExec(W_ len, AdjustorExecutable *exec_addr);
+void             freeExec (AdjustorExecutable p);
 
 // Used by GC checks in external .cmm code:
 extern W_ large_alloc_lim;
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index 5c4e54f..5d5470b 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -29,6 +29,9 @@
 #include "Trace.h"
 #include "GC.h"
 #include "Evac.h"
+#if defined(ios_HOST_OS)
+#include "Hash.h"
+#endif
 
 #include <string.h>
 
@@ -1094,7 +1097,7 @@ calcNeeded (rtsBool force_major, memcount *blocks_needed)
 // because it knows how to work around the restrictions put in place
 // by SELinux.
 
-void *allocateExec (W_ bytes, void **exec_ret)
+AdjustorWritable allocateExec (W_ bytes, AdjustorExecutable *exec_ret)
 {
     void **ret, **exec;
     ACQUIRE_SM_LOCK;
@@ -1107,18 +1110,65 @@ void *allocateExec (W_ bytes, void **exec_ret)
 }
 
 // freeExec gets passed the executable address, not the writable address. 
-void freeExec (void *addr)
+void freeExec (AdjustorExecutable addr)
 {
-    void *writable;
+    AdjustorWritable writable;
     writable = *((void**)addr - 1);
     ACQUIRE_SM_LOCK;
     ffi_closure_free (writable);
     RELEASE_SM_LOCK
 }
 
+#elif defined(ios_HOST_OS)
+
+static HashTable* allocatedExecs;
+
+AdjustorWritable allocateExec(W_ bytes, AdjustorExecutable *exec_ret)
+{
+    AdjustorWritable writ;
+    ffi_closure* cl;
+    if (bytes != sizeof(ffi_closure)) {
+        barf("allocateExec: for ffi_closure only");
+    }
+    ACQUIRE_SM_LOCK;
+    cl = writ = ffi_closure_alloc((size_t)bytes, exec_ret);
+    if (cl != NULL) {
+        if (allocatedExecs == NULL) {
+            allocatedExecs = allocHashTable();
+        }
+        insertHashTable(allocatedExecs, (StgWord)*exec_ret, writ);
+    }
+    RELEASE_SM_LOCK;
+    return writ;
+}
+
+AdjustorWritable execToWritable(AdjustorExecutable exec)
+{
+    AdjustorWritable writ;
+    ACQUIRE_SM_LOCK;
+    if (allocatedExecs == NULL ||
+       (writ = lookupHashTable(allocatedExecs, (StgWord)exec)) == NULL) {
+        RELEASE_SM_LOCK;
+        barf("execToWritable: not found");
+    }
+    RELEASE_SM_LOCK;
+    return writ;
+}
+
+void freeExec(AdjustorExecutable exec)
+{
+    AdjustorWritable writ;
+    ffi_closure* cl;
+    cl = writ = execToWritable(exec);
+    ACQUIRE_SM_LOCK;
+    removeHashTable(allocatedExecs, (StgWord)exec, writ);
+    ffi_closure_free(cl);
+    RELEASE_SM_LOCK
+}
+
 #else
 
-void *allocateExec (W_ bytes, void **exec_ret)
+AdjustorWritable allocateExec (W_ bytes, AdjustorExecutable *exec_ret)
 {
     void *ret;
     W_ n;





More information about the ghc-commits mailing list