X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FStorage.c;h=caadd6fc8c60ec135108f4a5059c76bd35c5a3b9;hb=256a006fc9ae215926e5a0645b85d86cd683701d;hp=a6c6bd06a50517614244937b8d5978dd6dbf212e;hpb=117bf3f003b3bed4988a029ce74ff07565c953ed;p=ghc-hetmet.git diff --git a/ghc/rts/Storage.c b/ghc/rts/Storage.c index a6c6bd0..caadd6f 100644 --- a/ghc/rts/Storage.c +++ b/ghc/rts/Storage.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: Storage.c,v 1.56 2001/11/28 14:30:32 simonmar Exp $ + * $Id: Storage.c,v 1.60 2002/03/21 11:23:59 sebc Exp $ * * (c) The GHC Team, 1998-1999 * @@ -21,10 +21,48 @@ #include "Storage.h" #include "Schedule.h" +#include "OSThreads.h" #include "StoragePriv.h" #include "RetainerProfile.h" // for counting memory blocks (memInventory) +#ifdef darwin_TARGET_OS +#include +#include +#include +#include +#include +#include +unsigned long macho_etext = 0; +unsigned long macho_edata = 0; +#define IN_RANGE(base,size,x) (((P_)base) <= ((P_)x) && ((P_)x) < ((P_)((unsigned long)base + size))) +static void macosx_get_memory_layout(void) +{ + vm_address_t address; + vm_size_t size; + struct vm_region_basic_info info; + mach_msg_type_number_t info_count; + mach_port_t object_name; + task_t task = mach_task_self(); + P_ in_text = ((P_*)(&stg_BLACKHOLE_info))[0]; + P_ in_data = (P_)&stg_dummy_ret_closure; + + address = 0; /* VM_MIN_ADDRESS */ + while (1) { + info_count = VM_REGION_BASIC_INFO_COUNT; + if (vm_region(task, &address, &size, VM_REGION_BASIC_INFO, + (vm_region_info_t)&info, &info_count, &object_name) + != KERN_SUCCESS) + break; + if (IN_RANGE(address, size, in_text)) + macho_etext = address + size; + if (IN_RANGE(address, size, in_data)) + macho_edata = address + size; + address += size; + } +} +#endif + StgClosure *caf_list = NULL; bdescr *small_alloc_list; /* allocate()d small objects */ @@ -48,7 +86,7 @@ lnat total_allocated = 0; /* total memory allocated during run */ * simultaneous access by two STG threads. */ #ifdef SMP -pthread_mutex_t sm_mutex = PTHREAD_MUTEX_INITIALIZER; +Mutex sm_mutex = INIT_MUTEX_VAR; #endif /* @@ -65,6 +103,30 @@ initStorage( void ) step *stp; generation *gen; +#if defined(darwin_TARGET_OS) + macosx_get_memory_layout(); +#endif + + /* Sanity check to make sure we are able to make the distinction + * between closures and infotables + */ + if (!LOOKS_LIKE_GHC_INFO(&stg_BLACKHOLE_info)) { + barf("LOOKS_LIKE_GHC_INFO+ is incorrectly defined"); + exit(0); + } + if (LOOKS_LIKE_GHC_INFO(&stg_dummy_ret_closure)) { + barf("LOOKS_LIKE_GHC_INFO- is incorrectly defined"); + exit(0); + } + if (LOOKS_LIKE_STATIC_CLOSURE(&stg_BLACKHOLE_info)) { + barf("LOOKS_LIKE_STATIC_CLOSURE- is incorrectly defined"); + exit(0); + } + if (!LOOKS_LIKE_STATIC_CLOSURE(&stg_dummy_ret_closure)) { + barf("LOOKS_LIKE_STATIC_CLOSURE+ is incorrectly defined"); + exit(0); + } + if (RtsFlags.GcFlags.maxHeapSize != 0 && RtsFlags.GcFlags.heapSizeSuggestion > RtsFlags.GcFlags.maxHeapSize) { @@ -80,6 +142,10 @@ initStorage( void ) initBlockAllocator(); +#if defined(SMP) + initCondition(&sm_mutex); +#endif + /* allocate generation info array */ generations = (generation *)stgMallocBytes(RtsFlags.GcFlags.generations * sizeof(struct _generation), @@ -190,8 +256,8 @@ initStorage( void ) /* Tell GNU multi-precision pkg about our custom alloc functions */ mp_set_memory_functions(stgAllocForGMP, stgReallocForGMP, stgDeallocForGMP); -#ifdef SMP - pthread_mutex_init(&sm_mutex, NULL); +#if defined(SMP) + initMutex(&sm_mutex); #endif IF_DEBUG(gc, statDescribeGens()); @@ -254,7 +320,7 @@ newCAF(StgClosure* caf) * come to do a major GC we won't need the mut_link field * any more and can use it as a STATIC_LINK. */ - ACQUIRE_LOCK(&sm_mutex); + ACQUIRE_SM_LOCK; if (is_dynamically_loaded_rwdata_ptr((StgPtr)caf)) { ((StgIndStatic *)caf)->saved_info = (StgInfoTable *)caf->header.info; @@ -266,7 +332,7 @@ newCAF(StgClosure* caf) oldest_gen->mut_once_list = (StgMutClosure *)caf; } - RELEASE_LOCK(&sm_mutex); + RELEASE_SM_LOCK; #ifdef PAR /* If we are PAR or DIST then we never forget a CAF */ @@ -293,9 +359,9 @@ allocNurseries( void ) g0s0->blocks = NULL; g0s0->n_blocks = 0; for (cap = free_capabilities; cap != NULL; cap = cap->link) { - cap->rNursery = allocNursery(NULL, RtsFlags.GcFlags.minAllocAreaSize); - cap->rCurrentNursery = cap->rNursery; - for (bd = cap->rNursery; bd != NULL; bd = bd->link) { + cap->r.rNursery = allocNursery(NULL, RtsFlags.GcFlags.minAllocAreaSize); + cap->r.rCurrentNursery = cap->r.rNursery; + for (bd = cap->r.rNursery; bd != NULL; bd = bd->link) { bd->u.back = (bdescr *)cap; } } @@ -325,29 +391,16 @@ resetNurseries( void ) ASSERT(n_free_capabilities == RtsFlags.ParFlags.nNodes); for (cap = free_capabilities; cap != NULL; cap = cap->link) { - for (bd = cap->rNursery; bd; bd = bd->link) { + for (bd = cap->r.rNursery; bd; bd = bd->link) { bd->free = bd->start; ASSERT(bd->gen_no == 0); ASSERT(bd->step == g0s0); IF_DEBUG(sanity,memset(bd->start, 0xaa, BLOCK_SIZE)); } - cap->rCurrentNursery = cap->rNursery; + cap->r.rCurrentNursery = cap->r.rNursery; } #else for (bd = g0s0->blocks; bd; bd = bd->link) { -#ifdef PROFILING - // Reset every word in the nursery to zero when doing LDV profiling. - // This relieves the mutator of the burden of zeroing every new closure, - // which is stored in the nursery. - // - // Todo: make it more efficient, e.g. memcpy() - // - StgPtr p; - if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_LDV) { - for (p = bd->start; p < bd->start + BLOCK_SIZE_W; p++) - *p = 0; - } -#endif bd->free = bd->start; ASSERT(bd->gen_no == 0); ASSERT(bd->step == g0s0); @@ -451,7 +504,7 @@ allocate( nat n ) bdescr *bd; StgPtr p; - ACQUIRE_LOCK(&sm_mutex); + ACQUIRE_SM_LOCK; TICK_ALLOC_HEAP_NOCTR(n); CCS_ALLOC(CCCS,n); @@ -472,7 +525,7 @@ allocate( nat n ) * much difference. */ alloc_blocks += req_blocks; - RELEASE_LOCK(&sm_mutex); + RELEASE_SM_LOCK; return bd->start; /* small allocation (= LARGE_OBJECT_THRESHOLD/sizeof(W_)) { - RELEASE_LOCK(&sm_mutex); + RELEASE_SM_LOCK; return allocate(n); } @@ -558,7 +611,7 @@ allocatePinned( nat n ) p = bd->free; bd->free += n; - RELEASE_LOCK(&sm_mutex); + RELEASE_SM_LOCK; return p; } @@ -648,13 +701,13 @@ calcAllocated( void ) + allocated_bytes(); for (cap = free_capabilities; cap != NULL; cap = cap->link) { - for ( bd = cap->rCurrentNursery->link; bd != NULL; bd = bd->link ) { + for ( bd = cap->r.rCurrentNursery->link; bd != NULL; bd = bd->link ) { allocated -= BLOCK_SIZE_W; } - if (cap->rCurrentNursery->free < cap->rCurrentNursery->start + if (cap->r.rCurrentNursery->free < cap->r.rCurrentNursery->start + BLOCK_SIZE_W) { - allocated -= (cap->rCurrentNursery->start + BLOCK_SIZE_W) - - cap->rCurrentNursery->free; + allocated -= (cap->r.rCurrentNursery->start + BLOCK_SIZE_W) + - cap->r.rCurrentNursery->free; } }