Thu, 29 Nov 2012 11:23:15 -0800
Merge
1 /*
2 * Copyright (c) 2001, 2012, 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 */
25 #ifndef SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP
26 #define SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP
28 #include "gc_interface/collectedHeap.hpp"
29 #include "memory/threadLocalAllocBuffer.inline.hpp"
30 #include "memory/universe.hpp"
31 #include "oops/arrayOop.hpp"
32 #include "prims/jvmtiExport.hpp"
33 #include "runtime/sharedRuntime.hpp"
34 #include "runtime/thread.inline.hpp"
35 #include "services/lowMemoryDetector.hpp"
36 #include "utilities/copy.hpp"
38 // Inline allocation implementations.
40 void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
41 HeapWord* obj) {
42 post_allocation_setup_no_klass_install(klass, obj);
43 post_allocation_install_obj_klass(klass, oop(obj));
44 }
46 void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
47 HeapWord* objPtr) {
48 oop obj = (oop)objPtr;
50 assert(obj != NULL, "NULL object pointer");
51 if (UseBiasedLocking && (klass() != NULL)) {
52 obj->set_mark(klass->prototype_header());
53 } else {
54 // May be bootstrapping
55 obj->set_mark(markOopDesc::prototype());
56 }
57 }
59 void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
60 oop obj) {
61 // These asserts are kind of complicated because of klassKlass
62 // and the beginning of the world.
63 assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass");
64 assert(klass() == NULL || klass()->is_klass(), "not a klass");
65 assert(obj != NULL, "NULL object pointer");
66 obj->set_klass(klass());
67 assert(!Universe::is_fully_initialized() || obj->klass() != NULL,
68 "missing klass");
69 }
71 // Support for jvmti and dtrace
72 inline void post_allocation_notify(KlassHandle klass, oop obj) {
73 // support low memory notifications (no-op if not enabled)
74 LowMemoryDetector::detect_low_memory_for_collected_pools();
76 // support for JVMTI VMObjectAlloc event (no-op if not enabled)
77 JvmtiExport::vm_object_alloc_event_collector(obj);
79 if (DTraceAllocProbes) {
80 // support for Dtrace object alloc event (no-op most of the time)
81 if (klass() != NULL && klass()->name() != NULL) {
82 SharedRuntime::dtrace_object_alloc(obj);
83 }
84 }
85 }
87 void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
88 HeapWord* obj) {
89 post_allocation_setup_common(klass, obj);
90 assert(Universe::is_bootstrapping() ||
91 !((oop)obj)->is_array(), "must not be an array");
92 // notify jvmti and dtrace
93 post_allocation_notify(klass, (oop)obj);
94 }
96 void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
97 HeapWord* obj,
98 int length) {
99 // Set array length before setting the _klass field
100 // in post_allocation_setup_common() because the klass field
101 // indicates that the object is parsable by concurrent GC.
102 assert(length >= 0, "length should be non-negative");
103 ((arrayOop)obj)->set_length(length);
104 post_allocation_setup_common(klass, obj);
105 assert(((oop)obj)->is_array(), "must be an array");
106 // notify jvmti and dtrace (must be after length is set for dtrace)
107 post_allocation_notify(klass, (oop)obj);
108 }
110 HeapWord* CollectedHeap::common_mem_allocate_noinit(size_t size, TRAPS) {
112 // Clear unhandled oops for memory allocation. Memory allocation might
113 // not take out a lock if from tlab, so clear here.
114 CHECK_UNHANDLED_OOPS_ONLY(THREAD->clear_unhandled_oops();)
116 if (HAS_PENDING_EXCEPTION) {
117 NOT_PRODUCT(guarantee(false, "Should not allocate with exception pending"));
118 return NULL; // caller does a CHECK_0 too
119 }
121 HeapWord* result = NULL;
122 if (UseTLAB) {
123 result = CollectedHeap::allocate_from_tlab(THREAD, size);
124 if (result != NULL) {
125 assert(!HAS_PENDING_EXCEPTION,
126 "Unexpected exception, will result in uninitialized storage");
127 return result;
128 }
129 }
130 bool gc_overhead_limit_was_exceeded = false;
131 result = Universe::heap()->mem_allocate(size,
132 &gc_overhead_limit_was_exceeded);
133 if (result != NULL) {
134 NOT_PRODUCT(Universe::heap()->
135 check_for_non_bad_heap_word_value(result, size));
136 assert(!HAS_PENDING_EXCEPTION,
137 "Unexpected exception, will result in uninitialized storage");
138 THREAD->incr_allocated_bytes(size * HeapWordSize);
139 return result;
140 }
143 if (!gc_overhead_limit_was_exceeded) {
144 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
145 report_java_out_of_memory("Java heap space");
147 if (JvmtiExport::should_post_resource_exhausted()) {
148 JvmtiExport::post_resource_exhausted(
149 JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
150 "Java heap space");
151 }
153 THROW_OOP_0(Universe::out_of_memory_error_java_heap());
154 } else {
155 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
156 report_java_out_of_memory("GC overhead limit exceeded");
158 if (JvmtiExport::should_post_resource_exhausted()) {
159 JvmtiExport::post_resource_exhausted(
160 JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
161 "GC overhead limit exceeded");
162 }
164 THROW_OOP_0(Universe::out_of_memory_error_gc_overhead_limit());
165 }
166 }
168 HeapWord* CollectedHeap::common_mem_allocate_init(size_t size, TRAPS) {
169 HeapWord* obj = common_mem_allocate_noinit(size, CHECK_NULL);
170 init_obj(obj, size);
171 return obj;
172 }
174 HeapWord* CollectedHeap::allocate_from_tlab(Thread* thread, size_t size) {
175 assert(UseTLAB, "should use UseTLAB");
177 HeapWord* obj = thread->tlab().allocate(size);
178 if (obj != NULL) {
179 return obj;
180 }
181 // Otherwise...
182 return allocate_from_tlab_slow(thread, size);
183 }
185 void CollectedHeap::init_obj(HeapWord* obj, size_t size) {
186 assert(obj != NULL, "cannot initialize NULL object");
187 const size_t hs = oopDesc::header_size();
188 assert(size >= hs, "unexpected object size");
189 ((oop)obj)->set_klass_gap(0);
190 Copy::fill_to_aligned_words(obj + hs, size - hs);
191 }
193 oop CollectedHeap::obj_allocate(KlassHandle klass, int size, TRAPS) {
194 debug_only(check_for_valid_allocation_state());
195 assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
196 assert(size >= 0, "int won't convert to size_t");
197 HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
198 post_allocation_setup_obj(klass, obj);
199 NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
200 return (oop)obj;
201 }
203 oop CollectedHeap::array_allocate(KlassHandle klass,
204 int size,
205 int length,
206 TRAPS) {
207 debug_only(check_for_valid_allocation_state());
208 assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
209 assert(size >= 0, "int won't convert to size_t");
210 HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
211 post_allocation_setup_array(klass, obj, length);
212 NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
213 return (oop)obj;
214 }
216 oop CollectedHeap::array_allocate_nozero(KlassHandle klass,
217 int size,
218 int length,
219 TRAPS) {
220 debug_only(check_for_valid_allocation_state());
221 assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
222 assert(size >= 0, "int won't convert to size_t");
223 HeapWord* obj = common_mem_allocate_noinit(size, CHECK_NULL);
224 ((oop)obj)->set_klass_gap(0);
225 post_allocation_setup_array(klass, obj, length);
226 #ifndef PRODUCT
227 const size_t hs = oopDesc::header_size()+1;
228 Universe::heap()->check_for_non_bad_heap_word_value(obj+hs, size-hs);
229 #endif
230 return (oop)obj;
231 }
233 inline void CollectedHeap::oop_iterate_no_header(OopClosure* cl) {
234 NoHeaderExtendedOopClosure no_header_cl(cl);
235 oop_iterate(&no_header_cl);
236 }
238 #ifndef PRODUCT
240 inline bool
241 CollectedHeap::promotion_should_fail(volatile size_t* count) {
242 // Access to count is not atomic; the value does not have to be exact.
243 if (PromotionFailureALot) {
244 const size_t gc_num = total_collections();
245 const size_t elapsed_gcs = gc_num - _promotion_failure_alot_gc_number;
246 if (elapsed_gcs >= PromotionFailureALotInterval) {
247 // Test for unsigned arithmetic wrap-around.
248 if (++*count >= PromotionFailureALotCount) {
249 *count = 0;
250 return true;
251 }
252 }
253 }
254 return false;
255 }
257 inline bool CollectedHeap::promotion_should_fail() {
258 return promotion_should_fail(&_promotion_failure_alot_count);
259 }
261 inline void CollectedHeap::reset_promotion_should_fail(volatile size_t* count) {
262 if (PromotionFailureALot) {
263 _promotion_failure_alot_gc_number = total_collections();
264 *count = 0;
265 }
266 }
268 inline void CollectedHeap::reset_promotion_should_fail() {
269 reset_promotion_should_fail(&_promotion_failure_alot_count);
270 }
271 #endif // #ifndef PRODUCT
273 #endif // SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP