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 #include "precompiled.hpp"
  25 #include "code/relocInfo.hpp"
  26 #include "code/nmethod.hpp"
  27 #include "code/icBuffer.hpp"
  28 #include "gc/shared/barrierSet.hpp"
  29 #include "gc/shared/barrierSetNMethod.hpp"
  30 #include "gc/z/zGlobals.hpp"
  31 #include "gc/z/zLock.inline.hpp"
  32 #include "gc/z/zNMethod.hpp"
  33 #include "gc/z/zNMethodData.hpp"
  34 #include "gc/z/zNMethodTable.hpp"
  35 #include "gc/z/zOopClosures.inline.hpp"
  36 #include "gc/z/zTask.hpp"
  37 #include "gc/z/zWorkers.hpp"
  38 #include "logging/log.hpp"
  39 #include "memory/allocation.inline.hpp"
  40 #include "memory/iterator.hpp"
  41 #include "memory/resourceArea.hpp"
  42 #include "memory/universe.hpp"
  43 #include "runtime/atomic.hpp"
  44 #include "runtime/orderAccess.hpp"
  45 #include "utilities/debug.hpp"
  46 
  47 static ZNMethodData* gc_data(const nmethod* nm) {
  48   return nm->gc_data<ZNMethodData>();
  49 }
  50 
  51 static void set_gc_data(nmethod* nm, ZNMethodData* data) {
  52   return nm->set_gc_data<ZNMethodData>(data);
  53 }
  54 
  55 void ZNMethod::attach_gc_data(nmethod* nm) {
  56   GrowableArray<oop*> immediate_oops;
  57   bool non_immediate_oops = false;
  58 
  59   // Find all oops relocations
  60   RelocIterator iter(nm);
  61   while (iter.next()) {
  62     if (iter.type() != relocInfo::oop_type) {
  63       // Not an oop
  64       continue;
  65     }
  66 
  67     oop_Relocation* r = iter.oop_reloc();
  68 
  69     if (!r->oop_is_immediate()) {
  70       // Non-immediate oop found
  71       non_immediate_oops = true;
  72       continue;
  73     }
  74 
  75     if (r->oop_value() != NULL) {
  76       // Non-NULL immediate oop found. NULL oops can safely be
  77       // ignored since the method will be re-registered if they
  78       // are later patched to be non-NULL.
  79       immediate_oops.push(r->oop_addr());
  80     }
  81   }
  82 
  83   // Attach GC data to nmethod
  84   ZNMethodData* data = gc_data(nm);
  85   if (data == NULL) {
  86     data = new ZNMethodData();
  87     set_gc_data(nm, data);
  88   }
  89 
  90   // Attach oops in GC data
  91   ZNMethodDataOops* const new_oops = ZNMethodDataOops::create(immediate_oops, non_immediate_oops);
  92   ZNMethodDataOops* const old_oops = data->swap_oops(new_oops);
  93   ZNMethodDataOops::destroy(old_oops);
  94 }
  95 
  96 ZReentrantLock* ZNMethod::lock_for_nmethod(nmethod* nm) {
  97   return gc_data(nm)->lock();
  98 }
  99 
 100 void ZNMethod::log_register(const nmethod* nm) {
 101   LogTarget(Trace, gc, nmethod) log;
 102   if (!log.is_enabled()) {
 103     return;
 104   }
 105 
 106   const ZNMethodDataOops* const oops = gc_data(nm)->oops();
 107 
 108   log.print("Register NMethod: %s.%s (" PTR_FORMAT "), "
 109             "Compiler: %s, Oops: %d, ImmediateOops: " SIZE_FORMAT ", NonImmediateOops: %s",
 110             nm->method()->method_holder()->external_name(),
 111             nm->method()->name()->as_C_string(),
 112             p2i(nm),
 113             nm->compiler_name(),
 114             nm->oops_count() - 1,
 115             oops->immediates_count(),
 116             oops->has_non_immediates() ? "Yes" : "No");
 117 
 118   LogTarget(Trace, gc, nmethod, oops) log_oops;
 119   if (!log_oops.is_enabled()) {
 120     return;
 121   }
 122 
 123   // Print nmethod oops table
 124   {
 125     oop* const begin = nm->oops_begin();
 126     oop* const end = nm->oops_end();
 127     for (oop* p = begin; p < end; p++) {
 128       log_oops.print("           Oop[" SIZE_FORMAT "] " PTR_FORMAT " (%s)",
 129                      (p - begin), p2i(*p), (*p)->klass()->external_name());
 130     }
 131   }
 132 
 133   // Print nmethod immediate oops
 134   {
 135     oop** const begin = oops->immediates_begin();
 136     oop** const end = oops->immediates_end();
 137     for (oop** p = begin; p < end; p++) {
 138       log_oops.print("  ImmediateOop[" SIZE_FORMAT "] " PTR_FORMAT " @ " PTR_FORMAT " (%s)",
 139                      (p - begin), p2i(**p), p2i(*p), (**p)->klass()->external_name());
 140     }
 141   }
 142 }
 143 
 144 void ZNMethod::log_unregister(const nmethod* nm) {
 145   LogTarget(Debug, gc, nmethod) log;
 146   if (!log.is_enabled()) {
 147     return;
 148   }
 149 
 150   log.print("Unregister NMethod: %s.%s (" PTR_FORMAT ")",
 151             nm->method()->method_holder()->external_name(),
 152             nm->method()->name()->as_C_string(),
 153             p2i(nm));
 154 }
 155 
 156 void ZNMethod::register_nmethod(nmethod* nm) {
 157   ResourceMark rm;
 158 
 159   // Create and attach gc data
 160   attach_gc_data(nm);
 161 
 162   log_register(nm);
 163 
 164   ZNMethodTable::register_nmethod(nm);
 165 
 166   // Disarm nmethod entry barrier
 167   disarm_nmethod(nm);
 168 }
 169 
 170 void ZNMethod::unregister_nmethod(nmethod* nm) {
 171   assert(CodeCache_lock->owned_by_self(), "Lock must be held");
 172 
 173   if (Thread::current()->is_Code_cache_sweeper_thread()) {
 174     // The sweeper must wait for any ongoing iteration to complete
 175     // before it can unregister an nmethod.
 176     ZNMethodTable::wait_until_iteration_done();
 177   }
 178 
 179   ResourceMark rm;
 180 
 181   log_unregister(nm);
 182 
 183   ZNMethodTable::unregister_nmethod(nm);
 184 }
 185 
 186 void ZNMethod::flush_nmethod(nmethod* nm) {
 187   // Destroy GC data
 188   delete gc_data(nm);
 189 }
 190 
 191 void ZNMethod::disarm_nmethod(nmethod* nm) {
 192   BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod();
 193   if (bs != NULL) {
 194     bs->disarm(nm);
 195   }
 196 }
 197 
 198 void ZNMethod::nmethod_oops_do(nmethod* nm, OopClosure* cl) {
 199   // Process oops table
 200   {
 201     oop* const begin = nm->oops_begin();
 202     oop* const end = nm->oops_end();
 203     for (oop* p = begin; p < end; p++) {
 204       if (*p != Universe::non_oop_word()) {
 205         cl->do_oop(p);
 206       }
 207     }
 208   }
 209 
 210   ZNMethodDataOops* const oops = gc_data(nm)->oops();
 211 
 212   // Process immediate oops
 213   {
 214     oop** const begin = oops->immediates_begin();
 215     oop** const end = oops->immediates_end();
 216     for (oop** p = begin; p < end; p++) {
 217       if (**p != Universe::non_oop_word()) {
 218         cl->do_oop(*p);
 219       }
 220     }
 221   }
 222 
 223   // Process non-immediate oops
 224   if (oops->has_non_immediates()) {
 225     nm->fix_oop_relocations();
 226   }
 227 }
 228 
 229 class ZNMethodToOopsDoClosure : public NMethodClosure {
 230 private:
 231   OopClosure* _cl;
 232 
 233 public:
 234   ZNMethodToOopsDoClosure(OopClosure* cl) :
 235       _cl(cl) {}
 236 
 237   virtual void do_nmethod(nmethod* nm) {
 238     ZNMethod::nmethod_oops_do(nm, _cl);
 239   }
 240 };
 241 
 242 void ZNMethod::oops_do_begin() {
 243   ZNMethodTable::nmethods_do_begin();
 244 }
 245 
 246 void ZNMethod::oops_do_end() {
 247   ZNMethodTable::nmethods_do_end();
 248 }
 249 
 250 void ZNMethod::oops_do(OopClosure* cl) {
 251   ZNMethodToOopsDoClosure nmethod_cl(cl);
 252   ZNMethodTable::nmethods_do(&nmethod_cl);
 253 }
 254 
 255 class ZNMethodUnlinkClosure : public NMethodClosure {
 256 private:
 257   bool          _unloading_occurred;
 258   volatile bool _failed;
 259 
 260   void set_failed() {
 261     Atomic::store(true, &_failed);
 262   }
 263 
 264   void unlink(nmethod* nm) {
 265     // Unlinking of the dependencies must happen before the
 266     // handshake separating unlink and purge.
 267     nm->flush_dependencies(false /* delete_immediately */);
 268 
 269     // unlink_from_method will take the CompiledMethod_lock.
 270     // In this case we don't strictly need it when unlinking nmethods from
 271     // the Method, because it is only concurrently unlinked by
 272     // the entry barrier, which acquires the per nmethod lock.
 273     nm->unlink_from_method();
 274 
 275     if (nm->is_osr_method()) {
 276       // Invalidate the osr nmethod before the handshake. The nmethod
 277       // will be made unloaded after the handshake. Then invalidate_osr_method()
 278       // will be called again, which will be a no-op.
 279       nm->invalidate_osr_method();
 280     }
 281   }
 282 
 283 public:
 284   ZNMethodUnlinkClosure(bool unloading_occurred) :
 285       _unloading_occurred(unloading_occurred),
 286       _failed(false) {}
 287 
 288   virtual void do_nmethod(nmethod* nm) {
 289     if (failed()) {
 290       return;
 291     }
 292 
 293     if (!nm->is_alive()) {
 294       return;
 295     }
 296 
 297     if (nm->is_unloading()) {
 298       ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
 299       unlink(nm);
 300       return;
 301     }
 302 
 303     ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
 304 
 305     // Heal oops and disarm
 306     ZNMethodOopClosure cl;
 307     ZNMethod::nmethod_oops_do(nm, &cl);
 308     ZNMethod::disarm_nmethod(nm);
 309 
 310     // Clear compiled ICs and exception caches
 311     if (!nm->unload_nmethod_caches(_unloading_occurred)) {
 312       set_failed();
 313     }
 314   }
 315 
 316   bool failed() const {
 317     return Atomic::load(&_failed);
 318   }
 319 };
 320 
 321 class ZNMethodUnlinkTask : public ZTask {
 322 private:
 323   ZNMethodUnlinkClosure _cl;
 324   ICRefillVerifier*     _verifier;
 325 
 326 public:
 327   ZNMethodUnlinkTask(bool unloading_occurred, ICRefillVerifier* verifier) :
 328       ZTask("ZNMethodUnlinkTask"),
 329       _cl(unloading_occurred),
 330       _verifier(verifier) {
 331     ZNMethodTable::nmethods_do_begin();
 332   }
 333 
 334   ~ZNMethodUnlinkTask() {
 335     ZNMethodTable::nmethods_do_end();
 336   }
 337 
 338   virtual void work() {
 339     ICRefillVerifierMark mark(_verifier);
 340     ZNMethodTable::nmethods_do(&_cl);
 341   }
 342 
 343   bool success() const {
 344     return !_cl.failed();
 345   }
 346 };
 347 
 348 void ZNMethod::unlink(ZWorkers* workers, bool unloading_occurred) {
 349   for (;;) {
 350     ICRefillVerifier verifier;
 351 
 352     {
 353       ZNMethodUnlinkTask task(unloading_occurred, &verifier);
 354       workers->run_concurrent(&task);
 355       if (task.success()) {
 356         return;
 357       }
 358     }
 359 
 360     // Cleaning failed because we ran out of transitional IC stubs,
 361     // so we have to refill and try again. Refilling requires taking
 362     // a safepoint, so we temporarily leave the suspendible thread set.
 363     SuspendibleThreadSetLeaver sts;
 364     InlineCacheBuffer::refill_ic_stubs();
 365   }
 366 }
 367 
 368 class ZNMethodPurgeClosure : public NMethodClosure {
 369 public:
 370   virtual void do_nmethod(nmethod* nm) {
 371     if (nm->is_alive() && nm->is_unloading()) {
 372       nm->make_unloaded();
 373     }
 374   }
 375 };
 376 
 377 class ZNMethodPurgeTask : public ZTask {
 378 private:
 379   ZNMethodPurgeClosure _cl;
 380 
 381 public:
 382   ZNMethodPurgeTask() :
 383       ZTask("ZNMethodPurgeTask"),
 384       _cl() {
 385     ZNMethodTable::nmethods_do_begin();
 386   }
 387 
 388   ~ZNMethodPurgeTask() {
 389     ZNMethodTable::nmethods_do_end();
 390   }
 391 
 392   virtual void work() {
 393     ZNMethodTable::nmethods_do(&_cl);
 394   }
 395 };
 396 
 397 void ZNMethod::purge(ZWorkers* workers) {
 398   ZNMethodPurgeTask task;
 399   workers->run_concurrent(&task);
 400 }