From ed44ee33c2ffbdf13e5c8d211c162784b86661e6 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 18 Jun 2018 15:23:58 +0100 Subject: [PATCH] Awl asserts on fixes to unaligned exact references. New MMQA test case conerr/61.c checks this. Copied from Perforce Change: 193904 --- mps/code/poolawl.c | 11 ++++++-- mps/code/poollo.c | 1 + mps/test/conerr/61.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 mps/test/conerr/61.c diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c index 8c0a4673d5e..71b9075cc6e 100644 --- a/mps/code/poolawl.c +++ b/mps/code/poolawl.c @@ -995,12 +995,19 @@ static Res AWLFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) if (base < SegBase(seg)) { return ResOK; } + + /* Not a real reference if unaligned. */ + if (!AddrIsAligned(base, PoolAlignment(pool))) { + AVER_CRITICAL(ss->rank == RankAMBIG); + return ResOK; + } + i = awlIndexOfAddr(SegBase(seg), awl, base); switch(ss->rank) { case RankAMBIG: - /* not a real pointer if not aligned or not allocated */ - if (!AddrIsAligned(base, sizeof(void *)) || !BTGet(awlseg->alloc, i)) + /* not a real reference if not allocated */ + if (!BTGet(awlseg->alloc, i)) return ResOK; /* falls through */ case RankEXACT: diff --git a/mps/code/poollo.c b/mps/code/poollo.c index d388bbacdc4..4a1ebea034a 100644 --- a/mps/code/poollo.c +++ b/mps/code/poollo.c @@ -717,6 +717,7 @@ static Res LOFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) return ResOK; } + /* Not a real reference if unaligned. */ if (!AddrIsAligned(base, PoolAlignment(pool))) { AVER_CRITICAL(ss->rank == RankAMBIG); return ResOK; diff --git a/mps/test/conerr/61.c b/mps/test/conerr/61.c new file mode 100644 index 00000000000..557375a8637 --- /dev/null +++ b/mps/test/conerr/61.c @@ -0,0 +1,65 @@ +/* +TEST_HEADER + id = $Id$ + summary = AWL pool asserts on unaligned exact reference + language = c + link = myfmt.o testlib.o +OUTPUT_SPEC + assert = true + assertfile P= poolawl.c + assertcond = ss->rank == RankAMBIG +END_HEADER +*/ + +#include "testlib.h" +#include "mpscawl.h" +#include "myfmt.h" + +static void test(void) +{ + void *marker = ▮ + mps_arena_t arena; + mps_pool_t pool; + mps_thr_t thread; + mps_root_t root; + mps_fmt_t format; + mps_ap_t ap; + mps_addr_t p, q, unaligned; + + cdie(mps_arena_create_k(&arena, mps_arena_class_vm(), mps_args_none), "create arena"); + mps_arena_park(arena); + cdie(mps_thread_reg(&thread, arena), "register thread"); + cdie(mps_root_create_thread(&root, arena, thread, marker), "create root"); + cdie(mps_fmt_create_A(&format, arena, &fmtA), "create format"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); + cdie(mps_pool_create_k(&pool, arena, mps_class_awl(), args), "pool"); + } MPS_ARGS_END(args); + cdie(mps_ap_create(&ap, pool, mps_rank_exact()), "ap"); + + /* p is in the AWL pool */ + p = allocone(ap, 0, NULL, NULL, sizeof(mycell)); + unaligned = (void *)((char*)p + 1); + + /* q is in the AWL pool with unaligned exact reference to p */ + q = allocone(ap, 1, p, unaligned, sizeof(mycell)); + + mps_arena_start_collect(arena); + mps_arena_park(arena); + + /* Keep q (and thus p) alive during the collection. */ + report("q", "%p", q); + + mps_ap_destroy(ap); + mps_pool_destroy(pool); + mps_fmt_destroy(format); + mps_root_destroy(root); + mps_thread_dereg(thread); + mps_arena_destroy(arena); +} + +int main(void) +{ + easy_tramp(test); + return 0; +}