Mercurial > hg > graal-compiler
comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 1717:688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
Summary: There are a few issues in the code that calculates whether to resize the heap and by how much: a) some calculations can overflow 32-bit size_t's, b) min_desired_capacity is not bounded by the max heap size, and c) the assrt that fires is in the wrong place. The fix also includes some tidying up of the related verbose code.
Reviewed-by: ysr, jmasa
author | tonyp |
---|---|
date | Tue, 17 Aug 2010 14:40:00 -0400 |
parents | 5f429ee79634 |
children | bb847e31b836 |
comparison
equal
deleted
inserted
replaced
1716:be3f9c242c9d | 1717:688c3755d7af |
---|---|
1042 // pre-allocated to support collections, as "used". | 1042 // pre-allocated to support collections, as "used". |
1043 const size_t used_after_gc = used(); | 1043 const size_t used_after_gc = used(); |
1044 const size_t capacity_after_gc = capacity(); | 1044 const size_t capacity_after_gc = capacity(); |
1045 const size_t free_after_gc = capacity_after_gc - used_after_gc; | 1045 const size_t free_after_gc = capacity_after_gc - used_after_gc; |
1046 | 1046 |
1047 // This is enforced in arguments.cpp. | |
1048 assert(MinHeapFreeRatio <= MaxHeapFreeRatio, | |
1049 "otherwise the code below doesn't make sense"); | |
1050 | |
1047 // We don't have floating point command-line arguments | 1051 // We don't have floating point command-line arguments |
1048 const double minimum_free_percentage = (double) MinHeapFreeRatio / 100; | 1052 const double minimum_free_percentage = (double) MinHeapFreeRatio / 100.0; |
1049 const double maximum_used_percentage = 1.0 - minimum_free_percentage; | 1053 const double maximum_used_percentage = 1.0 - minimum_free_percentage; |
1050 const double maximum_free_percentage = (double) MaxHeapFreeRatio / 100; | 1054 const double maximum_free_percentage = (double) MaxHeapFreeRatio / 100.0; |
1051 const double minimum_used_percentage = 1.0 - maximum_free_percentage; | 1055 const double minimum_used_percentage = 1.0 - maximum_free_percentage; |
1052 | 1056 |
1053 size_t minimum_desired_capacity = (size_t) (used_after_gc / maximum_used_percentage); | 1057 const size_t min_heap_size = collector_policy()->min_heap_byte_size(); |
1054 size_t maximum_desired_capacity = (size_t) (used_after_gc / minimum_used_percentage); | 1058 const size_t max_heap_size = collector_policy()->max_heap_byte_size(); |
1055 | 1059 |
1056 // Don't shrink less than the initial size. | 1060 // We have to be careful here as these two calculations can overflow |
1057 minimum_desired_capacity = | 1061 // 32-bit size_t's. |
1058 MAX2(minimum_desired_capacity, | 1062 double used_after_gc_d = (double) used_after_gc; |
1059 collector_policy()->initial_heap_byte_size()); | 1063 double minimum_desired_capacity_d = used_after_gc_d / maximum_used_percentage; |
1060 maximum_desired_capacity = | 1064 double maximum_desired_capacity_d = used_after_gc_d / minimum_used_percentage; |
1061 MAX2(maximum_desired_capacity, | 1065 |
1062 collector_policy()->initial_heap_byte_size()); | 1066 // Let's make sure that they are both under the max heap size, which |
1063 | 1067 // by default will make them fit into a size_t. |
1064 // We are failing here because minimum_desired_capacity is | 1068 double desired_capacity_upper_bound = (double) max_heap_size; |
1065 assert(used_after_gc <= minimum_desired_capacity, "sanity check"); | 1069 minimum_desired_capacity_d = MIN2(minimum_desired_capacity_d, |
1066 assert(minimum_desired_capacity <= maximum_desired_capacity, "sanity check"); | 1070 desired_capacity_upper_bound); |
1071 maximum_desired_capacity_d = MIN2(maximum_desired_capacity_d, | |
1072 desired_capacity_upper_bound); | |
1073 | |
1074 // We can now safely turn them into size_t's. | |
1075 size_t minimum_desired_capacity = (size_t) minimum_desired_capacity_d; | |
1076 size_t maximum_desired_capacity = (size_t) maximum_desired_capacity_d; | |
1077 | |
1078 // This assert only makes sense here, before we adjust them | |
1079 // with respect to the min and max heap size. | |
1080 assert(minimum_desired_capacity <= maximum_desired_capacity, | |
1081 err_msg("minimum_desired_capacity = "SIZE_FORMAT", " | |
1082 "maximum_desired_capacity = "SIZE_FORMAT, | |
1083 minimum_desired_capacity, maximum_desired_capacity)); | |
1084 | |
1085 // Should not be greater than the heap max size. No need to adjust | |
1086 // it with respect to the heap min size as it's a lower bound (i.e., | |
1087 // we'll try to make the capacity larger than it, not smaller). | |
1088 minimum_desired_capacity = MIN2(minimum_desired_capacity, max_heap_size); | |
1089 // Should not be less than the heap min size. No need to adjust it | |
1090 // with respect to the heap max size as it's an upper bound (i.e., | |
1091 // we'll try to make the capacity smaller than it, not greater). | |
1092 maximum_desired_capacity = MAX2(maximum_desired_capacity, min_heap_size); | |
1067 | 1093 |
1068 if (PrintGC && Verbose) { | 1094 if (PrintGC && Verbose) { |
1069 const double free_percentage = ((double)free_after_gc) / capacity(); | 1095 const double free_percentage = |
1096 (double) free_after_gc / (double) capacity_after_gc; | |
1070 gclog_or_tty->print_cr("Computing new size after full GC "); | 1097 gclog_or_tty->print_cr("Computing new size after full GC "); |
1071 gclog_or_tty->print_cr(" " | 1098 gclog_or_tty->print_cr(" " |
1072 " minimum_free_percentage: %6.2f", | 1099 " minimum_free_percentage: %6.2f", |
1073 minimum_free_percentage); | 1100 minimum_free_percentage); |
1074 gclog_or_tty->print_cr(" " | 1101 gclog_or_tty->print_cr(" " |
1076 maximum_free_percentage); | 1103 maximum_free_percentage); |
1077 gclog_or_tty->print_cr(" " | 1104 gclog_or_tty->print_cr(" " |
1078 " capacity: %6.1fK" | 1105 " capacity: %6.1fK" |
1079 " minimum_desired_capacity: %6.1fK" | 1106 " minimum_desired_capacity: %6.1fK" |
1080 " maximum_desired_capacity: %6.1fK", | 1107 " maximum_desired_capacity: %6.1fK", |
1081 capacity() / (double) K, | 1108 (double) capacity_after_gc / (double) K, |
1082 minimum_desired_capacity / (double) K, | 1109 (double) minimum_desired_capacity / (double) K, |
1083 maximum_desired_capacity / (double) K); | 1110 (double) maximum_desired_capacity / (double) K); |
1084 gclog_or_tty->print_cr(" " | 1111 gclog_or_tty->print_cr(" " |
1085 " free_after_gc : %6.1fK" | 1112 " free_after_gc: %6.1fK" |
1086 " used_after_gc : %6.1fK", | 1113 " used_after_gc: %6.1fK", |
1087 free_after_gc / (double) K, | 1114 (double) free_after_gc / (double) K, |
1088 used_after_gc / (double) K); | 1115 (double) used_after_gc / (double) K); |
1089 gclog_or_tty->print_cr(" " | 1116 gclog_or_tty->print_cr(" " |
1090 " free_percentage: %6.2f", | 1117 " free_percentage: %6.2f", |
1091 free_percentage); | 1118 free_percentage); |
1092 } | 1119 } |
1093 if (capacity() < minimum_desired_capacity) { | 1120 if (capacity_after_gc < minimum_desired_capacity) { |
1094 // Don't expand unless it's significant | 1121 // Don't expand unless it's significant |
1095 size_t expand_bytes = minimum_desired_capacity - capacity_after_gc; | 1122 size_t expand_bytes = minimum_desired_capacity - capacity_after_gc; |
1096 expand(expand_bytes); | 1123 expand(expand_bytes); |
1097 if (PrintGC && Verbose) { | 1124 if (PrintGC && Verbose) { |
1098 gclog_or_tty->print_cr(" expanding:" | 1125 gclog_or_tty->print_cr(" " |
1126 " expanding:" | |
1127 " max_heap_size: %6.1fK" | |
1099 " minimum_desired_capacity: %6.1fK" | 1128 " minimum_desired_capacity: %6.1fK" |
1100 " expand_bytes: %6.1fK", | 1129 " expand_bytes: %6.1fK", |
1101 minimum_desired_capacity / (double) K, | 1130 (double) max_heap_size / (double) K, |
1102 expand_bytes / (double) K); | 1131 (double) minimum_desired_capacity / (double) K, |
1132 (double) expand_bytes / (double) K); | |
1103 } | 1133 } |
1104 | 1134 |
1105 // No expansion, now see if we want to shrink | 1135 // No expansion, now see if we want to shrink |
1106 } else if (capacity() > maximum_desired_capacity) { | 1136 } else if (capacity_after_gc > maximum_desired_capacity) { |
1107 // Capacity too large, compute shrinking size | 1137 // Capacity too large, compute shrinking size |
1108 size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity; | 1138 size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity; |
1109 shrink(shrink_bytes); | 1139 shrink(shrink_bytes); |
1110 if (PrintGC && Verbose) { | 1140 if (PrintGC && Verbose) { |
1111 gclog_or_tty->print_cr(" " | 1141 gclog_or_tty->print_cr(" " |
1112 " shrinking:" | 1142 " shrinking:" |
1113 " initSize: %.1fK" | 1143 " min_heap_size: %6.1fK" |
1114 " maximum_desired_capacity: %.1fK", | 1144 " maximum_desired_capacity: %6.1fK" |
1115 collector_policy()->initial_heap_byte_size() / (double) K, | 1145 " shrink_bytes: %6.1fK", |
1116 maximum_desired_capacity / (double) K); | 1146 (double) min_heap_size / (double) K, |
1117 gclog_or_tty->print_cr(" " | 1147 (double) maximum_desired_capacity / (double) K, |
1118 " shrink_bytes: %.1fK", | 1148 (double) shrink_bytes / (double) K); |
1119 shrink_bytes / (double) K); | |
1120 } | 1149 } |
1121 } | 1150 } |
1122 } | 1151 } |
1123 | 1152 |
1124 | 1153 |