1 /* 2 * Copyright (c) 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 "code/codeCache.hpp" 27 #include "code/nmethod.hpp" 28 #include "compiler/compileTask.hpp" 29 #include "gc/shared/collectedHeap.hpp" 30 #include "gc/shared/scavengableNMethods.hpp" 31 #include "gc/shared/scavengableNMethodsData.hpp" 32 #include "logging/log.hpp" 33 #include "logging/logStream.hpp" 34 #include "memory/universe.hpp" 35 #include "utilities/debug.hpp" 36 37 static ScavengableNMethodsData gc_data(nmethod* nm) { 38 return ScavengableNMethodsData(nm); 39 } 40 41 nmethod* ScavengableNMethods::_head = NULL; 42 BoolObjectClosure* ScavengableNMethods::_is_scavengable = NULL; 43 44 void ScavengableNMethods::initialize(BoolObjectClosure* is_scavengable) { 45 _is_scavengable = is_scavengable; 46 } 47 48 // Conditionally adds the nmethod to the list if it is 49 // not already on the list and has a scavengeable root. 50 void ScavengableNMethods::register_nmethod(nmethod* nm) { 51 assert_locked_or_safepoint(CodeCache_lock); 52 53 ScavengableNMethodsData data = gc_data(nm); 54 55 if (data.on_list() || !has_scavengable_oops(nm)) { 56 return; 57 } 58 59 data.set_on_list(); 60 data.set_next(_head); 61 62 _head = nm; 63 64 CodeCache::print_trace("register_nmethod", nm); 65 } 66 67 void ScavengableNMethods::unregister_nmethod(nmethod* nm) { 68 assert_locked_or_safepoint(CodeCache_lock); 69 70 if (gc_data(nm).on_list()) { 71 nmethod* prev = NULL; 72 for (nmethod* cur = _head; cur != NULL; cur = gc_data(cur).next()) { 73 if (cur == nm) { 74 CodeCache::print_trace("unregister_nmethod", nm); 75 unlist_nmethod(cur, prev); 76 return; 77 } 78 prev = cur; 79 } 80 } 81 } 82 83 #ifndef PRODUCT 84 85 class DebugScavengableOops: public OopClosure { 86 BoolObjectClosure* _is_scavengable; 87 nmethod* _nm; 88 bool _ok; 89 public: 90 DebugScavengableOops(BoolObjectClosure* is_scavengable, nmethod* nm) : 91 _is_scavengable(is_scavengable), 92 _nm(nm), 93 _ok(true) { } 94 95 bool ok() { return _ok; } 96 virtual void do_oop(oop* p) { 97 if (*p == NULL || !_is_scavengable->do_object_b(*p)) { 98 return; 99 } 100 101 if (_ok) { 102 _nm->print_nmethod(true); 103 _ok = false; 104 } 105 tty->print_cr("*** scavengable oop " PTR_FORMAT " found at " PTR_FORMAT " (offset %d)", 106 p2i(*p), p2i(p), (int)((intptr_t)p - (intptr_t)_nm)); 107 (*p)->print(); 108 } 109 virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } 110 }; 111 112 #endif // PRODUCT 113 114 void ScavengableNMethods::verify_nmethod(nmethod* nm) { 115 #ifndef PRODUCT 116 if (!gc_data(nm).on_list()) { 117 // Actually look inside, to verify the claim that it's clean. 118 DebugScavengableOops cl(_is_scavengable, nm); 119 nm->oops_do(&cl); 120 if (!cl.ok()) 121 fatal("found an unadvertised bad scavengable oop in the code cache"); 122 } 123 assert(gc_data(nm).not_marked(), ""); 124 #endif // PRODUCT 125 } 126 127 class HasScavengableOops: public OopClosure { 128 BoolObjectClosure* _is_scavengable; 129 bool _found; 130 nmethod* _print_nm; 131 public: 132 HasScavengableOops(BoolObjectClosure* is_scavengable, nmethod* nm) : 133 _is_scavengable(is_scavengable), 134 _found(false), 135 _print_nm(nm) {} 136 137 bool found() { return _found; } 138 virtual void do_oop(oop* p) { 139 if (*p != NULL && _is_scavengable->do_object_b(*p)) { 140 NOT_PRODUCT(maybe_print(p)); 141 _found = true; 142 } 143 } 144 virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } 145 146 #ifndef PRODUCT 147 void maybe_print(oop* p) { 148 LogTarget(Trace, gc, nmethod) lt; 149 if (lt.is_enabled()) { 150 LogStream ls(lt); 151 if (!_found) { 152 CompileTask::print(&ls, _print_nm, "new scavengable oop", /*short_form:*/ true); 153 } 154 ls.print("" PTR_FORMAT "[offset=%d] found scavengable oop " PTR_FORMAT " (found at " PTR_FORMAT ") ", 155 p2i(_print_nm), (int)((intptr_t)p - (intptr_t)_print_nm), 156 p2i(*p), p2i(p)); 157 ls.cr(); 158 } 159 } 160 #endif //PRODUCT 161 }; 162 163 bool ScavengableNMethods::has_scavengable_oops(nmethod* nm) { 164 HasScavengableOops cl(_is_scavengable, nm); 165 nm->oops_do(&cl); 166 return cl.found(); 167 } 168 169 // Walk the list of methods which might contain oops to the java heap. 170 void ScavengableNMethods::scavengable_nmethods_do(CodeBlobToOopClosure* f) { 171 assert_locked_or_safepoint(CodeCache_lock); 172 173 const bool fix_relocations = f->fix_relocations(); 174 debug_only(mark_on_list_nmethods()); 175 176 nmethod* prev = NULL; 177 nmethod* cur = _head; 178 while (cur != NULL) { 179 ScavengableNMethodsData data = gc_data(cur); 180 debug_only(data.clear_marked()); 181 assert(data.not_marked(), ""); 182 assert(data.on_list(), "else shouldn't be on this list"); 183 184 bool is_live = (!cur->is_zombie() && !cur->is_unloaded()); 185 LogTarget(Trace, gc, nmethod) lt; 186 if (lt.is_enabled()) { 187 LogStream ls(lt); 188 CompileTask::print(&ls, cur, 189 is_live ? "scavengable root " : "dead scavengable root", /*short_form:*/ true); 190 } 191 if (is_live) { 192 // Perform cur->oops_do(f), maybe just once per nmethod. 193 f->do_code_blob(cur); 194 } 195 nmethod* const next = data.next(); 196 // The scavengable nmethod list must contain all methods with scavengable 197 // oops. It is safe to include more nmethod on the list, but we do not 198 // expect any live non-scavengable nmethods on the list. 199 if (fix_relocations) { 200 if (!is_live || !has_scavengable_oops(cur)) { 201 unlist_nmethod(cur, prev); 202 } else { 203 prev = cur; 204 } 205 } 206 cur = next; 207 } 208 209 // Check for stray marks. 210 debug_only(verify_unlisted_nmethods(NULL)); 211 } 212 213 #ifndef PRODUCT 214 void ScavengableNMethods::asserted_non_scavengable_nmethods_do(CodeBlobClosure* f) { 215 // While we are here, verify the integrity of the list. 216 mark_on_list_nmethods(); 217 for (nmethod* cur = _head; cur != NULL; cur = gc_data(cur).next()) { 218 assert(gc_data(cur).on_list(), "else shouldn't be on this list"); 219 gc_data(cur).clear_marked(); 220 } 221 verify_unlisted_nmethods(f); 222 } 223 #endif // PRODUCT 224 225 void ScavengableNMethods::unlist_nmethod(nmethod* nm, nmethod* prev) { 226 assert_locked_or_safepoint(CodeCache_lock); 227 228 assert((prev == NULL && _head == nm) || 229 (prev != NULL && gc_data(prev).next() == nm), "precondition"); 230 231 CodeCache::print_trace("unlist_nmethod", nm); 232 233 ScavengableNMethodsData data = gc_data(nm); 234 235 if (prev == NULL) { 236 _head = data.next(); 237 } else { 238 gc_data(prev).set_next(data.next()); 239 } 240 data.set_next(NULL); 241 data.clear_on_list(); 242 } 243 244 void ScavengableNMethods::prune_nmethods() { 245 assert_locked_or_safepoint(CodeCache_lock); 246 247 debug_only(mark_on_list_nmethods()); 248 249 nmethod* last = NULL; 250 nmethod* cur = _head; 251 while (cur != NULL) { 252 nmethod* next = gc_data(cur).next(); 253 debug_only(gc_data(cur).clear_marked()); 254 assert(gc_data(cur).on_list(), "else shouldn't be on this list"); 255 256 if (!cur->is_zombie() && !cur->is_unloaded() && has_scavengable_oops(cur)) { 257 // Keep it. Advance 'last' to prevent deletion. 258 last = cur; 259 } else { 260 // Prune it from the list, so we don't have to look at it any more. 261 CodeCache::print_trace("prune_nmethods", cur); 262 unlist_nmethod(cur, last); 263 } 264 cur = next; 265 } 266 267 // Check for stray marks. 268 debug_only(verify_unlisted_nmethods(NULL)); 269 } 270 271 #ifndef PRODUCT 272 // Temporarily mark nmethods that are claimed to be on the scavenge list. 273 void ScavengableNMethods::mark_on_list_nmethods() { 274 NMethodIterator iter(NMethodIterator::only_alive); 275 while(iter.next()) { 276 nmethod* nm = iter.method(); 277 ScavengableNMethodsData data = gc_data(nm); 278 assert(data.not_marked(), "clean state"); 279 if (data.on_list()) 280 data.set_marked(); 281 } 282 } 283 284 // If the closure is given, run it on the unlisted nmethods. 285 // Also make sure that the effects of mark_on_list_nmethods is gone. 286 void ScavengableNMethods::verify_unlisted_nmethods(CodeBlobClosure* f_or_null) { 287 NMethodIterator iter(NMethodIterator::only_alive); 288 while(iter.next()) { 289 nmethod* nm = iter.method(); 290 291 verify_nmethod(nm); 292 293 if (f_or_null != NULL && !gc_data(nm).on_list()) { 294 f_or_null->do_code_blob(nm); 295 } 296 } 297 } 298 299 #endif //PRODUCT