Initial revision
This commit is contained in:
		
							
								
								
									
										244
									
								
								gc/new_hblk.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								gc/new_hblk.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | ||||
| /* | ||||
|  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers | ||||
|  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved. | ||||
|  * | ||||
|  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED | ||||
|  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK. | ||||
|  * | ||||
|  * Permission is hereby granted to use or copy this program | ||||
|  * for any purpose,  provided the above notices are retained on all copies. | ||||
|  * Permission to modify the code and to distribute modified code is granted, | ||||
|  * provided the above notices are retained, and a notice that the code was | ||||
|  * modified is included with the above copyright notice. | ||||
|  * | ||||
|  * This file contains the functions: | ||||
|  *	ptr_t GC_build_flXXX(h, old_fl) | ||||
|  *	void GC_new_hblk(n) | ||||
|  */ | ||||
| /* Boehm, May 19, 1994 2:09 pm PDT */ | ||||
|  | ||||
|  | ||||
| # include <stdio.h> | ||||
| # include "gc_priv.h" | ||||
|  | ||||
| #ifndef SMALL_CONFIG | ||||
| /* | ||||
|  * Build a free list for size 1 objects inside hblk h.  Set the last link to | ||||
|  * be ofl.  Return a pointer tpo the first free list entry. | ||||
|  */ | ||||
| ptr_t GC_build_fl1(h, ofl) | ||||
| struct hblk *h; | ||||
| ptr_t ofl; | ||||
| { | ||||
|     register word * p = (word *)h; | ||||
|     register word * lim = (word *)(h + 1); | ||||
|      | ||||
|     p[0] = (word)ofl; | ||||
|     p[1] = (word)(p); | ||||
|     p[2] = (word)(p+1); | ||||
|     p[3] = (word)(p+2); | ||||
|     p += 4; | ||||
|     for (; p < lim; p += 4) { | ||||
|         p[0] = (word)(p-1); | ||||
|         p[1] = (word)(p); | ||||
|         p[2] = (word)(p+1); | ||||
|         p[3] = (word)(p+2); | ||||
|     }; | ||||
|     return((ptr_t)(p-1)); | ||||
| } | ||||
|  | ||||
| /* The same for size 2 cleared objects */ | ||||
| ptr_t GC_build_fl_clear2(h, ofl) | ||||
| struct hblk *h; | ||||
| ptr_t ofl; | ||||
| { | ||||
|     register word * p = (word *)h; | ||||
|     register word * lim = (word *)(h + 1); | ||||
|      | ||||
|     p[0] = (word)ofl; | ||||
|     p[1] = 0; | ||||
|     p[2] = (word)p; | ||||
|     p[3] = 0; | ||||
|     p += 4; | ||||
|     for (; p < lim; p += 4) { | ||||
|         p[0] = (word)(p-2); | ||||
|         p[1] = 0; | ||||
|         p[2] = (word)p; | ||||
|         p[3] = 0; | ||||
|     }; | ||||
|     return((ptr_t)(p-2)); | ||||
| } | ||||
|  | ||||
| /* The same for size 3 cleared objects */ | ||||
| ptr_t GC_build_fl_clear3(h, ofl) | ||||
| struct hblk *h; | ||||
| ptr_t ofl; | ||||
| { | ||||
|     register word * p = (word *)h; | ||||
|     register word * lim = (word *)(h + 1) - 2; | ||||
|      | ||||
|     p[0] = (word)ofl; | ||||
|     p[1] = 0; | ||||
|     p[2] = 0; | ||||
|     p += 3; | ||||
|     for (; p < lim; p += 3) { | ||||
|         p[0] = (word)(p-3); | ||||
|         p[1] = 0; | ||||
|         p[2] = 0; | ||||
|     }; | ||||
|     return((ptr_t)(p-3)); | ||||
| } | ||||
|  | ||||
| /* The same for size 4 cleared objects */ | ||||
| ptr_t GC_build_fl_clear4(h, ofl) | ||||
| struct hblk *h; | ||||
| ptr_t ofl; | ||||
| { | ||||
|     register word * p = (word *)h; | ||||
|     register word * lim = (word *)(h + 1); | ||||
|      | ||||
|     p[0] = (word)ofl; | ||||
|     p[1] = 0; | ||||
|     p[2] = 0; | ||||
|     p[3] = 0; | ||||
|     p += 4; | ||||
|     for (; p < lim; p += 4) { | ||||
|         p[0] = (word)(p-4); | ||||
|         p[1] = 0; | ||||
|         p[2] = 0; | ||||
|         p[3] = 0; | ||||
|     }; | ||||
|     return((ptr_t)(p-4)); | ||||
| } | ||||
|  | ||||
| /* The same for size 2 uncleared objects */ | ||||
| ptr_t GC_build_fl2(h, ofl) | ||||
| struct hblk *h; | ||||
| ptr_t ofl; | ||||
| { | ||||
|     register word * p = (word *)h; | ||||
|     register word * lim = (word *)(h + 1); | ||||
|      | ||||
|     p[0] = (word)ofl; | ||||
|     p[2] = (word)p; | ||||
|     p += 4; | ||||
|     for (; p < lim; p += 4) { | ||||
|         p[0] = (word)(p-2); | ||||
|         p[2] = (word)p; | ||||
|     }; | ||||
|     return((ptr_t)(p-2)); | ||||
| } | ||||
|  | ||||
| /* The same for size 4 uncleared objects */ | ||||
| ptr_t GC_build_fl4(h, ofl) | ||||
| struct hblk *h; | ||||
| ptr_t ofl; | ||||
| { | ||||
|     register word * p = (word *)h; | ||||
|     register word * lim = (word *)(h + 1); | ||||
|      | ||||
|     p[0] = (word)ofl; | ||||
|     p[4] = (word)p; | ||||
|     p += 8; | ||||
|     for (; p < lim; p += 8) { | ||||
|         p[0] = (word)(p-4); | ||||
|         p[4] = (word)p; | ||||
|     }; | ||||
|     return((ptr_t)(p-4)); | ||||
| } | ||||
|  | ||||
| #endif /* !SMALL_CONFIG */ | ||||
|  | ||||
| /* | ||||
|  * Allocate a new heapblock for small objects of size n. | ||||
|  * Add all of the heapblock's objects to the free list for objects | ||||
|  * of that size. | ||||
|  * Set all mark bits if objects are uncollectable. | ||||
|  * Will fail to do anything if we are out of memory. | ||||
|  */ | ||||
| void GC_new_hblk(sz, kind) | ||||
| register word sz; | ||||
| int kind; | ||||
| { | ||||
|     register word *p, | ||||
| 		  *prev; | ||||
|     word *last_object;		/* points to last object in new hblk	*/ | ||||
|     register struct hblk *h;	/* the new heap block			*/ | ||||
|     register GC_bool clear = GC_obj_kinds[kind].ok_init; | ||||
|  | ||||
| #   ifdef PRINTSTATS | ||||
| 	if ((sizeof (struct hblk)) > HBLKSIZE) { | ||||
| 	    ABORT("HBLK SZ inconsistency"); | ||||
|         } | ||||
| #   endif | ||||
|  | ||||
|   /* Allocate a new heap block */ | ||||
|     h = GC_allochblk(sz, kind, 0); | ||||
|     if (h == 0) return; | ||||
|  | ||||
|   /* Mark all objects if appropriate. */ | ||||
|       if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h)); | ||||
|  | ||||
|   /* Handle small objects sizes more efficiently.  For larger objects 	*/ | ||||
|   /* the difference is less significant.				*/ | ||||
| #  ifndef SMALL_CONFIG | ||||
|     switch (sz) { | ||||
|         case 1: GC_obj_kinds[kind].ok_freelist[1] = | ||||
|         	  GC_build_fl1(h, GC_obj_kinds[kind].ok_freelist[1]); | ||||
|         	return; | ||||
|         case 2: if (clear) { | ||||
|          	    GC_obj_kinds[kind].ok_freelist[2] = | ||||
|         	      GC_build_fl_clear2(h, GC_obj_kinds[kind].ok_freelist[2]); | ||||
|         	} else { | ||||
|         	    GC_obj_kinds[kind].ok_freelist[2] = | ||||
|         	      GC_build_fl2(h, GC_obj_kinds[kind].ok_freelist[2]); | ||||
|         	} | ||||
|         	return; | ||||
|         case 3: if (clear) { | ||||
|          	    GC_obj_kinds[kind].ok_freelist[3] = | ||||
|         	      GC_build_fl_clear3(h, GC_obj_kinds[kind].ok_freelist[3]); | ||||
|         	    return; | ||||
|         	} else { | ||||
|         	    /* It's messy to do better than the default here. */ | ||||
|         	    break; | ||||
|         	} | ||||
|         case 4: if (clear) { | ||||
|         	    GC_obj_kinds[kind].ok_freelist[4] = | ||||
|         	      GC_build_fl_clear4(h, GC_obj_kinds[kind].ok_freelist[4]); | ||||
|         	} else { | ||||
|         	    GC_obj_kinds[kind].ok_freelist[4] = | ||||
|         	      GC_build_fl4(h, GC_obj_kinds[kind].ok_freelist[4]); | ||||
|         	} | ||||
|         	return; | ||||
|         default: | ||||
|         	break; | ||||
|     } | ||||
| #  endif /* !SMALL_CONFIG */ | ||||
|      | ||||
|   /* Clear the page if necessary. */ | ||||
|     if (clear) BZERO(h, HBLKSIZE); | ||||
|      | ||||
|   /* Add objects to free list */ | ||||
|     p = &(h -> hb_body[sz]);	/* second object in *h	*/ | ||||
|     prev = &(h -> hb_body[0]);       	/* One object behind p	*/ | ||||
|     last_object = (word *)((char *)h + HBLKSIZE); | ||||
|     last_object -= sz; | ||||
| 			    /* Last place for last object to start */ | ||||
|  | ||||
|   /* make a list of all objects in *h with head as last object */ | ||||
|     while (p <= last_object) { | ||||
|       /* current object's link points to last object */ | ||||
|         obj_link(p) = (ptr_t)prev; | ||||
| 	prev = p; | ||||
| 	p += sz; | ||||
|     } | ||||
|     p -= sz;			/* p now points to last object */ | ||||
|  | ||||
|   /* | ||||
|    * put p (which is now head of list of objects in *h) as first | ||||
|    * pointer in the appropriate free list for this size. | ||||
|    */ | ||||
|       obj_link(h -> hb_body) = GC_obj_kinds[kind].ok_freelist[sz]; | ||||
|       GC_obj_kinds[kind].ok_freelist[sz] = ((ptr_t)p); | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user