Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions code/amcssth.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,22 @@ static mps_res_t area_scan(mps_ss_t ss, void *base, void *limit, void *closure)

static void churn(mps_ap_t ap, size_t roots_count)
{
size_t i;
size_t r;
size_t i, j, r;

++objs;
r = (size_t)rnd();
if (r & 1) {
mps_addr_t root;
i = (r >> 1) % exactRootsCOUNT;
if (exactRoots[i] != objNULL)
cdie(dylan_check(exactRoots[i]), "dying root check");
exactRoots[i] = make(ap, roots_count);
if (exactRoots[(exactRootsCOUNT-1) - i] != objNULL)
dylan_write(exactRoots[(exactRootsCOUNT-1) - i],
exactRoots, exactRootsCOUNT);
atomic_load(&exactRoots[i], &root);
if (root != objNULL)
cdie(dylan_check(root), "dying root check");
root = make(ap, roots_count);
atomic_store(&exactRoots[i], &root);
j = exactRootsCOUNT - i - 1;
atomic_load(&exactRoots[j], &root);
if (root != objNULL)
dylan_write(root, exactRoots, exactRootsCOUNT);
} else {
i = (r >> 1) % ambigRootsCOUNT;
ambigRoots[(ambigRootsCOUNT-1) - i] = make(ap, roots_count);
Expand Down Expand Up @@ -221,9 +224,11 @@ static void test_pool(const char *name, mps_pool_t pool, size_t roots_count)
(unsigned long)collections, objs,
(unsigned long)mps_arena_committed(arena));

for (i = 0; i < exactRootsCOUNT; ++i)
cdie(exactRoots[i] == objNULL || dylan_check(exactRoots[i]),
"all roots check");
for (i = 0; i < exactRootsCOUNT; ++i) {
mps_addr_t root;
atomic_load(&exactRoots[i], &root);
cdie(root == objNULL || dylan_check(root), "all roots check");
}

if (collections >= collectionsCOUNT / 2 && !walked)
{
Expand All @@ -248,9 +253,12 @@ static void test_pool(const char *name, mps_pool_t pool, size_t roots_count)
ramping = 0;
/* kill half of the roots */
for(i = 0; i < exactRootsCOUNT; i += 2) {
if (exactRoots[i] != objNULL) {
cdie(dylan_check(exactRoots[i]), "ramp kill check");
exactRoots[i] = objNULL;
mps_addr_t root;
atomic_load(&exactRoots[i], &root);
if (root != objNULL) {
cdie(dylan_check(root), "ramp kill check");
root = objNULL;
atomic_store(&exactRoots[i], &root);
}
}
}
Expand Down Expand Up @@ -298,6 +306,8 @@ static void test_arena(void)
mps_pool_t amc_pool, amcz_pool;
void *marker = &marker;

die(dylan_make_wrappers(), "make wrappers");

MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, testArenaSIZE);
MPS_ARGS_ADD(args, MPS_KEY_ARENA_GRAIN_SIZE, rnd_grain(testArenaSIZE));
Expand Down
17 changes: 17 additions & 0 deletions code/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,23 @@
#define WB_DEFER_HIT 1 /* boring scans after barrier hit */


/* Apple Hardened Runtime
*
* .hardened-runtime: On Apple Silicon, applications may be compiled
* with Hardened Runtime enabled. These applications have restricted
* capabilities: in particular, unless the "Allow Unsigned Executable
* Memory Entitlement" is enabled, these applications cannot create
* memory that is simultaneously writable and executable. Attempts to
* do so using mmap() and mprotect() fail with EACCES.
*
* See <https://developer.apple.com/documentation/security/hardened_runtime>
*/
#if defined(MPS_OS_XC) && defined(MPS_ARCH_A6)
#define MAYBE_HARDENED_RUNTIME 1
#else
#define MAYBE_HARDENED_RUNTIME 0
#endif

#endif /* config_h */


Expand Down
9 changes: 3 additions & 6 deletions code/fmtdytst.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ mps_res_t dylan_make_wrappers(void)
return MPS_RES_OK;
}

