Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp
41153 views
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 "classfile/javaClasses.inline.hpp"
27
#include "jfr/leakprofiler/chains/edge.hpp"
28
#include "jfr/leakprofiler/chains/edgeStore.hpp"
29
#include "jfr/leakprofiler/chains/edgeUtils.hpp"
30
#include "jfr/leakprofiler/utilities/unifiedOopRef.inline.hpp"
31
#include "oops/fieldStreams.inline.hpp"
32
#include "oops/instanceKlass.hpp"
33
#include "oops/instanceMirrorKlass.hpp"
34
#include "oops/objArrayOop.inline.hpp"
35
#include "oops/oopsHierarchy.hpp"
36
#include "runtime/handles.inline.hpp"
37
38
bool EdgeUtils::is_leak_edge(const Edge& edge) {
39
return (const Edge*)edge.pointee()->mark().to_pointer() == &edge;
40
}
41
42
static bool is_static_field(const oop ref_owner, const InstanceKlass* ik, int offset) {
43
assert(ref_owner != NULL, "invariant");
44
assert(ik != NULL, "invariant");
45
assert(ref_owner->klass() == ik, "invariant");
46
return ik->is_mirror_instance_klass() && offset >= InstanceMirrorKlass::cast(ik)->offset_of_static_fields();
47
}
48
49
static int field_offset(const Edge& edge, const oop ref_owner) {
50
assert(ref_owner != NULL, "invariant");
51
assert(!ref_owner->is_array(), "invariant");
52
assert(ref_owner->is_instance(), "invariant");
53
UnifiedOopRef reference = edge.reference();
54
assert(!reference.is_null(), "invariant");
55
const int offset = (int)(reference.addr<uintptr_t>() - cast_from_oop<uintptr_t>(ref_owner));
56
assert(offset < ref_owner->size() * HeapWordSize, "invariant");
57
return offset;
58
}
59
60
const Symbol* EdgeUtils::field_name(const Edge& edge, jshort* modifiers) {
61
assert(!edge.is_root(), "invariant");
62
assert(!EdgeUtils::is_array_element(edge), "invariant");
63
assert(modifiers != NULL, "invariant");
64
const oop ref_owner = edge.reference_owner();
65
assert(ref_owner != NULL, "invariant");
66
assert(ref_owner->klass()->is_instance_klass(), "invariant");
67
const InstanceKlass* ik = InstanceKlass::cast(ref_owner->klass());
68
const int offset = field_offset(edge, ref_owner);
69
if (is_static_field(ref_owner, ik, offset)) {
70
assert(ik->is_mirror_instance_klass(), "invariant");
71
assert(java_lang_Class::as_Klass(ref_owner)->is_instance_klass(), "invariant");
72
ik = InstanceKlass::cast(java_lang_Class::as_Klass(ref_owner));
73
}
74
while (ik != NULL) {
75
JavaFieldStream jfs(ik);
76
while (!jfs.done()) {
77
if (offset == jfs.offset()) {
78
*modifiers = jfs.access_flags().as_short();
79
return jfs.name();
80
}
81
jfs.next();
82
}
83
ik = (const InstanceKlass*)ik->super();
84
}
85
*modifiers = 0;
86
return NULL;
87
}
88
89
bool EdgeUtils::is_array_element(const Edge& edge) {
90
assert(!edge.is_root(), "invariant");
91
const oop ref_owner = edge.reference_owner();
92
assert(ref_owner != NULL, "invariant");
93
return ref_owner->is_objArray();
94
}
95
96
static int array_offset(const Edge& edge) {
97
assert(EdgeUtils::is_array_element(edge), "invariant");
98
const oop ref_owner = edge.reference_owner();
99
assert(ref_owner != NULL, "invariant");
100
UnifiedOopRef reference = edge.reference();
101
assert(!reference.is_null(), "invariant");
102
assert(ref_owner->is_array(), "invariant");
103
const objArrayOop ref_owner_array = static_cast<const objArrayOop>(ref_owner);
104
const int offset = (int)pointer_delta(reference.addr<HeapWord*>(), ref_owner_array->base(), heapOopSize);
105
assert(offset >= 0 && offset < ref_owner_array->length(), "invariant");
106
return offset;
107
}
108
109
int EdgeUtils::array_index(const Edge& edge) {
110
return array_offset(edge);
111
}
112
113
int EdgeUtils::array_size(const Edge& edge) {
114
assert(is_array_element(edge), "invariant");
115
const oop ref_owner = edge.reference_owner();
116
assert(ref_owner != NULL, "invariant");
117
assert(ref_owner->is_objArray(), "invariant");
118
return ((objArrayOop)ref_owner)->length();
119
}
120
121
const Edge* EdgeUtils::root(const Edge& edge) {
122
const Edge* current = &edge;
123
const Edge* parent = current->parent();
124
while (parent != NULL) {
125
current = parent;
126
parent = current->parent();
127
}
128
assert(current != NULL, "invariant");
129
return current;
130
}
131
132
const Edge* EdgeUtils::ancestor(const Edge& edge, size_t distance) {
133
const Edge* current = &edge;
134
const Edge* parent = current->parent();
135
size_t seek = 0;
136
while (parent != NULL && seek != distance) {
137
seek++;
138
current = parent;
139
parent = parent->parent();
140
}
141
return current;
142
}
143
144