summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorIan Lynagh <ian@well-typed.com>2013-06-08 15:22:24 +0100
committerIan Lynagh <ian@well-typed.com>2013-06-08 15:22:24 +0100
commit972c044d5da72cee3a43209ccb41e2229914211c (patch)
tree97fd5489787faebea8b275362277402cbe6459b5 /rts
parent0d860381cdca9ed9d92dc315358072a84696ba08 (diff)
downloadhaskell-972c044d5da72cee3a43209ccb41e2229914211c.tar.gz
use libffi for iOS adjustors; fixes #7718
Based on a patch from Stephen Blackheath.
Diffstat (limited to 'rts')
-rw-r--r--rts/sm/Storage.c58
1 files changed, 54 insertions, 4 deletions
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index 5c4e54f98d..5d5470b025 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;