Allocate or reallocate space for mark stack of size n entries. */ May silently fail. */
| 1164 | /* Allocate or reallocate space for mark stack of size n entries. */ |
| 1165 | /* May silently fail. */ |
| 1166 | static void alloc_mark_stack(size_t n) |
| 1167 | { |
| 1168 | mse * new_stack = (mse *)GC_scratch_alloc(n * sizeof(struct GC_ms_entry)); |
| 1169 | # ifdef GWW_VDB |
| 1170 | /* Don't recycle a stack segment obtained with the wrong flags. */ |
| 1171 | /* Win32 GetWriteWatch requires the right kind of memory. */ |
| 1172 | static GC_bool GC_incremental_at_stack_alloc = 0; |
| 1173 | GC_bool recycle_old = (!GC_incremental || GC_incremental_at_stack_alloc); |
| 1174 | |
| 1175 | GC_incremental_at_stack_alloc = GC_incremental; |
| 1176 | # else |
| 1177 | # define recycle_old 1 |
| 1178 | # endif |
| 1179 | |
| 1180 | GC_mark_stack_too_small = FALSE; |
| 1181 | if (GC_mark_stack_size != 0) { |
| 1182 | if (new_stack != 0) { |
| 1183 | if (recycle_old) { |
| 1184 | /* Recycle old space */ |
| 1185 | size_t page_offset = (word)GC_mark_stack & (GC_page_size - 1); |
| 1186 | size_t size = GC_mark_stack_size * sizeof(struct GC_ms_entry); |
| 1187 | size_t displ = 0; |
| 1188 | |
| 1189 | if (0 != page_offset) displ = GC_page_size - page_offset; |
| 1190 | size = (size - displ) & ~(GC_page_size - 1); |
| 1191 | if (size > 0) { |
| 1192 | GC_add_to_heap((struct hblk *) |
| 1193 | ((word)GC_mark_stack + displ), (word)size); |
| 1194 | } |
| 1195 | } |
| 1196 | GC_mark_stack = new_stack; |
| 1197 | GC_mark_stack_size = n; |
| 1198 | GC_mark_stack_limit = new_stack + n; |
| 1199 | if (GC_print_stats) { |
| 1200 | GC_log_printf("Grew mark stack to %lu frames\n", |
| 1201 | (unsigned long) GC_mark_stack_size); |
| 1202 | } |
| 1203 | } else { |
| 1204 | if (GC_print_stats) { |
| 1205 | GC_log_printf("Failed to grow mark stack to %lu frames\n", |
| 1206 | (unsigned long) n); |
| 1207 | } |
| 1208 | } |
| 1209 | } else { |
| 1210 | if (new_stack == 0) { |
| 1211 | GC_err_printf("No space for mark stack\n"); |
| 1212 | EXIT(); |
| 1213 | } |
| 1214 | GC_mark_stack = new_stack; |
| 1215 | GC_mark_stack_size = n; |
| 1216 | GC_mark_stack_limit = new_stack + n; |
| 1217 | } |
| 1218 | GC_mark_stack_top = GC_mark_stack-1; |
| 1219 | } |
| 1220 | |
| 1221 | void GC_mark_init() |
| 1222 | { |
no test coverage detected