[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