Line data Source code
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 :
16 : #include "private/gc_priv.h"
17 :
18 : /*
19 : * This file contains the functions:
20 : * ptr_t GC_build_flXXX(h, old_fl)
21 : * void GC_new_hblk(size)
22 : */
23 :
24 : #include <stdio.h>
25 :
26 : #ifndef SMALL_CONFIG
27 : /* Build a free list for size 2 (words) cleared objects inside */
28 : /* hblk h. Set the last link to be ofl. Return a pointer tpo the */
29 : /* first free list entry. */
30 332 : STATIC ptr_t GC_build_fl_clear2(struct hblk *h, ptr_t ofl)
31 : {
32 332 : word * p = (word *)(h -> hb_body);
33 332 : word * lim = (word *)(h + 1);
34 :
35 332 : p[0] = (word)ofl;
36 332 : p[1] = 0;
37 332 : p[2] = (word)p;
38 332 : p[3] = 0;
39 332 : p += 4;
40 42496 : for (; (word)p < (word)lim; p += 4) {
41 42164 : p[0] = (word)(p-2);
42 42164 : p[1] = 0;
43 42164 : p[2] = (word)p;
44 42164 : p[3] = 0;
45 : };
46 332 : return((ptr_t)(p-2));
47 : }
48 :
49 : /* The same for size 4 cleared objects. */
50 941 : STATIC ptr_t GC_build_fl_clear4(struct hblk *h, ptr_t ofl)
51 : {
52 941 : word * p = (word *)(h -> hb_body);
53 941 : word * lim = (word *)(h + 1);
54 :
55 941 : p[0] = (word)ofl;
56 941 : p[1] = 0;
57 941 : p[2] = 0;
58 941 : p[3] = 0;
59 941 : p += 4;
60 120448 : for (; (word)p < (word)lim; p += 4) {
61 119507 : PREFETCH_FOR_WRITE((ptr_t)(p+64));
62 119507 : p[0] = (word)(p-4);
63 119507 : p[1] = 0;
64 119507 : CLEAR_DOUBLE(p+2);
65 : };
66 941 : return((ptr_t)(p-4));
67 : }
68 :
69 : /* The same for size 2 uncleared objects. */
70 242 : STATIC ptr_t GC_build_fl2(struct hblk *h, ptr_t ofl)
71 : {
72 242 : word * p = (word *)(h -> hb_body);
73 242 : word * lim = (word *)(h + 1);
74 :
75 242 : p[0] = (word)ofl;
76 242 : p[2] = (word)p;
77 242 : p += 4;
78 30976 : for (; (word)p < (word)lim; p += 4) {
79 30734 : p[0] = (word)(p-2);
80 30734 : p[2] = (word)p;
81 : };
82 242 : return((ptr_t)(p-2));
83 : }
84 :
85 : /* The same for size 4 uncleared objects. */
86 2829 : STATIC ptr_t GC_build_fl4(struct hblk *h, ptr_t ofl)
87 : {
88 2829 : word * p = (word *)(h -> hb_body);
89 2829 : word * lim = (word *)(h + 1);
90 :
91 2829 : p[0] = (word)ofl;
92 2829 : p[4] = (word)p;
93 2829 : p += 8;
94 181056 : for (; (word)p < (word)lim; p += 8) {
95 178227 : PREFETCH_FOR_WRITE((ptr_t)(p+64));
96 178227 : p[0] = (word)(p-4);
97 178227 : p[4] = (word)p;
98 : };
99 2829 : return((ptr_t)(p-4));
100 : }
101 : #endif /* !SMALL_CONFIG */
102 :
103 : /* Build a free list for objects of size sz inside heap block h. */
104 : /* Clear objects inside h if clear is set. Add list to the end of */
105 : /* the free list we build. Return the new free list. */
106 : /* This could be called without the main GC lock, if we ensure that */
107 : /* there is no concurrent collection which might reclaim objects that */
108 : /* we have not yet allocated. */
109 51037 : GC_INNER ptr_t GC_build_fl(struct hblk *h, size_t sz, GC_bool clear,
110 : ptr_t list)
111 : {
112 : word *p, *prev;
113 : word *last_object; /* points to last object in new hblk */
114 :
115 : /* Do a few prefetches here, just because its cheap. */
116 : /* If we were more serious about it, these should go inside */
117 : /* the loops. But write prefetches usually don't seem to */
118 : /* matter much. */
119 51037 : PREFETCH_FOR_WRITE((ptr_t)h);
120 51037 : PREFETCH_FOR_WRITE((ptr_t)h + 128);
121 51037 : PREFETCH_FOR_WRITE((ptr_t)h + 256);
122 51037 : PREFETCH_FOR_WRITE((ptr_t)h + 378);
123 : # ifndef SMALL_CONFIG
124 : /* Handle small objects sizes more efficiently. For larger objects */
125 : /* the difference is less significant. */
126 51037 : switch (sz) {
127 574 : case 2: if (clear) {
128 332 : return GC_build_fl_clear2(h, list);
129 : } else {
130 242 : return GC_build_fl2(h, list);
131 : }
132 3770 : case 4: if (clear) {
133 941 : return GC_build_fl_clear4(h, list);
134 : } else {
135 2829 : return GC_build_fl4(h, list);
136 : }
137 : default:
138 : break;
139 : }
140 : # endif /* !SMALL_CONFIG */
141 :
142 : /* Clear the page if necessary. */
143 46693 : if (clear) BZERO(h, HBLKSIZE);
144 :
145 : /* Add objects to free list */
146 46693 : p = (word *)(h -> hb_body) + sz; /* second object in *h */
147 46693 : prev = (word *)(h -> hb_body); /* One object behind p */
148 46693 : last_object = (word *)((char *)h + HBLKSIZE);
149 46693 : last_object -= sz;
150 : /* Last place for last object to start */
151 :
152 : /* make a list of all objects in *h with head as last object */
153 1560000 : while ((word)p <= (word)last_object) {
154 : /* current object's link points to last object */
155 1466614 : obj_link(p) = (ptr_t)prev;
156 1466614 : prev = p;
157 1466614 : p += sz;
158 : }
159 46693 : p -= sz; /* p now points to last object */
160 :
161 : /* Put p (which is now head of list of objects in *h) as first */
162 : /* pointer in the appropriate free list for this size. */
163 46693 : *(ptr_t *)h = list;
164 46693 : return ((ptr_t)p);
165 : }
166 :
167 : /* Allocate a new heapblock for small objects of size gran granules. */
168 : /* Add all of the heapblock's objects to the free list for objects */
169 : /* of that size. Set all mark bits if objects are uncollectible. */
170 : /* Will fail to do anything if we are out of memory. */
171 17517 : GC_INNER void GC_new_hblk(size_t gran, int kind)
172 : {
173 : struct hblk *h; /* the new heap block */
174 17517 : GC_bool clear = GC_obj_kinds[kind].ok_init;
175 :
176 : GC_STATIC_ASSERT((sizeof (struct hblk)) == HBLKSIZE);
177 :
178 17517 : if (GC_debugging_started) clear = TRUE;
179 :
180 : /* Allocate a new heap block */
181 17517 : h = GC_allochblk(GRANULES_TO_BYTES(gran), kind, 0);
182 17517 : if (h == 0) return;
183 :
184 : /* Mark all objects if appropriate. */
185 17457 : if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
186 :
187 : /* Build the free list */
188 34914 : GC_obj_kinds[kind].ok_freelist[gran] =
189 17457 : GC_build_fl(h, GRANULES_TO_WORDS(gran), clear,
190 17457 : GC_obj_kinds[kind].ok_freelist[gran]);
191 : }
|