20 * or visit www.oracle.com if you need additional information or have any |
20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. |
21 * questions. |
22 * |
22 * |
23 */ |
23 */ |
24 |
24 |
|
25 /* |
|
26 * This file has been modified by Loongson Technology in 2015. These |
|
27 * modifications are Copyright (c) 2015 Loongson Technology, and are made |
|
28 * available on the same license terms set forth above. |
|
29 */ |
|
30 |
25 #include "precompiled.hpp" |
31 #include "precompiled.hpp" |
26 #include "classfile/symbolTable.hpp" |
32 #include "classfile/symbolTable.hpp" |
27 #include "code/codeCache.hpp" |
33 #include "code/codeCache.hpp" |
28 #include "gc_implementation/parallelScavenge/cardTableExtension.hpp" |
34 #include "gc_implementation/parallelScavenge/cardTableExtension.hpp" |
29 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" |
35 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" |
36 #include "gc_implementation/shared/gcHeapSummary.hpp" |
42 #include "gc_implementation/shared/gcHeapSummary.hpp" |
37 #include "gc_implementation/shared/gcTimer.hpp" |
43 #include "gc_implementation/shared/gcTimer.hpp" |
38 #include "gc_implementation/shared/gcTrace.hpp" |
44 #include "gc_implementation/shared/gcTrace.hpp" |
39 #include "gc_implementation/shared/gcTraceTime.hpp" |
45 #include "gc_implementation/shared/gcTraceTime.hpp" |
40 #include "gc_implementation/shared/isGCActiveMark.hpp" |
46 #include "gc_implementation/shared/isGCActiveMark.hpp" |
|
47 #include "gc_implementation/shared/mutableNUMASpace.hpp" |
41 #include "gc_implementation/shared/spaceDecorator.hpp" |
48 #include "gc_implementation/shared/spaceDecorator.hpp" |
42 #include "gc_interface/gcCause.hpp" |
49 #include "gc_interface/gcCause.hpp" |
43 #include "memory/collectorPolicy.hpp" |
50 #include "memory/collectorPolicy.hpp" |
44 #include "memory/gcLocker.inline.hpp" |
51 #include "memory/gcLocker.inline.hpp" |
45 #include "memory/referencePolicy.hpp" |
52 #include "memory/referencePolicy.hpp" |
228 |
235 |
229 PSAdaptiveSizePolicy* policy = heap->size_policy(); |
236 PSAdaptiveSizePolicy* policy = heap->size_policy(); |
230 IsGCActiveMark mark; |
237 IsGCActiveMark mark; |
231 |
238 |
232 const bool scavenge_done = PSScavenge::invoke_no_policy(); |
239 const bool scavenge_done = PSScavenge::invoke_no_policy(); |
233 const bool need_full_gc = !scavenge_done || |
240 bool need_full_gc; |
234 policy->should_full_GC(heap->old_gen()->free_in_bytes()); |
241 if(UseOldNUMA) { |
|
242 need_full_gc = !scavenge_done || |
|
243 policy->should_full_GC(heap->old_gen()->free_in_bytes_numa()); |
|
244 } |
|
245 else { |
|
246 need_full_gc = !scavenge_done || |
|
247 policy->should_full_GC(heap->old_gen()->free_in_bytes()); |
|
248 } |
235 bool full_gc_done = false; |
249 bool full_gc_done = false; |
236 |
250 |
237 if (UsePerfData) { |
251 if (UsePerfData) { |
238 PSGCAdaptivePolicyCounters* const counters = heap->gc_policy_counters(); |
252 PSGCAdaptivePolicyCounters* const counters = heap->gc_policy_counters(); |
239 const int ffs_val = need_full_gc ? full_follows_scavenge : not_skipped; |
253 const int ffs_val = need_full_gc ? full_follows_scavenge : not_skipped; |
252 } |
266 } |
253 } |
267 } |
254 |
268 |
255 return full_gc_done; |
269 return full_gc_done; |
256 } |
270 } |
|
271 |
|
272 /* 2014/7/7 Liao: Add these variables to stastic detail information during GC. */ |
|
273 /* Used for objects copy stastic. */ |
|
274 float each_gc_copy_time[16]; |
|
275 int each_gc_copy_fre[16]; |
|
276 |
|
277 /* Used for GC details stastic. */ |
|
278 float total_gc_time = 0; |
|
279 int total_gc_fre = 0; |
|
280 |
|
281 /* Used to statstic ThreadRoots optimization. */ |
|
282 int task_tag[16]; |
|
283 //Used to stastic each cpu |
|
284 int each_total_num[16]; |
|
285 int each_eden_total_num[3][16]; |
|
286 int each_eden_aligned_num[3][16]; |
|
287 //Used to stastic every GC |
|
288 int every_total_num; |
|
289 int every_eden_total_num[3]; |
|
290 int every_eden_aligned_num[3]; |
|
291 //Used to stastic all the time |
|
292 int all_total_num; |
|
293 int all_eden_total_num[3]; |
|
294 int all_eden_aligned_num[3]; |
257 |
295 |
258 // This method contains no policy. You should probably |
296 // This method contains no policy. You should probably |
259 // be calling invoke() instead. |
297 // be calling invoke() instead. |
260 bool PSScavenge::invoke_no_policy() { |
298 bool PSScavenge::invoke_no_policy() { |
261 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); |
299 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); |
306 if (ZapUnusedHeapArea) { |
344 if (ZapUnusedHeapArea) { |
307 // Save information needed to minimize mangling |
345 // Save information needed to minimize mangling |
308 heap->record_gen_tops_before_GC(); |
346 heap->record_gen_tops_before_GC(); |
309 } |
347 } |
310 |
348 |
|
349 if(UseStasticCopy) { |
|
350 for(uint i = 0; i < ParallelGCThreads; i++) { |
|
351 each_gc_copy_time[i] = 0; |
|
352 each_gc_copy_fre[i] = 0; |
|
353 } |
|
354 } |
|
355 |
|
356 if(UseStasticScavenge) { |
|
357 for(int j = 0; j < 3; j++) { |
|
358 for(uint i = 0; i < ParallelGCThreads; i++) { |
|
359 task_tag[i] = 0; |
|
360 |
|
361 each_total_num[i] = 0; |
|
362 each_eden_total_num[j][i] = 0; |
|
363 each_eden_aligned_num[j][i] = 0; |
|
364 |
|
365 every_total_num = 0; |
|
366 every_eden_total_num[j] = 0; |
|
367 every_eden_aligned_num[j] = 0; |
|
368 } |
|
369 } |
|
370 } |
|
371 |
311 heap->print_heap_before_gc(); |
372 heap->print_heap_before_gc(); |
312 heap->trace_heap_before_gc(&_gc_tracer); |
373 heap->trace_heap_before_gc(&_gc_tracer); |
313 |
374 |
314 assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity"); |
375 assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity"); |
315 assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity"); |
376 assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity"); |
400 GCTraceTime tm("Scavenge", false, false, &_gc_timer); |
461 GCTraceTime tm("Scavenge", false, false, &_gc_timer); |
401 ParallelScavengeHeap::ParStrongRootsScope psrs; |
462 ParallelScavengeHeap::ParStrongRootsScope psrs; |
402 |
463 |
403 GCTaskQueue* q = GCTaskQueue::create(); |
464 GCTaskQueue* q = GCTaskQueue::create(); |
404 |
465 |
405 if (!old_gen->object_space()->is_empty()) { |
466 if(UseOldNUMA) { |
406 // There are only old-to-young pointers if there are objects |
467 MutableSpace* sp; |
407 // in the old gen. |
468 MutableNUMASpace::LGRPSpace *ls; |
408 uint stripe_total = active_workers; |
469 MutableNUMASpace* s = (MutableNUMASpace*) old_gen->object_space(); |
409 for(uint i=0; i < stripe_total; i++) { |
470 int i, j; |
410 q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i, stripe_total)); |
471 i = s->lgrp_spaces()->length(); |
|
472 HeapWord** gen_top = (HeapWord**) malloc (i * sizeof(HeapWord)); |
|
473 for(j = 0; j < i; j++) { |
|
474 ls = s->lgrp_spaces()->at(j); |
|
475 sp = ls->space(); |
|
476 *(gen_top + j) = sp->top(); |
|
477 } |
|
478 |
|
479 if (!old_gen->object_space()->is_empty()) { |
|
480 uint stripe_total = active_workers; |
|
481 for(uint i=0; i < stripe_total; i++) { |
|
482 q->enqueue(new OldToYoungRootsTask_OldNUMA(old_gen, gen_top, i, stripe_total)); |
|
483 } |
|
484 } |
|
485 } |
|
486 else { |
|
487 if (!old_gen->object_space()->is_empty()) { |
|
488 // There are only old-to-young pointers if there are objects |
|
489 // in the old gen. |
|
490 uint stripe_total = active_workers; |
|
491 for(uint i=0; i < stripe_total; i++) { |
|
492 q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i, stripe_total)); |
|
493 } |
411 } |
494 } |
412 } |
495 } |
413 |
496 |
414 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe)); |
497 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe)); |
415 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jni_handles)); |
498 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jni_handles)); |
696 tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " " INT64_FORMAT, |
779 tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " " INT64_FORMAT, |
697 scavenge_entry.ticks(), scavenge_midpoint.ticks(), |
780 scavenge_entry.ticks(), scavenge_midpoint.ticks(), |
698 scavenge_exit.ticks()); |
781 scavenge_exit.ticks()); |
699 gc_task_manager()->print_task_time_stamps(); |
782 gc_task_manager()->print_task_time_stamps(); |
700 } |
783 } |
|
784 |
|
785 if(PrintGCDetails) { |
|
786 float young_gc_time; |
|
787 total_gc_fre++; |
|
788 young_gc_time = ((float)(scavenge_exit.ticks() - scavenge_entry.ticks()))/1e9; |
|
789 total_gc_time = total_gc_time + ((float)(scavenge_exit.ticks() - scavenge_entry.ticks()))/1e9; |
|
790 tty->print_cr("total_gc_fre = %d, young_gc_time = %f, total_gc_time = %f", total_gc_fre, young_gc_time, total_gc_time); |
|
791 } |
|
792 |
|
793 if(UseStasticCopy) { |
|
794 for(uint i = 0; i < ParallelGCThreads; i++) { |
|
795 tty->print_cr("each_gc_copy_time[%d] = %f", i, each_gc_copy_time[i]/each_gc_copy_fre[i]); |
|
796 } |
|
797 tty->print_cr(""); |
|
798 for(uint i = 0; i < ParallelGCThreads; i++) { |
|
799 tty->print_cr("each_gc_copy_fre[%d] = %d", i, each_gc_copy_fre[i]); |
|
800 } |
|
801 } |
|
802 |
|
803 if(UseStasticScavenge) { |
|
804 for(int i = 0; i < 3; i++) { |
|
805 for(uint j = 0; j < ParallelGCThreads; j++) { |
|
806 every_eden_total_num[i] += each_eden_total_num[i][j]; |
|
807 every_eden_aligned_num[i] += each_eden_aligned_num[i][j]; |
|
808 } |
|
809 } |
|
810 |
|
811 for(uint i = 0; i < ParallelGCThreads; i++) { |
|
812 every_total_num += each_total_num[i]; |
|
813 } |
|
814 |
|
815 all_total_num += every_total_num; |
|
816 |
|
817 for(int i = 0; i < 3; i++) { |
|
818 all_eden_total_num[i] += every_eden_total_num[i]; |
|
819 all_eden_aligned_num[i] += every_eden_aligned_num[i]; |
|
820 } |
|
821 |
|
822 tty->print_cr("============= Every GCDetails: ============="); |
|
823 tty->print_cr("ThreadRootTask: prop of all = %f, prop of aligned = %f", (float)every_eden_total_num[0]/(float)every_total_num, (float)every_eden_aligned_num[0]/(float)every_eden_total_num[0]); |
|
824 tty->print_cr("OldToYoungRootTask: prop of all = %f, prop of aligned = %f", (float)every_eden_total_num[1]/(float)every_total_num, (float)every_eden_aligned_num[1]/(float)every_eden_total_num[1]); |
|
825 tty->print_cr("StealTask: prop of all = %f, prop of aligned = %f", (float)every_eden_total_num[2]/(float)every_total_num, (float)every_eden_aligned_num[2]/(float)every_eden_total_num[2]); |
|
826 tty->print_cr(""); |
|
827 |
|
828 tty->print_cr("============= Total GCDetails: ============="); |
|
829 tty->print_cr("ThreadRootTask: prop of all = %f, prop of aligned = %f", (float)all_eden_total_num[0]/(float)all_total_num, (float)all_eden_aligned_num[0]/(float)all_eden_total_num[0]); |
|
830 tty->print_cr("OldToYoungRootTask: prop of all = %f, prop of aligned = %f", (float)all_eden_total_num[1]/(float)all_total_num, (float)all_eden_aligned_num[1]/(float)all_eden_total_num[1]); |
|
831 tty->print_cr("StealTask: prop of all = %f, prop of aligned = %f", (float)all_eden_total_num[2]/(float)all_total_num, (float)all_eden_aligned_num[2]/(float)all_eden_total_num[2]); |
|
832 tty->print_cr(""); |
|
833 } |
701 |
834 |
702 #ifdef TRACESPINNING |
835 #ifdef TRACESPINNING |
703 ParallelTaskTerminator::print_termination_counts(); |
836 ParallelTaskTerminator::print_termination_counts(); |
704 #endif |
837 #endif |
705 |
838 |