hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
changeset 386 7f121b1192f2
parent 186 32e6c95f8d9b
child 971 f0b20be4165d
child 670 ddf3e9583f2f
equal deleted inserted replaced
342:c7bc1fed1d90 386:7f121b1192f2
   588       MutexLocker ml(Heap_lock);
   588       MutexLocker ml(Heap_lock);
   589       gc_count      = Universe::heap()->total_collections();
   589       gc_count      = Universe::heap()->total_collections();
   590       full_gc_count = Universe::heap()->total_full_collections();
   590       full_gc_count = Universe::heap()->total_full_collections();
   591 
   591 
   592       result = perm_gen()->allocate_permanent(size);
   592       result = perm_gen()->allocate_permanent(size);
       
   593 
       
   594       if (result != NULL) {
       
   595         return result;
       
   596       }
       
   597 
       
   598       if (GC_locker::is_active_and_needs_gc()) {
       
   599         // If this thread is not in a jni critical section, we stall
       
   600         // the requestor until the critical section has cleared and
       
   601         // GC allowed. When the critical section clears, a GC is
       
   602         // initiated by the last thread exiting the critical section; so
       
   603         // we retry the allocation sequence from the beginning of the loop,
       
   604         // rather than causing more, now probably unnecessary, GC attempts.
       
   605         JavaThread* jthr = JavaThread::current();
       
   606         if (!jthr->in_critical()) {
       
   607           MutexUnlocker mul(Heap_lock);
       
   608           GC_locker::stall_until_clear();
       
   609           continue;
       
   610         } else {
       
   611           if (CheckJNICalls) {
       
   612             fatal("Possible deadlock due to allocating while"
       
   613                   " in jni critical section");
       
   614           }
       
   615           return NULL;
       
   616         }
       
   617       }
   593     }
   618     }
   594 
   619 
   595     if (result == NULL) {
   620     if (result == NULL) {
   596 
   621 
   597       // Exit the loop if the gc time limit has been exceeded.
   622       // Exit the loop if the gc time limit has been exceeded.
   620       // This prevents us from looping until time out on requests that can
   645       // This prevents us from looping until time out on requests that can
   621       // not be satisfied.
   646       // not be satisfied.
   622       if (op.prologue_succeeded()) {
   647       if (op.prologue_succeeded()) {
   623         assert(Universe::heap()->is_in_permanent_or_null(op.result()),
   648         assert(Universe::heap()->is_in_permanent_or_null(op.result()),
   624           "result not in heap");
   649           "result not in heap");
       
   650         // If GC was locked out during VM operation then retry allocation
       
   651         // and/or stall as necessary.
       
   652         if (op.gc_locked()) {
       
   653           assert(op.result() == NULL, "must be NULL if gc_locked() is true");
       
   654           continue;  // retry and/or stall as necessary
       
   655         }
   625         // If a NULL results is being returned, an out-of-memory
   656         // If a NULL results is being returned, an out-of-memory
   626         // will be thrown now.  Clear the gc_time_limit_exceeded
   657         // will be thrown now.  Clear the gc_time_limit_exceeded
   627         // flag to avoid the following situation.
   658         // flag to avoid the following situation.
   628         //      gc_time_limit_exceeded is set during a collection
   659         //      gc_time_limit_exceeded is set during a collection
   629         //      the collection fails to return enough space and an OOM is thrown
   660         //      the collection fails to return enough space and an OOM is thrown