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