author | zgu |
Wed, 27 Nov 2019 11:52:57 -0500 | |
changeset 59296 | 9186be5c78ba |
permissions | -rw-r--r-- |
59296
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
1 |
/* |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
2 |
* Copyright (c) 2019, Red Hat, Inc. All rights reserved. |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
3 |
* |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
4 |
* This code is free software; you can redistribute it and/or modify it |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
5 |
* under the terms of the GNU General Public License version 2 only, as |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
6 |
* published by the Free Software Foundation. |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
7 |
* |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
8 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
9 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
10 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
11 |
* version 2 for more details (a copy is included in the LICENSE file that |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
12 |
* accompanied this code). |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
13 |
* |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
14 |
* You should have received a copy of the GNU General Public License version |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
15 |
* 2 along with this work; if not, write to the Free Software Foundation, |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
16 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
17 |
* |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
18 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
19 |
* or visit www.oracle.com if you need additional information or have any |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
20 |
* questions. |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
21 |
* |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
22 |
*/ |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
23 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
24 |
#include "precompiled.hpp" |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
25 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
26 |
#include "gc/shenandoah/shenandoahClosures.inline.hpp" |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
27 |
#include "gc/shenandoah/shenandoahConcurrentRoots.hpp" |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
28 |
#include "gc/shenandoah/shenandoahHeap.inline.hpp" |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
29 |
#include "gc/shenandoah/shenandoahNMethod.inline.hpp" |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
30 |
#include "memory/resourceArea.hpp" |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
31 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
32 |
ShenandoahNMethod::ShenandoahNMethod(nmethod* nm, GrowableArray<oop*>& oops, bool non_immediate_oops) : |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
33 |
_nm(nm), _oops(NULL), _oops_count(0), _unregistered(false) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
34 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
35 |
if (!oops.is_empty()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
36 |
_oops_count = oops.length(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
37 |
_oops = NEW_C_HEAP_ARRAY(oop*, _oops_count, mtGC); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
38 |
for (int c = 0; c < _oops_count; c++) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
39 |
_oops[c] = oops.at(c); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
40 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
41 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
42 |
_has_non_immed_oops = non_immediate_oops; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
43 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
44 |
assert_same_oops(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
45 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
46 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
47 |
ShenandoahNMethod::~ShenandoahNMethod() { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
48 |
if (_oops != NULL) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
49 |
FREE_C_HEAP_ARRAY(oop*, _oops); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
50 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
51 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
52 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
53 |
class ShenandoahHasCSetOopClosure : public OopClosure { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
54 |
private: |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
55 |
ShenandoahHeap* const _heap; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
56 |
bool _has_cset_oops; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
57 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
58 |
public: |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
59 |
ShenandoahHasCSetOopClosure() : |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
60 |
_heap(ShenandoahHeap::heap()), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
61 |
_has_cset_oops(false) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
62 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
63 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
64 |
bool has_cset_oops() const { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
65 |
return _has_cset_oops; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
66 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
67 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
68 |
void do_oop(oop* p) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
69 |
oop value = RawAccess<>::oop_load(p); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
70 |
if (!_has_cset_oops && _heap->in_collection_set(value)) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
71 |
_has_cset_oops = true; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
72 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
73 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
74 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
75 |
void do_oop(narrowOop* p) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
76 |
ShouldNotReachHere(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
77 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
78 |
}; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
79 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
80 |
bool ShenandoahNMethod::has_cset_oops(ShenandoahHeap *heap) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
81 |
ShenandoahHasCSetOopClosure cl; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
82 |
oops_do(&cl); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
83 |
return cl.has_cset_oops(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
84 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
85 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
86 |
void ShenandoahNMethod::update() { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
87 |
ResourceMark rm; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
88 |
bool non_immediate_oops = false; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
89 |
GrowableArray<oop*> oops; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
90 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
91 |
detect_reloc_oops(nm(), oops, non_immediate_oops); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
92 |
if (oops.length() != _oops_count) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
93 |
if (_oops != NULL) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
94 |
FREE_C_HEAP_ARRAY(oop*, _oops); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
95 |
_oops = NULL; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
96 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
97 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
98 |
_oops_count = oops.length(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
99 |
if (_oops_count > 0) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
100 |
_oops = NEW_C_HEAP_ARRAY(oop*, _oops_count, mtGC); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
101 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
102 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
103 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
104 |
for (int index = 0; index < _oops_count; index ++) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
105 |
_oops[index] = oops.at(index); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
106 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
107 |
_has_non_immed_oops = non_immediate_oops; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
108 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
109 |
assert_same_oops(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
110 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
111 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
112 |
void ShenandoahNMethod::oops_do(OopClosure* oops, bool fix_relocations) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
113 |
for (int c = 0; c < _oops_count; c ++) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
114 |
oops->do_oop(_oops[c]); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
115 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
116 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
117 |
oop* const begin = _nm->oops_begin(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
118 |
oop* const end = _nm->oops_end(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
119 |
for (oop* p = begin; p < end; p++) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
120 |
if (*p != Universe::non_oop_word()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
121 |
oops->do_oop(p); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
122 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
123 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
124 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
125 |
if (fix_relocations && _has_non_immed_oops) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
126 |
_nm->fix_oop_relocations(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
127 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
128 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
129 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
130 |
void ShenandoahNMethod::detect_reloc_oops(nmethod* nm, GrowableArray<oop*>& oops, bool& has_non_immed_oops) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
131 |
has_non_immed_oops = false; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
132 |
// Find all oops relocations |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
133 |
RelocIterator iter(nm); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
134 |
while (iter.next()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
135 |
if (iter.type() != relocInfo::oop_type) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
136 |
// Not an oop |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
137 |
continue; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
138 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
139 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
140 |
oop_Relocation* r = iter.oop_reloc(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
141 |
if (!r->oop_is_immediate()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
142 |
// Non-immediate oop found |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
143 |
has_non_immed_oops = true; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
144 |
continue; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
145 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
146 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
147 |
if (r->oop_value() != NULL) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
148 |
// Non-NULL immediate oop found. NULL oops can safely be |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
149 |
// ignored since the method will be re-registered if they |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
150 |
// are later patched to be non-NULL. |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
151 |
oops.push(r->oop_addr()); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
152 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
153 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
154 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
155 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
156 |
ShenandoahNMethod* ShenandoahNMethod::for_nmethod(nmethod* nm) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
157 |
ResourceMark rm; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
158 |
bool non_immediate_oops = false; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
159 |
GrowableArray<oop*> oops; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
160 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
161 |
detect_reloc_oops(nm, oops, non_immediate_oops); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
162 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
163 |
// No embedded oops |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
164 |
if(!ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() && |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
165 |
oops.is_empty() && nm->oops_begin() >= nm->oops_end()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
166 |
return NULL; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
167 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
168 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
169 |
return new ShenandoahNMethod(nm, oops, non_immediate_oops); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
170 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
171 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
172 |
void ShenandoahNMethod::heal_nmethod(nmethod* nm) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
173 |
ShenandoahNMethod* data = gc_data(nm); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
174 |
assert(data != NULL, "Sanity"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
175 |
assert(data->lock()->owned_by_self(), "Must hold the lock"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
176 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
177 |
ShenandoahEvacuateUpdateRootsClosure cl; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
178 |
data->oops_do(&cl, true /*fix relocation*/); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
179 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
180 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
181 |
#ifdef ASSERT |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
182 |
void ShenandoahNMethod::assert_alive_and_correct() { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
183 |
assert(_nm->is_alive(), "only alive nmethods here"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
184 |
ShenandoahHeap* heap = ShenandoahHeap::heap(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
185 |
for (int c = 0; c < _oops_count; c++) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
186 |
oop *loc = _oops[c]; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
187 |
assert(_nm->code_contains((address) loc) || _nm->oops_contains(loc), "nmethod should contain the oop*"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
188 |
oop o = RawAccess<>::oop_load(loc); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
189 |
shenandoah_assert_correct_except(loc, o, o == NULL || heap->is_full_gc_move_in_progress()); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
190 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
191 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
192 |
oop* const begin = _nm->oops_begin(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
193 |
oop* const end = _nm->oops_end(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
194 |
for (oop* p = begin; p < end; p++) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
195 |
if (*p != Universe::non_oop_word()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
196 |
oop o = RawAccess<>::oop_load(p); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
197 |
shenandoah_assert_correct_except(p, o, o == NULL || heap->is_full_gc_move_in_progress()); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
198 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
199 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
200 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
201 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
202 |
class ShenandoahNMethodOopDetector : public OopClosure { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
203 |
private: |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
204 |
ResourceMark rm; // For growable array allocation below. |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
205 |
GrowableArray<oop*> _oops; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
206 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
207 |
public: |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
208 |
ShenandoahNMethodOopDetector() : _oops(10) {}; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
209 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
210 |
void do_oop(oop* o) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
211 |
_oops.append(o); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
212 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
213 |
void do_oop(narrowOop* o) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
214 |
fatal("NMethods should not have compressed oops embedded."); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
215 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
216 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
217 |
GrowableArray<oop*>* oops() { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
218 |
return &_oops; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
219 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
220 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
221 |
bool has_oops() { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
222 |
return !_oops.is_empty(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
223 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
224 |
}; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
225 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
226 |
void ShenandoahNMethod::assert_same_oops(bool allow_dead) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
227 |
ShenandoahNMethodOopDetector detector; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
228 |
nm()->oops_do(&detector, allow_dead); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
229 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
230 |
GrowableArray<oop*>* oops = detector.oops(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
231 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
232 |
assert(oops->length() == oop_count(), "Must match"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
233 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
234 |
for (int index = 0; index < _oops_count; index ++) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
235 |
assert(oops->contains(_oops[index]), "Must contain this oop"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
236 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
237 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
238 |
for (oop* p = nm()->oops_begin(); p < nm()->oops_end(); p ++) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
239 |
assert(oops->contains(p), "Must contain this oop"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
240 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
241 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
242 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
243 |
void ShenandoahNMethod::assert_no_oops(nmethod* nm, bool allow_dead) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
244 |
ShenandoahNMethodOopDetector detector; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
245 |
nm->oops_do(&detector, allow_dead); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
246 |
assert(detector.oops()->length() == 0, "Should not have oops"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
247 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
248 |
#endif |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
249 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
250 |
ShenandoahNMethodTable::ShenandoahNMethodTable() : |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
251 |
_heap(ShenandoahHeap::heap()), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
252 |
_size(minSize), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
253 |
_index(0), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
254 |
_iteration_in_progress(false) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
255 |
_array = NEW_C_HEAP_ARRAY(ShenandoahNMethod*, _size, mtGC); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
256 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
257 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
258 |
ShenandoahNMethodTable::~ShenandoahNMethodTable() { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
259 |
assert(_array != NULL, "Sanity"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
260 |
FREE_C_HEAP_ARRAY(ShenandoahNMethod*, _array); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
261 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
262 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
263 |
void ShenandoahNMethodTable::register_nmethod(nmethod* nm) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
264 |
assert(CodeCache_lock->owned_by_self(), "Must have CodeCache_lock held"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
265 |
assert(_index >= 0 && _index <= _size, "Sanity"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
266 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
267 |
ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
268 |
ShenandoahReentrantLocker data_locker(data != NULL ? data->lock() : NULL); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
269 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
270 |
if (data != NULL) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
271 |
assert(contain(nm), "Must have been registered"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
272 |
data->update(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
273 |
} else { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
274 |
data = ShenandoahNMethod::for_nmethod(nm); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
275 |
if (data == NULL) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
276 |
assert(!ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
277 |
"Only possible when concurrent class unloading is off"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
278 |
return; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
279 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
280 |
ShenandoahNMethod::attach_gc_data(nm, data); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
281 |
ShenandoahLocker locker(&_lock); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
282 |
log_register_nmethod(nm); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
283 |
append(data); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
284 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
285 |
// Disarm new nmethod |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
286 |
ShenandoahNMethod::disarm_nmethod(nm); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
287 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
288 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
289 |
void ShenandoahNMethodTable::unregister_nmethod(nmethod* nm) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
290 |
assert_locked_or_safepoint(CodeCache_lock); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
291 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
292 |
ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
293 |
if (data == NULL) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
294 |
assert(!ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
295 |
"Only possible when concurrent class unloading is off"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
296 |
ShenandoahNMethod::assert_no_oops(nm, true /*allow_dead*/); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
297 |
return; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
298 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
299 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
300 |
if (Thread::current()->is_Code_cache_sweeper_thread()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
301 |
wait_until_concurrent_iteration_done(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
302 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
303 |
log_unregister_nmethod(nm); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
304 |
ShenandoahLocker locker(&_lock); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
305 |
assert(contain(nm), "Must have been registered"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
306 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
307 |
ShenandoahReentrantLocker data_locker(data->lock()); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
308 |
data->mark_unregistered(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
309 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
310 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
311 |
void ShenandoahNMethodTable::flush_nmethod(nmethod* nm) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
312 |
assert(CodeCache_lock->owned_by_self(), "Must have CodeCache_lock held"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
313 |
assert(Thread::current()->is_Code_cache_sweeper_thread(), "Must from Sweep thread"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
314 |
ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
315 |
assert(data != NULL || !ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
316 |
"Only possible when concurrent class unloading is off"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
317 |
if (data == NULL) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
318 |
ShenandoahNMethod::assert_no_oops(nm, true /*allow_dead*/); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
319 |
return; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
320 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
321 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
322 |
// Can not alter the array when iteration is in progress |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
323 |
wait_until_concurrent_iteration_done(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
324 |
log_flush_nmethod(nm); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
325 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
326 |
ShenandoahLocker locker(&_lock); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
327 |
int idx = index_of(nm); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
328 |
assert(idx >= 0 && idx < _index, "Invalid index"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
329 |
ShenandoahNMethod::attach_gc_data(nm, NULL); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
330 |
remove(idx); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
331 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
332 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
333 |
bool ShenandoahNMethodTable::contain(nmethod* nm) const { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
334 |
return index_of(nm) != -1; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
335 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
336 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
337 |
ShenandoahNMethod* ShenandoahNMethodTable::at(int index) const { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
338 |
assert(index >= 0 && index < _index, "Out of bound"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
339 |
return _array[index]; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
340 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
341 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
342 |
int ShenandoahNMethodTable::index_of(nmethod* nm) const { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
343 |
for (int index = 0; index < length(); index ++) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
344 |
if (_array[index]->nm() == nm) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
345 |
return index; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
346 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
347 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
348 |
return -1; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
349 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
350 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
351 |
void ShenandoahNMethodTable::remove(int idx) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
352 |
shenandoah_assert_locked_or_safepoint(CodeCache_lock); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
353 |
assert(!_iteration_in_progress, "Can not happen"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
354 |
assert(_index >= 0 && _index <= _size, "Sanity"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
355 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
356 |
assert(idx >= 0 && idx < _index, "Out of bound"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
357 |
ShenandoahNMethod* snm = _array[idx]; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
358 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
359 |
_index --; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
360 |
_array[idx] = _array[_index]; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
361 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
362 |
delete snm; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
363 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
364 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
365 |
void ShenandoahNMethodTable::wait_until_concurrent_iteration_done() { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
366 |
assert(CodeCache_lock->owned_by_self(), "Lock must be held"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
367 |
while (iteration_in_progress()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
368 |
CodeCache_lock->wait_without_safepoint_check(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
369 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
370 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
371 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
372 |
void ShenandoahNMethodTable::append(ShenandoahNMethod* snm) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
373 |
if (is_full()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
374 |
int new_size = 2 * _size; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
375 |
ShenandoahNMethod** old_table = _array; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
376 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
377 |
// Rebuild table and replace current one |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
378 |
rebuild(new_size); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
379 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
380 |
// An iteration is in progress over early snapshot, |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
381 |
// can not release the array until iteration is completed |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
382 |
if (!iteration_in_progress()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
383 |
FREE_C_HEAP_ARRAY(ShenandoahNMethod*, old_table); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
384 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
385 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
386 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
387 |
_array[_index ++] = snm; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
388 |
assert(_index >= 0 && _index <= _size, "Sanity"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
389 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
390 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
391 |
void ShenandoahNMethodTable::rebuild(int size) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
392 |
ShenandoahNMethod** arr = NEW_C_HEAP_ARRAY(ShenandoahNMethod*, size, mtGC); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
393 |
for (int index = 0; index < _index; index ++) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
394 |
arr[index] = _array[index]; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
395 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
396 |
_array = arr; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
397 |
_size = size; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
398 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
399 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
400 |
ShenandoahNMethodTableSnapshot* ShenandoahNMethodTable::snapshot_for_iteration() { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
401 |
assert(!iteration_in_progress(), "Already in progress"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
402 |
_iteration_in_progress = true; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
403 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
404 |
return new ShenandoahNMethodTableSnapshot(this); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
405 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
406 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
407 |
void ShenandoahNMethodTable::finish_iteration(ShenandoahNMethodTableSnapshot* snapshot) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
408 |
assert(iteration_in_progress(), "Why we here?"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
409 |
assert(snapshot != NULL, "No snapshot"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
410 |
_iteration_in_progress = false; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
411 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
412 |
// Table has been rebuilt during iteration, free old table |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
413 |
if (snapshot->_array != _array) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
414 |
FREE_C_HEAP_ARRAY(ShenandoahNMethod*, snapshot->_array); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
415 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
416 |
delete snapshot; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
417 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
418 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
419 |
void ShenandoahNMethodTable::log_register_nmethod(nmethod* nm) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
420 |
LogTarget(Debug, gc, nmethod) log; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
421 |
if (!log.is_enabled()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
422 |
return; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
423 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
424 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
425 |
ResourceMark rm; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
426 |
log.print("Register NMethod: %s.%s [" PTR_FORMAT "] (%s)", |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
427 |
nm->method()->method_holder()->external_name(), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
428 |
nm->method()->name()->as_C_string(), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
429 |
p2i(nm), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
430 |
nm->compiler_name()); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
431 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
432 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
433 |
void ShenandoahNMethodTable::log_unregister_nmethod(nmethod* nm) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
434 |
LogTarget(Debug, gc, nmethod) log; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
435 |
if (!log.is_enabled()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
436 |
return; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
437 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
438 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
439 |
ResourceMark rm; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
440 |
log.print("Unregister NMethod: %s.%s [" PTR_FORMAT "]", |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
441 |
nm->method()->method_holder()->external_name(), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
442 |
nm->method()->name()->as_C_string(), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
443 |
p2i(nm)); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
444 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
445 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
446 |
void ShenandoahNMethodTable::log_flush_nmethod(nmethod* nm) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
447 |
LogTarget(Debug, gc, nmethod) log; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
448 |
if (!log.is_enabled()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
449 |
return; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
450 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
451 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
452 |
ResourceMark rm; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
453 |
log.print("Flush NMethod: (" PTR_FORMAT ")", p2i(nm)); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
454 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
455 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
456 |
#ifdef ASSERT |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
457 |
void ShenandoahNMethodTable::assert_nmethods_alive_and_correct() { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
458 |
assert_locked_or_safepoint(CodeCache_lock); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
459 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
460 |
for (int index = 0; index < length(); index ++) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
461 |
ShenandoahNMethod* m = _array[index]; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
462 |
// Concurrent unloading may have dead nmethods to be cleaned by sweeper |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
463 |
if (m->is_unregistered()) continue; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
464 |
m->assert_alive_and_correct(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
465 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
466 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
467 |
#endif |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
468 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
469 |
ShenandoahNMethodTableSnapshot::ShenandoahNMethodTableSnapshot(ShenandoahNMethodTable* table) : |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
470 |
_heap(ShenandoahHeap::heap()), _table(table), _array(table->_array), _length(table->_index), _claimed(0) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
471 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
472 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
473 |
void ShenandoahNMethodTableSnapshot::concurrent_nmethods_do(NMethodClosure* cl) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
474 |
size_t stride = 256; // educated guess |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
475 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
476 |
ShenandoahNMethod** list = _array; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
477 |
size_t max = (size_t)_length; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
478 |
while (_claimed < max) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
479 |
size_t cur = Atomic::add(&_claimed, stride) - stride; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
480 |
size_t start = cur; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
481 |
size_t end = MIN2(cur + stride, max); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
482 |
if (start >= max) break; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
483 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
484 |
for (size_t idx = start; idx < end; idx++) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
485 |
ShenandoahNMethod* data = list[idx]; |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
486 |
assert(data != NULL, "Should not be NULL"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
487 |
if (!data->is_unregistered()) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
488 |
cl->do_nmethod(data->nm()); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
489 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
490 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
491 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
492 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
493 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
494 |
ShenandoahConcurrentNMethodIterator::ShenandoahConcurrentNMethodIterator(ShenandoahNMethodTable* table) : |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
495 |
_table(table), _table_snapshot(NULL) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
496 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
497 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
498 |
void ShenandoahConcurrentNMethodIterator::nmethods_do_begin() { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
499 |
assert(CodeCache_lock->owned_by_self(), "Lock must be held"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
500 |
assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
501 |
"Only for concurrent class unloading"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
502 |
_table_snapshot = _table->snapshot_for_iteration(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
503 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
504 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
505 |
void ShenandoahConcurrentNMethodIterator::nmethods_do(NMethodClosure* cl) { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
506 |
assert(_table_snapshot != NULL, "Must first call nmethod_do_begin()"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
507 |
_table_snapshot->concurrent_nmethods_do(cl); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
508 |
} |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
509 |
|
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
510 |
void ShenandoahConcurrentNMethodIterator::nmethods_do_end() { |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
511 |
assert(CodeCache_lock->owned_by_self(), "Lock must be held"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
512 |
assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
513 |
"Only for concurrent class unloading"); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
514 |
_table->finish_iteration(_table_snapshot); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
515 |
CodeCache_lock->notify_all(); |
9186be5c78ba
8228720: Shenandoah: Implementation of concurrent class unloading
zgu
parents:
diff
changeset
|
516 |
} |