Mercurial > hg > graal-jvmci-8
annotate src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | 7b2fc3129653 |
children | ae52ee069062 |
rev | line source |
---|---|
20337 | 1 /* |
2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
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 | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
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_implementation/g1/g1BiasedArray.hpp" | |
27 #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp" | |
20339
7b2fc3129653
8055635: Missing include in g1RegionToSpaceMapper.hpp results in unresolved symbol of fastdebug build without precompiled headers
tschatzl
parents:
20337
diff
changeset
|
28 #include "memory/allocation.inline.hpp" |
20337 | 29 #include "runtime/virtualspace.hpp" |
30 #include "services/memTracker.hpp" | |
31 #include "utilities/bitMap.inline.hpp" | |
32 | |
33 G1RegionToSpaceMapper::G1RegionToSpaceMapper(ReservedSpace rs, | |
34 size_t commit_granularity, | |
35 size_t region_granularity, | |
36 MemoryType type) : | |
37 _storage(), | |
38 _commit_granularity(commit_granularity), | |
39 _region_granularity(region_granularity), | |
40 _listener(NULL), | |
41 _commit_map() { | |
42 guarantee(is_power_of_2(commit_granularity), "must be"); | |
43 guarantee(is_power_of_2(region_granularity), "must be"); | |
44 _storage.initialize_with_granularity(rs, commit_granularity); | |
45 | |
46 MemTracker::record_virtual_memory_type((address)rs.base(), type); | |
47 } | |
48 | |
49 // G1RegionToSpaceMapper implementation where the region granularity is larger than | |
50 // or the same as the commit granularity. | |
51 // Basically, the space corresponding to one region region spans several OS pages. | |
52 class G1RegionsLargerThanCommitSizeMapper : public G1RegionToSpaceMapper { | |
53 private: | |
54 size_t _pages_per_region; | |
55 | |
56 public: | |
57 G1RegionsLargerThanCommitSizeMapper(ReservedSpace rs, | |
58 size_t os_commit_granularity, | |
59 size_t alloc_granularity, | |
60 size_t commit_factor, | |
61 MemoryType type) : | |
62 G1RegionToSpaceMapper(rs, os_commit_granularity, alloc_granularity, type), | |
63 _pages_per_region(alloc_granularity / (os_commit_granularity * commit_factor)) { | |
64 | |
65 guarantee(alloc_granularity >= os_commit_granularity, "allocation granularity smaller than commit granularity"); | |
66 _commit_map.resize(rs.size() * commit_factor / alloc_granularity, /* in_resource_area */ false); | |
67 } | |
68 | |
69 virtual void commit_regions(uintptr_t start_idx, size_t num_regions) { | |
70 _storage.commit(start_idx * _pages_per_region, num_regions * _pages_per_region); | |
71 _commit_map.set_range(start_idx, start_idx + num_regions); | |
20543 | 72 fire_on_commit(start_idx, num_regions, true); |
20337 | 73 } |
74 | |
75 virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) { | |
76 _storage.uncommit(start_idx * _pages_per_region, num_regions * _pages_per_region); | |
77 _commit_map.clear_range(start_idx, start_idx + num_regions); | |
78 } | |
79 }; | |
80 | |
81 // G1RegionToSpaceMapper implementation where the region granularity is smaller | |
82 // than the commit granularity. | |
83 // Basically, the contents of one OS page span several regions. | |
84 class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper { | |
85 private: | |
86 class CommitRefcountArray : public G1BiasedMappedArray<uint> { | |
87 protected: | |
88 virtual uint default_value() const { return 0; } | |
89 }; | |
90 | |
91 size_t _regions_per_page; | |
92 | |
93 CommitRefcountArray _refcounts; | |
94 | |
95 uintptr_t region_idx_to_page_idx(uint region) const { | |
96 return region / _regions_per_page; | |
97 } | |
98 | |
99 public: | |
100 G1RegionsSmallerThanCommitSizeMapper(ReservedSpace rs, | |
101 size_t os_commit_granularity, | |
102 size_t alloc_granularity, | |
103 size_t commit_factor, | |
104 MemoryType type) : | |
105 G1RegionToSpaceMapper(rs, os_commit_granularity, alloc_granularity, type), | |
106 _regions_per_page((os_commit_granularity * commit_factor) / alloc_granularity), _refcounts() { | |
107 | |
108 guarantee((os_commit_granularity * commit_factor) >= alloc_granularity, "allocation granularity smaller than commit granularity"); | |
109 _refcounts.initialize((HeapWord*)rs.base(), (HeapWord*)(rs.base() + rs.size()), os_commit_granularity); | |
110 _commit_map.resize(rs.size() * commit_factor / alloc_granularity, /* in_resource_area */ false); | |
111 } | |
112 | |
113 virtual void commit_regions(uintptr_t start_idx, size_t num_regions) { | |
114 for (uintptr_t i = start_idx; i < start_idx + num_regions; i++) { | |
115 assert(!_commit_map.at(i), err_msg("Trying to commit storage at region "INTPTR_FORMAT" that is already committed", i)); | |
116 uintptr_t idx = region_idx_to_page_idx(i); | |
117 uint old_refcount = _refcounts.get_by_index(idx); | |
20543 | 118 bool zero_filled = false; |
20337 | 119 if (old_refcount == 0) { |
120 _storage.commit(idx, 1); | |
20543 | 121 zero_filled = true; |
20337 | 122 } |
123 _refcounts.set_by_index(idx, old_refcount + 1); | |
124 _commit_map.set_bit(i); | |
20543 | 125 fire_on_commit(i, 1, zero_filled); |
20337 | 126 } |
127 } | |
128 | |
129 virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) { | |
130 for (uintptr_t i = start_idx; i < start_idx + num_regions; i++) { | |
131 assert(_commit_map.at(i), err_msg("Trying to uncommit storage at region "INTPTR_FORMAT" that is not committed", i)); | |
132 uintptr_t idx = region_idx_to_page_idx(i); | |
133 uint old_refcount = _refcounts.get_by_index(idx); | |
134 assert(old_refcount > 0, "must be"); | |
135 if (old_refcount == 1) { | |
136 _storage.uncommit(idx, 1); | |
137 } | |
138 _refcounts.set_by_index(idx, old_refcount - 1); | |
139 _commit_map.clear_bit(i); | |
140 } | |
141 } | |
142 }; | |
143 | |
20543 | 144 void G1RegionToSpaceMapper::fire_on_commit(uint start_idx, size_t num_regions, bool zero_filled) { |
20337 | 145 if (_listener != NULL) { |
20543 | 146 _listener->on_commit(start_idx, num_regions, zero_filled); |
20337 | 147 } |
148 } | |
149 | |
150 G1RegionToSpaceMapper* G1RegionToSpaceMapper::create_mapper(ReservedSpace rs, | |
151 size_t os_commit_granularity, | |
152 size_t region_granularity, | |
153 size_t commit_factor, | |
154 MemoryType type) { | |
155 | |
156 if (region_granularity >= (os_commit_granularity * commit_factor)) { | |
157 return new G1RegionsLargerThanCommitSizeMapper(rs, os_commit_granularity, region_granularity, commit_factor, type); | |
158 } else { | |
159 return new G1RegionsSmallerThanCommitSizeMapper(rs, os_commit_granularity, region_granularity, commit_factor, type); | |
160 } | |
161 } |