collectedHeap.inline.hpp 10.2 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27
#ifndef SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP
#define SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP

S
sla 已提交
28
#include "gc_interface/allocTracer.hpp"
29 30 31 32 33 34
#include "gc_interface/collectedHeap.hpp"
#include "memory/threadLocalAllocBuffer.inline.hpp"
#include "memory/universe.hpp"
#include "oops/arrayOop.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/sharedRuntime.hpp"
35
#include "runtime/thread.inline.hpp"
36 37 38
#include "services/lowMemoryDetector.hpp"
#include "utilities/copy.hpp"

D
duke 已提交
39 40 41
// Inline allocation implementations.

void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
42 43 44
                                                 HeapWord* obj) {
  post_allocation_setup_no_klass_install(klass, obj);
  post_allocation_install_obj_klass(klass, oop(obj));
D
duke 已提交
45 46 47
}

void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
48
                                                           HeapWord* objPtr) {
D
duke 已提交
49 50 51 52 53 54 55 56 57 58 59 60
  oop obj = (oop)objPtr;

  assert(obj != NULL, "NULL object pointer");
  if (UseBiasedLocking && (klass() != NULL)) {
    obj->set_mark(klass->prototype_header());
  } else {
    // May be bootstrapping
    obj->set_mark(markOopDesc::prototype());
  }
}

void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
61
                                                   oop obj) {
D
duke 已提交
62 63 64 65 66 67
  // These asserts are kind of complicated because of klassKlass
  // and the beginning of the world.
  assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass");
  assert(klass() == NULL || klass()->is_klass(), "not a klass");
  assert(obj != NULL, "NULL object pointer");
  obj->set_klass(klass());
68 69
  assert(!Universe::is_fully_initialized() || obj->klass() != NULL,
         "missing klass");
70
}
D
duke 已提交
71

72
// Support for jvmti and dtrace
73
inline void post_allocation_notify(KlassHandle klass, oop obj, int size) {
74 75 76
  // support low memory notifications (no-op if not enabled)
  LowMemoryDetector::detect_low_memory_for_collected_pools();

D
duke 已提交
77 78 79 80 81
  // support for JVMTI VMObjectAlloc event (no-op if not enabled)
  JvmtiExport::vm_object_alloc_event_collector(obj);

  if (DTraceAllocProbes) {
    // support for Dtrace object alloc event (no-op most of the time)
82
    if (klass() != NULL && klass()->name() != NULL) {
83
      SharedRuntime::dtrace_object_alloc(obj, size);
D
duke 已提交
84 85 86 87 88
    }
  }
}

void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
89 90
                                              HeapWord* obj,
                                              int size) {
91
  post_allocation_setup_common(klass, obj);
D
duke 已提交
92
  assert(Universe::is_bootstrapping() ||
93
         !((oop)obj)->is_array(), "must not be an array");
94
  // notify jvmti and dtrace
95
  post_allocation_notify(klass, (oop)obj, size);
D
duke 已提交
96 97 98 99 100
}

void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
                                                HeapWord* obj,
                                                int length) {
101 102 103
  // Set array length before setting the _klass field
  // in post_allocation_setup_common() because the klass field
  // indicates that the object is parsable by concurrent GC.
D
duke 已提交
104
  assert(length >= 0, "length should be non-negative");
105
  ((arrayOop)obj)->set_length(length);
106
  post_allocation_setup_common(klass, obj);
107 108
  oop new_obj = (oop)obj;
  assert(new_obj->is_array(), "must be an array");
109
  // notify jvmti and dtrace (must be after length is set for dtrace)
110
  post_allocation_notify(klass, new_obj, new_obj->size());
D
duke 已提交
111 112
}

S
sla 已提交
113
HeapWord* CollectedHeap::common_mem_allocate_noinit(KlassHandle klass, size_t size, TRAPS) {
D
duke 已提交
114 115 116 117 118 119 120 121 122 123 124 125

  // Clear unhandled oops for memory allocation.  Memory allocation might
  // not take out a lock if from tlab, so clear here.
  CHECK_UNHANDLED_OOPS_ONLY(THREAD->clear_unhandled_oops();)

  if (HAS_PENDING_EXCEPTION) {
    NOT_PRODUCT(guarantee(false, "Should not allocate with exception pending"));
    return NULL;  // caller does a CHECK_0 too
  }

  HeapWord* result = NULL;
  if (UseTLAB) {
S
sla 已提交
126
    result = allocate_from_tlab(klass, THREAD, size);
D
duke 已提交
127 128 129 130 131 132
    if (result != NULL) {
      assert(!HAS_PENDING_EXCEPTION,
             "Unexpected exception, will result in uninitialized storage");
      return result;
    }
  }
133
  bool gc_overhead_limit_was_exceeded = false;
D
duke 已提交
134 135 136 137 138 139 140
  result = Universe::heap()->mem_allocate(size,
                                          &gc_overhead_limit_was_exceeded);
  if (result != NULL) {
    NOT_PRODUCT(Universe::heap()->
      check_for_non_bad_heap_word_value(result, size));
    assert(!HAS_PENDING_EXCEPTION,
           "Unexpected exception, will result in uninitialized storage");
141
    THREAD->incr_allocated_bytes(size * HeapWordSize);
S
sla 已提交
142 143 144

    AllocTracer::send_allocation_outside_tlab_event(klass, size * HeapWordSize);

D
duke 已提交
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
    return result;
  }


  if (!gc_overhead_limit_was_exceeded) {
    // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
    report_java_out_of_memory("Java heap space");

    if (JvmtiExport::should_post_resource_exhausted()) {
      JvmtiExport::post_resource_exhausted(
        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
        "Java heap space");
    }

    THROW_OOP_0(Universe::out_of_memory_error_java_heap());
  } else {
    // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
    report_java_out_of_memory("GC overhead limit exceeded");

    if (JvmtiExport::should_post_resource_exhausted()) {
      JvmtiExport::post_resource_exhausted(
        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
        "GC overhead limit exceeded");
    }

    THROW_OOP_0(Universe::out_of_memory_error_gc_overhead_limit());
  }
}

