1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/symbolTable.hpp" 27 #include "classfile/stringTable.hpp" 28 #include "code/codeCache.hpp" 29 #include "gc/shared/parallelCleaning.hpp" 30 #include "logging/log.hpp" 31 #include "memory/resourceArea.hpp" 32 #include "logging/log.hpp" 33 34 StringCleaningTask::StringCleaningTask(BoolObjectClosure* is_alive, StringDedupUnlinkOrOopsDoClosure* dedup_closure, bool process_strings) : 35 AbstractGangTask("String Unlinking"), 36 _is_alive(is_alive), 37 _dedup_closure(dedup_closure), 38 _par_state_string(StringTable::weak_storage()), 39 _initial_string_table_size((int) StringTable::the_table()->table_size()), 40 _process_strings(process_strings), _strings_processed(0), _strings_removed(0) { 41 42 if (process_strings) { 43 StringTable::reset_dead_counter(); 44 } 45 } 46 47 StringCleaningTask::~StringCleaningTask() { 48 log_info(gc, stringtable)( 49 "Cleaned string table, " 50 "strings: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed", 51 strings_processed(), strings_removed()); 52 if (_process_strings) { 53 StringTable::finish_dead_counter(); 54 } 55 } 56 57 void StringCleaningTask::work(uint worker_id) { 58 size_t strings_processed = 0; 59 size_t strings_removed = 0; 60 if (_process_strings) { 61 StringTable::possibly_parallel_unlink(&_par_state_string, _is_alive, &strings_processed, &strings_removed); 62 Atomic::add(strings_processed, &_strings_processed); 63 Atomic::add(strings_removed, &_strings_removed); 64 } 65 if (_dedup_closure != NULL) { 66 StringDedup::parallel_unlink(_dedup_closure, worker_id); 67 } 68 } 69 70 CodeCacheUnloadingTask::CodeCacheUnloadingTask(uint num_workers, BoolObjectClosure* is_alive, bool unloading_occurred) : 71 _unloading_scope(is_alive), 72 _unloading_occurred(unloading_occurred), 73 _num_workers(num_workers), 74 _first_nmethod(NULL), 75 _claimed_nmethod(NULL) { 76 // Get first alive nmethod 77 CompiledMethodIterator iter = CompiledMethodIterator(); 78 if(iter.next_alive()) { 79 _first_nmethod = iter.method(); 80 } 81 _claimed_nmethod = _first_nmethod; 82 } 83 84 CodeCacheUnloadingTask::~CodeCacheUnloadingTask() { 85 CodeCache::verify_clean_inline_caches(); 86 87 guarantee(CodeCache::scavenge_root_nmethods() == NULL, "Must be"); 88 89 CodeCache::verify_icholder_relocations(); 90 } 91 92 Monitor* CodeCacheUnloadingTask::_lock = new Monitor(Mutex::leaf, "Code Cache Unload lock", false, Monitor::_safepoint_check_never); 93 94 void CodeCacheUnloadingTask::claim_nmethods(CompiledMethod** claimed_nmethods, int *num_claimed_nmethods) { 95 CompiledMethod* first; 96 CompiledMethodIterator last; 97 98 do { 99 *num_claimed_nmethods = 0; 100 101 first = _claimed_nmethod; 102 last = CompiledMethodIterator(first); 103 104 if (first != NULL) { 105 106 for (int i = 0; i < MaxClaimNmethods; i++) { 107 if (!last.next_alive()) { 108 break; 109 } 110 claimed_nmethods[i] = last.method(); 111 (*num_claimed_nmethods)++; 112 } 113 } 114 115 } while (Atomic::cmpxchg(last.method(), &_claimed_nmethod, first) != first); 116 } 117 118 void CodeCacheUnloadingTask::work(uint worker_id) { 119 // The first nmethods is claimed by the first worker. 120 if (worker_id == 0 && _first_nmethod != NULL) { 121 _first_nmethod->do_unloading(_unloading_occurred); 122 _first_nmethod = NULL; 123 } 124 125 int num_claimed_nmethods; 126 CompiledMethod* claimed_nmethods[MaxClaimNmethods]; 127 128 while (true) { 129 claim_nmethods(claimed_nmethods, &num_claimed_nmethods); 130 131 if (num_claimed_nmethods == 0) { 132 break; 133 } 134 135 for (int i = 0; i < num_claimed_nmethods; i++) { 136 claimed_nmethods[i]->do_unloading(_unloading_occurred); 137 } 138 } 139 } 140 141 KlassCleaningTask::KlassCleaningTask() : 142 _clean_klass_tree_claimed(0), 143 _klass_iterator() { 144 } 145 146 bool KlassCleaningTask::claim_clean_klass_tree_task() { 147 if (_clean_klass_tree_claimed) { 148 return false; 149 } 150 151 return Atomic::cmpxchg(1, &_clean_klass_tree_claimed, 0) == 0; 152 } 153 154 InstanceKlass* KlassCleaningTask::claim_next_klass() { 155 Klass* klass; 156 do { 157 klass =_klass_iterator.next_klass(); 158 } while (klass != NULL && !klass->is_instance_klass()); 159 160 // this can be null so don't call InstanceKlass::cast 161 return static_cast<InstanceKlass*>(klass); 162 } 163 164 void KlassCleaningTask::work() { 165 ResourceMark rm; 166 167 // One worker will clean the subklass/sibling klass tree. 168 if (claim_clean_klass_tree_task()) { 169 Klass::clean_subklass_tree(); 170 } 171 172 // All workers will help cleaning the classes, 173 InstanceKlass* klass; 174 while ((klass = claim_next_klass()) != NULL) { 175 clean_klass(klass); 176 } 177 } 178 179 ParallelCleaningTask::ParallelCleaningTask(BoolObjectClosure* is_alive, 180 StringDedupUnlinkOrOopsDoClosure* dedup_closure, uint num_workers, bool unloading_occurred) : 181 AbstractGangTask("Parallel Cleaning"), 182 _unloading_occurred(unloading_occurred), 183 _string_task(is_alive, StringDedup::is_enabled() ? dedup_closure : NULL, true), 184 _code_cache_task(num_workers, is_alive, unloading_occurred), 185 _klass_cleaning_task() { 186 } 187 188 // The parallel work done by all worker threads. 189 void ParallelCleaningTask::work(uint worker_id) { 190 // Do first pass of code cache cleaning. 191 _code_cache_task.work(worker_id); 192 193 // Clean the Strings and Symbols. 194 _string_task.work(worker_id); 195 196 // Clean all klasses that were not unloaded. 197 // The weak metadata in klass doesn't need to be 198 // processed if there was no unloading. 199 if (_unloading_occurred) { 200 _klass_cleaning_task.work(); 201 } 202 }