Bladeren bron

added GC_INTERIOR_POINTERS support (for stack scan only)

Nicolas Cannasse 5 jaren geleden
bovenliggende
commit
cfc02e6eb5
2 gewijzigde bestanden met toevoegingen van 23 en 5 verwijderingen
  1. 12 5
      src/allocator.c
  2. 11 0
      src/gc.c

+ 12 - 5
src/allocator.c

@@ -422,13 +422,20 @@ static int gc_allocator_get_block_id( gc_pheader *page, void *block ) {
 	if( offset%page->alloc.block_size != 0 )
 	if( offset%page->alloc.block_size != 0 )
 		return -1;
 		return -1;
 	int bid = offset / page->alloc.block_size;
 	int bid = offset / page->alloc.block_size;
+	if( page->alloc.sizes && page->alloc.sizes[bid] == 0 ) return -1;
+	return bid;
+}
+
+static int gc_allocator_get_block_interior( gc_pheader *page, void **block ) {
+	int offset = (int)((unsigned char*)*block - page->base);
+	int bid = offset / page->alloc.block_size;
 	if( page->alloc.sizes ) {
 	if( page->alloc.sizes ) {
-		if( page->alloc.sizes[bid] == 0 ) return -1;
-	} else {
-		// no longer required ?
-		if( bid < page->alloc.first_block )
-			return -1;
+		while( page->alloc.sizes[bid] == 0 ) {
+			if( bid == page->alloc.first_block ) return -1;
+			bid--;
+		}
 	}
 	}
+	*block = page->base + bid * page->alloc.block_size;
 	return bid;
 	return bid;
 }
 }
 
 

+ 11 - 0
src/gc.c

@@ -73,6 +73,10 @@ static int_val gc_hash( void *ptr ) {
 #	define GC_MEMCHK
 #	define GC_MEMCHK
 #endif
 #endif
 
 
+#if defined(HL_NX)
+#	define GC_INTERIOR_POINTERS
+#endif
+
 #define out_of_memory(reason)		hl_fatal("Out of Memory (" reason ")")
 #define out_of_memory(reason)		hl_fatal("Out of Memory (" reason ")")
 
 
 typedef struct _gc_pheader gc_pheader;
 typedef struct _gc_pheader gc_pheader;
@@ -89,6 +93,9 @@ int gc_allocator_fast_block_size( gc_pheader *page, void *block );
 // Get the block id within the given page, or -1 if it's an invalid ptr. The block is already checked within page bounds
 // Get the block id within the given page, or -1 if it's an invalid ptr. The block is already checked within page bounds
 int gc_allocator_get_block_id( gc_pheader *page, void *block );
 int gc_allocator_get_block_id( gc_pheader *page, void *block );
 
 
+// Same as get_block_id but handles interior pointers and modify the block value
+int gc_allocator_get_block_id_interior( gc_pheader *page, void **block );
+
 // Called before marking starts: should update each page "bmp" with mark_bits
 // Called before marking starts: should update each page "bmp" with mark_bits
 void gc_allocator_before_mark( unsigned char *mark_bits );
 void gc_allocator_before_mark( unsigned char *mark_bits );
 
 
@@ -581,7 +588,11 @@ static void gc_mark_stack( void *start, void *end ) {
 		void *p = *stack_head++;
 		void *p = *stack_head++;
 		gc_pheader *page = GC_GET_PAGE(p);
 		gc_pheader *page = GC_GET_PAGE(p);
 		if( !page || !INPAGE(p,page) ) continue;
 		if( !page || !INPAGE(p,page) ) continue;
+#		ifdef GC_INTERIOR_POINTERS
+		int bid = gc_allocator_get_block_interior(page, &p);
+#		else
 		int bid = gc_allocator_get_block_id(page, p);
 		int bid = gc_allocator_get_block_id(page, p);
+#		endif
 		if( bid >= 0 && (page->bmp[bid>>3] & (1<<(bid&7))) == 0 ) {
 		if( bid >= 0 && (page->bmp[bid>>3] & (1<<(bid&7))) == 0 ) {
 			page->bmp[bid>>3] |= 1<<(bid&7);
 			page->bmp[bid>>3] |= 1<<(bid&7);
 			GC_PUSH_GEN(p,page);
 			GC_PUSH_GEN(p,page);