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 |