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