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