1.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Mon Nov 03 12:02:40 2014 -0800 1.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Oct 02 10:55:36 2014 +0200 1.3 @@ -23,6 +23,7 @@ 1.4 */ 1.5 1.6 #include "precompiled.hpp" 1.7 +#include "classfile/metadataOnStackMark.hpp" 1.8 #include "classfile/symbolTable.hpp" 1.9 #include "code/codeCache.hpp" 1.10 #include "gc_implementation/g1/concurrentMark.inline.hpp" 1.11 @@ -2602,17 +2603,27 @@ 1.12 G1RemarkGCTraceTime trace("Unloading", G1Log::finer()); 1.13 1.14 if (ClassUnloadingWithConcurrentMark) { 1.15 + // Cleaning of klasses depends on correct information from MetadataMarkOnStack. The CodeCache::mark_on_stack 1.16 + // part is too slow to be done serially, so it is handled during the weakRefsWorkParallelPart phase. 1.17 + // Defer the cleaning until we have complete on_stack data. 1.18 + MetadataOnStackMark md_on_stack(false /* Don't visit the code cache at this point */); 1.19 + 1.20 bool purged_classes; 1.21 1.22 { 1.23 G1RemarkGCTraceTime trace("System Dictionary Unloading", G1Log::finest()); 1.24 - purged_classes = SystemDictionary::do_unloading(&g1_is_alive); 1.25 + purged_classes = SystemDictionary::do_unloading(&g1_is_alive, false /* Defer klass cleaning */); 1.26 } 1.27 1.28 { 1.29 G1RemarkGCTraceTime trace("Parallel Unloading", G1Log::finest()); 1.30 weakRefsWorkParallelPart(&g1_is_alive, purged_classes); 1.31 } 1.32 + 1.33 + { 1.34 + G1RemarkGCTraceTime trace("Deallocate Metadata", G1Log::finest()); 1.35 + ClassLoaderDataGraph::free_deallocate_lists(); 1.36 + } 1.37 } 1.38 1.39 if (G1StringDedup::is_enabled()) {