Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/jfr/support/jfrKlassUnloading.cpp
41149 views
1
/*
2
* Copyright (c) 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 "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
27
#include "jfr/support/jfrKlassUnloading.hpp"
28
#include "jfr/utilities/jfrPredicate.hpp"
29
#include "jfr/utilities/jfrRelation.hpp"
30
#include "runtime/mutexLocker.hpp"
31
32
static const int initial_array_size = 64;
33
34
template <typename T>
35
static GrowableArray<T>* c_heap_allocate_array(int size = initial_array_size) {
36
return new (ResourceObj::C_HEAP, mtTracing) GrowableArray<T>(size, mtTracing);
37
}
38
39
// Track the set of unloaded klasses during a chunk / epoch.
40
static GrowableArray<traceid>* _unload_set_epoch_0 = NULL;
41
static GrowableArray<traceid>* _unload_set_epoch_1 = NULL;
42
43
static s8 event_klass_unloaded_count = 0;
44
45
static GrowableArray<traceid>* unload_set_epoch_0() {
46
if (_unload_set_epoch_0 == NULL) {
47
_unload_set_epoch_0 = c_heap_allocate_array<traceid>(initial_array_size);
48
}
49
return _unload_set_epoch_0;
50
}
51
52
static GrowableArray<traceid>* unload_set_epoch_1() {
53
if (_unload_set_epoch_1 == NULL) {
54
_unload_set_epoch_1 = c_heap_allocate_array<traceid>(initial_array_size);
55
}
56
return _unload_set_epoch_1;
57
}
58
59
static GrowableArray<traceid>* get_unload_set(u1 epoch) {
60
return epoch == 0 ? unload_set_epoch_0() : unload_set_epoch_1();
61
}
62
63
static GrowableArray<traceid>* get_unload_set() {
64
return get_unload_set(JfrTraceIdEpoch::current());
65
}
66
67
static GrowableArray<traceid>* get_unload_set_previous_epoch() {
68
return get_unload_set(JfrTraceIdEpoch::previous());
69
}
70
71
static void sort_set(GrowableArray<traceid>* set) {
72
assert(set != NULL, "invariant");
73
assert(set->is_nonempty(), "invariant");
74
set->sort(sort_traceid);
75
}
76
77
static bool is_nonempty_set(u1 epoch) {
78
if (epoch == 0) {
79
return _unload_set_epoch_0 != NULL && _unload_set_epoch_0->is_nonempty();
80
}
81
return _unload_set_epoch_1 != NULL && _unload_set_epoch_1->is_nonempty();
82
}
83
84
void JfrKlassUnloading::sort(bool previous_epoch) {
85
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
86
if (is_nonempty_set(JfrTraceIdEpoch::current())) {
87
sort_set(get_unload_set());
88
}
89
if (previous_epoch && is_nonempty_set(JfrTraceIdEpoch::previous())) {
90
sort_set(get_unload_set_previous_epoch());
91
}
92
}
93
94
void JfrKlassUnloading::clear() {
95
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
96
if (is_nonempty_set(JfrTraceIdEpoch::previous())) {
97
get_unload_set_previous_epoch()->clear();
98
}
99
}
100
101
static bool add_to_unloaded_klass_set(traceid klass_id, bool current_epoch) {
102
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
103
GrowableArray<traceid>* const unload_set = current_epoch ? get_unload_set() : get_unload_set_previous_epoch();
104
assert(unload_set != NULL, "invariant");
105
assert(unload_set->find(klass_id) == -1, "invariant");
106
unload_set->append(klass_id);
107
return true;
108
}
109
110
bool JfrKlassUnloading::on_unload(const Klass* k) {
111
assert(k != NULL, "invariant");
112
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
113
if (IS_JDK_JFR_EVENT_SUBKLASS(k)) {
114
++event_klass_unloaded_count;
115
}
116
return USED_ANY_EPOCH(k) && add_to_unloaded_klass_set(JfrTraceId::load_raw(k), USED_THIS_EPOCH(k));
117
}
118
119
bool JfrKlassUnloading::is_unloaded(traceid klass_id, bool previous_epoch /* false */) {
120
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
121
if (previous_epoch) {
122
if (JfrPredicate<traceid, compare_traceid>::test(get_unload_set_previous_epoch(), klass_id)) {
123
return true;
124
}
125
}
126
return JfrPredicate<traceid, compare_traceid>::test(get_unload_set(), klass_id);
127
}
128
129
int64_t JfrKlassUnloading::event_class_count() {
130
return event_klass_unloaded_count;
131
}
132
133