annotate src/hotspot/share/gc/z/zUnload.cpp @ 53894:bf1133e7dfba

8219469: ZGC: Extract functions out from ZNMethodTable into new ZNMethod class Reviewed-by: pliden
author stefank
date Thu, 21 Feb 2019 14:24:44 +0100
parents 9a8585f60c32
children a590b6107ab3
rev   line source
eosterlund@52939 1 /*
eosterlund@52939 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
eosterlund@52939 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
eosterlund@52939 4 *
eosterlund@52939 5 * This code is free software; you can redistribute it and/or modify it
eosterlund@52939 6 * under the terms of the GNU General Public License version 2 only, as
eosterlund@52939 7 * published by the Free Software Foundation.
eosterlund@52939 8 *
eosterlund@52939 9 * This code is distributed in the hope that it will be useful, but WITHOUT
eosterlund@52939 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
eosterlund@52939 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
eosterlund@52939 12 * version 2 for more details (a copy is included in the LICENSE file that
eosterlund@52939 13 * accompanied this code).
eosterlund@52939 14 *
eosterlund@52939 15 * You should have received a copy of the GNU General Public License version
eosterlund@52939 16 * 2 along with this work; if not, write to the Free Software Foundation,
eosterlund@52939 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
eosterlund@52939 18 *
eosterlund@52939 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
eosterlund@52939 20 * or visit www.oracle.com if you need additional information or have any
eosterlund@52939 21 * questions.
eosterlund@52939 22 */
eosterlund@52939 23
eosterlund@52939 24 #include "precompiled.hpp"
eosterlund@52939 25 #include "classfile/classLoaderDataGraph.hpp"
eosterlund@52939 26 #include "classfile/systemDictionary.hpp"
eosterlund@52939 27 #include "code/codeBehaviours.hpp"
eosterlund@52939 28 #include "code/codeCache.hpp"
eosterlund@52939 29 #include "code/dependencyContext.hpp"
eosterlund@52939 30 #include "gc/shared/gcBehaviours.hpp"
eosterlund@52939 31 #include "gc/shared/suspendibleThreadSet.hpp"
eosterlund@52939 32 #include "gc/z/zLock.inline.hpp"
stefank@53894 33 #include "gc/z/zNMethod.hpp"
eosterlund@52939 34 #include "gc/z/zOopClosures.hpp"
eosterlund@52939 35 #include "gc/z/zStat.hpp"
eosterlund@52939 36 #include "gc/z/zUnload.hpp"
eosterlund@52939 37 #include "oops/access.inline.hpp"
eosterlund@52939 38
eosterlund@52939 39 static const ZStatSubPhase ZSubPhaseConcurrentClassesUnload("Concurrent Classes Unload");
eosterlund@52939 40
eosterlund@52939 41 class ZIsUnloadingOopClosure : public OopClosure {
eosterlund@52939 42 private:
eosterlund@52939 43 ZPhantomIsAliveObjectClosure _is_alive;
eosterlund@52939 44 bool _is_unloading;
eosterlund@52939 45
eosterlund@52939 46 public:
eosterlund@52939 47 ZIsUnloadingOopClosure() :
eosterlund@52939 48 _is_alive(),
eosterlund@52939 49 _is_unloading(false) {}
eosterlund@52939 50
eosterlund@52939 51 virtual void do_oop(oop* p) {
eosterlund@52939 52 const oop o = RawAccess<>::oop_load(p);
eosterlund@52939 53 if (o != NULL && !_is_alive.do_object_b(o)) {
eosterlund@52939 54 _is_unloading = true;
eosterlund@52939 55 }
eosterlund@52939 56 }
eosterlund@52939 57
eosterlund@52939 58 virtual void do_oop(narrowOop* p) {
eosterlund@52939 59 ShouldNotReachHere();
eosterlund@52939 60 }
eosterlund@52939 61
eosterlund@52939 62 bool is_unloading() const {
eosterlund@52939 63 return _is_unloading;
eosterlund@52939 64 }
eosterlund@52939 65 };
eosterlund@52939 66
eosterlund@52939 67 class ZIsUnloadingBehaviour : public IsUnloadingBehaviour {
eosterlund@52939 68 private:
eosterlund@52939 69 bool is_unloading(nmethod* nm) const {
eosterlund@52939 70 ZIsUnloadingOopClosure cl;
eosterlund@52939 71 nm->oops_do(&cl, true /* allow_zombie */);
eosterlund@52939 72 return cl.is_unloading();
eosterlund@52939 73 }
eosterlund@52939 74
eosterlund@52939 75 public:
eosterlund@52939 76 virtual bool is_unloading(CompiledMethod* method) const {
eosterlund@52939 77 nmethod* const nm = method->as_nmethod();
stefank@53894 78 ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm);
eosterlund@52939 79 if (lock == NULL) {
eosterlund@52939 80 return is_unloading(nm);
eosterlund@52939 81 } else {
eosterlund@52939 82 ZLocker<ZReentrantLock> locker(lock);
eosterlund@52939 83 return is_unloading(nm);
eosterlund@52939 84 }
eosterlund@52939 85 }
eosterlund@52939 86 };
eosterlund@52939 87
eosterlund@52939 88 class ZCompiledICProtectionBehaviour : public CompiledICProtectionBehaviour {
eosterlund@52939 89 public:
eosterlund@52939 90 virtual bool lock(CompiledMethod* method) {
eosterlund@52939 91 nmethod* const nm = method->as_nmethod();
stefank@53894 92 ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm);
eosterlund@52939 93 if (lock != NULL) {
eosterlund@52939 94 lock->lock();
eosterlund@52939 95 }
eosterlund@52939 96 return true;
eosterlund@52939 97 }
eosterlund@52939 98
eosterlund@52939 99 virtual void unlock(CompiledMethod* method) {
eosterlund@52939 100 nmethod* const nm = method->as_nmethod();
stefank@53894 101 ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm);
eosterlund@52939 102 if (lock != NULL) {
eosterlund@52939 103 lock->unlock();
eosterlund@52939 104 }
eosterlund@52939 105 }
eosterlund@52939 106
eosterlund@52939 107 virtual bool is_safe(CompiledMethod* method) {
eosterlund@52939 108 if (SafepointSynchronize::is_at_safepoint()) {
eosterlund@52939 109 return true;
eosterlund@52939 110 }
eosterlund@52939 111
eosterlund@52939 112 nmethod* const nm = method->as_nmethod();
stefank@53894 113 ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm);
eosterlund@52939 114 return lock == NULL || lock->is_owned();
eosterlund@52939 115 }
eosterlund@52939 116 };
eosterlund@52939 117
eosterlund@52939 118 ZUnload::ZUnload(ZWorkers* workers) :
eosterlund@52939 119 _workers(workers) {
eosterlund@52939 120
eosterlund@52939 121 if (!ClassUnloading) {
eosterlund@52939 122 return;
eosterlund@52939 123 }
eosterlund@52939 124
eosterlund@52939 125 static ZIsUnloadingBehaviour is_unloading_behaviour;
eosterlund@52939 126 IsUnloadingBehaviour::set_current(&is_unloading_behaviour);
eosterlund@52939 127
eosterlund@52939 128 static ZCompiledICProtectionBehaviour ic_protection_behaviour;
eosterlund@52939 129 CompiledICProtectionBehaviour::set_current(&ic_protection_behaviour);
eosterlund@52939 130 }
eosterlund@52939 131
eosterlund@52939 132 void ZUnload::prepare() {
eosterlund@52939 133 if (!ClassUnloading) {
eosterlund@52939 134 return;
eosterlund@52939 135 }
eosterlund@52939 136
eosterlund@52939 137 CodeCache::increment_unloading_cycle();
eosterlund@52939 138 DependencyContext::cleaning_start();
eosterlund@52939 139 }
eosterlund@52939 140
eosterlund@52939 141 void ZUnload::unlink() {
eosterlund@52939 142 SuspendibleThreadSetJoiner sts;
eosterlund@52939 143 bool unloading_occurred;
eosterlund@52939 144
eosterlund@52939 145 {
eosterlund@52939 146 MutexLockerEx ml(ClassLoaderDataGraph_lock);
eosterlund@52939 147 unloading_occurred = SystemDictionary::do_unloading(ZStatPhase::timer());
eosterlund@52939 148 }
eosterlund@52939 149
eosterlund@52939 150 Klass::clean_weak_klass_links(unloading_occurred);
eosterlund@52939 151
stefank@53894 152 ZNMethod::unlink(_workers, unloading_occurred);
eosterlund@52939 153
eosterlund@52939 154 DependencyContext::cleaning_end();
eosterlund@52939 155 }
eosterlund@52939 156
eosterlund@52939 157 void ZUnload::purge() {
eosterlund@52939 158 {
eosterlund@52939 159 SuspendibleThreadSetJoiner sts;
stefank@53894 160 ZNMethod::purge(_workers);
eosterlund@52939 161 }
eosterlund@52939 162
eosterlund@52939 163 ClassLoaderDataGraph::purge();
eosterlund@52939 164 CodeCache::purge_exception_caches();
eosterlund@52939 165 }
eosterlund@52939 166
eosterlund@52939 167 class ZUnloadRendezvousClosure : public ThreadClosure {
eosterlund@52939 168 public:
eosterlund@52939 169 void do_thread(Thread* thread) {}
eosterlund@52939 170 };
eosterlund@52939 171
eosterlund@52939 172 void ZUnload::unload() {
eosterlund@52939 173 if (!ClassUnloading) {
eosterlund@52939 174 return;
eosterlund@52939 175 }
eosterlund@52939 176
eosterlund@52939 177 ZStatTimer timer(ZSubPhaseConcurrentClassesUnload);
eosterlund@52939 178
eosterlund@52939 179 // Unlink stale metadata and nmethods
eosterlund@52939 180 unlink();
eosterlund@52939 181
eosterlund@52939 182 // Make sure stale metadata and nmethods are no longer observable
eosterlund@52939 183 ZUnloadRendezvousClosure cl;
eosterlund@52939 184 Handshake::execute(&cl);
eosterlund@52939 185
eosterlund@52939 186 // Purge stale metadata and nmethods that were unlinked
eosterlund@52939 187 purge();
eosterlund@52939 188 }
eosterlund@52939 189
eosterlund@52939 190 void ZUnload::finish() {
eosterlund@52939 191 // Resize and verify metaspace
eosterlund@52939 192 MetaspaceGC::compute_new_size();
eosterlund@52939 193 MetaspaceUtils::verify_metrics();
eosterlund@52939 194 }