comparison src/share/vm/gc_implementation/shared/mutableSpace.cpp @ 535:4e400c36026f

6783381: NUMA allocator: don't pretouch eden space with UseNUMA Summary: Moved pretouching to MutableSpace. Also MutableSpace now turns on page interleaving for the region it covers. Reviewed-by: jmasa, jcoomes
author iveresov
date Tue, 27 Jan 2009 18:13:59 -0800
parents 850fdf70db2b
children 0fbdb4381b99
comparison
equal deleted inserted replaced
534:5cfd8d19e546 535:4e400c36026f
23 */ 23 */
24 24
25 # include "incls/_precompiled.incl" 25 # include "incls/_precompiled.incl"
26 # include "incls/_mutableSpace.cpp.incl" 26 # include "incls/_mutableSpace.cpp.incl"
27 27
28 MutableSpace::MutableSpace(): ImmutableSpace(), _top(NULL) { 28 MutableSpace::MutableSpace(size_t alignment): ImmutableSpace(), _top(NULL), _alignment(alignment) {
29 assert(MutableSpace::alignment() >= 0 &&
30 MutableSpace::alignment() % os::vm_page_size() == 0,
31 "Space should be aligned");
29 _mangler = new MutableSpaceMangler(this); 32 _mangler = new MutableSpaceMangler(this);
30 } 33 }
31 34
32 MutableSpace::~MutableSpace() { 35 MutableSpace::~MutableSpace() {
33 delete _mangler; 36 delete _mangler;
34 } 37 }
35 38
39 void MutableSpace::numa_setup_pages(MemRegion mr, bool clear_space) {
40 if (!mr.is_empty()) {
41 size_t page_size = UseLargePages ? alignment() : os::vm_page_size();
42 HeapWord *start = (HeapWord*)round_to((intptr_t) mr.start(), page_size);
43 HeapWord *end = (HeapWord*)round_down((intptr_t) mr.end(), page_size);
44 if (end > start) {
45 size_t size = pointer_delta(end, start, sizeof(char));
46 if (clear_space) {
47 // Prefer page reallocation to migration.
48 os::free_memory((char*)start, size);
49 }
50 os::numa_make_global((char*)start, size);
51 }
52 }
53 }
54
55 void MutableSpace::pretouch_pages(MemRegion mr) {
56 for (volatile char *p = (char*)mr.start(); p < (char*)mr.end(); p += os::vm_page_size()) {
57 char t = *p; *p = t;
58 }
59 }
60
36 void MutableSpace::initialize(MemRegion mr, 61 void MutableSpace::initialize(MemRegion mr,
37 bool clear_space, 62 bool clear_space,
38 bool mangle_space) { 63 bool mangle_space,
39 HeapWord* bottom = mr.start(); 64 bool setup_pages) {
40 HeapWord* end = mr.end(); 65
41 66 assert(Universe::on_page_boundary(mr.start()) && Universe::on_page_boundary(mr.end()),
42 assert(Universe::on_page_boundary(bottom) && Universe::on_page_boundary(end),
43 "invalid space boundaries"); 67 "invalid space boundaries");
44 set_bottom(bottom); 68
45 set_end(end); 69 if (setup_pages && (UseNUMA || AlwaysPreTouch)) {
70 // The space may move left and right or expand/shrink.
71 // We'd like to enforce the desired page placement.
72 MemRegion head, tail;
73 if (last_setup_region().is_empty()) {
74 // If it's the first initialization don't limit the amount of work.
75 head = mr;
76 tail = MemRegion(mr.end(), mr.end());
77 } else {
78 // Is there an intersection with the address space?
79 MemRegion intersection = last_setup_region().intersection(mr);
80 if (intersection.is_empty()) {
81 intersection = MemRegion(mr.end(), mr.end());
82 }
83 // All the sizes below are in words.
84 size_t head_size = 0, tail_size = 0;
85 if (mr.start() <= intersection.start()) {
86 head_size = pointer_delta(intersection.start(), mr.start());
87 }
88 if(intersection.end() <= mr.end()) {
89 tail_size = pointer_delta(mr.end(), intersection.end());
90 }
91 // Limit the amount of page manipulation if necessary.
92 if (NUMASpaceResizeRate > 0 && !AlwaysPreTouch) {
93 const size_t change_size = head_size + tail_size;
94 const float setup_rate_words = NUMASpaceResizeRate >> LogBytesPerWord;
95 head_size = MIN2((size_t)(setup_rate_words * head_size / change_size),
96 head_size);
97 tail_size = MIN2((size_t)(setup_rate_words * tail_size / change_size),
98 tail_size);
99 }
100 head = MemRegion(intersection.start() - head_size, intersection.start());
101 tail = MemRegion(intersection.end(), intersection.end() + tail_size);
102 }
103 assert(mr.contains(head) && mr.contains(tail), "Sanity");
104
105 if (UseNUMA) {
106 numa_setup_pages(head, clear_space);
107 numa_setup_pages(tail, clear_space);
108 }
109
110 if (AlwaysPreTouch) {
111 pretouch_pages(head);
112 pretouch_pages(tail);
113 }
114
115 // Remember where we stopped so that we can continue later.
116 set_last_setup_region(MemRegion(head.start(), tail.end()));
117 }
118
119 set_bottom(mr.start());
120 set_end(mr.end());
46 121
47 if (clear_space) { 122 if (clear_space) {
48 clear(mangle_space); 123 clear(mangle_space);
49 } 124 }
50 } 125 }