/* dylan_init -- turn raw memory into initialised dylan-vector (or pad)
/* dylan_init -- turn raw memory into initialised dylan-vector
*
* If the raw memory is large enough, initialises it to a dylan-vector,
* whose slots are initialised to either dylan-ints, or valid refs, at
Expand All @@ -78,8 +78,6 @@ mps_res_t dylan_make_wrappers(void)
* and "nr_refs" arguments. If "nr_refs" is 0, all slots are
* initialized to dylan-ints: this may be useful for making leaf
* objects.
*
* (Makes a pad if the raw memory is too small to hold a dylan-vector)
*/

mps_res_t dylan_init(mps_addr_t addr, size_t size,
Expand All @@ -93,8 +91,7 @@ mps_res_t dylan_init(mps_addr_t addr, size_t size,
if (res != MPS_RES_OK)
return res;

/* If there is enough room, make a vector, otherwise just */
/* make a padding object. */
/* If there is enough room, make a vector. */
if(size >= sizeof(mps_word_t) * 2) {
mps_word_t *p = (mps_word_t *)addr;
mps_word_t i, t = (size / sizeof(mps_word_t)) - 2;
Expand All @@ -110,7 +107,7 @@ mps_res_t dylan_init(mps_addr_t addr, size_t size,
p[2+i] = (mps_word_t)refs[(r >> 1) % nr_refs]; /* random ptr */
}
} else {
dylan_pad(addr, size);
return MPS_RES_UNIMPL;
}

return MPS_RES_OK;
Expand Down
22 changes: 19 additions & 3 deletions code/protix.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,29 @@

#include "vm.h"

#include <errno.h>
#include <limits.h>
#include <signal.h> /* sig_atomic_t */
#include <stddef.h>
#include <sys/mman.h>
#include <sys/types.h>

SRCID(protix, "$Id$");


/* Value for memory protection corresponding to AccessSetEMPTY. */

static sig_atomic_t prot_all = PROT_READ | PROT_WRITE | PROT_EXEC;


/* ProtSet -- set protection
*
* This is just a thin veneer on top of mprotect(2).
*/

void ProtSet(Addr base, Addr limit, AccessSet mode)
{
int flags;
int flags, result;

AVER(sizeof(size_t) == sizeof(Addr));
AVER(base < limit);
Expand All @@ -82,15 +90,23 @@ void ProtSet(Addr base, Addr limit, AccessSet mode)
flags = PROT_READ | PROT_EXEC;
break;
case AccessSetEMPTY:
flags = PROT_READ | PROT_WRITE | PROT_EXEC;
flags = prot_all;
break;
default:
NOTREACHED;
flags = PROT_NONE;
}

/* .assume.mprotect.base */
if(mprotect((void *)base, (size_t)AddrOffset(base, limit), flags) != 0)
result = mprotect((void *)base, (size_t)AddrOffset(base, limit), flags);
if (MAYBE_HARDENED_RUNTIME && result != 0 && errno == EACCES
&& (flags & PROT_WRITE) && (flags & PROT_EXEC))
{
/* See <config.h#hardened-runtime>. */
prot_all = PROT_READ | PROT_WRITE;
result = mprotect((void *)base, (size_t)AddrOffset(base, limit), flags & prot_all);
}
if (result != 0)
NOTREACHED;
}

Expand Down
19 changes: 19 additions & 0 deletions code/testlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,25 @@ extern void randomize(int argc, char *argv[]);
extern void testlib_init(int argc, char *argv[]);


/* Memory-model-aware operations */

#if defined(MPS_BUILD_GC) || defined(MPS_BUILD_LL)

/* See <https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html>
* and <https://clang.llvm.org/docs/LanguageExtensions.html> */
#define atomic_load(SRC, DEST) __atomic_load(SRC, DEST, __ATOMIC_ACQUIRE)
#define atomic_store(DEST, SRC) __atomic_store(DEST, SRC, __ATOMIC_RELEASE)

#elif defined(MPS_BUILD_MV)

/* Microsoft Visual C/C++ does not need memory-model-aware load and store as
* loads and stores of register-sized values are atomic on Intel. */
#define atomic_load(SRC, DEST) (*(DEST) = *(SRC))
#define atomic_store(DEST, SRC) (*(DEST) = *(SRC))

#endif


#endif /* testlib_h */


Expand Down
25 changes: 20 additions & 5 deletions code/vmix.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "vm.h"

#include <errno.h> /* errno */
#include <signal.h> /* sig_atomic_t */
#include <sys/mman.h> /* see .feature.li in config.h */
#include <sys/types.h> /* mmap, munmap */
#include <unistd.h> /* getpagesize */
Expand Down Expand Up @@ -156,11 +157,17 @@ void VMFinish(VM vm)
}


