Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @ 18058:54bc75c144b0
Merge
author | asaha |
---|---|
date | Thu, 29 May 2014 13:14:25 -0700 |
parents | 78bbf4d43a14 |
children | 52b4284cb496 ce8f6bb717c9 6e56d7f1634f |
comparison
equal
deleted
inserted
replaced
18055:1fa005fb28f5 | 18058:54bc75c144b0 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
425 } | 425 } |
426 | 426 |
427 void LinearAllocBlock::print_on(outputStream* st) const { | 427 void LinearAllocBlock::print_on(outputStream* st) const { |
428 st->print_cr(" LinearAllocBlock: ptr = " PTR_FORMAT ", word_size = " SIZE_FORMAT | 428 st->print_cr(" LinearAllocBlock: ptr = " PTR_FORMAT ", word_size = " SIZE_FORMAT |
429 ", refillsize = " SIZE_FORMAT ", allocation_size_limit = " SIZE_FORMAT, | 429 ", refillsize = " SIZE_FORMAT ", allocation_size_limit = " SIZE_FORMAT, |
430 _ptr, _word_size, _refillSize, _allocation_size_limit); | 430 p2i(_ptr), _word_size, _refillSize, _allocation_size_limit); |
431 } | 431 } |
432 | 432 |
433 void CompactibleFreeListSpace::print_on(outputStream* st) const { | 433 void CompactibleFreeListSpace::print_on(outputStream* st) const { |
434 st->print_cr("COMPACTIBLE FREELIST SPACE"); | 434 st->print_cr("COMPACTIBLE FREELIST SPACE"); |
435 st->print_cr(" Space:"); | 435 st->print_cr(" Space:"); |
456 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { | 456 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { |
457 _indexedFreeList[i].print_on(gclog_or_tty); | 457 _indexedFreeList[i].print_on(gclog_or_tty); |
458 for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL; | 458 for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL; |
459 fc = fc->next()) { | 459 fc = fc->next()) { |
460 gclog_or_tty->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s", | 460 gclog_or_tty->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s", |
461 fc, (HeapWord*)fc + i, | 461 p2i(fc), p2i((HeapWord*)fc + i), |
462 fc->cantCoalesce() ? "\t CC" : ""); | 462 fc->cantCoalesce() ? "\t CC" : ""); |
463 } | 463 } |
464 } | 464 } |
465 } | 465 } |
466 | 466 |
500 size_t sz = _sp->block_size_no_stall(addr, _collector); | 500 size_t sz = _sp->block_size_no_stall(addr, _collector); |
501 assert(sz != 0, "Should always be able to compute a size"); | 501 assert(sz != 0, "Should always be able to compute a size"); |
502 if (_sp->block_is_obj(addr)) { | 502 if (_sp->block_is_obj(addr)) { |
503 const bool dead = _post_remark && !_live_bit_map->isMarked(addr); | 503 const bool dead = _post_remark && !_live_bit_map->isMarked(addr); |
504 _st->print_cr(PTR_FORMAT ": %s object of size " SIZE_FORMAT "%s", | 504 _st->print_cr(PTR_FORMAT ": %s object of size " SIZE_FORMAT "%s", |
505 addr, | 505 p2i(addr), |
506 dead ? "dead" : "live", | 506 dead ? "dead" : "live", |
507 sz, | 507 sz, |
508 (!dead && CMSPrintObjectsInDump) ? ":" : "."); | 508 (!dead && CMSPrintObjectsInDump) ? ":" : "."); |
509 if (CMSPrintObjectsInDump && !dead) { | 509 if (CMSPrintObjectsInDump && !dead) { |
510 oop(addr)->print_on(_st); | 510 oop(addr)->print_on(_st); |
511 _st->print_cr("--------------------------------------"); | 511 _st->print_cr("--------------------------------------"); |
512 } | 512 } |
513 } else { // free block | 513 } else { // free block |
514 _st->print_cr(PTR_FORMAT ": free block of size " SIZE_FORMAT "%s", | 514 _st->print_cr(PTR_FORMAT ": free block of size " SIZE_FORMAT "%s", |
515 addr, sz, CMSPrintChunksInDump ? ":" : "."); | 515 p2i(addr), sz, CMSPrintChunksInDump ? ":" : "."); |
516 if (CMSPrintChunksInDump) { | 516 if (CMSPrintChunksInDump) { |
517 ((FreeChunk*)addr)->print_on(_st); | 517 ((FreeChunk*)addr)->print_on(_st); |
518 _st->print_cr("--------------------------------------"); | 518 _st->print_cr("--------------------------------------"); |
519 } | 519 } |
520 } | 520 } |
562 assert_lock_strong(&_freelistLock); | 562 assert_lock_strong(&_freelistLock); |
563 gclog_or_tty->print("Statistics for IndexedFreeLists:\n" | 563 gclog_or_tty->print("Statistics for IndexedFreeLists:\n" |
564 "--------------------------------\n"); | 564 "--------------------------------\n"); |
565 size_t total_size = totalSizeInIndexedFreeLists(); | 565 size_t total_size = totalSizeInIndexedFreeLists(); |
566 size_t free_blocks = numFreeBlocksInIndexedFreeLists(); | 566 size_t free_blocks = numFreeBlocksInIndexedFreeLists(); |
567 gclog_or_tty->print("Total Free Space: %d\n", total_size); | 567 gclog_or_tty->print("Total Free Space: " SIZE_FORMAT "\n", total_size); |
568 gclog_or_tty->print("Max Chunk Size: %d\n", maxChunkSizeInIndexedFreeLists()); | 568 gclog_or_tty->print("Max Chunk Size: " SIZE_FORMAT "\n", maxChunkSizeInIndexedFreeLists()); |
569 gclog_or_tty->print("Number of Blocks: %d\n", free_blocks); | 569 gclog_or_tty->print("Number of Blocks: " SIZE_FORMAT "\n", free_blocks); |
570 if (free_blocks != 0) { | 570 if (free_blocks != 0) { |
571 gclog_or_tty->print("Av. Block Size: %d\n", total_size/free_blocks); | 571 gclog_or_tty->print("Av. Block Size: " SIZE_FORMAT "\n", total_size/free_blocks); |
572 } | 572 } |
573 } | 573 } |
574 | 574 |
575 size_t CompactibleFreeListSpace::numFreeBlocksInIndexedFreeLists() const { | 575 size_t CompactibleFreeListSpace::numFreeBlocksInIndexedFreeLists() const { |
576 size_t res = 0; | 576 size_t res = 0; |
995 while (true) { | 995 while (true) { |
996 // We must do this until we get a consistent view of the object. | 996 // We must do this until we get a consistent view of the object. |
997 if (FreeChunk::indicatesFreeChunk(p)) { | 997 if (FreeChunk::indicatesFreeChunk(p)) { |
998 volatile FreeChunk* fc = (volatile FreeChunk*)p; | 998 volatile FreeChunk* fc = (volatile FreeChunk*)p; |
999 size_t res = fc->size(); | 999 size_t res = fc->size(); |
1000 | |
1001 // Bugfix for systems with weak memory model (PPC64/IA64). The | |
1002 // block's free bit was set and we have read the size of the | |
1003 // block. Acquire and check the free bit again. If the block is | |
1004 // still free, the read size is correct. | |
1005 OrderAccess::acquire(); | |
1006 | |
1000 // If the object is still a free chunk, return the size, else it | 1007 // If the object is still a free chunk, return the size, else it |
1001 // has been allocated so try again. | 1008 // has been allocated so try again. |
1002 if (FreeChunk::indicatesFreeChunk(p)) { | 1009 if (FreeChunk::indicatesFreeChunk(p)) { |
1003 assert(res != 0, "Block size should not be 0"); | 1010 assert(res != 0, "Block size should not be 0"); |
1004 return res; | 1011 return res; |
1008 Klass* k = ((volatile oopDesc*)p)->klass_or_null(); | 1015 Klass* k = ((volatile oopDesc*)p)->klass_or_null(); |
1009 if (k != NULL) { | 1016 if (k != NULL) { |
1010 assert(k->is_klass(), "Should really be klass oop."); | 1017 assert(k->is_klass(), "Should really be klass oop."); |
1011 oop o = (oop)p; | 1018 oop o = (oop)p; |
1012 assert(o->is_oop(true /* ignore mark word */), "Should be an oop."); | 1019 assert(o->is_oop(true /* ignore mark word */), "Should be an oop."); |
1020 | |
1021 // Bugfix for systems with weak memory model (PPC64/IA64). | |
1022 // The object o may be an array. Acquire to make sure that the array | |
1023 // size (third word) is consistent. | |
1024 OrderAccess::acquire(); | |
1025 | |
1013 size_t res = o->size_given_klass(k); | 1026 size_t res = o->size_given_klass(k); |
1014 res = adjustObjectSize(res); | 1027 res = adjustObjectSize(res); |
1015 assert(res != 0, "Block size should not be 0"); | 1028 assert(res != 0, "Block size should not be 0"); |
1016 return res; | 1029 return res; |
1017 } | 1030 } |
1038 while (true) { | 1051 while (true) { |
1039 // We must do this until we get a consistent view of the object. | 1052 // We must do this until we get a consistent view of the object. |
1040 if (FreeChunk::indicatesFreeChunk(p)) { | 1053 if (FreeChunk::indicatesFreeChunk(p)) { |
1041 volatile FreeChunk* fc = (volatile FreeChunk*)p; | 1054 volatile FreeChunk* fc = (volatile FreeChunk*)p; |
1042 size_t res = fc->size(); | 1055 size_t res = fc->size(); |
1056 | |
1057 // Bugfix for systems with weak memory model (PPC64/IA64). The | |
1058 // free bit of the block was set and we have read the size of | |
1059 // the block. Acquire and check the free bit again. If the | |
1060 // block is still free, the read size is correct. | |
1061 OrderAccess::acquire(); | |
1062 | |
1043 if (FreeChunk::indicatesFreeChunk(p)) { | 1063 if (FreeChunk::indicatesFreeChunk(p)) { |
1044 assert(res != 0, "Block size should not be 0"); | 1064 assert(res != 0, "Block size should not be 0"); |
1045 assert(loops == 0, "Should be 0"); | 1065 assert(loops == 0, "Should be 0"); |
1046 return res; | 1066 return res; |
1047 } | 1067 } |
1053 // -- irrespective of its conc_safe-ty. | 1073 // -- irrespective of its conc_safe-ty. |
1054 if (k != NULL) { | 1074 if (k != NULL) { |
1055 assert(k->is_klass(), "Should really be klass oop."); | 1075 assert(k->is_klass(), "Should really be klass oop."); |
1056 oop o = (oop)p; | 1076 oop o = (oop)p; |
1057 assert(o->is_oop(), "Should be an oop"); | 1077 assert(o->is_oop(), "Should be an oop"); |
1078 | |
1079 // Bugfix for systems with weak memory model (PPC64/IA64). | |
1080 // The object o may be an array. Acquire to make sure that the array | |
1081 // size (third word) is consistent. | |
1082 OrderAccess::acquire(); | |
1083 | |
1058 size_t res = o->size_given_klass(k); | 1084 size_t res = o->size_given_klass(k); |
1059 res = adjustObjectSize(res); | 1085 res = adjustObjectSize(res); |
1060 assert(res != 0, "Block size should not be 0"); | 1086 assert(res != 0, "Block size should not be 0"); |
1061 return res; | 1087 return res; |
1062 } else { | 1088 } else { |
1702 // adjust _unallocated_block downward, as necessary | 1728 // adjust _unallocated_block downward, as necessary |
1703 _bt.freed((HeapWord*)chunk, size); | 1729 _bt.freed((HeapWord*)chunk, size); |
1704 _dictionary->return_chunk(chunk); | 1730 _dictionary->return_chunk(chunk); |
1705 #ifndef PRODUCT | 1731 #ifndef PRODUCT |
1706 if (CMSCollector::abstract_state() != CMSCollector::Sweeping) { | 1732 if (CMSCollector::abstract_state() != CMSCollector::Sweeping) { |
1707 TreeChunk<FreeChunk, AdaptiveFreeList>* tc = TreeChunk<FreeChunk, AdaptiveFreeList>::as_TreeChunk(chunk); | 1733 TreeChunk<FreeChunk, AdaptiveFreeList<FreeChunk> >* tc = TreeChunk<FreeChunk, AdaptiveFreeList<FreeChunk> >::as_TreeChunk(chunk); |
1708 TreeList<FreeChunk, AdaptiveFreeList>* tl = tc->list(); | 1734 TreeList<FreeChunk, AdaptiveFreeList<FreeChunk> >* tl = tc->list(); |
1709 tl->verify_stats(); | 1735 tl->verify_stats(); |
1710 } | 1736 } |
1711 #endif // PRODUCT | 1737 #endif // PRODUCT |
1712 } | 1738 } |
1713 | 1739 |
1983 MemRegion ur = used_region(); | 2009 MemRegion ur = used_region(); |
1984 MemRegion urasm = used_region_at_save_marks(); | 2010 MemRegion urasm = used_region_at_save_marks(); |
1985 assert(ur.contains(urasm), | 2011 assert(ur.contains(urasm), |
1986 err_msg(" Error at save_marks(): [" PTR_FORMAT "," PTR_FORMAT ")" | 2012 err_msg(" Error at save_marks(): [" PTR_FORMAT "," PTR_FORMAT ")" |
1987 " should contain [" PTR_FORMAT "," PTR_FORMAT ")", | 2013 " should contain [" PTR_FORMAT "," PTR_FORMAT ")", |
1988 ur.start(), ur.end(), urasm.start(), urasm.end())); | 2014 p2i(ur.start()), p2i(ur.end()), p2i(urasm.start()), p2i(urasm.end()))); |
1989 #endif | 2015 #endif |
1990 // inform allocator that promotions should be tracked. | 2016 // inform allocator that promotions should be tracked. |
1991 assert(_promoInfo.noPromotions(), "_promoInfo inconsistency"); | 2017 assert(_promoInfo.noPromotions(), "_promoInfo inconsistency"); |
1992 _promoInfo.startTrackingPromotions(); | 2018 _promoInfo.startTrackingPromotions(); |
1993 } | 2019 } |
2153 assert_locked(); | 2179 assert_locked(); |
2154 size_t i; | 2180 size_t i; |
2155 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { | 2181 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { |
2156 AdaptiveFreeList<FreeChunk>* fl = &_indexedFreeList[i]; | 2182 AdaptiveFreeList<FreeChunk>* fl = &_indexedFreeList[i]; |
2157 if (PrintFLSStatistics > 1) { | 2183 if (PrintFLSStatistics > 1) { |
2158 gclog_or_tty->print("size[%d] : ", i); | 2184 gclog_or_tty->print("size[" SIZE_FORMAT "] : ", i); |
2159 } | 2185 } |
2160 fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate); | 2186 fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate); |
2161 fl->set_coal_desired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent)); | 2187 fl->set_coal_desired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent)); |
2162 fl->set_before_sweep(fl->count()); | 2188 fl->set_before_sweep(fl->count()); |
2163 fl->set_bfr_surp(fl->surplus()); | 2189 fl->set_bfr_surp(fl->surplus()); |
2206 | 2232 |
2207 void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) { | 2233 void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) { |
2208 if (PrintFLSStatistics > 0) { | 2234 if (PrintFLSStatistics > 0) { |
2209 HeapWord* largestAddr = (HeapWord*) dictionary()->find_largest_dict(); | 2235 HeapWord* largestAddr = (HeapWord*) dictionary()->find_largest_dict(); |
2210 gclog_or_tty->print_cr("CMS: Large block " PTR_FORMAT, | 2236 gclog_or_tty->print_cr("CMS: Large block " PTR_FORMAT, |
2211 largestAddr); | 2237 p2i(largestAddr)); |
2212 } | 2238 } |
2213 setFLSurplus(); | 2239 setFLSurplus(); |
2214 setFLHints(); | 2240 setFLHints(); |
2215 if (PrintGC && PrintFLSCensus > 0) { | 2241 if (PrintGC && PrintFLSCensus > 0) { |
2216 printFLCensus(sweep_count); | 2242 printFLCensus(sweep_count); |
2355 if (res == 0) { | 2381 if (res == 0) { |
2356 gclog_or_tty->print_cr("Livelock: no rank reduction!"); | 2382 gclog_or_tty->print_cr("Livelock: no rank reduction!"); |
2357 gclog_or_tty->print_cr( | 2383 gclog_or_tty->print_cr( |
2358 " Current: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n" | 2384 " Current: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n" |
2359 " Previous: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n", | 2385 " Previous: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n", |
2360 addr, res, was_obj ?"true":"false", was_live ?"true":"false", | 2386 p2i(addr), res, was_obj ?"true":"false", was_live ?"true":"false", |
2361 _last_addr, _last_size, _last_was_obj?"true":"false", _last_was_live?"true":"false"); | 2387 p2i(_last_addr), _last_size, _last_was_obj?"true":"false", _last_was_live?"true":"false"); |
2362 _sp->print_on(gclog_or_tty); | 2388 _sp->print_on(gclog_or_tty); |
2363 guarantee(false, "Seppuku!"); | 2389 guarantee(false, "Seppuku!"); |
2364 } | 2390 } |
2365 _last_addr = addr; | 2391 _last_addr = addr; |
2366 _last_size = res; | 2392 _last_size = res; |
2513 guarantee(n == num, "Incorrect count"); | 2539 guarantee(n == num, "Incorrect count"); |
2514 } | 2540 } |
2515 | 2541 |
2516 #ifndef PRODUCT | 2542 #ifndef PRODUCT |
2517 void CompactibleFreeListSpace::check_free_list_consistency() const { | 2543 void CompactibleFreeListSpace::check_free_list_consistency() const { |
2518 assert((TreeChunk<FreeChunk, AdaptiveFreeList>::min_size() <= IndexSetSize), | 2544 assert((TreeChunk<FreeChunk, AdaptiveFreeList<FreeChunk> >::min_size() <= IndexSetSize), |
2519 "Some sizes can't be allocated without recourse to" | 2545 "Some sizes can't be allocated without recourse to" |
2520 " linear allocation buffers"); | 2546 " linear allocation buffers"); |
2521 assert((TreeChunk<FreeChunk, AdaptiveFreeList>::min_size()*HeapWordSize == sizeof(TreeChunk<FreeChunk, AdaptiveFreeList>)), | 2547 assert((TreeChunk<FreeChunk, AdaptiveFreeList<FreeChunk> >::min_size()*HeapWordSize == sizeof(TreeChunk<FreeChunk, AdaptiveFreeList<FreeChunk> >)), |
2522 "else MIN_TREE_CHUNK_SIZE is wrong"); | 2548 "else MIN_TREE_CHUNK_SIZE is wrong"); |
2523 assert(IndexSetStart != 0, "IndexSetStart not initialized"); | 2549 assert(IndexSetStart != 0, "IndexSetStart not initialized"); |
2524 assert(IndexSetStride != 0, "IndexSetStride not initialized"); | 2550 assert(IndexSetStride != 0, "IndexSetStride not initialized"); |
2525 } | 2551 } |
2526 #endif | 2552 #endif |
2684 } | 2710 } |
2685 // Reset counters for next round | 2711 // Reset counters for next round |
2686 _global_num_workers[i] = 0; | 2712 _global_num_workers[i] = 0; |
2687 _global_num_blocks[i] = 0; | 2713 _global_num_blocks[i] = 0; |
2688 if (PrintOldPLAB) { | 2714 if (PrintOldPLAB) { |
2689 gclog_or_tty->print_cr("[%d]: %d", i, (size_t)_blocks_to_claim[i].average()); | 2715 gclog_or_tty->print_cr("[" SIZE_FORMAT "]: " SIZE_FORMAT, i, (size_t)_blocks_to_claim[i].average()); |
2690 } | 2716 } |
2691 } | 2717 } |
2692 } | 2718 } |
2693 } | 2719 } |
2694 | 2720 |
2723 _indexedFreeList[i] = AdaptiveFreeList<FreeChunk>(); | 2749 _indexedFreeList[i] = AdaptiveFreeList<FreeChunk>(); |
2724 _indexedFreeList[i].set_size(i); | 2750 _indexedFreeList[i].set_size(i); |
2725 } | 2751 } |
2726 } | 2752 } |
2727 if (PrintOldPLAB) { | 2753 if (PrintOldPLAB) { |
2728 gclog_or_tty->print_cr("%d[%d]: %d/%d/%d", | 2754 gclog_or_tty->print_cr("%d[" SIZE_FORMAT "]: " SIZE_FORMAT "/" SIZE_FORMAT "/" SIZE_FORMAT, |
2729 tid, i, num_retire, _num_blocks[i], (size_t)_blocks_to_claim[i].average()); | 2755 tid, i, num_retire, _num_blocks[i], (size_t)_blocks_to_claim[i].average()); |
2730 } | 2756 } |
2731 // Reset stats for next round | 2757 // Reset stats for next round |
2732 _num_blocks[i] = 0; | 2758 _num_blocks[i] = 0; |
2733 } | 2759 } |