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