Mercurial > hg > truffle
comparison src/share/vm/gc_interface/collectedHeap.inline.hpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | 9a9bb0010c91 |
children | 59c790074993 f34d701e952e |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
72 oop obj) { | 72 oop obj) { |
73 // These asserts are kind of complicated because of klassKlass | 73 // These asserts are kind of complicated because of klassKlass |
74 // and the beginning of the world. | 74 // and the beginning of the world. |
75 assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass"); | 75 assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass"); |
76 assert(klass() == NULL || klass()->is_klass(), "not a klass"); | 76 assert(klass() == NULL || klass()->is_klass(), "not a klass"); |
77 assert(klass() == NULL || klass()->klass_part() != NULL, "not a klass"); | |
78 assert(obj != NULL, "NULL object pointer"); | 77 assert(obj != NULL, "NULL object pointer"); |
79 obj->set_klass(klass()); | 78 obj->set_klass(klass()); |
80 assert(!Universe::is_fully_initialized() || obj->blueprint() != NULL, | 79 assert(!Universe::is_fully_initialized() || obj->klass() != NULL, |
81 "missing blueprint"); | 80 "missing klass"); |
82 } | 81 } |
83 | 82 |
84 // Support for jvmti and dtrace | 83 // Support for jvmti and dtrace |
85 inline void post_allocation_notify(KlassHandle klass, oop obj) { | 84 inline void post_allocation_notify(KlassHandle klass, oop obj) { |
86 // support low memory notifications (no-op if not enabled) | 85 // support low memory notifications (no-op if not enabled) |
89 // support for JVMTI VMObjectAlloc event (no-op if not enabled) | 88 // support for JVMTI VMObjectAlloc event (no-op if not enabled) |
90 JvmtiExport::vm_object_alloc_event_collector(obj); | 89 JvmtiExport::vm_object_alloc_event_collector(obj); |
91 | 90 |
92 if (DTraceAllocProbes) { | 91 if (DTraceAllocProbes) { |
93 // support for Dtrace object alloc event (no-op most of the time) | 92 // support for Dtrace object alloc event (no-op most of the time) |
94 if (klass() != NULL && klass()->klass_part()->name() != NULL) { | 93 if (klass() != NULL && klass()->name() != NULL) { |
95 SharedRuntime::dtrace_object_alloc(obj); | 94 SharedRuntime::dtrace_object_alloc(obj); |
96 } | 95 } |
97 } | 96 } |
98 } | 97 } |
99 | 98 |
100 void CollectedHeap::post_allocation_setup_obj(KlassHandle klass, | 99 void CollectedHeap::post_allocation_setup_obj(KlassHandle klass, |
101 HeapWord* obj) { | 100 HeapWord* obj) { |
102 post_allocation_setup_common(klass, obj); | 101 post_allocation_setup_common(klass, obj); |
103 assert(Universe::is_bootstrapping() || | 102 assert(Universe::is_bootstrapping() || |
104 !((oop)obj)->blueprint()->oop_is_array(), "must not be an array"); | 103 !((oop)obj)->is_array(), "must not be an array"); |
105 // notify jvmti and dtrace | 104 // notify jvmti and dtrace |
106 post_allocation_notify(klass, (oop)obj); | 105 post_allocation_notify(klass, (oop)obj); |
107 } | 106 } |
108 | 107 |
109 void CollectedHeap::post_allocation_setup_array(KlassHandle klass, | 108 void CollectedHeap::post_allocation_setup_array(KlassHandle klass, |
113 // in post_allocation_setup_common() because the klass field | 112 // in post_allocation_setup_common() because the klass field |
114 // indicates that the object is parsable by concurrent GC. | 113 // indicates that the object is parsable by concurrent GC. |
115 assert(length >= 0, "length should be non-negative"); | 114 assert(length >= 0, "length should be non-negative"); |
116 ((arrayOop)obj)->set_length(length); | 115 ((arrayOop)obj)->set_length(length); |
117 post_allocation_setup_common(klass, obj); | 116 post_allocation_setup_common(klass, obj); |
118 assert(((oop)obj)->blueprint()->oop_is_array(), "must be an array"); | 117 assert(((oop)obj)->is_array(), "must be an array"); |
119 // notify jvmti and dtrace (must be after length is set for dtrace) | 118 // notify jvmti and dtrace (must be after length is set for dtrace) |
120 post_allocation_notify(klass, (oop)obj); | 119 post_allocation_notify(klass, (oop)obj); |
121 } | 120 } |
122 | 121 |
123 HeapWord* CollectedHeap::common_mem_allocate_noinit(size_t size, TRAPS) { | 122 HeapWord* CollectedHeap::common_mem_allocate_noinit(size_t size, TRAPS) { |
178 } | 177 } |
179 } | 178 } |
180 | 179 |
181 HeapWord* CollectedHeap::common_mem_allocate_init(size_t size, TRAPS) { | 180 HeapWord* CollectedHeap::common_mem_allocate_init(size_t size, TRAPS) { |
182 HeapWord* obj = common_mem_allocate_noinit(size, CHECK_NULL); | 181 HeapWord* obj = common_mem_allocate_noinit(size, CHECK_NULL); |
183 init_obj(obj, size); | |
184 return obj; | |
185 } | |
186 | |
187 // Need to investigate, do we really want to throw OOM exception here? | |
188 HeapWord* CollectedHeap::common_permanent_mem_allocate_noinit(size_t size, TRAPS) { | |
189 if (HAS_PENDING_EXCEPTION) { | |
190 NOT_PRODUCT(guarantee(false, "Should not allocate with exception pending")); | |
191 return NULL; // caller does a CHECK_NULL too | |
192 } | |
193 | |
194 #ifdef ASSERT | |
195 if (CIFireOOMAt > 0 && THREAD->is_Compiler_thread() && | |
196 ++_fire_out_of_memory_count >= CIFireOOMAt) { | |
197 // For testing of OOM handling in the CI throw an OOM and see how | |
198 // it does. Historically improper handling of these has resulted | |
199 // in crashes which we really don't want to have in the CI. | |
200 THROW_OOP_0(Universe::out_of_memory_error_perm_gen()); | |
201 } | |
202 #endif | |
203 | |
204 HeapWord* result = Universe::heap()->permanent_mem_allocate(size); | |
205 if (result != NULL) { | |
206 NOT_PRODUCT(Universe::heap()-> | |
207 check_for_non_bad_heap_word_value(result, size)); | |
208 assert(!HAS_PENDING_EXCEPTION, | |
209 "Unexpected exception, will result in uninitialized storage"); | |
210 return result; | |
211 } | |
212 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support | |
213 report_java_out_of_memory("PermGen space"); | |
214 | |
215 if (JvmtiExport::should_post_resource_exhausted()) { | |
216 JvmtiExport::post_resource_exhausted( | |
217 JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR, | |
218 "PermGen space"); | |
219 } | |
220 | |
221 THROW_OOP_0(Universe::out_of_memory_error_perm_gen()); | |
222 } | |
223 | |
224 HeapWord* CollectedHeap::common_permanent_mem_allocate_init(size_t size, TRAPS) { | |
225 HeapWord* obj = common_permanent_mem_allocate_noinit(size, CHECK_NULL); | |
226 init_obj(obj, size); | 182 init_obj(obj, size); |
227 return obj; | 183 return obj; |
228 } | 184 } |
229 | 185 |
230 HeapWord* CollectedHeap::allocate_from_tlab(Thread* thread, size_t size) { | 186 HeapWord* CollectedHeap::allocate_from_tlab(Thread* thread, size_t size) { |
284 Universe::heap()->check_for_non_bad_heap_word_value(obj+hs, size-hs); | 240 Universe::heap()->check_for_non_bad_heap_word_value(obj+hs, size-hs); |
285 #endif | 241 #endif |
286 return (oop)obj; | 242 return (oop)obj; |
287 } | 243 } |
288 | 244 |
289 oop CollectedHeap::permanent_obj_allocate(KlassHandle klass, int size, TRAPS) { | |
290 oop obj = permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL); | |
291 post_allocation_install_obj_klass(klass, obj); | |
292 NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj, | |
293 size)); | |
294 return obj; | |
295 } | |
296 | |
297 oop CollectedHeap::permanent_obj_allocate_no_klass_install(KlassHandle klass, | |
298 int size, | |
299 TRAPS) { | |
300 debug_only(check_for_valid_allocation_state()); | |
301 assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed"); | |
302 assert(size >= 0, "int won't convert to size_t"); | |
303 HeapWord* obj = common_permanent_mem_allocate_init(size, CHECK_NULL); | |
304 post_allocation_setup_no_klass_install(klass, obj); | |
305 #ifndef PRODUCT | |
306 const size_t hs = oopDesc::header_size(); | |
307 Universe::heap()->check_for_bad_heap_word_value(obj+hs, size-hs); | |
308 #endif | |
309 return (oop)obj; | |
310 } | |
311 | |
312 oop CollectedHeap::permanent_array_allocate(KlassHandle klass, | |
313 int size, | |
314 int length, | |
315 TRAPS) { | |
316 debug_only(check_for_valid_allocation_state()); | |
317 assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed"); | |
318 assert(size >= 0, "int won't convert to size_t"); | |
319 HeapWord* obj = common_permanent_mem_allocate_init(size, CHECK_NULL); | |
320 post_allocation_setup_array(klass, obj, length); | |
321 NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size)); | |
322 return (oop)obj; | |
323 } | |
324 | |
325 // Returns "TRUE" if "p" is a method oop in the | 245 // Returns "TRUE" if "p" is a method oop in the |
326 // current heap with high probability. NOTE: The main | 246 // current heap with high probability. NOTE: The main |
327 // current consumers of this interface are Forte:: | 247 // current consumers of this interface are Forte:: |
328 // and ThreadProfiler::. In these cases, the | 248 // and ThreadProfiler::. In these cases, the |
329 // interpreter frame from which "p" came, may be | 249 // interpreter frame from which "p" came, may be |
332 // valid method before using it. Nonetheless since | 252 // valid method before using it. Nonetheless since |
333 // the clients do not typically lock out GC, the | 253 // the clients do not typically lock out GC, the |
334 // predicate is_valid_method() is not stable, so | 254 // predicate is_valid_method() is not stable, so |
335 // it is possible that by the time "p" is used, it | 255 // it is possible that by the time "p" is used, it |
336 // is no longer valid. | 256 // is no longer valid. |
337 inline bool CollectedHeap::is_valid_method(oop p) const { | 257 inline bool CollectedHeap::is_valid_method(Method* p) const { |
338 return | 258 return |
339 p != NULL && | 259 p != NULL && |
340 | 260 |
341 // Check whether it is aligned at a HeapWord boundary. | 261 // Check whether "method" is metadata |
342 Space::is_aligned(p) && | 262 p->is_metadata() && |
343 | |
344 // Check whether "method" is in the allocated part of the | |
345 // permanent generation -- this needs to be checked before | |
346 // p->klass() below to avoid a SEGV (but see below | |
347 // for a potential window of vulnerability). | |
348 is_permanent((void*)p) && | |
349 | 263 |
350 // See if GC is active; however, there is still an | 264 // See if GC is active; however, there is still an |
351 // apparently unavoidable window after this call | 265 // apparently unavoidable window after this call |
352 // and before the client of this interface uses "p". | 266 // and before the client of this interface uses "p". |
353 // If the client chooses not to lock out GC, then | 267 // If the client chooses not to lock out GC, then |
354 // it's a risk the client must accept. | 268 // it's a risk the client must accept. |
355 !is_gc_active() && | 269 !is_gc_active() && |
356 | 270 |
357 // Check that p is a methodOop. | 271 // Check that p is a Method*. |
358 p->klass() == Universe::methodKlassObj(); | 272 p->is_method(); |
359 } | 273 } |
360 | 274 |
275 inline void CollectedHeap::oop_iterate_no_header(OopClosure* cl) { | |
276 NoHeaderExtendedOopClosure no_header_cl(cl); | |
277 oop_iterate(&no_header_cl); | |
278 } | |
361 | 279 |
362 #ifndef PRODUCT | 280 #ifndef PRODUCT |
363 | 281 |
364 inline bool | 282 inline bool |
365 CollectedHeap::promotion_should_fail(volatile size_t* count) { | 283 CollectedHeap::promotion_should_fail(volatile size_t* count) { |