/* Value to use for protection of newly allocated pages. */

static sig_atomic_t vm_prot = PROT_READ | PROT_WRITE | PROT_EXEC;


/* VMMap -- map the given range of memory */

Res VMMap(VM vm, Addr base, Addr limit)
{
Size size;
void *result;

AVERT(VM, vm);
AVER(sizeof(void *) == sizeof(Addr));
Expand All @@ -172,11 +179,19 @@ Res VMMap(VM vm, Addr base, Addr limit)

size = AddrOffset(base, limit);

if(mmap((void *)base, (size_t)size,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANON | MAP_PRIVATE | MAP_FIXED,
-1, 0)
== MAP_FAILED) {
result = mmap((void *)base, (size_t)size, vm_prot,
MAP_ANON | MAP_PRIVATE | MAP_FIXED,
-1, 0);
if (MAYBE_HARDENED_RUNTIME && result == MAP_FAILED && errno == EACCES
&& (vm_prot & PROT_WRITE) && (vm_prot & PROT_EXEC))
{
/* See <config.h#hardened-runtime>. */
vm_prot = PROT_READ | PROT_WRITE;
result = mmap((void *)base, (size_t)size, vm_prot,
MAP_ANON | MAP_PRIVATE | MAP_FIXED,
-1, 0);
}
if (result == MAP_FAILED) {
AVER(errno == ENOMEM); /* .assume.mmap.err */
return ResMEMORY;
}
Expand Down
18 changes: 11 additions & 7 deletions test/function/150.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ OUTPUT_SPEC
count1 < 50
count2 < 50
collect = true
collect_not_condemned <= 4096
collect_not_condemned_grains <= 1
result = pass
END_HEADER
*/
Expand All @@ -30,6 +30,7 @@ mps_arena_t arena;

int final_count = 0;

size_t grain_size = 0;

enum {
FINAL_DISCARD,
Expand Down Expand Up @@ -115,12 +116,12 @@ static void qpoll(mycell **ref, int faction)
static void process_stats(mps_message_t message)
{
report("collect", "true");
report("collect_live", "%ld",
mps_message_gc_live_size(arena, message));
report("collect_condemned", "%ld",
mps_message_gc_condemned_size(arena, message));
report("collect_not_condemned", "%ld",
mps_message_gc_not_condemned_size(arena, message));
report("collect_live_grains", "%ld",
mps_message_gc_live_size(arena, message) / grain_size);
report("collect_condemned_grains", "%ld",
mps_message_gc_condemned_size(arena, message) / grain_size);
report("collect_not_condemned_grains", "%ld",
mps_message_gc_not_condemned_size(arena, message) / grain_size);
mps_message_discard(arena, message);
}

Expand Down Expand Up @@ -191,6 +192,9 @@ static void test(void *stack_pointer)

a = allocone(apamc, 2, 1);

/* Deduce arena's grain size from the total size of the AMC pool. */
grain_size = mps_pool_total_size(poolamc);

for (j=0; j<1000; j++) {
b = allocone(apamc, 2, mps_rank_exact());
c = allocone(apawl, 2, mps_rank_weak());
Expand Down