diff --git a/src/racket/gc2/newgc.c b/src/racket/gc2/newgc.c index 77d704a43c..9d871a4cf4 100644 --- a/src/racket/gc2/newgc.c +++ b/src/racket/gc2/newgc.c @@ -48,7 +48,6 @@ intptr_t mp_ac_freed; #if 0 #define POINTER_OWNERSHIP_CHECK -#define LOCK_PAGE_TABLES_FOR_DEBUG #endif #define MZ_PRECISE_GC /* required for mz includes to work right */ @@ -378,17 +377,67 @@ inline static void check_used_against_max(NewGC *gc, size_t len) #include "vm.c" +#ifdef POINTER_OWNERSHIP_CHECK +# define SHARED_PAGE_ORPHANED ((NewGC *)0x1) +static mzrt_mutex *lock; +static PageMap shared_pagemap; +inline static void pagemap_set(PageMap page_maps1, void *p, mpage *value); +inline static mpage *pagemap_find_page(PageMap page_maps1, const void *p); +void shared_pagemap_set(void *ptr, size_t len, NewGC *owner) +{ + if (!lock) { + mzrt_mutex_create(&lock); +# ifdef SIXTY_FOUR_BIT_INTEGERS + shared_pagemap = ofm_malloc_zero(PAGEMAP64_LEVEL1_SIZE * sizeof (mpage***)); +# else + shared_pagemap = ofm_malloc_zero(PAGEMAP32_SIZE * sizeof (mpage*)); +# endif + } + + mzrt_mutex_lock(lock); + while (len > 0) { + pagemap_set(shared_pagemap, ptr, (mpage*)owner); + len -= APAGE_SIZE; + ptr = (char *)ptr + APAGE_SIZE; + } + mzrt_mutex_unlock(lock); +} +void check_page_owner(NewGC *gc, const void *p) +{ + NewGC *owner; + owner = (NewGC *)pagemap_find_page(shared_pagemap, p); + if (owner && (owner != gc) && (owner != MASTERGC) && (owner != SHARED_PAGE_ORPHANED)) { + mzrt_mutex_lock(lock); + owner = (NewGC *)pagemap_find_page(shared_pagemap, p); + if (owner && (owner != gc) && (owner != MASTERGC) && (owner != SHARED_PAGE_ORPHANED)) { + printf("%p is owned by place %i not the current place %i\n", p, owner->place_id, gc->place_id); + abort(); + } + mzrt_mutex_unlock(lock); + } +} +#endif + static void *malloc_pages(NewGC *gc, size_t len, size_t alignment, int dirty, int type, int expect_mprotect, void **src_block) { void *ptr; check_used_against_max(gc, len); ptr = mmu_alloc_page(gc->mmu, len, alignment, dirty, type, expect_mprotect, src_block); if (!ptr) out_of_memory(); + +#ifdef POINTER_OWNERSHIP_CHECK + shared_pagemap_set(ptr, len, gc); +#endif + return ptr; } static void free_pages(NewGC *gc, void *p, size_t len, int type, int expect_mprotect, void **src_block) { +#ifdef POINTER_OWNERSHIP_CHECK + shared_pagemap_set(p, len, NULL); +#endif + gc->used_pages -= size_to_apage_count(len); mmu_free_page(gc->mmu, p, len, type, expect_mprotect, src_block, 1); } @@ -403,6 +452,10 @@ static void check_excessive_free_pages(NewGC *gc) { } static void free_orphaned_page(NewGC *gc, mpage *tmp) { +#ifdef POINTER_OWNERSHIP_CHECK + shared_pagemap_set(tmp->addr, round_to_apage_size(tmp->size), NULL); +#endif + /* free_pages decrements gc->used_pages which is incorrect, since this is an orphaned page, * so we use mmu_free_page directly */ mmu_free_page(gc->mmu, tmp->addr, round_to_apage_size(tmp->size), @@ -423,6 +476,11 @@ static void orphan_page_accounting(NewGC *gc, size_t allocate_size) { inline static void pagemap_add_with_size(PageMap pagemap, mpage *page, intptr_t size); static void adopt_page_accounting(NewGC *gc, mpage* tmp) { size_t realpagesize = real_page_size(tmp); + +#ifdef POINTER_OWNERSHIP_CHECK + shared_pagemap_set(tmp->addr, realpagesize, gc); +#endif + pagemap_add_with_size(gc->page_maps, tmp, realpagesize); mmu_memory_allocated_inc(gc->mmu, realpagesize); gc->used_pages += size_to_apage_count(realpagesize); @@ -480,10 +538,6 @@ inline static void free_page_maps(PageMap page_maps1) { /* the page map makes a nice mapping from addresses to pages, allowing fairly fast lookup. this is useful. */ inline static void pagemap_set(PageMap page_maps1, void *p, mpage *value) { -#ifdef LOCK_PAGE_TABLES_FOR_DEBUG - NewGC *gc = GC_get_GC(); - mzrt_mutex_lock(gc->pagetable_lock); -#endif #ifdef SIXTY_FOUR_BIT_INTEGERS uintptr_t pos; mpage ***page_maps2; @@ -505,34 +559,9 @@ inline static void pagemap_set(PageMap page_maps1, void *p, mpage *value) { #else page_maps1[PAGEMAP32_BITS(p)] = value; #endif -#ifdef LOCK_PAGE_TABLES_FOR_DEBUG - mzrt_mutex_unlock(gc->pagetable_lock); -#endif } inline static mpage *pagemap_find_page(PageMap page_maps1, const void *p) { -#ifdef LOCK_PAGE_TABLES_FOR_DEBUG - - mpage *result = NULL; - NewGC *gc = GC_get_GC(); - mzrt_mutex_lock(gc->pagetable_lock); -#ifdef SIXTY_FOUR_BIT_INTEGERS - mpage ***page_maps2; - mpage **page_maps3; - - page_maps2 = page_maps1[PAGEMAP64_LEVEL1_BITS(p)]; - if (!page_maps2) goto done; - page_maps3 = page_maps2[PAGEMAP64_LEVEL2_BITS(p)]; - if (!page_maps3) goto done; - result = page_maps3[PAGEMAP64_LEVEL3_BITS(p)]; - done: -#else - result = page_maps1[PAGEMAP32_BITS(p)]; -#endif - mzrt_mutex_unlock(gc->pagetable_lock); - return result; -#else - #ifdef SIXTY_FOUR_BIT_INTEGERS mpage ***page_maps2; mpage **page_maps3; @@ -545,8 +574,6 @@ inline static mpage *pagemap_find_page(PageMap page_maps1, const void *p) { #else return page_maps1[PAGEMAP32_BITS(p)]; #endif - -#endif } #if 0 @@ -958,6 +985,9 @@ static void *allocate_big(const size_t request_size_bytes, int type) page is going to be sent to a different place, so don't account for it here, and don't put it in the page_map */ orphan_page_accounting(gc, allocate_size); +#ifdef POINTER_OWNERSHIP_CHECK + shared_pagemap_set(bpage->addr, round_to_apage_size(allocate_size), SHARED_PAGE_ORPHANED); +#endif } else pagemap_add(gc->page_maps, bpage); @@ -994,9 +1024,12 @@ inline static mpage *create_new_medium_page(NewGC *gc, const int sz, const int p gc->med_pages[pos] = page; gc->med_freelist_pages[pos] = page; - if (gc->saved_allocator) /* see MESSAGE ALLOCATION above */ + if (gc->saved_allocator) { /* see MESSAGE ALLOCATION above */ orphan_page_accounting(gc, APAGE_SIZE); - else +#ifdef POINTER_OWNERSHIP_CHECK + shared_pagemap_set(page->addr, APAGE_SIZE, SHARED_PAGE_ORPHANED); +#endif + } else pagemap_add(gc->page_maps, page); return page; @@ -1105,9 +1138,12 @@ inline static mpage *gen0_create_new_nursery_mpage(NewGC *gc, const size_t page_ page->size = PREFIX_SIZE; GEN0_ALLOC_SIZE(page) = page_size; - if (gc->saved_allocator) /* see MESSAGE ALLOCATION above */ + if (gc->saved_allocator) { /* see MESSAGE ALLOCATION above */ orphan_page_accounting(gc, page_size); - else +#ifdef POINTER_OWNERSHIP_CHECK + shared_pagemap_set(page->addr, page_size, SHARED_PAGE_ORPHANED); +#endif + } else pagemap_add_with_size(gc->page_maps, page, page_size); GCVERBOSEPAGE(gc, "NEW gen0", page); @@ -2417,9 +2453,6 @@ static void NewGCMasterInfo_initialize() { MASTERGCINFO->alive = 0; MASTERGCINFO->ready = 0; MASTERGCINFO->signal_fds = realloc(MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size); -#ifdef POINTER_OWNERSHIP_CHECK - MASTERGCINFO->places_gcs = ofm_malloc_zero(sizeof(NewGC*) * MASTERGCINFO->size); -#endif for (i=0; i < 32; i++ ) { MASTERGCINFO->signal_fds[i] = (void *)REAPED_SLOT_AVAILABLE; } @@ -2564,9 +2597,6 @@ static intptr_t NewGCMasterInfo_find_free_id() { MASTERGCINFO->size++; MASTERGCINFO->alive++; MASTERGCINFO->signal_fds = realloc(MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size); -#ifdef POINTER_OWNERSHIP_CHECK - MASTERGCINFO->places_gcs= realloc(MASTERGCINFO->places_gcs, sizeof(NewGC*) * MASTERGCINFO->size); -#endif return MASTERGCINFO->size - 1; } else { @@ -2590,9 +2620,6 @@ static void NewGCMasterInfo_register_gc(NewGC *newgc) { intptr_t newid = NewGCMasterInfo_find_free_id(); newgc->place_id = newid; MASTERGCINFO->signal_fds[newid] = (void *) CREATED_BUT_NOT_REGISTERED; -#ifdef POINTER_OWNERSHIP_CHECK - MASTERGCINFO->places_gcs[newid] = newgc; -#endif } GC_LOCK_DEBUG("UNMGCLOCK NewGCMasterInfo_register_gc\n"); mzrt_rwlock_unlock(MASTERGCINFO->cangc); @@ -2665,9 +2692,6 @@ static NewGC *init_type_tags_worker(NewGC *inheritgc, NewGC *parentgc, NewGC *gc; gc = ofm_malloc_zero(sizeof(NewGC)); -#ifdef LOCK_PAGE_TABLES_FOR_DEBUG - mzrt_mutex_create(&gc->pagetable_lock); -#endif /* NOTE sets the constructed GC as the new Thread Specific GC. */ GC_set_GC(gc); @@ -2742,9 +2766,6 @@ void GC_destruct_child_gc() { waiting = MASTERGC->major_places_gc; if (!waiting) { MASTERGCINFO->signal_fds[gc->place_id] = (void *) REAPED_SLOT_AVAILABLE; -#ifdef POINTER_OWNERSHIP_CHECK - MASTERGCINFO->places_gcs[gc->place_id] = NULL; -#endif gc->place_id = -1; MASTERGCINFO->alive--; } @@ -2964,23 +2985,7 @@ void GC_mark2(const void *const_p, struct NewGC *gc) #endif { #ifdef POINTER_OWNERSHIP_CHECK - mzrt_rwlock_wrlock(MASTERGCINFO->cangc); - { - int i; - int size = MASTERGCINFO->size; - for (i = 1; i < size; i++) { - if (gc->place_id != i - && MASTERGCINFO->signal_fds[i] != (void*) REAPED_SLOT_AVAILABLE - && MASTERGCINFO->signal_fds[i] != (void*) CREATED_BUT_NOT_REGISTERED - && MASTERGCINFO->signal_fds[i] != (void*) SIGNALED_BUT_NOT_REGISTERED) { - if((page = pagemap_find_page(MASTERGCINFO->places_gcs[i]->page_maps, p))) { - printf("%p is owned by place %i not the current place %i\n", p, i, gc->place_id); - asm("int3"); - } - } - } - } - mzrt_rwlock_unlock(MASTERGCINFO->cangc); + check_page_owner(gc, p); #endif GCDEBUG((DEBUGOUTF,"Not marking %p (no page)\n",p)); return; @@ -3319,7 +3324,12 @@ void GC_fixup2(void *pp, struct NewGC *gc) if(info->mark && info->moved) *(void**)pp = *(void**)p; else GCDEBUG((DEBUGOUTF, "Not repairing %p from %p (not moved)\n",p,pp)); - } else GCDEBUG((DEBUGOUTF, "Not repairing %p from %p (no page)\n", p, pp)); + } else { +#ifdef POINTER_OWNERSHIP_CHECK + check_page_owner(gc, p); +#endif + GCDEBUG((DEBUGOUTF, "Not repairing %p from %p (no page)\n", p, pp)); + } } void GC_fixup(void *pp) diff --git a/src/racket/gc2/newgc.h b/src/racket/gc2/newgc.h index 04a47f45d0..1afef913b3 100644 --- a/src/racket/gc2/newgc.h +++ b/src/racket/gc2/newgc.h @@ -119,9 +119,6 @@ typedef struct NewGCMasterInfo { uintptr_t alive; uintptr_t ready; void **signal_fds; -#ifdef POINTER_OWNERSHIP_CHECK - struct NewGC **places_gcs; -#endif mzrt_rwlock *cangc; mzrt_sema *wait_sema; } NewGCMasterInfo; @@ -140,9 +137,6 @@ typedef struct NewGC { Mark2_Proc *mark_table; /* the table of mark procs */ Fixup2_Proc *fixup_table; /* the table of repair procs */ PageMap page_maps; -#ifdef LOCK_PAGE_TABLES_FOR_DEBUG - mzrt_mutex *pagetable_lock; -#endif /* All non-gen0 pages are held in the following structure. */ struct mpage *gen1_pages[PAGE_TYPES];