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
25#include "precompiled.hpp"
26#include "gc/g1/g1CollectedHeap.hpp"
27#include "gc/g1/g1FullGCMarker.inline.hpp"
28#include "gc/g1/g1FullGCOopClosures.inline.hpp"
29#include "logging/logStream.hpp"
30#include "memory/iterator.inline.hpp"
31#include "oops/access.inline.hpp"
32#include "oops/compressedOops.inline.hpp"
33#include "oops/oop.inline.hpp"
34
35void G1FollowStackClosure::do_void() { _marker->drain_stack(); }
36
37void G1FullKeepAliveClosure::do_oop(oop* p) { do_oop_work(p); }
38void G1FullKeepAliveClosure::do_oop(narrowOop* p) { do_oop_work(p); }
39
40G1VerifyOopClosure::G1VerifyOopClosure(VerifyOption option) :
41 _g1h(G1CollectedHeap::heap()),
42 _failures(false),
43 _containing_obj(NULL),
44 _verify_option(option),
45 _cc(0) {
46}
47
48void G1VerifyOopClosure::print_object(outputStream* out, oop obj) {
49#ifdef PRODUCT
50 Klass* k = obj->klass();
51 const char* class_name = InstanceKlass::cast(k)->external_name();
52 out->print_cr("class name %s", class_name);
53#else // PRODUCT
54 obj->print_on(out);
55#endif // PRODUCT
56}
57
58template <class T> void G1VerifyOopClosure::do_oop_work(T* p) {
59 T heap_oop = RawAccess<>::oop_load(p);
60 if (!CompressedOops::is_null(heap_oop)) {
61 _cc++;
62 oop obj = CompressedOops::decode_not_null(heap_oop);
63 bool failed = false;
64 if (!_g1h->is_in(obj) || _g1h->is_obj_dead_cond(obj, _verify_option)) {
65 MutexLocker x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
66 LogStreamHandle(Error, gc, verify) yy;
67 if (!_failures) {
68 yy.cr();
69 yy.print_cr("----------");
70 }
71 if (!_g1h->is_in(obj)) {
72 HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
73 yy.print_cr("Field " PTR_FORMAT " of live obj " PTR_FORMAT " in region " HR_FORMAT,
74 p2i(p), p2i(_containing_obj), HR_FORMAT_PARAMS(from));
75 print_object(&yy, _containing_obj);
76 yy.print_cr("points to obj " PTR_FORMAT " not in the heap",
77 p2i(obj));
78 } else {
79 HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
80 HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj);
81 yy.print_cr("Field " PTR_FORMAT " of live obj " PTR_FORMAT " in region " HR_FORMAT,
82 p2i(p), p2i(_containing_obj), HR_FORMAT_PARAMS(from));
83 print_object(&yy, _containing_obj);
84 yy.print_cr("points to dead obj " PTR_FORMAT " in region " HR_FORMAT,
85 p2i(obj), HR_FORMAT_PARAMS(to));
86 print_object(&yy, obj);
87 }
88 yy.print_cr("----------");
89 yy.flush();
90 _failures = true;
91 failed = true;
92 }
93 }
94}
95
96template void G1VerifyOopClosure::do_oop_work(oop*);
97template void G1VerifyOopClosure::do_oop_work(narrowOop*);
98