index

src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp

Print this page
rev 8024 : imported patch event1
* * *
imported patch event2


 244 // and the rest will not be executed. For that reason, this method loops
 245 // during failed allocation attempts. If the java heap becomes exhausted,
 246 // we rely on the size_policy object to force a bail out.
 247 HeapWord* ParallelScavengeHeap::mem_allocate(
 248                                      size_t size,
 249                                      bool* gc_overhead_limit_was_exceeded) {
 250   assert(!SafepointSynchronize::is_at_safepoint(), "should not be at safepoint");
 251   assert(Thread::current() != (Thread*)VMThread::vm_thread(), "should not be in vm thread");
 252   assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock");
 253 
 254   // In general gc_overhead_limit_was_exceeded should be false so
 255   // set it so here and reset it to true only if the gc time
 256   // limit is being exceeded as checked below.
 257   *gc_overhead_limit_was_exceeded = false;
 258 
 259   HeapWord* result = young_gen()->allocate(size);
 260 
 261   uint loop_count = 0;
 262   uint gc_count = 0;
 263   uint gclocker_stalled_count = 0;

 264 
 265   while (result == NULL) {
 266     // We don't want to have multiple collections for a single filled generation.
 267     // To prevent this, each thread tracks the total_collections() value, and if
 268     // the count has changed, does not do a new collection.
 269     //
 270     // The collection count must be read only while holding the heap lock. VM
 271     // operations also hold the heap lock during collections. There is a lock
 272     // contention case where thread A blocks waiting on the Heap_lock, while
 273     // thread B is holding it doing a collection. When thread A gets the lock,
 274     // the collection count has already changed. To prevent duplicate collections,
 275     // The policy MUST attempt allocations during the same period it reads the
 276     // total_collections() value!
 277     {
 278       MutexLocker ml(Heap_lock);
 279       gc_count = Universe::heap()->total_collections();
 280 
 281       result = young_gen()->allocate(size);
 282       if (result != NULL) {
 283         return result;


 302         // we retry the allocation sequence from the beginning of the loop,
 303         // rather than causing more, now probably unnecessary, GC attempts.
 304         JavaThread* jthr = JavaThread::current();
 305         if (!jthr->in_critical()) {
 306           MutexUnlocker mul(Heap_lock);
 307           GC_locker::stall_until_clear();
 308           gclocker_stalled_count += 1;
 309           continue;
 310         } else {
 311           if (CheckJNICalls) {
 312             fatal("Possible deadlock due to allocating while"
 313                   " in jni critical section");
 314           }
 315           return NULL;
 316         }
 317       }
 318     }
 319 
 320     if (result == NULL) {
 321       // Generate a VM operation
 322       VM_ParallelGCFailedAllocation op(size, gc_count);
 323       VMThread::execute(&op);
 324 
 325       // Did the VM operation execute? If so, return the result directly.
 326       // This prevents us from looping until time out on requests that can
 327       // not be satisfied.
 328       if (op.prologue_succeeded()) {
 329         assert(Universe::heap()->is_in_or_null(op.result()),
 330           "result not in heap");
 331 
 332         // If GC was locked out during VM operation then retry allocation
 333         // and/or stall as necessary.
 334         if (op.gc_locked()) {
 335           assert(op.result() == NULL, "must be NULL if gc_locked() is true");
 336           continue;  // retry and/or stall as necessary
 337         }
 338 
 339         // Exit the loop if the gc time limit has been exceeded.
 340         // The allocation must have failed above ("result" guarding
 341         // this path is NULL) and the most recent collection has exceeded the
 342         // gc overhead limit (although enough may have been collected to




 244 // and the rest will not be executed. For that reason, this method loops
 245 // during failed allocation attempts. If the java heap becomes exhausted,
 246 // we rely on the size_policy object to force a bail out.
 247 HeapWord* ParallelScavengeHeap::mem_allocate(
 248                                      size_t size,
 249                                      bool* gc_overhead_limit_was_exceeded) {
 250   assert(!SafepointSynchronize::is_at_safepoint(), "should not be at safepoint");
 251   assert(Thread::current() != (Thread*)VMThread::vm_thread(), "should not be in vm thread");
 252   assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock");
 253 
 254   // In general gc_overhead_limit_was_exceeded should be false so
 255   // set it so here and reset it to true only if the gc time
 256   // limit is being exceeded as checked below.
 257   *gc_overhead_limit_was_exceeded = false;
 258 
 259   HeapWord* result = young_gen()->allocate(size);
 260 
 261   uint loop_count = 0;
 262   uint gc_count = 0;
 263   uint gclocker_stalled_count = 0;
 264   uint gc_attempt = 1;
 265 
 266   while (result == NULL) {
 267     // We don't want to have multiple collections for a single filled generation.
 268     // To prevent this, each thread tracks the total_collections() value, and if
 269     // the count has changed, does not do a new collection.
 270     //
 271     // The collection count must be read only while holding the heap lock. VM
 272     // operations also hold the heap lock during collections. There is a lock
 273     // contention case where thread A blocks waiting on the Heap_lock, while
 274     // thread B is holding it doing a collection. When thread A gets the lock,
 275     // the collection count has already changed. To prevent duplicate collections,
 276     // The policy MUST attempt allocations during the same period it reads the
 277     // total_collections() value!
 278     {
 279       MutexLocker ml(Heap_lock);
 280       gc_count = Universe::heap()->total_collections();
 281 
 282       result = young_gen()->allocate(size);
 283       if (result != NULL) {
 284         return result;


 303         // we retry the allocation sequence from the beginning of the loop,
 304         // rather than causing more, now probably unnecessary, GC attempts.
 305         JavaThread* jthr = JavaThread::current();
 306         if (!jthr->in_critical()) {
 307           MutexUnlocker mul(Heap_lock);
 308           GC_locker::stall_until_clear();
 309           gclocker_stalled_count += 1;
 310           continue;
 311         } else {
 312           if (CheckJNICalls) {
 313             fatal("Possible deadlock due to allocating while"
 314                   " in jni critical section");
 315           }
 316           return NULL;
 317         }
 318       }
 319     }
 320 
 321     if (result == NULL) {
 322       // Generate a VM operation
 323       VM_ParallelGCFailedAllocation op(size, gc_count, gc_attempt++);
 324       VMThread::execute(&op);
 325 
 326       // Did the VM operation execute? If so, return the result directly.
 327       // This prevents us from looping until time out on requests that can
 328       // not be satisfied.
 329       if (op.prologue_succeeded()) {
 330         assert(Universe::heap()->is_in_or_null(op.result()),
 331           "result not in heap");
 332 
 333         // If GC was locked out during VM operation then retry allocation
 334         // and/or stall as necessary.
 335         if (op.gc_locked()) {
 336           assert(op.result() == NULL, "must be NULL if gc_locked() is true");
 337           continue;  // retry and/or stall as necessary
 338         }
 339 
 340         // Exit the loop if the gc time limit has been exceeded.
 341         // The allocation must have failed above ("result" guarding
 342         // this path is NULL) and the most recent collection has exceeded the
 343         // gc overhead limit (although enough may have been collected to


index