comparison src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp @ 144:e3729351c946

6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator. Summary: Don't move tops of the chunks in ensure_parsibility(). Handle the situation with Solaris when a machine has a locality group with no memory. Reviewed-by: apetrusenko, jcoomes, ysr
author iveresov
date Fri, 09 May 2008 16:34:08 +0400
parents fcbfc50865ab
children d1635bf93939
comparison
equal deleted inserted replaced
143:b5489bb705c9 144:e3729351c946
60 // that should be filled with dead objects to ensure parseability. 60 // that should be filled with dead objects to ensure parseability.
61 void MutableNUMASpace::ensure_parsability() { 61 void MutableNUMASpace::ensure_parsability() {
62 for (int i = 0; i < lgrp_spaces()->length(); i++) { 62 for (int i = 0; i < lgrp_spaces()->length(); i++) {
63 LGRPSpace *ls = lgrp_spaces()->at(i); 63 LGRPSpace *ls = lgrp_spaces()->at(i);
64 MutableSpace *s = ls->space(); 64 MutableSpace *s = ls->space();
65 if (!s->contains(top())) { 65 if (s->top() < top()) { // For all spaces preceeding the one containing top()
66 if (s->free_in_words() > 0) { 66 if (s->free_in_words() > 0) {
67 SharedHeap::fill_region_with_object(MemRegion(s->top(), s->end())); 67 SharedHeap::fill_region_with_object(MemRegion(s->top(), s->end()));
68 size_t area_touched_words = pointer_delta(s->end(), s->top(), sizeof(HeapWordSize)); 68 size_t area_touched_words = pointer_delta(s->end(), s->top());
69 #ifndef ASSERT 69 #ifndef ASSERT
70 if (!ZapUnusedHeapArea) { 70 if (!ZapUnusedHeapArea) {
71 area_touched_words = MIN2((size_t)align_object_size(typeArrayOopDesc::header_size(T_INT)), 71 area_touched_words = MIN2((size_t)align_object_size(typeArrayOopDesc::header_size(T_INT)),
72 area_touched_words); 72 area_touched_words);
73 } 73 }
86 invalid = MemRegion(start, end); 86 invalid = MemRegion(start, end);
87 } 87 }
88 88
89 ls->add_invalid_region(invalid); 89 ls->add_invalid_region(invalid);
90 } 90 }
91 s->set_top(s->end());
92 } 91 }
93 } else { 92 } else {
94 if (!os::numa_has_static_binding()) { 93 if (!os::numa_has_static_binding()) {
95 #ifdef ASSERT 94 #ifdef ASSERT
96 MemRegion invalid(s->top(), s->end()); 95 MemRegion invalid(s->top(), s->end());
97 ls->add_invalid_region(invalid); 96 ls->add_invalid_region(invalid);
98 #else 97 #else
99 if (ZapUnusedHeapArea) { 98 if (ZapUnusedHeapArea) {
100 MemRegion invalid(s->top(), s->end()); 99 MemRegion invalid(s->top(), s->end());
101 ls->add_invalid_region(invalid); 100 ls->add_invalid_region(invalid);
102 } else break; 101 } else {
102 return;
103 }
103 #endif 104 #endif
105 } else {
106 return;
104 } 107 }
105 } 108 }
106 } 109 }
107 } 110 }
108 111
656 } 659 }
657 660
658 MutableSpace *s = lgrp_spaces()->at(i)->space(); 661 MutableSpace *s = lgrp_spaces()->at(i)->space();
659 HeapWord *p = s->allocate(size); 662 HeapWord *p = s->allocate(size);
660 663
661 if (p != NULL && s->free_in_words() < (size_t)oopDesc::header_size()) { 664 if (p != NULL) {
662 s->set_top(s->top() - size); 665 size_t remainder = s->free_in_words();
663 p = NULL; 666 if (remainder < (size_t)oopDesc::header_size() && remainder > 0) {
667 s->set_top(s->top() - size);
668 p = NULL;
669 }
664 } 670 }
665 if (p != NULL) { 671 if (p != NULL) {
666 if (top() < s->top()) { // Keep _top updated. 672 if (top() < s->top()) { // Keep _top updated.
667 MutableSpace::set_top(s->top()); 673 MutableSpace::set_top(s->top());
668 } 674 }
691 if (i == -1) { 697 if (i == -1) {
692 i = os::random() % lgrp_spaces()->length(); 698 i = os::random() % lgrp_spaces()->length();
693 } 699 }
694 MutableSpace *s = lgrp_spaces()->at(i)->space(); 700 MutableSpace *s = lgrp_spaces()->at(i)->space();
695 HeapWord *p = s->cas_allocate(size); 701 HeapWord *p = s->cas_allocate(size);
696 if (p != NULL && s->free_in_words() < (size_t)oopDesc::header_size()) { 702 if (p != NULL) {
697 if (s->cas_deallocate(p, size)) { 703 size_t remainder = pointer_delta(s->end(), p);
698 // We were the last to allocate and created a fragment less than 704 if (remainder < (size_t)oopDesc::header_size() && remainder > 0) {
699 // a minimal object. 705 if (s->cas_deallocate(p, size)) {
700 p = NULL; 706 // We were the last to allocate and created a fragment less than
707 // a minimal object.
708 p = NULL;
709 }
701 } 710 }
702 } 711 }
703 if (p != NULL) { 712 if (p != NULL) {
704 HeapWord* cur_top, *cur_chunk_top = p + size; 713 HeapWord* cur_top, *cur_chunk_top = p + size;
705 while ((cur_top = top()) < cur_chunk_top) { // Keep _top updated. 714 while ((cur_top = top()) < cur_chunk_top) { // Keep _top updated.
736 for (int i = 0; i < lgrp_spaces()->length(); i++) { 745 for (int i = 0; i < lgrp_spaces()->length(); i++) {
737 LGRPSpace *ls = lgrp_spaces()->at(i); 746 LGRPSpace *ls = lgrp_spaces()->at(i);
738 st->print(" lgrp %d", ls->lgrp_id()); 747 st->print(" lgrp %d", ls->lgrp_id());
739 ls->space()->print_on(st); 748 ls->space()->print_on(st);
740 if (NUMAStats) { 749 if (NUMAStats) {
750 for (int i = 0; i < lgrp_spaces()->length(); i++) {
751 lgrp_spaces()->at(i)->accumulate_statistics(page_size());
752 }
741 st->print(" local/remote/unbiased/uncommitted: %dK/%dK/%dK/%dK, large/small pages: %d/%d\n", 753 st->print(" local/remote/unbiased/uncommitted: %dK/%dK/%dK/%dK, large/small pages: %d/%d\n",
742 ls->space_stats()->_local_space / K, 754 ls->space_stats()->_local_space / K,
743 ls->space_stats()->_remote_space / K, 755 ls->space_stats()->_remote_space / K,
744 ls->space_stats()->_unbiased_space / K, 756 ls->space_stats()->_unbiased_space / K,
745 ls->space_stats()->_uncommited_space / K, 757 ls->space_stats()->_uncommited_space / K,