Skip to content

Commit

Permalink
use libffi for iOS adjustors; fixes #7718
Browse files Browse the repository at this point in the history
Based on a patch from Stephen Blackheath.
  • Loading branch information
Ian Lynagh committed Jun 8, 2013
1 parent 0d86038 commit 972c044
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 6 deletions.
7 changes: 5 additions & 2 deletions includes/rts/storage/GC.h
Expand Up @@ -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;
Expand Down
58 changes: 54 additions & 4 deletions rts/sm/Storage.c
Expand Up @@ -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>

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit 972c044

Please sign in to comment.