comparison src/share/vm/memory/collectorPolicy.cpp @ 14909:4ca6dc0799b6

Backout jdk9 merge
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 01 Apr 2014 13:57:07 +0200
parents f7f0c6a77d6d
children 52b4284cb496
comparison
equal deleted inserted replaced
14908:8db6e76cb658 14909:4ca6dc0799b6
43 #if INCLUDE_ALL_GCS 43 #if INCLUDE_ALL_GCS
44 #include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp" 44 #include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp"
45 #include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp" 45 #include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp"
46 #endif // INCLUDE_ALL_GCS 46 #endif // INCLUDE_ALL_GCS
47 47
48 // CollectorPolicy methods 48 // CollectorPolicy methods.
49 49
50 CollectorPolicy::CollectorPolicy() : 50 CollectorPolicy::CollectorPolicy() :
51 _space_alignment(0), 51 _space_alignment(0),
52 _heap_alignment(0), 52 _heap_alignment(0),
53 _initial_heap_byte_size(InitialHeapSize), 53 _initial_heap_byte_size(InitialHeapSize),
176 // committed in os pages as well. Make sure they are entirely full (to 176 // committed in os pages as well. Make sure they are entirely full (to
177 // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1 177 // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
178 // byte entry and the os page size is 4096, the maximum heap size should 178 // byte entry and the os page size is 4096, the maximum heap size should
179 // be 512*4096 = 2MB aligned. 179 // be 512*4096 = 2MB aligned.
180 180
181 size_t alignment = GenRemSet::max_alignment_constraint(); 181 // There is only the GenRemSet in Hotspot and only the GenRemSet::CardTable
182 // is supported.
183 // Requirements of any new remembered set implementations must be added here.
184 size_t alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable);
182 185
183 // Parallel GC does its own alignment of the generations to avoid requiring a 186 // Parallel GC does its own alignment of the generations to avoid requiring a
184 // large page (256M on some platforms) for the permanent generation. The 187 // large page (256M on some platforms) for the permanent generation. The
185 // other collectors should also be updated to do their own alignment and then 188 // other collectors should also be updated to do their own alignment and then
186 // this use of lcm() should be removed. 189 // this use of lcm() should be removed.
187 if (UseLargePages && !UseParallelGC) { 190 if (UseLargePages && !UseParallelGC) {
188 // In presence of large pages we have to make sure that our 191 // in presence of large pages we have to make sure that our
189 // alignment is large page aware 192 // alignment is large page aware
190 alignment = lcm(os::large_page_size(), alignment); 193 alignment = lcm(os::large_page_size(), alignment);
191 } 194 }
192 195
193 return alignment; 196 return alignment;
194 } 197 }
195 198
196 // GenCollectorPolicy methods 199 // GenCollectorPolicy methods.
197 200
198 GenCollectorPolicy::GenCollectorPolicy() : 201 GenCollectorPolicy::GenCollectorPolicy() :
199 _min_gen0_size(0), 202 _min_gen0_size(0),
200 _initial_gen0_size(0), 203 _initial_gen0_size(0),
201 _max_gen0_size(0), 204 _max_gen0_size(0),
373 _max_heap_byte_size = MaxHeapSize; 376 _max_heap_byte_size = MaxHeapSize;
374 FLAG_SET_ERGO(uintx, InitialHeapSize, calculated_heapsize); 377 FLAG_SET_ERGO(uintx, InitialHeapSize, calculated_heapsize);
375 _initial_heap_byte_size = InitialHeapSize; 378 _initial_heap_byte_size = InitialHeapSize;
376 } 379 }
377 380
378 // Adjust NewSize and OldSize or MaxHeapSize to match each other 381 // adjust max heap size if necessary
379 if (NewSize + OldSize > MaxHeapSize) { 382 if (NewSize + OldSize > MaxHeapSize) {
380 if (_max_heap_size_cmdline) { 383 if (_max_heap_size_cmdline) {
381 // Somebody has set a maximum heap size with the intention that we should not 384 // somebody set a maximum heap size with the intention that we should not
382 // exceed it. Adjust New/OldSize as necessary. 385 // exceed it. Adjust New/OldSize as necessary.
383 uintx calculated_size = NewSize + OldSize; 386 uintx calculated_size = NewSize + OldSize;
384 double shrink_factor = (double) MaxHeapSize / calculated_size; 387 double shrink_factor = (double) MaxHeapSize / calculated_size;
385 uintx smaller_new_size = align_size_down((uintx)(NewSize * shrink_factor), _gen_alignment); 388 uintx smaller_new_size = align_size_down((uintx)(NewSize * shrink_factor), _gen_alignment);
386 FLAG_SET_ERGO(uintx, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size)); 389 FLAG_SET_ERGO(uintx, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));
437 440
438 // Given the maximum gen0 size, determine the initial and 441 // Given the maximum gen0 size, determine the initial and
439 // minimum gen0 sizes. 442 // minimum gen0 sizes.
440 443
441 if (_max_heap_byte_size == _min_heap_byte_size) { 444 if (_max_heap_byte_size == _min_heap_byte_size) {
442 // The maximum and minimum heap sizes are the same so the generations 445 // The maximum and minimum heap sizes are the same so
443 // minimum and initial must be the same as its maximum. 446 // the generations minimum and initial must be the
447 // same as its maximum.
444 _min_gen0_size = max_new_size; 448 _min_gen0_size = max_new_size;
445 _initial_gen0_size = max_new_size; 449 _initial_gen0_size = max_new_size;
446 _max_gen0_size = max_new_size; 450 _max_gen0_size = max_new_size;
447 } else { 451 } else {
448 size_t desired_new_size = 0; 452 size_t desired_new_size = 0;
449 if (FLAG_IS_CMDLINE(NewSize)) { 453 if (!FLAG_IS_DEFAULT(NewSize)) {
450 // If NewSize is set on the command line, we must use it as 454 // If NewSize is set ergonomically (for example by cms), it
451 // the initial size and it also makes sense to use it as the 455 // would make sense to use it. If it is used, also use it
452 // lower limit. 456 // to set the initial size. Although there is no reason
457 // the minimum size and the initial size have to be the same,
458 // the current implementation gets into trouble during the calculation
459 // of the tenured generation sizes if they are different.
460 // Note that this makes the initial size and the minimum size
461 // generally small compared to the NewRatio calculation.
453 _min_gen0_size = NewSize; 462 _min_gen0_size = NewSize;
454 desired_new_size = NewSize; 463 desired_new_size = NewSize;
455 max_new_size = MAX2(max_new_size, NewSize);
456 } else if (FLAG_IS_ERGO(NewSize)) {
457 // If NewSize is set ergonomically, we should use it as a lower
458 // limit, but use NewRatio to calculate the initial size.
459 _min_gen0_size = NewSize;
460 desired_new_size =
461 MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize);
462 max_new_size = MAX2(max_new_size, NewSize); 464 max_new_size = MAX2(max_new_size, NewSize);
463 } else { 465 } else {
464 // For the case where NewSize is the default, use NewRatio 466 // For the case where NewSize is the default, use NewRatio
465 // to size the minimum and initial generation sizes. 467 // to size the minimum and initial generation sizes.
466 // Use the default NewSize as the floor for these values. If 468 // Use the default NewSize as the floor for these values. If
467 // NewRatio is overly large, the resulting sizes can be too small. 469 // NewRatio is overly large, the resulting sizes can be too
470 // small.
468 _min_gen0_size = MAX2(scale_by_NewRatio_aligned(_min_heap_byte_size), NewSize); 471 _min_gen0_size = MAX2(scale_by_NewRatio_aligned(_min_heap_byte_size), NewSize);
469 desired_new_size = 472 desired_new_size =
470 MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize); 473 MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize);
471 } 474 }
472 475
481 _min_gen0_size = bound_minus_alignment(_min_gen0_size, _min_heap_byte_size); 484 _min_gen0_size = bound_minus_alignment(_min_gen0_size, _min_heap_byte_size);
482 _initial_gen0_size = bound_minus_alignment(_initial_gen0_size, _initial_heap_byte_size); 485 _initial_gen0_size = bound_minus_alignment(_initial_gen0_size, _initial_heap_byte_size);
483 _max_gen0_size = bound_minus_alignment(_max_gen0_size, _max_heap_byte_size); 486 _max_gen0_size = bound_minus_alignment(_max_gen0_size, _max_heap_byte_size);
484 487
485 // At this point all three sizes have been checked against the 488 // At this point all three sizes have been checked against the
486 // maximum sizes but have not been checked for consistency among the three. 489 // maximum sizes but have not been checked for consistency
490 // among the three.
487 491
488 // Final check min <= initial <= max 492 // Final check min <= initial <= max
489 _min_gen0_size = MIN2(_min_gen0_size, _max_gen0_size); 493 _min_gen0_size = MIN2(_min_gen0_size, _max_gen0_size);
490 _initial_gen0_size = MAX2(MIN2(_initial_gen0_size, _max_gen0_size), _min_gen0_size); 494 _initial_gen0_size = MAX2(MIN2(_initial_gen0_size, _max_gen0_size), _min_gen0_size);
491 _min_gen0_size = MIN2(_min_gen0_size, _initial_gen0_size); 495 _min_gen0_size = MIN2(_min_gen0_size, _initial_gen0_size);
492 } 496 }
493 497
494 // Write back to flags if necessary. 498 // Write back to flags if necessary
495 if (NewSize != _initial_gen0_size) { 499 if (NewSize != _initial_gen0_size) {
496 FLAG_SET_ERGO(uintx, NewSize, _initial_gen0_size); 500 FLAG_SET_ERGO(uintx, NewSize, _initial_gen0_size);
497 } 501 }
498 502
499 if (MaxNewSize != _max_gen0_size) { 503 if (MaxNewSize != _max_gen0_size) {
535 } 539 }
536 return result; 540 return result;
537 } 541 }
538 542
539 // Minimum sizes of the generations may be different than 543 // Minimum sizes of the generations may be different than
540 // the initial sizes. An inconsistency is permitted here 544 // the initial sizes. An inconsistently is permitted here
541 // in the total size that can be specified explicitly by 545 // in the total size that can be specified explicitly by
542 // command line specification of OldSize and NewSize and 546 // command line specification of OldSize and NewSize and
543 // also a command line specification of -Xms. Issue a warning 547 // also a command line specification of -Xms. Issue a warning
544 // but allow the values to pass. 548 // but allow the values to pass.
545 549
547 GenCollectorPolicy::initialize_size_info(); 551 GenCollectorPolicy::initialize_size_info();
548 552
549 // At this point the minimum, initial and maximum sizes 553 // At this point the minimum, initial and maximum sizes
550 // of the overall heap and of gen0 have been determined. 554 // of the overall heap and of gen0 have been determined.
551 // The maximum gen1 size can be determined from the maximum gen0 555 // The maximum gen1 size can be determined from the maximum gen0
552 // and maximum heap size since no explicit flags exist 556 // and maximum heap size since no explicit flags exits
553 // for setting the gen1 maximum. 557 // for setting the gen1 maximum.
554 _max_gen1_size = MAX2(_max_heap_byte_size - _max_gen0_size, _gen_alignment); 558 _max_gen1_size = MAX2(_max_heap_byte_size - _max_gen0_size, _gen_alignment);
555 559
556 // If no explicit command line flag has been set for the 560 // If no explicit command line flag has been set for the
557 // gen1 size, use what is left for gen1 561 // gen1 size, use what is left for gen1.
558 if (!FLAG_IS_CMDLINE(OldSize)) { 562 if (!FLAG_IS_CMDLINE(OldSize)) {
559 // The user has not specified any value but the ergonomics 563 // The user has not specified any value but the ergonomics
560 // may have chosen a value (which may or may not be consistent 564 // may have chosen a value (which may or may not be consistent
561 // with the overall heap size). In either case make 565 // with the overall heap size). In either case make
562 // the minimum, maximum and initial sizes consistent 566 // the minimum, maximum and initial sizes consistent
564 _min_gen1_size = MAX2(_min_heap_byte_size - _min_gen0_size, _gen_alignment); 568 _min_gen1_size = MAX2(_min_heap_byte_size - _min_gen0_size, _gen_alignment);
565 _initial_gen1_size = MAX2(_initial_heap_byte_size - _initial_gen0_size, _gen_alignment); 569 _initial_gen1_size = MAX2(_initial_heap_byte_size - _initial_gen0_size, _gen_alignment);
566 // _max_gen1_size has already been made consistent above 570 // _max_gen1_size has already been made consistent above
567 FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size); 571 FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size);
568 } else { 572 } else {
569 // OldSize has been explicitly set on the command line. Use the 573 // It's been explicitly set on the command line. Use the
570 // OldSize and then determine the consequences. 574 // OldSize and then determine the consequences.
571 _min_gen1_size = MIN2(OldSize, _min_heap_byte_size - _min_gen0_size); 575 _min_gen1_size = MIN2(OldSize, _min_heap_byte_size - _min_gen0_size);
572 _initial_gen1_size = OldSize; 576 _initial_gen1_size = OldSize;
573 577
574 // If the user has explicitly set an OldSize that is inconsistent 578 // If the user has explicitly set an OldSize that is inconsistent
575 // with other command line flags, issue a warning. 579 // with other command line flags, issue a warning.
576 // The generation minimums and the overall heap minimum should 580 // The generation minimums and the overall heap mimimum should
577 // be within one generation alignment. 581 // be within one generation alignment.
578 if ((_min_gen1_size + _min_gen0_size + _gen_alignment) < _min_heap_byte_size) { 582 if ((_min_gen1_size + _min_gen0_size + _gen_alignment) < _min_heap_byte_size) {
579 warning("Inconsistency between minimum heap size and minimum " 583 warning("Inconsistency between minimum heap size and minimum "
580 "generation sizes: using minimum heap = " SIZE_FORMAT, 584 "generation sizes: using minimum heap = " SIZE_FORMAT,
581 _min_heap_byte_size); 585 _min_heap_byte_size);
593 gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 " 597 gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
594 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, 598 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
595 _min_gen0_size, _initial_gen0_size, _max_gen0_size); 599 _min_gen0_size, _initial_gen0_size, _max_gen0_size);
596 } 600 }
597 } 601 }
598 // The same as above for the old gen initial size. 602 // Initial size
599 if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size, 603 if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size,
600 _initial_heap_byte_size)) { 604 _initial_heap_byte_size)) {
601 if (PrintGCDetails && Verbose) { 605 if (PrintGCDetails && Verbose) {
602 gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT " Initial gen0 " 606 gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
603 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, 607 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
604 _min_gen0_size, _initial_gen0_size, _max_gen0_size); 608 _min_gen0_size, _initial_gen0_size, _max_gen0_size);
605 } 609 }
606 } 610 }
607 } 611 }
608 612 // Enforce the maximum gen1 size.
609 _min_gen1_size = MIN2(_min_gen1_size, _max_gen1_size); 613 _min_gen1_size = MIN2(_min_gen1_size, _max_gen1_size);
610 614
611 // Make sure that min gen1 <= initial gen1 <= max gen1. 615 // Check that min gen1 <= initial gen1 <= max gen1
612 _initial_gen1_size = MAX2(_initial_gen1_size, _min_gen1_size); 616 _initial_gen1_size = MAX2(_initial_gen1_size, _min_gen1_size);
613 _initial_gen1_size = MIN2(_initial_gen1_size, _max_gen1_size); 617 _initial_gen1_size = MIN2(_initial_gen1_size, _max_gen1_size);
614 618
615 // Write back to flags if necessary 619 // Write back to flags if necessary
616 if (NewSize != _initial_gen0_size) { 620 if (NewSize != _initial_gen0_size) {
647 // limit is being exceeded as checked below. 651 // limit is being exceeded as checked below.
648 *gc_overhead_limit_was_exceeded = false; 652 *gc_overhead_limit_was_exceeded = false;
649 653
650 HeapWord* result = NULL; 654 HeapWord* result = NULL;
651 655
652 // Loop until the allocation is satisfied, or unsatisfied after GC. 656 // Loop until the allocation is satisified,
657 // or unsatisfied after GC.
653 for (int try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) { 658 for (int try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) {
654 HandleMark hm; // Discard any handles allocated in each iteration. 659 HandleMark hm; // discard any handles allocated in each iteration
655 660
656 // First allocation attempt is lock-free. 661 // First allocation attempt is lock-free.
657 Generation *gen0 = gch->get_gen(0); 662 Generation *gen0 = gch->get_gen(0);
658 assert(gen0->supports_inline_contig_alloc(), 663 assert(gen0->supports_inline_contig_alloc(),
659 "Otherwise, must do alloc within heap lock"); 664 "Otherwise, must do alloc within heap lock");
662 if (result != NULL) { 667 if (result != NULL) {
663 assert(gch->is_in_reserved(result), "result not in heap"); 668 assert(gch->is_in_reserved(result), "result not in heap");
664 return result; 669 return result;
665 } 670 }
666 } 671 }
667 unsigned int gc_count_before; // Read inside the Heap_lock locked region. 672 unsigned int gc_count_before; // read inside the Heap_lock locked region
668 { 673 {
669 MutexLocker ml(Heap_lock); 674 MutexLocker ml(Heap_lock);
670 if (PrintGC && Verbose) { 675 if (PrintGC && Verbose) {
671 gclog_or_tty->print_cr("TwoGenerationCollectorPolicy::mem_allocate_work:" 676 gclog_or_tty->print_cr("TwoGenerationCollectorPolicy::mem_allocate_work:"
672 " attempting locked slow path allocation"); 677 " attempting locked slow path allocation");
681 return result; 686 return result;
682 } 687 }
683 688
684 if (GC_locker::is_active_and_needs_gc()) { 689 if (GC_locker::is_active_and_needs_gc()) {
685 if (is_tlab) { 690 if (is_tlab) {
686 return NULL; // Caller will retry allocating individual object. 691 return NULL; // Caller will retry allocating individual object
687 } 692 }
688 if (!gch->is_maximal_no_gc()) { 693 if (!gch->is_maximal_no_gc()) {
689 // Try and expand heap to satisfy request. 694 // Try and expand heap to satisfy request
690 result = expand_heap_and_allocate(size, is_tlab); 695 result = expand_heap_and_allocate(size, is_tlab);
691 // Result could be null if we are out of space. 696 // result could be null if we are out of space
692 if (result != NULL) { 697 if (result != NULL) {
693 return result; 698 return result;
694 } 699 }
695 } 700 }
696 701
697 if (gclocker_stalled_count > GCLockerRetryAllocationCount) { 702 if (gclocker_stalled_count > GCLockerRetryAllocationCount) {
698 return NULL; // We didn't get to do a GC and we didn't get any memory. 703 return NULL; // we didn't get to do a GC and we didn't get any memory
699 } 704 }
700 705
701 // If this thread is not in a jni critical section, we stall 706 // If this thread is not in a jni critical section, we stall
702 // the requestor until the critical section has cleared and 707 // the requestor until the critical section has cleared and
703 // GC allowed. When the critical section clears, a GC is 708 // GC allowed. When the critical section clears, a GC is
728 VMThread::execute(&op); 733 VMThread::execute(&op);
729 if (op.prologue_succeeded()) { 734 if (op.prologue_succeeded()) {
730 result = op.result(); 735 result = op.result();
731 if (op.gc_locked()) { 736 if (op.gc_locked()) {
732 assert(result == NULL, "must be NULL if gc_locked() is true"); 737 assert(result == NULL, "must be NULL if gc_locked() is true");
733 continue; // Retry and/or stall as necessary. 738 continue; // retry and/or stall as necessary
734 } 739 }
735 740
736 // Allocation has failed and a collection 741 // Allocation has failed and a collection
737 // has been done. If the gc time limit was exceeded the 742 // has been done. If the gc time limit was exceeded the
738 // this time, return NULL so that an out-of-memory 743 // this time, return NULL so that an out-of-memory
789 // GC locker is active; instead of a collection we will attempt 794 // GC locker is active; instead of a collection we will attempt
790 // to expand the heap, if there's room for expansion. 795 // to expand the heap, if there's room for expansion.
791 if (!gch->is_maximal_no_gc()) { 796 if (!gch->is_maximal_no_gc()) {
792 result = expand_heap_and_allocate(size, is_tlab); 797 result = expand_heap_and_allocate(size, is_tlab);
793 } 798 }
794 return result; // Could be null if we are out of space. 799 return result; // could be null if we are out of space
795 } else if (!gch->incremental_collection_will_fail(false /* don't consult_young */)) { 800 } else if (!gch->incremental_collection_will_fail(false /* don't consult_young */)) {
796 // Do an incremental collection. 801 // Do an incremental collection.
797 gch->do_collection(false /* full */, 802 gch->do_collection(false /* full */,
798 false /* clear_all_soft_refs */, 803 false /* clear_all_soft_refs */,
799 size /* size */, 804 size /* size */,
911 gc_count, 916 gc_count,
912 full_gc_count, 917 full_gc_count,
913 GCCause::_metadata_GC_threshold); 918 GCCause::_metadata_GC_threshold);
914 VMThread::execute(&op); 919 VMThread::execute(&op);
915 920
916 // If GC was locked out, try again. Check before checking success because the 921 // If GC was locked out, try again. Check
917 // prologue could have succeeded and the GC still have been locked out. 922 // before checking success because the prologue
923 // could have succeeded and the GC still have
924 // been locked out.
918 if (op.gc_locked()) { 925 if (op.gc_locked()) {
919 continue; 926 continue;
920 } 927 }
921 928
922 if (op.prologue_succeeded()) { 929 if (op.prologue_succeeded()) {
973 vm_exit_during_initialization("Unable to allocate gen spec"); 980 vm_exit_during_initialization("Unable to allocate gen spec");
974 } 981 }
975 } 982 }
976 983
977 void MarkSweepPolicy::initialize_gc_policy_counters() { 984 void MarkSweepPolicy::initialize_gc_policy_counters() {
978 // Initialize the policy counters - 2 collectors, 3 generations. 985 // initialize the policy counters - 2 collectors, 3 generations
979 if (UseParNewGC) { 986 if (UseParNewGC) {
980 _gc_policy_counters = new GCPolicyCounters("ParNew:MSC", 2, 3); 987 _gc_policy_counters = new GCPolicyCounters("ParNew:MSC", 2, 3);
981 } else { 988 } else {
982 _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3); 989 _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3);
983 } 990 }
984 } 991 }
985
986 /////////////// Unit tests ///////////////
987
988 #ifndef PRODUCT
989 // Testing that the NewSize flag is handled correct is hard because it
990 // depends on so many other configurable variables. This test only tries to
991 // verify that there are some basic rules for NewSize honored by the policies.
992 class TestGenCollectorPolicy {
993 public:
994 static void test() {
995 size_t flag_value;
996
997 save_flags();
998
999 // Set some limits that makes the math simple.
1000 FLAG_SET_ERGO(uintx, MaxHeapSize, 180 * M);
1001 FLAG_SET_ERGO(uintx, InitialHeapSize, 120 * M);
1002 Arguments::set_min_heap_size(40 * M);
1003
1004 // If NewSize is set on the command line, it should be used
1005 // for both min and initial young size if less than min heap.
1006 flag_value = 20 * M;
1007 FLAG_SET_CMDLINE(uintx, NewSize, flag_value);
1008 verify_min(flag_value);
1009 verify_initial(flag_value);
1010
1011 // If NewSize is set on command line, but is larger than the min
1012 // heap size, it should only be used for initial young size.
1013 flag_value = 80 * M;
1014 FLAG_SET_CMDLINE(uintx, NewSize, flag_value);
1015 verify_initial(flag_value);
1016
1017 // If NewSize has been ergonomically set, the collector policy
1018 // should use it for min but calculate the initial young size
1019 // using NewRatio.
1020 flag_value = 20 * M;
1021 FLAG_SET_ERGO(uintx, NewSize, flag_value);
1022 verify_min(flag_value);
1023 verify_scaled_initial(InitialHeapSize);
1024
1025 restore_flags();
1026
1027 }
1028
1029 static void verify_min(size_t expected) {
1030 MarkSweepPolicy msp;
1031 msp.initialize_all();
1032
1033 assert(msp.min_gen0_size() <= expected, err_msg("%zu > %zu", msp.min_gen0_size(), expected));
1034 }
1035
1036 static void verify_initial(size_t expected) {
1037 MarkSweepPolicy msp;
1038 msp.initialize_all();
1039
1040 assert(msp.initial_gen0_size() == expected, err_msg("%zu != %zu", msp.initial_gen0_size(), expected));
1041 }
1042
1043 static void verify_scaled_initial(size_t initial_heap_size) {
1044 MarkSweepPolicy msp;
1045 msp.initialize_all();
1046
1047 size_t expected = msp.scale_by_NewRatio_aligned(initial_heap_size);
1048 assert(msp.initial_gen0_size() == expected, err_msg("%zu != %zu", msp.initial_gen0_size(), expected));
1049 assert(FLAG_IS_ERGO(NewSize) && NewSize == expected,
1050 err_msg("NewSize should have been set ergonomically to %zu, but was %zu", expected, NewSize));
1051 }
1052
1053 private:
1054 static size_t original_InitialHeapSize;
1055 static size_t original_MaxHeapSize;
1056 static size_t original_MaxNewSize;
1057 static size_t original_MinHeapDeltaBytes;
1058 static size_t original_NewSize;
1059 static size_t original_OldSize;
1060
1061 static void save_flags() {
1062 original_InitialHeapSize = InitialHeapSize;
1063 original_MaxHeapSize = MaxHeapSize;
1064 original_MaxNewSize = MaxNewSize;
1065 original_MinHeapDeltaBytes = MinHeapDeltaBytes;
1066 original_NewSize = NewSize;
1067 original_OldSize = OldSize;
1068 }
1069
1070 static void restore_flags() {
1071 InitialHeapSize = original_InitialHeapSize;
1072 MaxHeapSize = original_MaxHeapSize;
1073 MaxNewSize = original_MaxNewSize;
1074 MinHeapDeltaBytes = original_MinHeapDeltaBytes;
1075 NewSize = original_NewSize;
1076 OldSize = original_OldSize;
1077 }
1078 };
1079
1080 size_t TestGenCollectorPolicy::original_InitialHeapSize = 0;
1081 size_t TestGenCollectorPolicy::original_MaxHeapSize = 0;
1082 size_t TestGenCollectorPolicy::original_MaxNewSize = 0;
1083 size_t TestGenCollectorPolicy::original_MinHeapDeltaBytes = 0;
1084 size_t TestGenCollectorPolicy::original_NewSize = 0;
1085 size_t TestGenCollectorPolicy::original_OldSize = 0;
1086
1087 void TestNewSize_test() {
1088 TestGenCollectorPolicy::test();
1089 }
1090
1091 #endif