static void push(void **block) { void *obj = *block; struct segment *seg; size_t index; bitptr_t b; if (!IS_IN_HEAP(obj)) { DBG(("%p at %p outside", obj, block)); if (obj != NULL) sml_trace_ptr(obj); return; } seg = OBJ_TO_SEGMENT(obj); index = OBJ_TO_INDEX(seg, obj); BITPTR_INIT(b, BITMAP0_BASE(seg), index); if (BITPTR_TEST(b)) { DBG(("already marked: %p", obj)); return; } MARKBIT(b, index, seg); DBG(("MARK: %p", obj)); if (OBJ_HAS_NO_POINTER(obj)) { DBG(("EARLYMARK: %p", obj)); return; } STACK_PUSH(obj, seg, index); DBG(("PUSH: %p", obj)); }
SML_PRIMITIVE void sml_write(void *objaddr, void **writeaddr, void *new_value) { *writeaddr = new_value; if (!IS_IN_HEAP(writeaddr)) sml_global_barrier(writeaddr, objaddr); }
static void mark(void **block) { void *obj = *block; struct segment *seg; size_t index; bitptr_t b; ASSERT(STACK_TOP() == NULL); if (!IS_IN_HEAP(obj)) { DBG(("%p at %p outside", obj, block)); if (obj != NULL) sml_trace_ptr(obj); return; } seg = OBJ_TO_SEGMENT(obj); index = OBJ_TO_INDEX(seg, obj); BITPTR_INIT(b, BITMAP0_BASE(seg), index); if (BITPTR_TEST(b)) { DBG(("already marked: %p", obj)); return; } MARKBIT(b, index, seg); DBG(("MARK: %p", obj)); if (OBJ_HAS_NO_POINTER(obj)) { DBG(("EARLYMARK: %p", obj)); return; } for (;;) { sml_obj_enum_ptr(obj, push); obj = STACK_TOP(); if (obj == NULL) { DBG(("MARK END")); break; } STACK_POP(obj); DBG(("POP: %p", obj)); } }
_WCRTLINK void _nfree( void_nptr cstg ) { heapblk_nptr heap; heapblk_nptr heap2; if( cstg == NULL ) return; _AccessNHeap(); do { // first try some likely locations heap = __MiniHeapFreeRover; if( heap != NULL ) { if( IS_IN_HEAP( cstg, heap ) ) { break; } heap2 = heap; heap = heap->prev.nptr; if( heap != NULL ) { if( IS_IN_HEAP( cstg, heap ) ) { break; } } heap = heap2->next.nptr; if( heap != NULL ) { if( IS_IN_HEAP( cstg, heap ) ) { break; } } } heap = __MiniHeapRover; if( heap != NULL ) { if( IS_IN_HEAP( cstg, heap ) ) { break; } heap2 = heap; heap = heap->prev.nptr; if( heap != NULL ) { if( IS_IN_HEAP( cstg, heap ) ) { break; } } heap = heap2->next.nptr; if( heap != NULL ) { if( IS_IN_HEAP( cstg, heap ) ) { break; } } } // not found near rover, so search the list for( heap = __nheapbeg; heap != NULL; heap = heap->next.nptr ) { if( IS_IN_HEAP( cstg, heap ) ) { // break twice! goto found_it; } } // this pointer is not in the heap _ReleaseNHeap(); return; } while( 0 ); found_it: // we found the miniheap, free the storage #ifdef _M_I86 __MemFree( cstg, _DGroup(), heap ); #else __MemFree( cstg, heap ); #endif __MiniHeapFreeRover = heap; if( heap < __MiniHeapRover ) { if( __LargestSizeB4MiniHeapRover < heap->largest_blk ) { __LargestSizeB4MiniHeapRover = heap->largest_blk; } } _ReleaseNHeap(); }