Synopsis - Cross-Reference

File: /src/Synopsis/gc/new_hblk.c
  1/*
  2 * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  3 * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
  4 * Copyright (c) 2000 by Hewlett-Packard Company.  All rights reserved.
  5 *
  6 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  7 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  8 *
  9 * Permission is hereby granted to use or copy this program
 10 * for any purpose,  provided the above notices are retained on all copies.
 11 * Permission to modify the code and to distribute modified code is granted,
 12 * provided the above notices are retained, and a notice that the code was
 13 * modified is included with the above copyright notice.
 14 *
 15 * This file contains the functions:
 16 *	ptr_t GC_build_flXXX(h, old_fl)
 17 *	void GC_new_hblk(size)
 18 */
 19/* Boehm, May 19, 1994 2:09 pm PDT */
 20
 21
 22# include <stdio.h>
 23# include "private/gc_priv.h"
 24
 25#ifndef SMALL_CONFIG
 26/*
 27 * Build a free list for size 2 (words) cleared objects inside hblk h.
 28 * Set the last link to
 29 * be ofl.  Return a pointer tpo the first free list entry.
 30 */
 31ptr_t GC_build_fl_clear2(struct hblk *h, ptr_t ofl)
 32{
 33    word * p = (word *)(h -> hb_body);
 34    word * lim = (word *)(h + 1);
 35    
 36    p[0] = (word)ofl;
 37    p[1] = 0;
 38    p[2] = (word)p;
 39    p[3] = 0;
 40    p += 4;
 41    for (; p < lim; p += 4) {
 42        p[0] = (word)(p-2);
 43        p[1] = 0;
 44        p[2] = (word)p;
 45        p[3] = 0;
 46    };
 47    return((ptr_t)(p-2));
 48}
 49
 50/* The same for size 4 cleared objects */
 51ptr_t GC_build_fl_clear4(struct hblk *h, ptr_t ofl)
 52{
 53    word * p = (word *)(h -> hb_body);
 54    word * lim = (word *)(h + 1);
 55    
 56    p[0] = (word)ofl;
 57    p[1] = 0;
 58    p[2] = 0;
 59    p[3] = 0;
 60    p += 4;
 61    for (; p < lim; p += 4) {
 62	PREFETCH_FOR_WRITE((ptr_t)(p+64));
 63        p[0] = (word)(p-4);
 64        p[1] = 0;
 65	CLEAR_DOUBLE(p+2);
 66    };
 67    return((ptr_t)(p-4));
 68}
 69
 70/* The same for size 2 uncleared objects */
 71ptr_t GC_build_fl2(struct hblk *h, ptr_t ofl)
 72{
 73    word * p = (word *)(h -> hb_body);
 74    word * lim = (word *)(h + 1);
 75    
 76    p[0] = (word)ofl;
 77    p[2] = (word)p;
 78    p += 4;
 79    for (; p < lim; p += 4) {
 80        p[0] = (word)(p-2);
 81        p[2] = (word)p;
 82    };
 83    return((ptr_t)(p-2));
 84}
 85
 86/* The same for size 4 uncleared objects */
 87ptr_t GC_build_fl4(struct hblk *h, ptr_t ofl)
 88{
 89    word * p = (word *)(h -> hb_body);
 90    word * lim = (word *)(h + 1);
 91    
 92    p[0] = (word)ofl;
 93    p[4] = (word)p;
 94    p += 8;
 95    for (; p < lim; p += 8) {
 96	PREFETCH_FOR_WRITE((ptr_t)(p+64));
 97        p[0] = (word)(p-4);
 98        p[4] = (word)p;
 99    };
100    return((ptr_t)(p-4));
101}
102
103#endif /* !SMALL_CONFIG */
104
105
106/* Build a free list for objects of size sz inside heap block h.	*/
107/* Clear objects inside h if clear is set.  Add list to the end of	*/
108/* the free list we build.  Return the new free list.			*/
109/* This could be called without the main GC lock, if we ensure that	*/
110/* there is no concurrent collection which might reclaim objects that	*/
111/* we have not yet allocated.						*/
112ptr_t GC_build_fl(struct hblk *h, size_t sz, GC_bool clear, ptr_t list)
113{
114  word *p, *prev;
115  word *last_object;		/* points to last object in new hblk	*/
116
117  /* Do a few prefetches here, just because its cheap.  	*/
118  /* If we were more serious about it, these should go inside	*/
119  /* the loops.  But write prefetches usually don't seem to	*/
120  /* matter much.						*/
121    PREFETCH_FOR_WRITE((ptr_t)h);
122    PREFETCH_FOR_WRITE((ptr_t)h + 128);
123    PREFETCH_FOR_WRITE((ptr_t)h + 256);
124    PREFETCH_FOR_WRITE((ptr_t)h + 378);
125  /* Handle small objects sizes more efficiently.  For larger objects 	*/
126  /* the difference is less significant.				*/
127#  ifndef SMALL_CONFIG
128    switch (sz) {
129        case 2: if (clear) {
130        	    return GC_build_fl_clear2(h, list);
131        	} else {
132        	    return GC_build_fl2(h, list);
133        	}
134        case 4: if (clear) {
135        	    return GC_build_fl_clear4(h, list);
136        	} else {
137        	    return GC_build_fl4(h, list);
138        	}
139        default:
140        	break;
141    }
142#  endif /* !SMALL_CONFIG */
143    
144  /* Clear the page if necessary. */
145    if (clear) BZERO(h, HBLKSIZE);
146    
147  /* Add objects to free list */
148    p = (word *)(h -> hb_body) + sz;	/* second object in *h	*/
149    prev = (word *)(h -> hb_body);       	/* One object behind p	*/
150    last_object = (word *)((char *)h + HBLKSIZE);
151    last_object -= sz;
152			    /* Last place for last object to start */
153
154  /* make a list of all objects in *h with head as last object */
155    while (p <= last_object) {
156      /* current object's link points to last object */
157        obj_link(p) = (ptr_t)prev;
158	prev = p;
159	p += sz;
160    }
161    p -= sz;			/* p now points to last object */
162
163  /*
164   * put p (which is now head of list of objects in *h) as first
165   * pointer in the appropriate free list for this size.
166   */
167      obj_link(h -> hb_body) = list;
168      return ((ptr_t)p);
169}
170
171
172/*
173 * Allocate a new heapblock for small objects of size gran granules.
174 * Add all of the heapblock's objects to the free list for objects
175 * of that size.
176 * Set all mark bits if objects are uncollectable.
177 * Will fail to do anything if we are out of memory.
178 */
179void GC_new_hblk(size_t gran, int kind)
180{
181  struct hblk *h;	/* the new heap block			*/
182  GC_bool clear = GC_obj_kinds[kind].ok_init;
183
184  /* Ignore gcc "no effect" warning on the following: */
185  GC_STATIC_ASSERT((sizeof (struct hblk)) == HBLKSIZE);
186  
187  if (GC_debugging_started) clear = TRUE;
188
189  /* Allocate a new heap block */
190    h = GC_allochblk(GRANULES_TO_BYTES(gran), kind, 0);
191    if (h == 0) return;
192
193  /* Mark all objects if appropriate. */
194      if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
195
196  /* Build the free list */
197      GC_obj_kinds[kind].ok_freelist[gran] =
198	GC_build_fl(h, GRANULES_TO_WORDS(gran), clear,
199		    GC_obj_kinds[kind].ok_freelist[gran]);
200}
201