collectedHeap.inline.hpp revision 13242:fcb4803050e8
1/*
2 * Copyright (c) 2001, 2017, 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 */
24
25#ifndef SHARE_VM_GC_SHARED_COLLECTEDHEAP_INLINE_HPP
26#define SHARE_VM_GC_SHARED_COLLECTEDHEAP_INLINE_HPP
27
28#include "classfile/javaClasses.hpp"
29#include "gc/shared/allocTracer.hpp"
30#include "gc/shared/collectedHeap.hpp"
31#include "gc/shared/threadLocalAllocBuffer.inline.hpp"
32#include "memory/universe.hpp"
33#include "oops/arrayOop.hpp"
34#include "oops/oop.inline.hpp"
35#include "prims/jvmtiExport.hpp"
36#include "runtime/sharedRuntime.hpp"
37#include "runtime/thread.inline.hpp"
38#include "services/lowMemoryDetector.hpp"
39#include "utilities/copy.hpp"
40
41// Inline allocation implementations.
42
43void CollectedHeap::post_allocation_setup_common(Klass* klass,
44                                                 HeapWord* obj_ptr) {
45  post_allocation_setup_no_klass_install(klass, obj_ptr);
46  oop obj = (oop)obj_ptr;
47#if ! INCLUDE_ALL_GCS
48  obj->set_klass(klass);
49#else
50  // Need a release store to ensure array/class length, mark word, and
51  // object zeroing are visible before setting the klass non-NULL, for
52  // concurrent collectors.
53  obj->release_set_klass(klass);
54#endif
55}
56
57void CollectedHeap::post_allocation_setup_no_klass_install(Klass* klass,
58                                                           HeapWord* obj_ptr) {
59  oop obj = (oop)obj_ptr;
60
61  assert(obj != NULL, "NULL object pointer");
62  if (UseBiasedLocking && (klass != NULL)) {
63    obj->set_mark(klass->prototype_header());
64  } else {
65    // May be bootstrapping
66    obj->set_mark(markOopDesc::prototype());
67  }
68}
69
70// Support for jvmti and dtrace
71inline void post_allocation_notify(Klass* klass, oop obj, int size) {
72  // support low memory notifications (no-op if not enabled)
73  LowMemoryDetector::detect_low_memory_for_collected_pools();
74
75  // support for JVMTI VMObjectAlloc event (no-op if not enabled)
76  JvmtiExport::vm_object_alloc_event_collector(obj);
77
78  if (DTraceAllocProbes) {
79    // support for Dtrace object alloc event (no-op most of the time)
80    if (klass != NULL && klass->name() != NULL) {
81      SharedRuntime::dtrace_object_alloc(obj, size);
82    }
83  }
84}
85
86void CollectedHeap::post_allocation_setup_obj(Klass* klass,
87                                              HeapWord* obj_ptr,
88                                              int size) {
89  post_allocation_setup_common(klass, obj_ptr);
90  oop obj = (oop)obj_ptr;
91  assert(Universe::is_bootstrapping() ||
92         !obj->is_array(), "must not be an array");
93  // notify jvmti and dtrace
94  post_allocation_notify(klass, obj, size);
95}
96
97void CollectedHeap::post_allocation_setup_class(Klass* klass,
98                                                HeapWord* obj_ptr,
99                                                int size) {
100  // Set oop_size field before setting the _klass field because a
101  // non-NULL _klass field indicates that the object is parsable by
102  // concurrent GC.
103  oop new_cls = (oop)obj_ptr;
104  assert(size > 0, "oop_size must be positive.");
105  java_lang_Class::set_oop_size(new_cls, size);
106  post_allocation_setup_common(klass, obj_ptr);
107  assert(Universe::is_bootstrapping() ||
108         !new_cls->is_array(), "must not be an array");
109  // notify jvmti and dtrace
110  post_allocation_notify(klass, new_cls, size);
111}
112
113void CollectedHeap::post_allocation_setup_array(Klass* klass,
114                                                HeapWord* obj_ptr,
115                                                int length) {
116  // Set array length before setting the _klass field because a
117  // non-NULL klass field indicates that the object is parsable by
118  // concurrent GC.
119  assert(length >= 0, "length should be non-negative");
120  ((arrayOop)obj_ptr)->set_length(length);
121  post_allocation_setup_common(klass, obj_ptr);
122  oop new_obj = (oop)obj_ptr;
123  assert(new_obj->is_array(), "must be an array");
124  // notify jvmti and dtrace (must be after length is set for dtrace)
125  post_allocation_notify(klass, new_obj, new_obj->size());
126}
127
128HeapWord* CollectedHeap::common_mem_allocate_noinit(Klass* klass, size_t size, TRAPS) {
129
130  // Clear unhandled oops for memory allocation.  Memory allocation might
131  // not take out a lock if from tlab, so clear here.
132  CHECK_UNHANDLED_OOPS_ONLY(THREAD->clear_unhandled_oops();)
133
134  if (HAS_PENDING_EXCEPTION) {
135    NOT_PRODUCT(guarantee(false, "Should not allocate with exception pending"));
136    return NULL;  // caller does a CHECK_0 too
137  }
138
139  HeapWord* result = NULL;
140  if (UseTLAB) {
141    result = allocate_from_tlab(klass, THREAD, size);
142    if (result != NULL) {
143      assert(!HAS_PENDING_EXCEPTION,
144             "Unexpected exception, will result in uninitialized storage");
145      return result;
146    }
147  }
148  bool gc_overhead_limit_was_exceeded = false;
149  result = Universe::heap()->mem_allocate(size,
150                                          &gc_overhead_limit_was_exceeded);
151  if (result != NULL) {
152    NOT_PRODUCT(Universe::heap()->
153      check_for_non_bad_heap_word_value(result, size));
154    assert(!HAS_PENDING_EXCEPTION,
155           "Unexpected exception, will result in uninitialized storage");
156    THREAD->incr_allocated_bytes(size * HeapWordSize);
157
158    AllocTracer::send_allocation_outside_tlab_event(klass, size * HeapWordSize);
159
160    return result;
161  }
162
163
164  if (!gc_overhead_limit_was_exceeded) {
165    // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
166    report_java_out_of_memory("Java heap space");
167
168    if (JvmtiExport::should_post_resource_exhausted()) {
169      JvmtiExport::post_resource_exhausted(
170        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
171        "Java heap space");
172    }
173
174    THROW_OOP_0(Universe::out_of_memory_error_java_heap());
175  } else {
176    // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
177    report_java_out_of_memory("GC overhead limit exceeded");
178
179    if (JvmtiExport::should_post_resource_exhausted()) {
180      JvmtiExport::post_resource_exhausted(
181        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
182        "GC overhead limit exceeded");
183    }
184
185    THROW_OOP_0(Universe::out_of_memory_error_gc_overhead_limit());
186  }
187}
188
189HeapWord* CollectedHeap::common_mem_allocate_init(Klass* klass, size_t size, TRAPS) {
190  HeapWord* obj = common_mem_allocate_noinit(klass, size, CHECK_NULL);
191  init_obj(obj, size);
192  return obj;
193}
194
195HeapWord* CollectedHeap::allocate_from_tlab(Klass* klass, Thread* thread, size_t size) {
196  assert(UseTLAB, "should use UseTLAB");
197
198  HeapWord* obj = thread->tlab().allocate(size);
199  if (obj != NULL) {
200    return obj;
201  }
202  // Otherwise...
203  return allocate_from_tlab_slow(klass, thread, size);
204}
205
206void CollectedHeap::init_obj(HeapWord* obj, size_t size) {
207  assert(obj != NULL, "cannot initialize NULL object");
208  const size_t hs = oopDesc::header_size();
209  assert(size >= hs, "unexpected object size");
210  ((oop)obj)->set_klass_gap(0);
211  Copy::fill_to_aligned_words(obj + hs, size - hs);
212}
213
214oop CollectedHeap::obj_allocate(Klass* klass, int size, TRAPS) {
215  debug_only(check_for_valid_allocation_state());
216  assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
217  assert(size >= 0, "int won't convert to size_t");
218  HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL);
219  post_allocation_setup_obj(klass, obj, size);
220  NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
221  return (oop)obj;
222}
223
224oop CollectedHeap::class_allocate(Klass* klass, int size, TRAPS) {
225  debug_only(check_for_valid_allocation_state());
226  assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
227  assert(size >= 0, "int won't convert to size_t");
228  HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL);
229  post_allocation_setup_class(klass, obj, size); // set oop_size
230  NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
231  return (oop)obj;
232}
233
234oop CollectedHeap::array_allocate(Klass* klass,
235                                  int size,
236                                  int length,
237                                  TRAPS) {
238  debug_only(check_for_valid_allocation_state());
239  assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
240  assert(size >= 0, "int won't convert to size_t");
241  HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL);
242  post_allocation_setup_array(klass, obj, length);
243  NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
244  return (oop)obj;
245}
246
247oop CollectedHeap::array_allocate_nozero(Klass* klass,
248                                         int size,
249                                         int length,
250                                         TRAPS) {
251  debug_only(check_for_valid_allocation_state());
252  assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
253  assert(size >= 0, "int won't convert to size_t");
254  HeapWord* obj = common_mem_allocate_noinit(klass, size, CHECK_NULL);
255  ((oop)obj)->set_klass_gap(0);
256  post_allocation_setup_array(klass, obj, length);
257#ifndef PRODUCT
258  const size_t hs = oopDesc::header_size()+1;
259  Universe::heap()->check_for_non_bad_heap_word_value(obj+hs, size-hs);
260#endif
261  return (oop)obj;
262}
263
264inline HeapWord* CollectedHeap::align_allocation_or_fail(HeapWord* addr,
265                                                         HeapWord* end,
266                                                         unsigned short alignment_in_bytes) {
267  if (alignment_in_bytes <= ObjectAlignmentInBytes) {
268    return addr;
269  }
270
271  assert(is_ptr_aligned(addr, HeapWordSize),
272         "Address " PTR_FORMAT " is not properly aligned.", p2i(addr));
273  assert(is_size_aligned(alignment_in_bytes, HeapWordSize),
274         "Alignment size %u is incorrect.", alignment_in_bytes);
275
276  HeapWord* new_addr = align_ptr_up(addr, alignment_in_bytes);
277  size_t padding = pointer_delta(new_addr, addr);
278
279  if (padding == 0) {
280    return addr;
281  }
282
283  if (padding < CollectedHeap::min_fill_size()) {
284    padding += alignment_in_bytes / HeapWordSize;
285    assert(padding >= CollectedHeap::min_fill_size(),
286           "alignment_in_bytes %u is expect to be larger "
287           "than the minimum object size", alignment_in_bytes);
288    new_addr = addr + padding;
289  }
290
291  assert(new_addr > addr, "Unexpected arithmetic overflow "
292         PTR_FORMAT " not greater than " PTR_FORMAT, p2i(new_addr), p2i(addr));
293  if(new_addr < end) {
294    CollectedHeap::fill_with_object(addr, padding);
295    return new_addr;
296  } else {
297    return NULL;
298  }
299}
300
301#ifndef PRODUCT
302
303inline bool
304CollectedHeap::promotion_should_fail(volatile size_t* count) {
305  // Access to count is not atomic; the value does not have to be exact.
306  if (PromotionFailureALot) {
307    const size_t gc_num = total_collections();
308    const size_t elapsed_gcs = gc_num - _promotion_failure_alot_gc_number;
309    if (elapsed_gcs >= PromotionFailureALotInterval) {
310      // Test for unsigned arithmetic wrap-around.
311      if (++*count >= PromotionFailureALotCount) {
312        *count = 0;
313        return true;
314      }
315    }
316  }
317  return false;
318}
319
320inline bool CollectedHeap::promotion_should_fail() {
321  return promotion_should_fail(&_promotion_failure_alot_count);
322}
323
324inline void CollectedHeap::reset_promotion_should_fail(volatile size_t* count) {
325  if (PromotionFailureALot) {
326    _promotion_failure_alot_gc_number = total_collections();
327    *count = 0;
328  }
329}
330
331inline void CollectedHeap::reset_promotion_should_fail() {
332  reset_promotion_should_fail(&_promotion_failure_alot_count);
333}
334#endif  // #ifndef PRODUCT
335
336#endif // SHARE_VM_GC_SHARED_COLLECTEDHEAP_INLINE_HPP
337