Mercurial > hg > truffle
annotate src/share/vm/services/g1MemoryPool.hpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | c18cbe5936b8 |
children | e967bad2a9ab |
rev | line source |
---|---|
1089 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1093
diff
changeset
|
2 * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. |
1089 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1093
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1093
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1093
diff
changeset
|
21 * questions. |
1089 | 22 * |
23 */ | |
24 | |
25 class G1CollectedHeap; | |
26 | |
27 // This file contains the three classes that represent the memory | |
28 // pools of the G1 spaces: G1EdenPool, G1SurvivorPool, and | |
29 // G1OldGenPool. In G1, unlike our other GCs, we do not have a | |
30 // physical space for each of those spaces. Instead, we allocate | |
31 // regions for all three spaces out of a single pool of regions (that | |
32 // pool basically covers the entire heap). As a result, the eden, | |
33 // survivor, and old gen are considered logical spaces in G1, as each | |
34 // is a set of non-contiguous regions. This is also reflected in the | |
35 // way we map them to memory pools here. The easiest way to have done | |
36 // this would have been to map the entire G1 heap to a single memory | |
37 // pool. However, it's helpful to show how large the eden and survivor | |
38 // get, as this does affect the performance and behavior of G1. Which | |
39 // is why we introduce the three memory pools implemented here. | |
40 // | |
41 // The above approach inroduces a couple of challenging issues in the | |
42 // implementation of the three memory pools: | |
43 // | |
44 // 1) The used space calculation for a pool is not necessarily | |
45 // independent of the others. We can easily get from G1 the overall | |
46 // used space in the entire heap, the number of regions in the young | |
47 // generation (includes both eden and survivors), and the number of | |
48 // survivor regions. So, from that we calculate: | |
49 // | |
50 // survivor_used = survivor_num * region_size | |
51 // eden_used = young_region_num * region_size - survivor_used | |
52 // old_gen_used = overall_used - eden_used - survivor_used | |
53 // | |
54 // Note that survivor_used and eden_used are upper bounds. To get the | |
55 // actual value we would have to iterate over the regions and add up | |
56 // ->used(). But that'd be expensive. So, we'll accept some lack of | |
57 // accuracy for those two. But, we have to be careful when calculating | |
58 // old_gen_used, in case we subtract from overall_used more then the | |
59 // actual number and our result goes negative. | |
60 // | |
61 // 2) Calculating the used space is straightforward, as described | |
62 // above. However, how do we calculate the committed space, given that | |
63 // we allocate space for the eden, survivor, and old gen out of the | |
64 // same pool of regions? One way to do this is to use the used value | |
65 // as also the committed value for the eden and survivor spaces and | |
66 // then calculate the old gen committed space as follows: | |
67 // | |
68 // old_gen_committed = overall_committed - eden_committed - survivor_committed | |
69 // | |
70 // Maybe a better way to do that would be to calculate used for eden | |
71 // and survivor as a sum of ->used() over their regions and then | |
72 // calculate committed as region_num * region_size (i.e., what we use | |
73 // to calculate the used space now). This is something to consider | |
74 // in the future. | |
75 // | |
76 // 3) Another decision that is again not straightforward is what is | |
77 // the max size that each memory pool can grow to. Right now, we set | |
78 // that the committed size for the eden and the survivors and | |
79 // calculate the old gen max as follows (basically, it's a similar | |
80 // pattern to what we use for the committed space, as described | |
81 // above): | |
82 // | |
83 // old_gen_max = overall_max - eden_max - survivor_max | |
84 // | |
85 // 4) Now, there is a very subtle issue with all the above. The | |
86 // framework will call get_memory_usage() on the three pools | |
87 // asynchronously. As a result, each call might get a different value | |
88 // for, say, survivor_num which will yield inconsistent values for | |
89 // eden_used, survivor_used, and old_gen_used (as survivor_num is used | |
90 // in the calculation of all three). This would normally be | |
91 // ok. However, it's possible that this might cause the sum of | |
92 // eden_used, survivor_used, and old_gen_used to go over the max heap | |
93 // size and this seems to sometimes cause JConsole (and maybe other | |
94 // clients) to get confused. There's not a really an easy / clean | |
95 // solution to this problem, due to the asynchrounous nature of the | |
96 // framework. | |
97 | |
98 | |
99 // This class is shared by the three G1 memory pool classes | |
100 // (G1EdenPool, G1SurvivorPool, G1OldGenPool). Given that the way we | |
101 // calculate used / committed bytes for these three pools is related | |
102 // (see comment above), we put the calculations in this class so that | |
103 // we can easily share them among the subclasses. | |
104 class G1MemoryPoolSuper : public CollectedMemoryPool { | |
105 private: | |
106 // It returns x - y if x > y, 0 otherwise. | |
107 // As described in the comment above, some of the inputs to the | |
108 // calculations we have to do are obtained concurrently and hence | |
109 // may be inconsistent with each other. So, this provides a | |
110 // defensive way of performing the subtraction and avoids the value | |
111 // going negative (which would mean a very large result, given that | |
112 // the parameter are size_t). | |
113 static size_t subtract_up_to_zero(size_t x, size_t y) { | |
114 if (x > y) { | |
115 return x - y; | |
116 } else { | |
117 return 0; | |
118 } | |
119 } | |
120 | |
121 protected: | |
1093
afc30fccf324
6906565: G1: deal with compilation warning in g1MemoryPool.hpp
tonyp
parents:
1092
diff
changeset
|
122 G1CollectedHeap* _g1h; |
afc30fccf324
6906565: G1: deal with compilation warning in g1MemoryPool.hpp
tonyp
parents:
1092
diff
changeset
|
123 |
1089 | 124 // Would only be called from subclasses. |
125 G1MemoryPoolSuper(G1CollectedHeap* g1h, | |
126 const char* name, | |
127 size_t init_size, | |
128 size_t max_size, | |
129 bool support_usage_threshold); | |
130 | |
131 // The reason why all the code is in static methods is so that it | |
132 // can be safely called from the constructors of the subclasses. | |
133 | |
134 static size_t overall_committed(G1CollectedHeap* g1h) { | |
135 return g1h->capacity(); | |
136 } | |
137 static size_t overall_used(G1CollectedHeap* g1h) { | |
138 return g1h->used_unlocked(); | |
139 } | |
1092
ed52bcc32739
6880903: G1: G1 reports incorrect Runtime.maxMemory()
tonyp
parents:
1089
diff
changeset
|
140 static size_t overall_max(G1CollectedHeap* g1h) { |
ed52bcc32739
6880903: G1: G1 reports incorrect Runtime.maxMemory()
tonyp
parents:
1089
diff
changeset
|
141 return g1h->g1_reserved_obj_bytes(); |
ed52bcc32739
6880903: G1: G1 reports incorrect Runtime.maxMemory()
tonyp
parents:
1089
diff
changeset
|
142 } |
1089 | 143 |
144 static size_t eden_space_committed(G1CollectedHeap* g1h); | |
145 static size_t eden_space_used(G1CollectedHeap* g1h); | |
146 static size_t eden_space_max(G1CollectedHeap* g1h); | |
147 | |
148 static size_t survivor_space_committed(G1CollectedHeap* g1h); | |
149 static size_t survivor_space_used(G1CollectedHeap* g1h); | |
150 static size_t survivor_space_max(G1CollectedHeap* g1h); | |
151 | |
152 static size_t old_space_committed(G1CollectedHeap* g1h); | |
153 static size_t old_space_used(G1CollectedHeap* g1h); | |
154 static size_t old_space_max(G1CollectedHeap* g1h); | |
155 }; | |
156 | |
157 // Memory pool that represents the G1 eden. | |
158 class G1EdenPool : public G1MemoryPoolSuper { | |
159 public: | |
160 G1EdenPool(G1CollectedHeap* g1h); | |
161 | |
162 size_t used_in_bytes() { | |
1093
afc30fccf324
6906565: G1: deal with compilation warning in g1MemoryPool.hpp
tonyp
parents:
1092
diff
changeset
|
163 return eden_space_used(_g1h); |
1089 | 164 } |
1093
afc30fccf324
6906565: G1: deal with compilation warning in g1MemoryPool.hpp
tonyp
parents:
1092
diff
changeset
|
165 size_t max_size() const { |
afc30fccf324
6906565: G1: deal with compilation warning in g1MemoryPool.hpp
tonyp
parents:
1092
diff
changeset
|
166 return eden_space_max(_g1h); |
1089 | 167 } |
168 MemoryUsage get_memory_usage(); | |
169 }; | |
170 | |
171 // Memory pool that represents the G1 survivor. | |
172 class G1SurvivorPool : public G1MemoryPoolSuper { | |
173 public: | |
174 G1SurvivorPool(G1CollectedHeap* g1h); | |
175 | |
176 size_t used_in_bytes() { | |
1093
afc30fccf324
6906565: G1: deal with compilation warning in g1MemoryPool.hpp
tonyp
parents:
1092
diff
changeset
|
177 return survivor_space_used(_g1h); |
1089 | 178 } |
1093
afc30fccf324
6906565: G1: deal with compilation warning in g1MemoryPool.hpp
tonyp
parents:
1092
diff
changeset
|
179 size_t max_size() const { |
afc30fccf324
6906565: G1: deal with compilation warning in g1MemoryPool.hpp
tonyp
parents:
1092
diff
changeset
|
180 return survivor_space_max(_g1h); |
1089 | 181 } |
182 MemoryUsage get_memory_usage(); | |
183 }; | |
184 | |
185 // Memory pool that represents the G1 old gen. | |
186 class G1OldGenPool : public G1MemoryPoolSuper { | |
187 public: | |
188 G1OldGenPool(G1CollectedHeap* g1h); | |
189 | |
190 size_t used_in_bytes() { | |
1093
afc30fccf324
6906565: G1: deal with compilation warning in g1MemoryPool.hpp
tonyp
parents:
1092
diff
changeset
|
191 return old_space_used(_g1h); |
1089 | 192 } |
1093
afc30fccf324
6906565: G1: deal with compilation warning in g1MemoryPool.hpp
tonyp
parents:
1092
diff
changeset
|
193 size_t max_size() const { |
afc30fccf324
6906565: G1: deal with compilation warning in g1MemoryPool.hpp
tonyp
parents:
1092
diff
changeset
|
194 return old_space_max(_g1h); |
1089 | 195 } |
196 MemoryUsage get_memory_usage(); | |
197 }; |