15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/g1CollectedHeap.hpp"
27 #include "gc/g1/g1CollectionSet.hpp"
28 #include "gc/g1/g1CollectorState.hpp"
29 #include "gc/g1/g1Policy.hpp"
30 #include "gc/g1/heapRegion.inline.hpp"
31 #include "gc/g1/heapRegionRemSet.hpp"
32 #include "gc/g1/heapRegionSet.hpp"
33 #include "logging/logStream.hpp"
34 #include "utilities/debug.hpp"
35
36 G1CollectorState* G1CollectionSet::collector_state() {
37 return _g1->collector_state();
38 }
39
40 G1GCPhaseTimes* G1CollectionSet::phase_times() {
41 return _policy->phase_times();
42 }
43
44 CollectionSetChooser* G1CollectionSet::cset_chooser() {
45 return _cset_chooser;
46 }
47
48 double G1CollectionSet::predict_region_elapsed_time_ms(HeapRegion* hr) {
49 return _policy->predict_region_elapsed_time_ms(hr, collector_state()->gcs_are_young());
50 }
51
52 G1CollectionSet::G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy) :
53 _g1(g1h),
54 _policy(policy),
379
380 // Clear the fields that point to the survivor list - they are all young now.
381 survivors->convert_to_eden();
382
383 _bytes_used_before = _inc_bytes_used_before;
384 time_remaining_ms = MAX2(time_remaining_ms - _inc_predicted_elapsed_time_ms, 0.0);
385
386 log_trace(gc, ergo, cset)("Add young regions to CSet. eden: %u regions, survivors: %u regions, predicted young region time: %1.2fms, target pause time: %1.2fms",
387 eden_region_length, survivor_region_length, _inc_predicted_elapsed_time_ms, target_pause_time_ms);
388
389 // The number of recorded young regions is the incremental
390 // collection set's current size
391 set_recorded_rs_lengths(_inc_recorded_rs_lengths);
392
393 double young_end_time_sec = os::elapsedTime();
394 phase_times()->record_young_cset_choice_time_ms((young_end_time_sec - young_start_time_sec) * 1000.0);
395
396 return time_remaining_ms;
397 }
398
399 static int compare_region_idx(const void *a, const void*b) {
400 uint const first = *(uint*)a;
401 uint const second = *(uint*)b;
402 assert(first != second, "Two regions with the same index %u in the collection set", first);
403 if (first > second) {
404 return 1;
405 } else {
406 return -1;
407 }
408 }
409
410 void G1CollectionSet::finalize_old_part(double time_remaining_ms) {
411 double non_young_start_time_sec = os::elapsedTime();
412 double predicted_old_time_ms = 0.0;
413
414 if (!collector_state()->gcs_are_young()) {
415 cset_chooser()->verify();
416 const uint min_old_cset_length = _policy->calc_min_old_cset_length();
417 const uint max_old_cset_length = _policy->calc_max_old_cset_length();
418
419 uint expensive_region_num = 0;
420 bool check_time_remaining = _policy->adaptive_young_list_length();
421
422 HeapRegion* hr = cset_chooser()->peek();
423 while (hr != NULL) {
424 if (old_region_length() >= max_old_cset_length) {
488 if (expensive_region_num > 0) {
489 // We print the information once here at the end, predicated on
490 // whether we added any apparently expensive regions or not, to
491 // avoid generating output per region.
492 log_debug(gc, ergo, cset)("Added expensive regions to CSet (old CSet region num not reached min)."
493 "old: %u regions, expensive: %u regions, min: %u regions, remaining time: %1.2fms",
494 old_region_length(), expensive_region_num, min_old_cset_length, time_remaining_ms);
495 }
496
497 cset_chooser()->verify();
498 }
499
500 stop_incremental_building();
501
502 log_debug(gc, ergo, cset)("Finish choosing CSet. old: %u regions, predicted old region time: %1.2fms, time remaining: %1.2f",
503 old_region_length(), predicted_old_time_ms, time_remaining_ms);
504
505 double non_young_end_time_sec = os::elapsedTime();
506 phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
507
508 qsort(_collection_set_regions, _collection_set_cur_length, sizeof(uint), compare_region_idx);
509 }
510
511 #ifdef ASSERT
512 class G1VerifyYoungCSetIndicesClosure : public HeapRegionClosure {
513 private:
514 size_t _young_length;
515 int* _heap_region_indices;
516 public:
517 G1VerifyYoungCSetIndicesClosure(size_t young_length) : HeapRegionClosure(), _young_length(young_length) {
518 _heap_region_indices = NEW_C_HEAP_ARRAY(int, young_length, mtGC);
519 for (size_t i = 0; i < young_length; i++) {
520 _heap_region_indices[i] = -1;
521 }
522 }
523 ~G1VerifyYoungCSetIndicesClosure() {
524 FREE_C_HEAP_ARRAY(int, _heap_region_indices);
525 }
526
527 virtual bool doHeapRegion(HeapRegion* r) {
528 const int idx = r->young_index_in_cset();
|
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/g1CollectedHeap.hpp"
27 #include "gc/g1/g1CollectionSet.hpp"
28 #include "gc/g1/g1CollectorState.hpp"
29 #include "gc/g1/g1Policy.hpp"
30 #include "gc/g1/heapRegion.inline.hpp"
31 #include "gc/g1/heapRegionRemSet.hpp"
32 #include "gc/g1/heapRegionSet.hpp"
33 #include "logging/logStream.hpp"
34 #include "utilities/debug.hpp"
35 #include "utilities/quickSort.hpp"
36
37 G1CollectorState* G1CollectionSet::collector_state() {
38 return _g1->collector_state();
39 }
40
41 G1GCPhaseTimes* G1CollectionSet::phase_times() {
42 return _policy->phase_times();
43 }
44
45 CollectionSetChooser* G1CollectionSet::cset_chooser() {
46 return _cset_chooser;
47 }
48
49 double G1CollectionSet::predict_region_elapsed_time_ms(HeapRegion* hr) {
50 return _policy->predict_region_elapsed_time_ms(hr, collector_state()->gcs_are_young());
51 }
52
53 G1CollectionSet::G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy) :
54 _g1(g1h),
55 _policy(policy),
380
381 // Clear the fields that point to the survivor list - they are all young now.
382 survivors->convert_to_eden();
383
384 _bytes_used_before = _inc_bytes_used_before;
385 time_remaining_ms = MAX2(time_remaining_ms - _inc_predicted_elapsed_time_ms, 0.0);
386
387 log_trace(gc, ergo, cset)("Add young regions to CSet. eden: %u regions, survivors: %u regions, predicted young region time: %1.2fms, target pause time: %1.2fms",
388 eden_region_length, survivor_region_length, _inc_predicted_elapsed_time_ms, target_pause_time_ms);
389
390 // The number of recorded young regions is the incremental
391 // collection set's current size
392 set_recorded_rs_lengths(_inc_recorded_rs_lengths);
393
394 double young_end_time_sec = os::elapsedTime();
395 phase_times()->record_young_cset_choice_time_ms((young_end_time_sec - young_start_time_sec) * 1000.0);
396
397 return time_remaining_ms;
398 }
399
400 static int compare_region_idx(const uint a, const uint b) {
401 if (a > b) {
402 return 1;
403 } else if (a == b) {
404 return 0;
405 } else {
406 return -1;
407 }
408 }
409
410 void G1CollectionSet::finalize_old_part(double time_remaining_ms) {
411 double non_young_start_time_sec = os::elapsedTime();
412 double predicted_old_time_ms = 0.0;
413
414 if (!collector_state()->gcs_are_young()) {
415 cset_chooser()->verify();
416 const uint min_old_cset_length = _policy->calc_min_old_cset_length();
417 const uint max_old_cset_length = _policy->calc_max_old_cset_length();
418
419 uint expensive_region_num = 0;
420 bool check_time_remaining = _policy->adaptive_young_list_length();
421
422 HeapRegion* hr = cset_chooser()->peek();
423 while (hr != NULL) {
424 if (old_region_length() >= max_old_cset_length) {
488 if (expensive_region_num > 0) {
489 // We print the information once here at the end, predicated on
490 // whether we added any apparently expensive regions or not, to
491 // avoid generating output per region.
492 log_debug(gc, ergo, cset)("Added expensive regions to CSet (old CSet region num not reached min)."
493 "old: %u regions, expensive: %u regions, min: %u regions, remaining time: %1.2fms",
494 old_region_length(), expensive_region_num, min_old_cset_length, time_remaining_ms);
495 }
496
497 cset_chooser()->verify();
498 }
499
500 stop_incremental_building();
501
502 log_debug(gc, ergo, cset)("Finish choosing CSet. old: %u regions, predicted old region time: %1.2fms, time remaining: %1.2f",
503 old_region_length(), predicted_old_time_ms, time_remaining_ms);
504
505 double non_young_end_time_sec = os::elapsedTime();
506 phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
507
508 QuickSort::sort<uint>(_collection_set_regions, (int)_collection_set_cur_length, compare_region_idx, true);
509 }
510
511 #ifdef ASSERT
512 class G1VerifyYoungCSetIndicesClosure : public HeapRegionClosure {
513 private:
514 size_t _young_length;
515 int* _heap_region_indices;
516 public:
517 G1VerifyYoungCSetIndicesClosure(size_t young_length) : HeapRegionClosure(), _young_length(young_length) {
518 _heap_region_indices = NEW_C_HEAP_ARRAY(int, young_length, mtGC);
519 for (size_t i = 0; i < young_length; i++) {
520 _heap_region_indices[i] = -1;
521 }
522 }
523 ~G1VerifyYoungCSetIndicesClosure() {
524 FREE_C_HEAP_ARRAY(int, _heap_region_indices);
525 }
526
527 virtual bool doHeapRegion(HeapRegion* r) {
528 const int idx = r->young_index_in_cset();
|