- if (major_gc) {
- oldest_gen->max_blocks =
- stg_max(oldest_gen->steps[0].to_blocks * RtsFlags.GcFlags.oldGenFactor,
- RtsFlags.GcFlags.minOldGenSize);
- if (oldest_gen->max_blocks > RtsFlags.GcFlags.maxHeapSize / 2) {
- oldest_gen->max_blocks = RtsFlags.GcFlags.maxHeapSize / 2;
- if (((int)oldest_gen->max_blocks - (int)oldest_gen->steps[0].to_blocks) <
- (RtsFlags.GcFlags.pcFreeHeap *
- RtsFlags.GcFlags.maxHeapSize / 200)) {
+ if (RtsFlags.GcFlags.generations > 1) {
+ if (major_gc) {
+ oldest_gen->max_blocks =
+ stg_max(oldest_gen->steps[0].to_blocks * RtsFlags.GcFlags.oldGenFactor,
+ RtsFlags.GcFlags.minOldGenSize);
+ if (oldest_gen->max_blocks > RtsFlags.GcFlags.maxHeapSize / 2) {
+ oldest_gen->max_blocks = RtsFlags.GcFlags.maxHeapSize / 2;
+ if (((int)oldest_gen->max_blocks -
+ (int)oldest_gen->steps[0].to_blocks) <
+ (RtsFlags.GcFlags.pcFreeHeap *
+ RtsFlags.GcFlags.maxHeapSize / 200)) {
+ }
+ }
+ }
+ } else {
+ /* For a two-space collector, we need to resize the nursery. */
+
+ /* set up a new nursery. Allocate a nursery size based on a
+ * function of the amount of live data (currently a factor of 2,
+ * should be configurable (ToDo)). Use the blocks from the old
+ * nursery if possible, freeing up any left over blocks.
+ *
+ * If we get near the maximum heap size, then adjust our nursery
+ * size accordingly. If the nursery is the same size as the live
+ * data (L), then we need 3L bytes. We can reduce the size of the
+ * nursery to bring the required memory down near 2L bytes.
+ *
+ * A normal 2-space collector would need 4L bytes to give the same
+ * performance we get from 3L bytes, reducing to the same
+ * performance at 2L bytes.
+ */
+ nat blocks = g0s0->to_blocks;
+
+ if ( blocks * 4 > RtsFlags.GcFlags.maxHeapSize ) {
+ int adjusted_blocks; /* signed on purpose */
+ int pc_free;
+
+ adjusted_blocks = (RtsFlags.GcFlags.maxHeapSize - 2 * blocks);
+ IF_DEBUG(gc, fprintf(stderr, "Near maximum heap size of 0x%x blocks, blocks = %d, adjusted to %d\n", RtsFlags.GcFlags.maxHeapSize, blocks, adjusted_blocks));
+ pc_free = adjusted_blocks * 100 / RtsFlags.GcFlags.maxHeapSize;
+ if (pc_free < RtsFlags.GcFlags.pcFreeHeap) /* might even be < 0 */ {