1 /*
  2  * Copyright (c) 2014, 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 
 25 #include "precompiled.hpp"
 26 #include "aot/aotLoader.hpp"
 27 #include "classfile/stringTable.hpp"
 28 #include "gc/shared/strongRootsScope.hpp"
 29 #include "jfr/leakprofiler/utilities/unifiedOop.hpp"
 30 #include "jfr/leakprofiler/checkpoint/rootResolver.hpp"
 31 #include "memory/iterator.hpp"
 32 #include "oops/klass.hpp"
 33 #include "oops/markOop.hpp"
 34 #include "oops/oop.hpp"
 35 #include "prims/jvmtiThreadState.hpp"
 36 #include "prims/privilegedStack.hpp"
 37 #include "runtime/frame.inline.hpp"
 38 #include "runtime/mutexLocker.hpp"
 39 #include "runtime/threadSMR.inline.hpp"
 40 #include "runtime/vframe_hp.hpp"
 41 #include "services/management.hpp"
 42 #include "utilities/growableArray.hpp"
 43 
 44 class ReferenceLocateClosure : public OopClosure {
 45  protected:
 46   RootCallback& _callback;
 47   RootCallbackInfo _info;
 48   bool _complete;
 49 
 50   void do_oop_shared(const void* ref);
 51 
 52  public:
 53   ReferenceLocateClosure(RootCallback& callback,
 54                          OldObjectRoot::System system,
 55                          OldObjectRoot::Type type,
 56                          const void* context) : _callback(callback),
 57                                                 _info(),
 58                                                 _complete(false) {
 59     _info._high = NULL;
 60     _info._low = NULL;
 61     _info._system = system;
 62     _info._type = type;
 63     _info._context = context;
 64   }
 65 
 66   virtual void do_oop(oop* ref);
 67   virtual void do_oop(narrowOop* ref);
 68 
 69   bool complete() const {
 70     return _complete;
 71   }
 72 };
 73 
 74 void ReferenceLocateClosure::do_oop_shared(const void* ref) {
 75   assert(ref != NULL, "invariant");
 76   if (!_complete) {
 77     _info._high = ref;
 78     _complete = _callback.process(_info);
 79   }
 80 }
 81 
 82 void ReferenceLocateClosure::do_oop(oop* ref) {
 83   do_oop_shared(ref);
 84 }
 85 
 86 void ReferenceLocateClosure::do_oop(narrowOop* ref) {
 87   do_oop_shared(ref);
 88 }
 89 
 90 class ReferenceToRootClosure : public StackObj {
 91  private:
 92   RootCallback& _callback;
 93   RootCallbackInfo _info;
 94   bool _complete;
 95 
 96   bool do_cldg_roots();
 97   bool do_object_synchronizer_roots();
 98   bool do_universe_roots();
 99   bool do_jni_handle_roots();
100   bool do_jvmti_roots();
101   bool do_system_dictionary_roots();
102   bool do_management_roots();
103   bool do_string_table_roots();
104   bool do_aot_loader_roots();
105 
106   bool do_roots();
107 
108  public:
109   ReferenceToRootClosure(RootCallback& callback) : _callback(callback),
110                                                    _info(),
111                                                    _complete(false) {
112     _info._high = NULL;
113     _info._low = NULL;
114     _info._context = NULL;
115     _info._system = OldObjectRoot::_system_undetermined;
116     _info._type = OldObjectRoot::_type_undetermined;
117 
118     assert_locked_or_safepoint(Threads_lock);
119     do_roots();
120   }
121 
122   bool complete() const {
123     return _complete;
124   }
125 };
126 
127 bool ReferenceToRootClosure::do_cldg_roots() {
128   assert(!complete(), "invariant");
129   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_class_loader_data, OldObjectRoot::_type_undetermined, NULL);
130   CLDToOopClosure cldt_closure(&rlc);
131   ClassLoaderDataGraph::always_strong_cld_do(&cldt_closure);
132   return rlc.complete();
133 }
134 
135 bool ReferenceToRootClosure::do_object_synchronizer_roots() {
136   assert(!complete(), "invariant");
137   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_object_synchronizer, OldObjectRoot::_type_undetermined, NULL);
138   ObjectSynchronizer::oops_do(&rlc);
139   return rlc.complete();
140 }
141 
142 bool ReferenceToRootClosure::do_universe_roots() {
143   assert(!complete(), "invariant");
144   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_universe, OldObjectRoot::_type_undetermined, NULL);
145   Universe::oops_do(&rlc);
146   return rlc.complete();
147 }
148 
149 bool ReferenceToRootClosure::do_jni_handle_roots() {
150   assert(!complete(), "invariant");
151   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_global_jni_handles, OldObjectRoot::_global_jni_handle, NULL);
152   JNIHandles::oops_do(&rlc);
153   return rlc.complete();
154 }
155 
156 bool ReferenceToRootClosure::do_jvmti_roots() {
157   assert(!complete(), "invariant");
158   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_jvmti, OldObjectRoot::_global_jni_handle, NULL);
159   JvmtiExport::oops_do(&rlc);
160   return rlc.complete();
161 }
162 
163 bool ReferenceToRootClosure::do_system_dictionary_roots() {
164   assert(!complete(), "invariant");
165   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_system_dictionary, OldObjectRoot::_type_undetermined, NULL);
166   SystemDictionary::oops_do(&rlc);
167   return rlc.complete();
168 }
169 
170 bool ReferenceToRootClosure::do_management_roots() {
171   assert(!complete(), "invariant");
172   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_management, OldObjectRoot::_type_undetermined, NULL);
173   Management::oops_do(&rlc);
174   return rlc.complete();
175 }
176 
177 bool ReferenceToRootClosure::do_string_table_roots() {
178   assert(!complete(), "invariant");
179   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_string_table, OldObjectRoot::_type_undetermined, NULL);
180   StringTable::oops_do(&rlc);
181   return rlc.complete();
182 }
183 
184 bool ReferenceToRootClosure::do_aot_loader_roots() {
185   assert(!complete(), "invariant");
186   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_aot, OldObjectRoot::_type_undetermined, NULL);
187   AOTLoader::oops_do(&rcl);
188   return rcl.complete();
189 }
190 
191 bool ReferenceToRootClosure::do_roots() {
192   assert(!complete(), "invariant");
193   assert(OldObjectRoot::_system_undetermined == _info._system, "invariant");
194   assert(OldObjectRoot::_type_undetermined == _info._type, "invariant");
195 
196   if (do_cldg_roots()) {
197     _complete = true;
198     return true;
199   }
200 
201   if (do_object_synchronizer_roots()) {
202    _complete = true;
203     return true;
204   }
205 
206   if (do_universe_roots()) {
207    _complete = true;
208     return true;
209   }
210 
211   if (do_jni_handle_roots()) {
212    _complete = true;
213     return true;
214   }
215 
216   if (do_jvmti_roots()) {
217    _complete = true;
218     return true;
219   }
220 
221   if (do_system_dictionary_roots()) {
222    _complete = true;
223     return true;
224   }
225 
226   if (do_management_roots()) {
227    _complete = true;
228     return true;
229   }
230 
231   if (do_string_table_roots()) {
232    _complete = true;
233     return true;
234   }
235 
236   if (do_aot_loader_roots()) {
237    _complete = true;
238     return true;
239   }
240 
241   return false;
242 }
243 
244 class ReferenceToThreadRootClosure : public StackObj {
245  private:
246   RootCallback& _callback;
247   bool _complete;
248 
249   bool do_java_threads_oops(JavaThread* jt);
250   bool do_thread_roots(JavaThread* jt);
251   bool do_thread_stack_fast(JavaThread* jt);
252   bool do_thread_stack_detailed(JavaThread* jt);
253   bool do_thread_jni_handles(JavaThread* jt);
254   bool do_thread_handle_area(JavaThread* jt);
255 
256  public:
257   ReferenceToThreadRootClosure(RootCallback& callback) :_callback(callback), _complete(false) {
258     assert_locked_or_safepoint(Threads_lock);
259     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
260       if (do_thread_roots(jt)) {
261         return;
262       }
263     }
264   }
265 
266   bool complete() const {
267     return _complete;
268   }
269 };
270 
271 bool ReferenceToThreadRootClosure::do_thread_handle_area(JavaThread* jt) {
272   assert(jt != NULL, "invariant");
273   assert(!complete(), "invariant");
274   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_handle_area, jt);
275   jt->handle_area()->oops_do(&rcl);
276   return rcl.complete();
277 }
278 
279 bool ReferenceToThreadRootClosure::do_thread_jni_handles(JavaThread* jt) {
280   assert(jt != NULL, "invariant");
281   assert(!complete(), "invariant");
282 
283   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_local_jni_handle, jt);
284   jt->active_handles()->oops_do(&rcl);
285   return rcl.complete();
286 }
287 
288 bool ReferenceToThreadRootClosure::do_thread_stack_fast(JavaThread* jt) {
289   assert(jt != NULL, "invariant");
290   assert(!complete(), "invariant");
291 
292   if (_callback.entries() == 0) {
293     _complete = true;
294     return true;
295   }
296 
297   RootCallbackInfo info;
298   info._high = NULL;
299   info._low = NULL;
300   info._context = jt;
301   info._system = OldObjectRoot::_threads;
302   info._type = OldObjectRoot::_stack_variable;
303 
304   for (int i = 0; i < _callback.entries(); ++i) {
305     const address adr = (address)_callback.at(i);
306     if (jt->is_in_usable_stack(adr)) {
307       info._high = adr;
308       _complete = _callback.process(info);
309       if (_complete) {
310         return true;
311       }
312     }
313   }
314   assert(!complete(), "invariant");
315   return false;
316 }
317 
318 bool ReferenceToThreadRootClosure::do_thread_stack_detailed(JavaThread* jt) {
319   assert(jt != NULL, "invariant");
320   assert(!complete(), "invariant");
321 
322   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_stack_variable, jt);
323 
324   if (jt->has_last_Java_frame()) {
325     PrivilegedElement* const pelem = jt->privileged_stack_top();
326     if (pelem != NULL) {
327       pelem->oops_do(&rcl);
328       if (rcl.complete()) {
329         return true;
330       }
331     }
332 
333     // traverse the registered growable array gc_array
334     // can't do this as it is not reachable from outside
335 
336     // Traverse the monitor chunks
337     MonitorChunk* chunk = jt->monitor_chunks();
338     for (; chunk != NULL; chunk = chunk->next()) {
339       chunk->oops_do(&rcl);
340     }
341 
342     if (rcl.complete()) {
343       return true;
344     }
345 
346     // Traverse the execution stack
347     for (StackFrameStream fst(jt); !fst.is_done(); fst.next()) {
348       fst.current()->oops_do(&rcl, NULL, fst.register_map());
349     }
350 
351   } // last java frame
352 
353   if (rcl.complete()) {
354     return true;
355   }
356 
357   GrowableArray<jvmtiDeferredLocalVariableSet*>* const list = jt->deferred_locals();
358   if (list != NULL) {
359     for (int i = 0; i < list->length(); i++) {
360       list->at(i)->oops_do(&rcl);
361     }
362   }
363 
364   if (rcl.complete()) {
365     return true;
366   }
367 
368   // Traverse instance variables at the end since the GC may be moving things
369   // around using this function
370   /*
371   * // can't reach these oop* from the outside
372   f->do_oop((oop*) &_threadObj);
373   f->do_oop((oop*) &_vm_result);
374   f->do_oop((oop*) &_exception_oop);
375   f->do_oop((oop*) &_pending_async_exception);
376   */
377 
378   JvmtiThreadState* const jvmti_thread_state = jt->jvmti_thread_state();
379   if (jvmti_thread_state != NULL) {
380     jvmti_thread_state->oops_do(&rcl);
381   }
382 
383   return rcl.complete();
384 }
385 
386 bool ReferenceToThreadRootClosure::do_java_threads_oops(JavaThread* jt) {
387   assert(jt != NULL, "invariant");
388   assert(!complete(), "invariant");
389 
390   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_global_jni_handle, jt);
391   jt->oops_do(&rcl, NULL);
392   return rcl.complete();
393 }
394 
395 bool ReferenceToThreadRootClosure::do_thread_roots(JavaThread* jt) {
396   assert(jt != NULL, "invariant");
397 
398   if (do_thread_stack_fast(jt)) {
399     _complete = true;
400     return true;
401   }
402 
403   if (do_thread_jni_handles(jt)) {
404     _complete = true;
405     return true;
406   }
407 
408   if (do_thread_handle_area(jt)) {
409     _complete = true;
410     return true;
411   }
412 
413   if (do_thread_stack_detailed(jt)) {
414     _complete = true;
415     return true;
416   }
417 
418   return false;
419 }
420 
421 class RootResolverMarkScope : public MarkScope {
422 };
423 
424 void RootResolver::resolve(RootCallback& callback) {
425 
426   // Need to clear cld claim bit before starting
427   ClassLoaderDataGraph::clear_claimed_marks();
428   RootResolverMarkScope mark_scope;
429 
430   // thread local roots
431   ReferenceToThreadRootClosure rtrc(callback);
432   if (rtrc.complete()) {
433     return;
434   }
435   // system global roots
436   ReferenceToRootClosure rrc(callback);
437 }