Mercurial > hg > graal-compiler
annotate src/share/vm/memory/compactingPermGenGen.hpp @ 1716:be3f9c242c9d
6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode.
Reviewed-by: chrisphi, johnc, poonam
author | ysr |
---|---|
date | Mon, 16 Aug 2010 15:58:42 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1051
diff
changeset
|
2 * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. |
0 | 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:
1051
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1051
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:
1051
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 // All heaps contains a "permanent generation," containing permanent | |
26 // (reflective) objects. This is like a regular generation in some ways, | |
27 // but unlike one in others, and so is split apart. | |
28 | |
29 class PermanentGenerationSpec; | |
30 | |
31 // This is the "generation" view of a CompactingPermGen. | |
1051
26f1542097f1
6801625: CDS: HeapDump tests crash with internal error in compactingPermGenGen.cpp
ysr
parents:
409
diff
changeset
|
32 // NOTE: the shared spaces used for CDS are here handled in |
26f1542097f1
6801625: CDS: HeapDump tests crash with internal error in compactingPermGenGen.cpp
ysr
parents:
409
diff
changeset
|
33 // a somewhat awkward and potentially buggy fashion, see CR 6801625. |
26f1542097f1
6801625: CDS: HeapDump tests crash with internal error in compactingPermGenGen.cpp
ysr
parents:
409
diff
changeset
|
34 // This infelicity should be fixed, see CR 6897789. |
0 | 35 class CompactingPermGenGen: public OneContigSpaceCardGeneration { |
36 friend class VMStructs; | |
37 // Abstractly, this is a subtype that gets access to protected fields. | |
38 friend class CompactingPermGen; | |
39 | |
40 private: | |
41 // Shared spaces | |
42 PermanentGenerationSpec* _spec; | |
43 size_t _shared_space_size; | |
44 VirtualSpace _ro_vs; | |
45 VirtualSpace _rw_vs; | |
46 VirtualSpace _md_vs; | |
47 VirtualSpace _mc_vs; | |
48 BlockOffsetSharedArray* _ro_bts; | |
49 BlockOffsetSharedArray* _rw_bts; | |
50 OffsetTableContigSpace* _ro_space; | |
51 OffsetTableContigSpace* _rw_space; | |
52 | |
1051
26f1542097f1
6801625: CDS: HeapDump tests crash with internal error in compactingPermGenGen.cpp
ysr
parents:
409
diff
changeset
|
53 // With shared spaces there is a dichotomy in the use of the |
0 | 54 // _virtual_space of the generation. There is a portion of the |
55 // _virtual_space that is used for the unshared part of the | |
56 // permanent generation and a portion that is reserved for the shared part. | |
57 // The _reserved field in the generation represents both the | |
58 // unshared and shared parts of the generation. The _reserved | |
59 // variable is initialized for only the unshared part but is | |
60 // later extended to include the shared part during initialization | |
61 // if shared spaces are being used. | |
62 // The reserved size for the _virtual_space for CompactingPermGenGen | |
63 // is the size of the space for the permanent generation including the | |
64 // the shared spaces. This can be seen by the use of MaxPermSize | |
65 // in the allocation of PermanentGenerationSpec. The space for the | |
66 // shared spaces is committed separately (???). | |
67 // In general at initialization only a part of the | |
68 // space for the unshared part of the permanent generation is | |
69 // committed and more is committed as the permanent generation is | |
70 // grown. In growing the permanent generation the capacity() and | |
71 // max_capacity() of the generation are used. For the permanent | |
72 // generation (implemented with a CompactingPermGenGen) the capacity() | |
73 // is taken from the capacity of the space (_the_space variable used for the | |
74 // unshared part of the generation) and the max_capacity() is based | |
75 // on the size of the _reserved variable (which includes the size of the | |
76 // shared spaces) minus the size of the shared spaces. | |
77 | |
78 // These values are redundant, but are called out separately to avoid | |
79 // going through heap/space/gen pointers for performance. | |
80 static HeapWord* unshared_bottom; | |
81 static HeapWord* unshared_end; | |
82 static HeapWord* shared_bottom; | |
83 static HeapWord* readonly_bottom; | |
84 static HeapWord* readonly_end; | |
85 static HeapWord* readwrite_bottom; | |
86 static HeapWord* readwrite_end; | |
87 static HeapWord* miscdata_bottom; | |
88 static HeapWord* miscdata_end; | |
89 static HeapWord* misccode_bottom; | |
90 static HeapWord* misccode_end; | |
91 static HeapWord* shared_end; | |
92 | |
93 // List of klassOops whose vtbl entries are used to patch others. | |
94 static void** _vtbl_list; | |
95 | |
96 // Performance Counters | |
97 GenerationCounters* _gen_counters; | |
98 CSpaceCounters* _space_counters; | |
99 | |
100 void initialize_performance_counters(); | |
101 | |
102 public: | |
103 | |
104 enum { | |
105 vtbl_list_size = 16, // number of entries in the shared space vtable list. | |
408 | 106 num_virtuals = 200 // number of virtual methods in Klass (or |
0 | 107 // subclass) objects, or greater. |
108 }; | |
109 | |
110 enum { | |
111 ro = 0, // read-only shared space in the heap | |
112 rw = 1, // read-write shared space in the heap | |
113 md = 2, // miscellaneous data for initializing tables, etc. | |
114 mc = 3, // miscellaneous code - vtable replacement. | |
115 n_regions = 4 | |
116 }; | |
117 | |
118 CompactingPermGenGen(ReservedSpace rs, ReservedSpace shared_rs, | |
119 size_t initial_byte_size, int level, GenRemSet* remset, | |
120 ContiguousSpace* space, | |
121 PermanentGenerationSpec* perm_spec); | |
122 | |
123 const char* name() const { | |
124 return "compacting perm gen"; | |
125 } | |
126 | |
127 const char* short_name() const { | |
128 return "Perm"; | |
129 } | |
130 | |
131 // Return the maximum capacity for the object space. This | |
132 // explicitly does not include the shared spaces. | |
133 size_t max_capacity() const; | |
134 | |
135 void update_counters(); | |
136 | |
137 void compute_new_size() { | |
138 assert(false, "Should not call this -- handled at PermGen level."); | |
139 } | |
140 | |
141 bool must_be_youngest() const { return false; } | |
142 bool must_be_oldest() const { return false; } | |
143 | |
144 OffsetTableContigSpace* ro_space() const { return _ro_space; } | |
145 OffsetTableContigSpace* rw_space() const { return _rw_space; } | |
146 VirtualSpace* md_space() { return &_md_vs; } | |
147 VirtualSpace* mc_space() { return &_mc_vs; } | |
148 ContiguousSpace* unshared_space() const { return _the_space; } | |
149 | |
150 static bool inline is_shared(const oopDesc* p) { | |
151 return (HeapWord*)p >= shared_bottom && (HeapWord*)p < shared_end; | |
152 } | |
153 // RedefineClasses note: this tester is used to check residence of | |
154 // the specified oop in the shared readonly space and not whether | |
155 // the oop is readonly. | |
156 static bool inline is_shared_readonly(const oopDesc* p) { | |
157 return (HeapWord*)p >= readonly_bottom && (HeapWord*)p < readonly_end; | |
158 } | |
159 // RedefineClasses note: this tester is used to check residence of | |
160 // the specified oop in the shared readwrite space and not whether | |
161 // the oop is readwrite. | |
162 static bool inline is_shared_readwrite(const oopDesc* p) { | |
163 return (HeapWord*)p >= readwrite_bottom && (HeapWord*)p < readwrite_end; | |
164 } | |
165 | |
166 bool is_in_unshared(const void* p) const { | |
167 return OneContigSpaceCardGeneration::is_in(p); | |
168 } | |
169 | |
170 bool is_in_shared(const void* p) const { | |
171 return p >= shared_bottom && p < shared_end; | |
172 } | |
173 | |
174 inline bool is_in(const void* p) const { | |
175 return is_in_unshared(p) || is_in_shared(p); | |
176 } | |
177 | |
178 inline PermanentGenerationSpec* spec() const { return _spec; } | |
179 inline void set_spec(PermanentGenerationSpec* spec) { _spec = spec; } | |
180 | |
181 void pre_adjust_pointers(); | |
182 void adjust_pointers(); | |
183 void space_iterate(SpaceClosure* blk, bool usedOnly = false); | |
184 void print_on(outputStream* st) const; | |
185 void younger_refs_iterate(OopsInGenClosure* blk); | |
186 void compact(); | |
187 void post_compact(); | |
188 size_t contiguous_available() const; | |
189 | |
190 void clear_remembered_set(); | |
191 void invalidate_remembered_set(); | |
192 | |
193 inline bool block_is_obj(const HeapWord* addr) const { | |
194 if (addr < the_space()->top()) return true; | |
195 else if (addr < the_space()->end()) return false; | |
196 else if (addr < ro_space()->top()) return true; | |
197 else if (addr < ro_space()->end()) return false; | |
198 else if (addr < rw_space()->top()) return true; | |
199 else return false; | |
200 } | |
201 | |
202 | |
203 inline size_t block_size(const HeapWord* addr) const { | |
204 if (addr < the_space()->top()) { | |
205 return oop(addr)->size(); | |
206 } | |
207 else if (addr < the_space()->end()) { | |
208 assert(addr == the_space()->top(), "non-block head arg to block_size"); | |
209 return the_space()->end() - the_space()->top(); | |
210 } | |
211 | |
212 else if (addr < ro_space()->top()) { | |
213 return oop(addr)->size(); | |
214 } | |
215 else if (addr < ro_space()->end()) { | |
216 assert(addr == ro_space()->top(), "non-block head arg to block_size"); | |
217 return ro_space()->end() - ro_space()->top(); | |
218 } | |
219 | |
220 else if (addr < rw_space()->top()) { | |
221 return oop(addr)->size(); | |
222 } | |
223 else { | |
224 assert(addr == rw_space()->top(), "non-block head arg to block_size"); | |
225 return rw_space()->end() - rw_space()->top(); | |
226 } | |
227 } | |
228 | |
229 static void generate_vtable_methods(void** vtbl_list, | |
230 void** vtable, | |
231 char** md_top, char* md_end, | |
232 char** mc_top, char* mc_end); | |
233 | |
234 void verify(bool allow_dirty); | |
235 | |
236 // Serialization | |
237 static void initialize_oops() KERNEL_RETURN; | |
238 static void serialize_oops(SerializeOopClosure* soc); | |
239 void serialize_bts(SerializeOopClosure* soc); | |
240 | |
241 // Initiate dumping of shared file. | |
242 static jint dump_shared(GrowableArray<oop>* class_promote_order, TRAPS); | |
243 | |
244 // JVM/TI RedefineClasses() support: | |
245 // Remap the shared readonly space to shared readwrite, private if | |
246 // sharing is enabled. Simply returns true if sharing is not enabled | |
247 // or if the remapping has already been done by a prior call. | |
248 static bool remap_shared_readonly_as_readwrite(); | |
249 }; |