1 /* 2 * Copyright (c) 2017, 2019, 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/stringTable.hpp" 27 #include "gc/shared/oopStorage.inline.hpp" 28 #include "gc/shared/oopStorageParState.inline.hpp" 29 #include "gc/shared/weakProcessor.inline.hpp" 30 #include "gc/shared/weakProcessorPhases.hpp" 31 #include "gc/shared/weakProcessorPhaseTimes.hpp" 32 #include "memory/allocation.inline.hpp" 33 #include "memory/iterator.hpp" 34 #include "runtime/globals.hpp" 35 #include "utilities/macros.hpp" 36 37 void WeakProcessor::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive) { 38 StringTable::reset_dead_counter(); 39 FOR_EACH_WEAK_PROCESSOR_PHASE(phase) { 40 if (WeakProcessorPhases::is_serial(phase)) { 41 CountingIsAliveClosure<BoolObjectClosure> cl(is_alive); 42 WeakProcessorPhases::processor(phase)(&cl, keep_alive); 43 } else { 44 CountingSkippedIsAliveClosure<BoolObjectClosure, OopClosure> cl(is_alive, keep_alive); 45 WeakProcessorPhases::oop_storage(phase)->oops_do(&cl); 46 if (WeakProcessorPhases::is_stringtable(phase)) { 47 StringTable::inc_dead_counter(cl.num_dead() + cl.num_skipped()); 48 } 49 } 50 } 51 StringTable::finish_dead_counter(); 52 } 53 54 void WeakProcessor::oops_do(OopClosure* closure) { 55 AlwaysTrueClosure always_true; 56 weak_oops_do(&always_true, closure); 57 } 58 59 uint WeakProcessor::ergo_workers(uint max_workers) { 60 // Ignore ParallelRefProcEnabled; that's for j.l.r.Reference processing. 61 if (ReferencesPerThread == 0) { 62 // Configuration says always use all the threads. 63 return max_workers; 64 } 65 66 // One thread per ReferencesPerThread references (or fraction thereof) 67 // in the various OopStorage objects, bounded by max_threads. 68 // 69 // Serial phases are ignored in this calculation, because of the 70 // cost of running unnecessary threads. These phases are normally 71 // small or empty (assuming they are configured to exist at all), 72 // and development oriented, so not allocating any threads 73 // specifically for them is okay. 74 size_t ref_count = 0; 75 FOR_EACH_WEAK_PROCESSOR_OOP_STORAGE_PHASE(phase) { 76 ref_count += WeakProcessorPhases::oop_storage(phase)->allocation_count(); 77 } 78 79 // +1 to (approx) round up the ref per thread division. 80 size_t nworkers = 1 + (ref_count / ReferencesPerThread); 81 nworkers = MIN2(nworkers, static_cast<size_t>(max_workers)); 82 return static_cast<uint>(nworkers); 83 } 84 85 void WeakProcessor::Task::initialize() { 86 assert(_nworkers != 0, "must be"); 87 assert(_phase_times == NULL || _nworkers <= _phase_times->max_threads(), 88 "nworkers (%u) exceeds max threads (%u)", 89 _nworkers, _phase_times->max_threads()); 90 91 if (_phase_times) { 92 _phase_times->set_active_workers(_nworkers); 93 } 94 95 uint storage_count = WeakProcessorPhases::oop_storage_phase_count; 96 _storage_states = NEW_C_HEAP_ARRAY(StorageState, storage_count, mtGC); 97 98 StorageState* states = _storage_states; 99 FOR_EACH_WEAK_PROCESSOR_OOP_STORAGE_PHASE(phase) { 100 OopStorage* storage = WeakProcessorPhases::oop_storage(phase); 101 new (states++) StorageState(storage, _nworkers); 102 } 103 StringTable::reset_dead_counter(); 104 } 105 106 WeakProcessor::Task::Task(uint nworkers) : 107 _phase_times(NULL), 108 _nworkers(nworkers), 109 _serial_phases_done(WeakProcessorPhases::serial_phase_count), 110 _storage_states(NULL) 111 { 112 initialize(); 113 } 114 115 WeakProcessor::Task::Task(WeakProcessorPhaseTimes* phase_times, uint nworkers) : 116 _phase_times(phase_times), 117 _nworkers(nworkers), 118 _serial_phases_done(WeakProcessorPhases::serial_phase_count), 119 _storage_states(NULL) 120 { 121 initialize(); 122 } 123 124 WeakProcessor::Task::~Task() { 125 if (_storage_states != NULL) { 126 StorageState* states = _storage_states; 127 FOR_EACH_WEAK_PROCESSOR_OOP_STORAGE_PHASE(phase) { 128 states->StorageState::~StorageState(); 129 ++states; 130 } 131 FREE_C_HEAP_ARRAY(StorageState, _storage_states); 132 } 133 StringTable::finish_dead_counter(); 134 } 135 136 void WeakProcessor::GangTask::work(uint worker_id) { 137 _erased_do_work(this, worker_id); 138 }