S
sla 已提交
174 175
HeapWord* CollectedHeap::common_mem_allocate_init(KlassHandle klass, size_t size, TRAPS) {
  HeapWord* obj = common_mem_allocate_noinit(klass, size, CHECK_NULL);
D
duke 已提交
176 177 178 179
  init_obj(obj, size);
  return obj;
}

S
sla 已提交
180
HeapWord* CollectedHeap::allocate_from_tlab(KlassHandle klass, Thread* thread, size_t size) {
D
duke 已提交
181 182 183 184 185 186 187
  assert(UseTLAB, "should use UseTLAB");

  HeapWord* obj = thread->tlab().allocate(size);
  if (obj != NULL) {
    return obj;
  }
  // Otherwise...
S
sla 已提交
188
  return allocate_from_tlab_slow(klass, thread, size);
D
duke 已提交
189 190 191 192 193 194
}

void CollectedHeap::init_obj(HeapWord* obj, size_t size) {
  assert(obj != NULL, "cannot initialize NULL object");
  const size_t hs = oopDesc::header_size();
  assert(size >= hs, "unexpected object size");
195
  ((oop)obj)->set_klass_gap(0);
D
duke 已提交
196 197 198 199 200 201 202
  Copy::fill_to_aligned_words(obj + hs, size - hs);
}

oop CollectedHeap::obj_allocate(KlassHandle klass, int size, TRAPS) {
  debug_only(check_for_valid_allocation_state());
  assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
  assert(size >= 0, "int won't convert to size_t");
S
sla 已提交
203
  HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL);
204
  post_allocation_setup_obj(klass, obj, size);
D
duke 已提交
205 206 207 208 209 210 211 212 213 214 215
  NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
  return (oop)obj;
}

oop CollectedHeap::array_allocate(KlassHandle klass,
                                  int size,
                                  int length,
                                  TRAPS) {
  debug_only(check_for_valid_allocation_state());
  assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
  assert(size >= 0, "int won't convert to size_t");
S
sla 已提交
216
  HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL);
217
  post_allocation_setup_array(klass, obj, length);
D
duke 已提交
218 219 220 221
  NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
  return (oop)obj;
}

222 223 224 225 226 227 228
oop CollectedHeap::array_allocate_nozero(KlassHandle klass,
                                         int size,
                                         int length,
                                         TRAPS) {
  debug_only(check_for_valid_allocation_state());
  assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
  assert(size >= 0, "int won't convert to size_t");
S
sla 已提交
229
  HeapWord* obj = common_mem_allocate_noinit(klass, size, CHECK_NULL);
230
  ((oop)obj)->set_klass_gap(0);
231
  post_allocation_setup_array(klass, obj, length);
232 233 234 235 236 237 238
#ifndef PRODUCT
  const size_t hs = oopDesc::header_size()+1;
  Universe::heap()->check_for_non_bad_heap_word_value(obj+hs, size-hs);
#endif
  return (oop)obj;
}

239 240 241 242
inline void CollectedHeap::oop_iterate_no_header(OopClosure* cl) {
  NoHeaderExtendedOopClosure no_header_cl(cl);
  oop_iterate(&no_header_cl);
}
D
duke 已提交
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277

#ifndef PRODUCT

inline bool
CollectedHeap::promotion_should_fail(volatile size_t* count) {
  // Access to count is not atomic; the value does not have to be exact.
  if (PromotionFailureALot) {
    const size_t gc_num = total_collections();
    const size_t elapsed_gcs = gc_num - _promotion_failure_alot_gc_number;
    if (elapsed_gcs >= PromotionFailureALotInterval) {
      // Test for unsigned arithmetic wrap-around.
      if (++*count >= PromotionFailureALotCount) {
        *count = 0;
        return true;
      }
    }
  }
  return false;
}

inline bool CollectedHeap::promotion_should_fail() {
  return promotion_should_fail(&_promotion_failure_alot_count);
}

inline void CollectedHeap::reset_promotion_should_fail(volatile size_t* count) {
  if (PromotionFailureALot) {
    _promotion_failure_alot_gc_number = total_collections();
    *count = 0;
  }
}

inline void CollectedHeap::reset_promotion_should_fail() {
  reset_promotion_should_fail(&_promotion_failure_alot_count);
}
#endif  // #ifndef PRODUCT
278 279

#endif // SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP