comparison src/share/vm/gc_interface/collectedHeap.inline.hpp @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children ba764ed4b6f2
comparison
equal deleted inserted replaced
-1:000000000000 0:a61af66fc99e
1 /*
2 * Copyright 2001-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25 // Inline allocation implementations.
26
27 void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
28 HeapWord* obj,
29 size_t size) {
30 post_allocation_setup_no_klass_install(klass, obj, size);
31 post_allocation_install_obj_klass(klass, oop(obj), (int) size);
32 }
33
34 void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
35 HeapWord* objPtr,
36 size_t size) {
37
38 oop obj = (oop)objPtr;
39
40 assert(obj != NULL, "NULL object pointer");
41 if (UseBiasedLocking && (klass() != NULL)) {
42 obj->set_mark(klass->prototype_header());
43 } else {
44 // May be bootstrapping
45 obj->set_mark(markOopDesc::prototype());
46 }
47
48 // support low memory notifications (no-op if not enabled)
49 LowMemoryDetector::detect_low_memory_for_collected_pools();
50 }
51
52 void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
53 oop obj,
54 int size) {
55 // These asserts are kind of complicated because of klassKlass
56 // and the beginning of the world.
57 assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass");
58 assert(klass() == NULL || klass()->is_klass(), "not a klass");
59 assert(klass() == NULL || klass()->klass_part() != NULL, "not a klass");
60 assert(obj != NULL, "NULL object pointer");
61 obj->set_klass(klass());
62 assert(!Universe::is_fully_initialized() || obj->blueprint() != NULL,
63 "missing blueprint");
64
65 // support for JVMTI VMObjectAlloc event (no-op if not enabled)
66 JvmtiExport::vm_object_alloc_event_collector(obj);
67
68 if (DTraceAllocProbes) {
69 // support for Dtrace object alloc event (no-op most of the time)
70 if (klass() != NULL && klass()->klass_part()->name() != NULL) {
71 SharedRuntime::dtrace_object_alloc(obj);
72 }
73 }
74 }
75
76 void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
77 HeapWord* obj,
78 size_t size) {
79 post_allocation_setup_common(klass, obj, size);
80 assert(Universe::is_bootstrapping() ||
81 !((oop)obj)->blueprint()->oop_is_array(), "must not be an array");
82 }
83
84 void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
85 HeapWord* obj,
86 size_t size,
87 int length) {
88 // Set array length before posting jvmti object alloc event
89 // in post_allocation_setup_common()
90 assert(length >= 0, "length should be non-negative");
91 ((arrayOop)obj)->set_length(length);
92 post_allocation_setup_common(klass, obj, size);
93 assert(((oop)obj)->blueprint()->oop_is_array(), "must be an array");
94 }
95
96 HeapWord* CollectedHeap::common_mem_allocate_noinit(size_t size, bool is_noref, TRAPS) {
97
98 // Clear unhandled oops for memory allocation. Memory allocation might
99 // not take out a lock if from tlab, so clear here.
100 CHECK_UNHANDLED_OOPS_ONLY(THREAD->clear_unhandled_oops();)
101
102 if (HAS_PENDING_EXCEPTION) {
103 NOT_PRODUCT(guarantee(false, "Should not allocate with exception pending"));
104 return NULL; // caller does a CHECK_0 too
105 }
106
107 // We may want to update this, is_noref objects might not be allocated in TLABs.
108 HeapWord* result = NULL;
109 if (UseTLAB) {
110 result = CollectedHeap::allocate_from_tlab(THREAD, size);
111 if (result != NULL) {
112 assert(!HAS_PENDING_EXCEPTION,
113 "Unexpected exception, will result in uninitialized storage");
114 return result;
115 }
116 }
117 bool gc_overhead_limit_was_exceeded;
118 result = Universe::heap()->mem_allocate(size,
119 is_noref,
120 false,
121 &gc_overhead_limit_was_exceeded);
122 if (result != NULL) {
123 NOT_PRODUCT(Universe::heap()->
124 check_for_non_bad_heap_word_value(result, size));
125 assert(!HAS_PENDING_EXCEPTION,
126 "Unexpected exception, will result in uninitialized storage");
127 return result;
128 }
129
130
131 if (!gc_overhead_limit_was_exceeded) {
132 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
133 report_java_out_of_memory("Java heap space");
134
135 if (JvmtiExport::should_post_resource_exhausted()) {
136 JvmtiExport::post_resource_exhausted(
137 JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
138 "Java heap space");
139 }
140
141 THROW_OOP_0(Universe::out_of_memory_error_java_heap());
142 } else {
143 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
144 report_java_out_of_memory("GC overhead limit exceeded");
145
146 if (JvmtiExport::should_post_resource_exhausted()) {
147 JvmtiExport::post_resource_exhausted(
148 JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
149 "GC overhead limit exceeded");
150 }
151
152 THROW_OOP_0(Universe::out_of_memory_error_gc_overhead_limit());
153 }
154 }
155
156 HeapWord* CollectedHeap::common_mem_allocate_init(size_t size, bool is_noref, TRAPS) {
157 HeapWord* obj = common_mem_allocate_noinit(size, is_noref, CHECK_NULL);
158 init_obj(obj, size);
159 return obj;
160 }
161
162 // Need to investigate, do we really want to throw OOM exception here?
163 HeapWord* CollectedHeap::common_permanent_mem_allocate_noinit(size_t size, TRAPS) {
164 if (HAS_PENDING_EXCEPTION) {
165 NOT_PRODUCT(guarantee(false, "Should not allocate with exception pending"));
166 return NULL; // caller does a CHECK_NULL too
167 }
168
169 #ifdef ASSERT
170 if (CIFireOOMAt > 0 && THREAD->is_Compiler_thread() &&
171 ++_fire_out_of_memory_count >= CIFireOOMAt) {
172 // For testing of OOM handling in the CI throw an OOM and see how
173 // it does. Historically improper handling of these has resulted
174 // in crashes which we really don't want to have in the CI.
175 THROW_OOP_0(Universe::out_of_memory_error_perm_gen());
176 }
177 #endif
178
179 HeapWord* result = Universe::heap()->permanent_mem_allocate(size);
180 if (result != NULL) {
181 NOT_PRODUCT(Universe::heap()->
182 check_for_non_bad_heap_word_value(result, size));
183 assert(!HAS_PENDING_EXCEPTION,
184 "Unexpected exception, will result in uninitialized storage");
185 return result;
186 }
187 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
188 report_java_out_of_memory("PermGen space");
189
190 if (JvmtiExport::should_post_resource_exhausted()) {
191 JvmtiExport::post_resource_exhausted(
192 JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
193 "PermGen space");
194 }
195
196 THROW_OOP_0(Universe::out_of_memory_error_perm_gen());
197 }
198
199 HeapWord* CollectedHeap::common_permanent_mem_allocate_init(size_t size, TRAPS) {
200 HeapWord* obj = common_permanent_mem_allocate_noinit(size, CHECK_NULL);
201 init_obj(obj, size);
202 return obj;
203 }
204
205 HeapWord* CollectedHeap::allocate_from_tlab(Thread* thread, size_t size) {
206 assert(UseTLAB, "should use UseTLAB");
207
208 HeapWord* obj = thread->tlab().allocate(size);
209 if (obj != NULL) {
210 return obj;
211 }
212 // Otherwise...
213 return allocate_from_tlab_slow(thread, size);
214 }
215
216 void CollectedHeap::init_obj(HeapWord* obj, size_t size) {
217 assert(obj != NULL, "cannot initialize NULL object");
218 const size_t hs = oopDesc::header_size();
219 assert(size >= hs, "unexpected object size");
220 Copy::fill_to_aligned_words(obj + hs, size - hs);
221 }
222
223 oop CollectedHeap::obj_allocate(KlassHandle klass, int size, TRAPS) {
224 debug_only(check_for_valid_allocation_state());
225 assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
226 assert(size >= 0, "int won't convert to size_t");
227 HeapWord* obj = common_mem_allocate_init(size, false, CHECK_NULL);
228 post_allocation_setup_obj(klass, obj, size);
229 NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
230 return (oop)obj;
231 }
232
233 oop CollectedHeap::array_allocate(KlassHandle klass,
234 int size,
235 int length,
236 TRAPS) {
237 debug_only(check_for_valid_allocation_state());
238 assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
239 assert(size >= 0, "int won't convert to size_t");
240 HeapWord* obj = common_mem_allocate_init(size, false, CHECK_NULL);
241 post_allocation_setup_array(klass, obj, size, length);
242 NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
243 return (oop)obj;
244 }
245
246 oop CollectedHeap::large_typearray_allocate(KlassHandle klass,
247 int size,
248 int length,
249 TRAPS) {
250 debug_only(check_for_valid_allocation_state());
251 assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
252 assert(size >= 0, "int won't convert to size_t");
253 HeapWord* obj = common_mem_allocate_init(size, true, CHECK_NULL);
254 post_allocation_setup_array(klass, obj, size, length);
255 NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
256 return (oop)obj;
257 }
258
259 oop CollectedHeap::permanent_obj_allocate(KlassHandle klass, int size, TRAPS) {
260 oop obj = permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL);
261 post_allocation_install_obj_klass(klass, obj, size);
262 NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj,
263 size));
264 return obj;
265 }
266
267 oop CollectedHeap::permanent_obj_allocate_no_klass_install(KlassHandle klass,
268 int size,
269 TRAPS) {
270 debug_only(check_for_valid_allocation_state());
271 assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
272 assert(size >= 0, "int won't convert to size_t");
273 HeapWord* obj = common_permanent_mem_allocate_init(size, CHECK_NULL);
274 post_allocation_setup_no_klass_install(klass, obj, size);
275 NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
276 return (oop)obj;
277 }
278
279 oop CollectedHeap::permanent_array_allocate(KlassHandle klass,
280 int size,
281 int length,
282 TRAPS) {
283 debug_only(check_for_valid_allocation_state());
284 assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
285 assert(size >= 0, "int won't convert to size_t");
286 HeapWord* obj = common_permanent_mem_allocate_init(size, CHECK_NULL);
287 post_allocation_setup_array(klass, obj, size, length);
288 NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
289 return (oop)obj;
290 }
291
292 // Returns "TRUE" if "p" is a method oop in the
293 // current heap with high probability. NOTE: The main
294 // current consumers of this interface are Forte::
295 // and ThreadProfiler::. In these cases, the
296 // interpreter frame from which "p" came, may be
297 // under construction when sampled asynchronously, so
298 // the clients want to check that it represents a
299 // valid method before using it. Nonetheless since
300 // the clients do not typically lock out GC, the
301 // predicate is_valid_method() is not stable, so
302 // it is possible that by the time "p" is used, it
303 // is no longer valid.
304 inline bool CollectedHeap::is_valid_method(oop p) const {
305 return
306 p != NULL &&
307
308 // Check whether it is aligned at a HeapWord boundary.
309 Space::is_aligned(p) &&
310
311 // Check whether "method" is in the allocated part of the
312 // permanent generation -- this needs to be checked before
313 // p->klass() below to avoid a SEGV (but see below
314 // for a potential window of vulnerability).
315 is_permanent((void*)p) &&
316
317 // See if GC is active; however, there is still an
318 // apparently unavoidable window after this call
319 // and before the client of this interface uses "p".
320 // If the client chooses not to lock out GC, then
321 // it's a risk the client must accept.
322 !is_gc_active() &&
323
324 // Check that p is a methodOop.
325 p->klass() == Universe::methodKlassObj();
326 }
327
328
329 #ifndef PRODUCT
330
331 inline bool
332 CollectedHeap::promotion_should_fail(volatile size_t* count) {
333 // Access to count is not atomic; the value does not have to be exact.
334 if (PromotionFailureALot) {
335 const size_t gc_num = total_collections();
336 const size_t elapsed_gcs = gc_num - _promotion_failure_alot_gc_number;
337 if (elapsed_gcs >= PromotionFailureALotInterval) {
338 // Test for unsigned arithmetic wrap-around.
339 if (++*count >= PromotionFailureALotCount) {
340 *count = 0;
341 return true;
342 }
343 }
344 }
345 return false;
346 }
347
348 inline bool CollectedHeap::promotion_should_fail() {
349 return promotion_should_fail(&_promotion_failure_alot_count);
350 }
351
352 inline void CollectedHeap::reset_promotion_should_fail(volatile size_t* count) {
353 if (PromotionFailureALot) {
354 _promotion_failure_alot_gc_number = total_collections();
355 *count = 0;
356 }
357 }
358
359 inline void CollectedHeap::reset_promotion_should_fail() {
360 reset_promotion_should_fail(&_promotion_failure_alot_count);
361 }
362 #endif // #ifndef PRODUCT