Mercurial > hg > truffle
diff src/share/vm/gc_implementation/shared/vmGCOperations.cpp @ 6948:e522a00b91aa
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/ after NPG - C++ build works
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 12 Nov 2012 23:14:12 +0100 |
parents | 097d78aaf2b5 |
children | 16fb9f942703 db9981fd3124 |
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Mon Nov 12 18:11:17 2012 +0100 +++ b/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Mon Nov 12 23:14:12 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,13 +70,13 @@ void VM_GC_Operation::acquire_pending_list_lock() { // we may enter this with pending exception set - instanceRefKlass::acquire_pending_list_lock(&_pending_list_basic_lock); + InstanceRefKlass::acquire_pending_list_lock(&_pending_list_basic_lock); } void VM_GC_Operation::release_and_notify_pending_list_lock() { - instanceRefKlass::release_and_notify_pending_list_lock(&_pending_list_basic_lock); + InstanceRefKlass::release_and_notify_pending_list_lock(&_pending_list_basic_lock); } // Allocations may fail in several threads at about the same time, @@ -192,31 +192,55 @@ gch->do_full_collection(gch->must_clear_all_soft_refs(), _max_level); } -void VM_GenCollectForPermanentAllocation::doit() { +void VM_CollectForMetadataAllocation::doit() { SvcGCMarker sgcm(SvcGCMarker::FULL); - SharedHeap* heap = (SharedHeap*)Universe::heap(); + CollectedHeap* heap = Universe::heap(); GCCauseSetter gccs(heap, _gc_cause); - switch (heap->kind()) { - case (CollectedHeap::GenCollectedHeap): { - GenCollectedHeap* gch = (GenCollectedHeap*)heap; - gch->do_full_collection(gch->must_clear_all_soft_refs(), - gch->n_gens() - 1); - break; + + // Check again if the space is available. Another thread + // may have similarly failed a metadata allocation and induced + // a GC that freed space for the allocation. + if (!MetadataAllocationFailALot) { + _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype); + } + + if (_result == NULL) { + if (UseConcMarkSweepGC) { + if (CMSClassUnloadingEnabled) { + MetaspaceGC::set_should_concurrent_collect(true); + } + // For CMS expand since the collection is going to be concurrent. + _result = + _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype); } -#ifndef SERIALGC - case (CollectedHeap::G1CollectedHeap): { - G1CollectedHeap* g1h = (G1CollectedHeap*)heap; - g1h->do_full_collection(_gc_cause == GCCause::_last_ditch_collection); - break; + if (_result == NULL) { + // Don't clear the soft refs. This GC is for reclaiming metadata + // and is unrelated to the fullness of the Java heap which should + // be the criteria for clearing SoftReferences. + if (Verbose && PrintGCDetails && UseConcMarkSweepGC) { + gclog_or_tty->print_cr("\nCMS full GC for Metaspace"); + } + heap->collect_as_vm_thread(GCCause::_metadata_GC_threshold); + _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype); } -#endif // SERIALGC - default: - ShouldNotReachHere(); + if (_result == NULL && !UseConcMarkSweepGC /* CMS already tried */) { + // If still failing, allow the Metaspace to expand. + // See delta_capacity_until_GC() for explanation of the + // amount of the expansion. + // This should work unless there really is no more space + // or a MaxMetaspaceSize has been specified on the command line. + _result = + _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype); + + } + if (Verbose && PrintGCDetails && _result == NULL) { + gclog_or_tty->print_cr("\nAfter Metaspace GC failed to allocate size " + SIZE_FORMAT, _size); + } } - _res = heap->perm_gen()->allocate(_size, false); - assert(heap->is_in_reserved_or_null(_res), "result not in heap"); - if (_res == NULL && GC_locker::is_active_and_needs_gc()) { + + if (_result == NULL && GC_locker::is_active_and_needs_gc()) { set_gc_locked(); } }