Annotation of OpenXM_contrib2/asir2000/gc/new_hblk.c, Revision 1.3
1.1 noro 1: /*
2: * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
3: * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
1.3 ! noro 4: * Copyright (c) 2000 by Hewlett-Packard Company. All rights reserved.
1.1 noro 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(n)
18: */
19: /* Boehm, May 19, 1994 2:09 pm PDT */
20:
21:
22: # include <stdio.h>
1.3 ! noro 23: # include "private/gc_priv.h"
1.1 noro 24:
25: #ifndef SMALL_CONFIG
26: /*
27: * Build a free list for size 1 objects inside hblk h. Set the last link to
28: * be ofl. Return a pointer tpo the first free list entry.
29: */
30: ptr_t GC_build_fl1(h, ofl)
31: struct hblk *h;
32: ptr_t ofl;
33: {
1.3 ! noro 34: register word * p = h -> hb_body;
1.1 noro 35: register word * lim = (word *)(h + 1);
36:
37: p[0] = (word)ofl;
38: p[1] = (word)(p);
39: p[2] = (word)(p+1);
40: p[3] = (word)(p+2);
41: p += 4;
42: for (; p < lim; p += 4) {
43: p[0] = (word)(p-1);
44: p[1] = (word)(p);
45: p[2] = (word)(p+1);
46: p[3] = (word)(p+2);
47: };
48: return((ptr_t)(p-1));
49: }
50:
51: /* The same for size 2 cleared objects */
52: ptr_t GC_build_fl_clear2(h, ofl)
53: struct hblk *h;
54: ptr_t ofl;
55: {
1.3 ! noro 56: register word * p = h -> hb_body;
1.1 noro 57: register word * lim = (word *)(h + 1);
58:
59: p[0] = (word)ofl;
60: p[1] = 0;
61: p[2] = (word)p;
62: p[3] = 0;
63: p += 4;
64: for (; p < lim; p += 4) {
65: p[0] = (word)(p-2);
66: p[1] = 0;
67: p[2] = (word)p;
68: p[3] = 0;
69: };
70: return((ptr_t)(p-2));
71: }
72:
73: /* The same for size 3 cleared objects */
74: ptr_t GC_build_fl_clear3(h, ofl)
75: struct hblk *h;
76: ptr_t ofl;
77: {
1.3 ! noro 78: register word * p = h -> hb_body;
1.1 noro 79: register word * lim = (word *)(h + 1) - 2;
80:
81: p[0] = (word)ofl;
82: p[1] = 0;
83: p[2] = 0;
84: p += 3;
85: for (; p < lim; p += 3) {
86: p[0] = (word)(p-3);
87: p[1] = 0;
88: p[2] = 0;
89: };
90: return((ptr_t)(p-3));
91: }
92:
93: /* The same for size 4 cleared objects */
94: ptr_t GC_build_fl_clear4(h, ofl)
95: struct hblk *h;
96: ptr_t ofl;
97: {
1.3 ! noro 98: register word * p = h -> hb_body;
1.1 noro 99: register word * lim = (word *)(h + 1);
100:
101: p[0] = (word)ofl;
102: p[1] = 0;
103: p[2] = 0;
104: p[3] = 0;
105: p += 4;
106: for (; p < lim; p += 4) {
1.2 noro 107: PREFETCH_FOR_WRITE(p+64);
1.1 noro 108: p[0] = (word)(p-4);
109: p[1] = 0;
1.2 noro 110: CLEAR_DOUBLE(p+2);
1.1 noro 111: };
112: return((ptr_t)(p-4));
113: }
114:
115: /* The same for size 2 uncleared objects */
116: ptr_t GC_build_fl2(h, ofl)
117: struct hblk *h;
118: ptr_t ofl;
119: {
1.3 ! noro 120: register word * p = h -> hb_body;
1.1 noro 121: register word * lim = (word *)(h + 1);
122:
123: p[0] = (word)ofl;
124: p[2] = (word)p;
125: p += 4;
126: for (; p < lim; p += 4) {
127: p[0] = (word)(p-2);
128: p[2] = (word)p;
129: };
130: return((ptr_t)(p-2));
131: }
132:
133: /* The same for size 4 uncleared objects */
134: ptr_t GC_build_fl4(h, ofl)
135: struct hblk *h;
136: ptr_t ofl;
137: {
1.3 ! noro 138: register word * p = h -> hb_body;
1.1 noro 139: register word * lim = (word *)(h + 1);
140:
141: p[0] = (word)ofl;
142: p[4] = (word)p;
143: p += 8;
144: for (; p < lim; p += 8) {
1.2 noro 145: PREFETCH_FOR_WRITE(p+64);
1.1 noro 146: p[0] = (word)(p-4);
147: p[4] = (word)p;
148: };
149: return((ptr_t)(p-4));
150: }
151:
152: #endif /* !SMALL_CONFIG */
153:
1.3 ! noro 154:
! 155: /* Build a free list for objects of size sz inside heap block h. */
! 156: /* Clear objects inside h if clear is set. Add list to the end of */
! 157: /* the free list we build. Return the new free list. */
! 158: /* This could be called without the main GC lock, if we ensure that */
! 159: /* there is no concurrent collection which might reclaim objects that */
! 160: /* we have not yet allocated. */
! 161: ptr_t GC_build_fl(h, sz, clear, list)
! 162: struct hblk *h;
! 163: word sz;
! 164: GC_bool clear;
! 165: ptr_t list;
1.1 noro 166: {
1.3 ! noro 167: word *p, *prev;
! 168: word *last_object; /* points to last object in new hblk */
1.1 noro 169:
1.3 ! noro 170: /* Do a few prefetches here, just because its cheap. */
! 171: /* If we were more serious about it, these should go inside */
! 172: /* the loops. But write prefetches usually don't seem to */
! 173: /* matter much. */
! 174: PREFETCH_FOR_WRITE((char *)h);
! 175: PREFETCH_FOR_WRITE((char *)h + 128);
! 176: PREFETCH_FOR_WRITE((char *)h + 256);
! 177: PREFETCH_FOR_WRITE((char *)h + 378);
1.1 noro 178: /* Handle small objects sizes more efficiently. For larger objects */
179: /* the difference is less significant. */
180: # ifndef SMALL_CONFIG
181: switch (sz) {
1.3 ! noro 182: case 1: return GC_build_fl1(h, list);
1.1 noro 183: case 2: if (clear) {
1.3 ! noro 184: return GC_build_fl_clear2(h, list);
1.1 noro 185: } else {
1.3 ! noro 186: return GC_build_fl2(h, list);
1.1 noro 187: }
188: case 3: if (clear) {
1.3 ! noro 189: return GC_build_fl_clear3(h, list);
1.1 noro 190: } else {
191: /* It's messy to do better than the default here. */
192: break;
193: }
194: case 4: if (clear) {
1.3 ! noro 195: return GC_build_fl_clear4(h, list);
1.1 noro 196: } else {
1.3 ! noro 197: return GC_build_fl4(h, list);
1.1 noro 198: }
199: default:
200: break;
201: }
202: # endif /* !SMALL_CONFIG */
203:
204: /* Clear the page if necessary. */
205: if (clear) BZERO(h, HBLKSIZE);
206:
207: /* Add objects to free list */
208: p = &(h -> hb_body[sz]); /* second object in *h */
209: prev = &(h -> hb_body[0]); /* One object behind p */
210: last_object = (word *)((char *)h + HBLKSIZE);
211: last_object -= sz;
212: /* Last place for last object to start */
213:
214: /* make a list of all objects in *h with head as last object */
215: while (p <= last_object) {
216: /* current object's link points to last object */
217: obj_link(p) = (ptr_t)prev;
218: prev = p;
219: p += sz;
220: }
221: p -= sz; /* p now points to last object */
222:
223: /*
224: * put p (which is now head of list of objects in *h) as first
225: * pointer in the appropriate free list for this size.
226: */
1.3 ! noro 227: obj_link(h -> hb_body) = list;
! 228: return ((ptr_t)p);
! 229: }
! 230:
! 231: /*
! 232: * Allocate a new heapblock for small objects of size n.
! 233: * Add all of the heapblock's objects to the free list for objects
! 234: * of that size.
! 235: * Set all mark bits if objects are uncollectable.
! 236: * Will fail to do anything if we are out of memory.
! 237: */
! 238: void GC_new_hblk(sz, kind)
! 239: register word sz;
! 240: int kind;
! 241: {
! 242: register struct hblk *h; /* the new heap block */
! 243: register GC_bool clear = GC_obj_kinds[kind].ok_init;
! 244:
! 245: # ifdef PRINTSTATS
! 246: if ((sizeof (struct hblk)) > HBLKSIZE) {
! 247: ABORT("HBLK SZ inconsistency");
! 248: }
! 249: # endif
! 250:
! 251: /* Allocate a new heap block */
! 252: h = GC_allochblk(sz, kind, 0);
! 253: if (h == 0) return;
! 254:
! 255: /* Mark all objects if appropriate. */
! 256: if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
! 257:
! 258: /* Build the free list */
! 259: GC_obj_kinds[kind].ok_freelist[sz] =
! 260: GC_build_fl(h, sz, clear, GC_obj_kinds[kind].ok_freelist[sz]);
1.1 noro 261: }
262:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>