Mercurial > hg > truffle
annotate src/share/vm/runtime/sweeper.cpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | da91efe96a93 |
children | e522a00b91aa 0cfa93c2fcc4 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1538
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1538
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1538
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "code/codeCache.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
27 #include "code/compiledIC.hpp" |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
28 #include "code/icBuffer.hpp" |
1972 | 29 #include "code/nmethod.hpp" |
30 #include "compiler/compileBroker.hpp" | |
31 #include "memory/resourceArea.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
32 #include "oops/method.hpp" |
1972 | 33 #include "runtime/atomic.hpp" |
34 #include "runtime/compilationPolicy.hpp" | |
35 #include "runtime/mutexLocker.hpp" | |
36 #include "runtime/os.hpp" | |
37 #include "runtime/sweeper.hpp" | |
38 #include "runtime/vm_operations.hpp" | |
39 #include "utilities/events.hpp" | |
40 #include "utilities/xmlstream.hpp" | |
0 | 41 |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
42 #ifdef ASSERT |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
43 |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
44 #define SWEEP(nm) record_sweep(nm, __LINE__) |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
45 // Sweeper logging code |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
46 class SweeperRecord { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
47 public: |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
48 int traversal; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
49 int invocation; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
50 int compile_id; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
51 long traversal_mark; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
52 int state; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
53 const char* kind; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
54 address vep; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
55 address uep; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
56 int line; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
57 |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
58 void print() { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
59 tty->print_cr("traversal = %d invocation = %d compile_id = %d %s uep = " PTR_FORMAT " vep = " |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
60 PTR_FORMAT " state = %d traversal_mark %d line = %d", |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
61 traversal, |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
62 invocation, |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
63 compile_id, |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
64 kind == NULL ? "" : kind, |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
65 uep, |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
66 vep, |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
67 state, |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
68 traversal_mark, |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
69 line); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
70 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
71 }; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
72 |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
73 static int _sweep_index = 0; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
74 static SweeperRecord* _records = NULL; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
75 |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
76 void NMethodSweeper::report_events(int id, address entry) { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
77 if (_records != NULL) { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
78 for (int i = _sweep_index; i < SweeperLogEntries; i++) { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
79 if (_records[i].uep == entry || |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
80 _records[i].vep == entry || |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
81 _records[i].compile_id == id) { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
82 _records[i].print(); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
83 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
84 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
85 for (int i = 0; i < _sweep_index; i++) { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
86 if (_records[i].uep == entry || |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
87 _records[i].vep == entry || |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
88 _records[i].compile_id == id) { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
89 _records[i].print(); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
90 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
91 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
92 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
93 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
94 |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
95 void NMethodSweeper::report_events() { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
96 if (_records != NULL) { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
97 for (int i = _sweep_index; i < SweeperLogEntries; i++) { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
98 // skip empty records |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
99 if (_records[i].vep == NULL) continue; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
100 _records[i].print(); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
101 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
102 for (int i = 0; i < _sweep_index; i++) { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
103 // skip empty records |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
104 if (_records[i].vep == NULL) continue; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
105 _records[i].print(); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
106 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
107 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
108 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
109 |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
110 void NMethodSweeper::record_sweep(nmethod* nm, int line) { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
111 if (_records != NULL) { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
112 _records[_sweep_index].traversal = _traversals; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
113 _records[_sweep_index].traversal_mark = nm->_stack_traversal_mark; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
114 _records[_sweep_index].invocation = _invocations; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
115 _records[_sweep_index].compile_id = nm->compile_id(); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
116 _records[_sweep_index].kind = nm->compile_kind(); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
117 _records[_sweep_index].state = nm->_state; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
118 _records[_sweep_index].vep = nm->verified_entry_point(); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
119 _records[_sweep_index].uep = nm->entry_point(); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
120 _records[_sweep_index].line = line; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
121 |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
122 _sweep_index = (_sweep_index + 1) % SweeperLogEntries; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
123 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
124 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
125 #else |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
126 #define SWEEP(nm) |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
127 #endif |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
128 |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
129 |
0 | 130 long NMethodSweeper::_traversals = 0; // No. of stack traversals performed |
1615
ff38d05ea86f
6956958: assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted() || is_optimized() || is_megam
never
parents:
1552
diff
changeset
|
131 nmethod* NMethodSweeper::_current = NULL; // Current nmethod |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
132 int NMethodSweeper::_seen = 0 ; // No. of nmethods we have currently processed in current pass of CodeCache |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
133 |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
134 volatile int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
135 volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress. |
0 | 136 |
137 jint NMethodSweeper::_locked_seen = 0; | |
138 jint NMethodSweeper::_not_entrant_seen_on_stack = 0; | |
139 bool NMethodSweeper::_rescan = false; | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
140 bool NMethodSweeper::_do_sweep = false; |
1202 | 141 bool NMethodSweeper::_was_full = false; |
142 jint NMethodSweeper::_advise_to_sweep = 0; | |
143 jlong NMethodSweeper::_last_was_full = 0; | |
144 uint NMethodSweeper::_highest_marked = 0; | |
145 long NMethodSweeper::_was_full_traversal = 0; | |
0 | 146 |
989 | 147 class MarkActivationClosure: public CodeBlobClosure { |
148 public: | |
149 virtual void do_code_blob(CodeBlob* cb) { | |
150 // If we see an activation belonging to a non_entrant nmethod, we mark it. | |
151 if (cb->is_nmethod() && ((nmethod*)cb)->is_not_entrant()) { | |
152 ((nmethod*)cb)->mark_as_seen_on_stack(); | |
153 } | |
154 } | |
155 }; | |
156 static MarkActivationClosure mark_activation_closure; | |
157 | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
158 void NMethodSweeper::scan_stacks() { |
0 | 159 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint"); |
160 if (!MethodFlushing) return; | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
161 _do_sweep = true; |
0 | 162 |
163 // No need to synchronize access, since this is always executed at a | |
164 // safepoint. If we aren't in the middle of scan and a rescan | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
165 // hasn't been requested then just return. If UseCodeCacheFlushing is on and |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
166 // code cache flushing is in progress, don't skip sweeping to help make progress |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
167 // clearing space in the code cache. |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
168 if ((_current == NULL && !_rescan) && !(UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs())) { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
169 _do_sweep = false; |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
170 return; |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
171 } |
0 | 172 |
173 // Make sure CompiledIC_lock in unlocked, since we might update some | |
174 // inline caches. If it is, we just bail-out and try later. | |
175 if (CompiledIC_lock->is_locked() || Patching_lock->is_locked()) return; | |
176 | |
177 // Check for restart | |
178 assert(CodeCache::find_blob_unsafe(_current) == _current, "Sweeper nmethod cached state invalid"); | |
179 if (_current == NULL) { | |
180 _seen = 0; | |
181 _invocations = NmethodSweepFraction; | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
182 _current = CodeCache::first_nmethod(); |
0 | 183 _traversals += 1; |
184 if (PrintMethodFlushing) { | |
185 tty->print_cr("### Sweep: stack traversal %d", _traversals); | |
186 } | |
989 | 187 Threads::nmethods_do(&mark_activation_closure); |
0 | 188 |
189 // reset the flags since we started a scan from the beginning. | |
190 _rescan = false; | |
191 _locked_seen = 0; | |
192 _not_entrant_seen_on_stack = 0; | |
193 } | |
194 | |
1202 | 195 if (UseCodeCacheFlushing) { |
196 if (!CodeCache::needs_flushing()) { | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
197 // scan_stacks() runs during a safepoint, no race with setters |
1202 | 198 _advise_to_sweep = 0; |
199 } | |
200 | |
201 if (was_full()) { | |
202 // There was some progress so attempt to restart the compiler | |
203 jlong now = os::javaTimeMillis(); | |
204 jlong max_interval = (jlong)MinCodeCacheFlushingInterval * (jlong)1000; | |
205 jlong curr_interval = now - _last_was_full; | |
206 if ((!CodeCache::needs_flushing()) && (curr_interval > max_interval)) { | |
207 CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); | |
208 set_was_full(false); | |
209 | |
210 // Update the _last_was_full time so we can tell how fast the | |
211 // code cache is filling up | |
212 _last_was_full = os::javaTimeMillis(); | |
213 | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
214 log_sweep("restart_compiler"); |
1202 | 215 } |
216 } | |
217 } | |
0 | 218 } |
219 | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
220 void NMethodSweeper::possibly_sweep() { |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
221 assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode"); |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
222 if ((!MethodFlushing) || (!_do_sweep)) return; |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
223 |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
224 if (_invocations > 0) { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
225 // Only one thread at a time will sweep |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
226 jint old = Atomic::cmpxchg( 1, &_sweep_started, 0 ); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
227 if (old != 0) { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
228 return; |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
229 } |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
230 #ifdef ASSERT |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
231 if (LogSweeper && _records == NULL) { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
232 // Create the ring buffer for the logging code |
6197 | 233 _records = NEW_C_HEAP_ARRAY(SweeperRecord, SweeperLogEntries, mtGC); |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
234 memset(_records, 0, sizeof(SweeperRecord) * SweeperLogEntries); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
235 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
236 #endif |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
237 if (_invocations > 0) { |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
238 sweep_code_cache(); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
239 _invocations--; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
240 } |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
241 _sweep_started = 0; |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
242 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
243 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
244 |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
245 void NMethodSweeper::sweep_code_cache() { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
246 #ifdef ASSERT |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
247 jlong sweep_start; |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
248 if (PrintMethodFlushing) { |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
249 sweep_start = os::javaTimeMillis(); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
250 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
251 #endif |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
252 if (PrintMethodFlushing && Verbose) { |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
253 tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _invocations); |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
254 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
255 |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
256 // We want to visit all nmethods after NmethodSweepFraction |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
257 // invocations so divide the remaining number of nmethods by the |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
258 // remaining number of invocations. This is only an estimate since |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
259 // the number of nmethods changes during the sweep so the final |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
260 // stage must iterate until it there are no more nmethods. |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
261 int todo = (CodeCache::nof_nmethods() - _seen) / _invocations; |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
262 |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
263 assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here"); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
264 assert(!CodeCache_lock->owned_by_self(), "just checking"); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
265 |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
266 { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
267 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
268 |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
269 // The last invocation iterates until there are no more nmethods |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
270 for (int i = 0; (i < todo || _invocations == 1) && _current != NULL; i++) { |
4945
cfdfbeac0a5b
7145345: Code cache sweeper must cooperate with safepoints
iveresov
parents:
3384
diff
changeset
|
271 if (SafepointSynchronize::is_synchronizing()) { // Safepoint request |
cfdfbeac0a5b
7145345: Code cache sweeper must cooperate with safepoints
iveresov
parents:
3384
diff
changeset
|
272 if (PrintMethodFlushing && Verbose) { |
cfdfbeac0a5b
7145345: Code cache sweeper must cooperate with safepoints
iveresov
parents:
3384
diff
changeset
|
273 tty->print_cr("### Sweep at %d out of %d, invocation: %d, yielding to safepoint", _seen, CodeCache::nof_nmethods(), _invocations); |
cfdfbeac0a5b
7145345: Code cache sweeper must cooperate with safepoints
iveresov
parents:
3384
diff
changeset
|
274 } |
cfdfbeac0a5b
7145345: Code cache sweeper must cooperate with safepoints
iveresov
parents:
3384
diff
changeset
|
275 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
276 |
4945
cfdfbeac0a5b
7145345: Code cache sweeper must cooperate with safepoints
iveresov
parents:
3384
diff
changeset
|
277 assert(Thread::current()->is_Java_thread(), "should be java thread"); |
cfdfbeac0a5b
7145345: Code cache sweeper must cooperate with safepoints
iveresov
parents:
3384
diff
changeset
|
278 JavaThread* thread = (JavaThread*)Thread::current(); |
cfdfbeac0a5b
7145345: Code cache sweeper must cooperate with safepoints
iveresov
parents:
3384
diff
changeset
|
279 ThreadBlockInVM tbivm(thread); |
cfdfbeac0a5b
7145345: Code cache sweeper must cooperate with safepoints
iveresov
parents:
3384
diff
changeset
|
280 thread->java_suspend_self(); |
cfdfbeac0a5b
7145345: Code cache sweeper must cooperate with safepoints
iveresov
parents:
3384
diff
changeset
|
281 } |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
282 // Since we will give up the CodeCache_lock, always skip ahead |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
283 // to the next nmethod. Other blobs can be deleted by other |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
284 // threads but nmethods are only reclaimed by the sweeper. |
1615
ff38d05ea86f
6956958: assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted() || is_optimized() || is_megam
never
parents:
1552
diff
changeset
|
285 nmethod* next = CodeCache::next_nmethod(_current); |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
286 |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
287 // Now ready to process nmethod and give up CodeCache_lock |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
288 { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
289 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
1615
ff38d05ea86f
6956958: assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted() || is_optimized() || is_megam
never
parents:
1552
diff
changeset
|
290 process_nmethod(_current); |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
291 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
292 _seen++; |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
293 _current = next; |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
294 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
295 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
296 |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
297 assert(_invocations > 1 || _current == NULL, "must have scanned the whole cache"); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
298 |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
299 if (_current == NULL && !_rescan && (_locked_seen || _not_entrant_seen_on_stack)) { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
300 // we've completed a scan without making progress but there were |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
301 // nmethods we were unable to process either because they were |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
302 // locked or were still on stack. We don't have to aggresively |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
303 // clean them up so just stop scanning. We could scan once more |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
304 // but that complicates the control logic and it's unlikely to |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
305 // matter much. |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
306 if (PrintMethodFlushing) { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
307 tty->print_cr("### Couldn't make progress on some nmethods so stopping sweep"); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
308 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
309 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
310 |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
311 #ifdef ASSERT |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
312 if(PrintMethodFlushing) { |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
313 jlong sweep_end = os::javaTimeMillis(); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
314 tty->print_cr("### sweeper: sweep time(%d): " INT64_FORMAT, _invocations, sweep_end - sweep_start); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
315 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
316 #endif |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
317 |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
318 if (_invocations == 1) { |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
319 log_sweep("finished"); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
320 } |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
321 } |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
322 |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
323 class NMethodMarker: public StackObj { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
324 private: |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
325 CompilerThread* _thread; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
326 public: |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
327 NMethodMarker(nmethod* nm) { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
328 _thread = CompilerThread::current(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
329 if (!nm->is_zombie() && !nm->is_unloaded()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
330 // Only expose live nmethods for scanning |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
331 _thread->set_scanned_nmethod(nm); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
332 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
333 } |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
334 ~NMethodMarker() { |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
335 _thread->set_scanned_nmethod(NULL); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
336 } |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
337 }; |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
338 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
339 void NMethodSweeper::release_nmethod(nmethod *nm) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
340 // Clean up any CompiledICHolders |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
341 { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
342 ResourceMark rm; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
343 MutexLocker ml_patch(CompiledIC_lock); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
344 RelocIterator iter(nm); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
345 while (iter.next()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
346 if (iter.type() == relocInfo::virtual_call_type) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
347 CompiledIC::cleanup_call_site(iter.virtual_call_reloc()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
348 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
349 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
350 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
351 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
352 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
353 nm->flush(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
354 } |
0 | 355 |
356 void NMethodSweeper::process_nmethod(nmethod *nm) { | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
357 assert(!CodeCache_lock->owned_by_self(), "just checking"); |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
358 |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
359 // Make sure this nmethod doesn't get unloaded during the scan, |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
360 // since the locks acquired below might safepoint. |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
361 NMethodMarker nmm(nm); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
362 |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
363 SWEEP(nm); |
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
364 |
0 | 365 // Skip methods that are currently referenced by the VM |
366 if (nm->is_locked_by_vm()) { | |
367 // But still remember to clean-up inline caches for alive nmethods | |
368 if (nm->is_alive()) { | |
369 // Clean-up all inline caches that points to zombie/non-reentrant methods | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
370 MutexLocker cl(CompiledIC_lock); |
0 | 371 nm->cleanup_inline_caches(); |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
372 SWEEP(nm); |
0 | 373 } else { |
374 _locked_seen++; | |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
375 SWEEP(nm); |
0 | 376 } |
377 return; | |
378 } | |
379 | |
380 if (nm->is_zombie()) { | |
381 // If it is first time, we see nmethod then we mark it. Otherwise, | |
382 // we reclame it. When we have seen a zombie method twice, we know that | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
383 // there are no inline caches that refer to it. |
0 | 384 if (nm->is_marked_for_reclamation()) { |
385 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); | |
941 | 386 if (PrintMethodFlushing && Verbose) { |
1202 | 387 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm); |
941 | 388 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
389 release_nmethod(nm); |
0 | 390 } else { |
941 | 391 if (PrintMethodFlushing && Verbose) { |
1202 | 392 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm); |
941 | 393 } |
0 | 394 nm->mark_for_reclamation(); |
395 _rescan = true; | |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
396 SWEEP(nm); |
0 | 397 } |
398 } else if (nm->is_not_entrant()) { | |
399 // If there is no current activations of this method on the | |
400 // stack we can safely convert it to a zombie method | |
401 if (nm->can_not_entrant_be_converted()) { | |
941 | 402 if (PrintMethodFlushing && Verbose) { |
1202 | 403 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm); |
941 | 404 } |
0 | 405 nm->make_zombie(); |
406 _rescan = true; | |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
407 SWEEP(nm); |
0 | 408 } else { |
409 // Still alive, clean up its inline caches | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
410 MutexLocker cl(CompiledIC_lock); |
0 | 411 nm->cleanup_inline_caches(); |
412 // we coudn't transition this nmethod so don't immediately | |
413 // request a rescan. If this method stays on the stack for a | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
414 // long time we don't want to keep rescanning the code cache. |
0 | 415 _not_entrant_seen_on_stack++; |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
416 SWEEP(nm); |
0 | 417 } |
418 } else if (nm->is_unloaded()) { | |
419 // Unloaded code, just make it a zombie | |
941 | 420 if (PrintMethodFlushing && Verbose) |
1202 | 421 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm); |
941 | 422 if (nm->is_osr_method()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
423 SWEEP(nm); |
0 | 424 // No inline caches will ever point to osr methods, so we can just remove it |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
425 release_nmethod(nm); |
0 | 426 } else { |
427 nm->make_zombie(); | |
428 _rescan = true; | |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
429 SWEEP(nm); |
0 | 430 } |
431 } else { | |
432 assert(nm->is_alive(), "should be alive"); | |
1202 | 433 |
434 if (UseCodeCacheFlushing) { | |
435 if ((nm->method()->code() != nm) && !(nm->is_locked_by_vm()) && !(nm->is_osr_method()) && | |
436 (_traversals > _was_full_traversal+2) && (((uint)nm->compile_id()) < _highest_marked) && | |
437 CodeCache::needs_flushing()) { | |
438 // This method has not been called since the forced cleanup happened | |
439 nm->make_not_entrant(); | |
440 } | |
441 } | |
442 | |
0 | 443 // Clean-up all inline caches that points to zombie/non-reentrant methods |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
444 MutexLocker cl(CompiledIC_lock); |
0 | 445 nm->cleanup_inline_caches(); |
3384
f52ed367b66d
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents:
2482
diff
changeset
|
446 SWEEP(nm); |
0 | 447 } |
448 } | |
1202 | 449 |
450 // Code cache unloading: when compilers notice the code cache is getting full, | |
451 // they will call a vm op that comes here. This code attempts to speculatively | |
452 // unload the oldest half of the nmethods (based on the compile job id) by | |
453 // saving the old code in a list in the CodeCache. Then | |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
454 // execution resumes. If a method so marked is not called by the second sweeper |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
455 // stack traversal after the current one, the nmethod will be marked non-entrant and |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
456 // got rid of by normal sweeping. If the method is called, the Method*'s |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
457 // _code field is restored and the Method*/nmethod |
1202 | 458 // go back to their normal state. |
459 void NMethodSweeper::handle_full_code_cache(bool is_full) { | |
460 // Only the first one to notice can advise us to start early cleaning | |
461 if (!is_full){ | |
462 jint old = Atomic::cmpxchg( 1, &_advise_to_sweep, 0 ); | |
463 if (old != 0) { | |
464 return; | |
465 } | |
466 } | |
467 | |
468 if (is_full) { | |
469 // Since code cache is full, immediately stop new compiles | |
470 bool did_set = CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation); | |
471 if (!did_set) { | |
472 // only the first to notice can start the cleaning, | |
473 // others will go back and block | |
474 return; | |
475 } | |
476 set_was_full(true); | |
477 | |
478 // If we run out within MinCodeCacheFlushingInterval of the last unload time, give up | |
479 jlong now = os::javaTimeMillis(); | |
480 jlong max_interval = (jlong)MinCodeCacheFlushingInterval * (jlong)1000; | |
481 jlong curr_interval = now - _last_was_full; | |
482 if (curr_interval < max_interval) { | |
483 _rescan = true; | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
484 log_sweep("disable_compiler", "flushing_interval='" UINT64_FORMAT "'", |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
485 curr_interval/1000); |
1202 | 486 return; |
487 } | |
488 } | |
489 | |
490 VM_HandleFullCodeCache op(is_full); | |
491 VMThread::execute(&op); | |
492 | |
493 // rescan again as soon as possible | |
494 _rescan = true; | |
495 } | |
496 | |
497 void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) { | |
498 // If there was a race in detecting full code cache, only run | |
499 // one vm op for it or keep the compiler shut off | |
500 | |
501 debug_only(jlong start = os::javaTimeMillis();) | |
502 | |
503 if ((!was_full()) && (is_full)) { | |
504 if (!CodeCache::needs_flushing()) { | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
505 log_sweep("restart_compiler"); |
1202 | 506 CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); |
507 return; | |
508 } | |
509 } | |
510 | |
511 // Traverse the code cache trying to dump the oldest nmethods | |
512 uint curr_max_comp_id = CompileBroker::get_compilation_id(); | |
513 uint flush_target = ((curr_max_comp_id - _highest_marked) >> 1) + _highest_marked; | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
514 log_sweep("start_cleaning"); |
1202 | 515 |
516 nmethod* nm = CodeCache::alive_nmethod(CodeCache::first()); | |
517 jint disconnected = 0; | |
518 jint made_not_entrant = 0; | |
519 while ((nm != NULL)){ | |
520 uint curr_comp_id = nm->compile_id(); | |
521 | |
522 // OSR methods cannot be flushed like this. Also, don't flush native methods | |
523 // since they are part of the JDK in most cases | |
524 if (nm->is_in_use() && (!nm->is_osr_method()) && (!nm->is_locked_by_vm()) && | |
525 (!nm->is_native_method()) && ((curr_comp_id < flush_target))) { | |
526 | |
527 if ((nm->method()->code() == nm)) { | |
528 // This method has not been previously considered for | |
529 // unloading or it was restored already | |
530 CodeCache::speculatively_disconnect(nm); | |
531 disconnected++; | |
532 } else if (nm->is_speculatively_disconnected()) { | |
533 // This method was previously considered for preemptive unloading and was not called since then | |
1783 | 534 CompilationPolicy::policy()->delay_compilation(nm->method()); |
1202 | 535 nm->make_not_entrant(); |
536 made_not_entrant++; | |
537 } | |
538 | |
539 if (curr_comp_id > _highest_marked) { | |
540 _highest_marked = curr_comp_id; | |
541 } | |
542 } | |
543 nm = CodeCache::alive_nmethod(CodeCache::next(nm)); | |
544 } | |
545 | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
546 log_sweep("stop_cleaning", |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
547 "disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "'", |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
548 disconnected, made_not_entrant); |
1202 | 549 |
1538
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
550 // Shut off compiler. Sweeper will start over with a new stack scan and |
bfe29ec02863
6950075: nmethod sweeper should operate concurrently
never
parents:
1202
diff
changeset
|
551 // traversal cycle and turn it back on if it clears enough space. |
1202 | 552 if (was_full()) { |
553 _last_was_full = os::javaTimeMillis(); | |
554 CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation); | |
555 } | |
556 | |
557 // After two more traversals the sweeper will get rid of unrestored nmethods | |
558 _was_full_traversal = _traversals; | |
559 #ifdef ASSERT | |
560 jlong end = os::javaTimeMillis(); | |
561 if(PrintMethodFlushing && Verbose) { | |
562 tty->print_cr("### sweeper: unload time: " INT64_FORMAT, end-start); | |
563 } | |
564 #endif | |
565 } | |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
566 |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
567 |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
568 // Print out some state information about the current sweep and the |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
569 // state of the code cache if it's requested. |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
570 void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
571 if (PrintMethodFlushing) { |
2482
dbccacb79c63
7036236: VM crashes assert((!inside_attrs()) || is_error_reported()) failed ...
iveresov
parents:
2426
diff
changeset
|
572 stringStream s; |
dbccacb79c63
7036236: VM crashes assert((!inside_attrs()) || is_error_reported()) failed ...
iveresov
parents:
2426
diff
changeset
|
573 // Dump code cache state into a buffer before locking the tty, |
dbccacb79c63
7036236: VM crashes assert((!inside_attrs()) || is_error_reported()) failed ...
iveresov
parents:
2426
diff
changeset
|
574 // because log_state() will use locks causing lock conflicts. |
dbccacb79c63
7036236: VM crashes assert((!inside_attrs()) || is_error_reported()) failed ...
iveresov
parents:
2426
diff
changeset
|
575 CodeCache::log_state(&s); |
dbccacb79c63
7036236: VM crashes assert((!inside_attrs()) || is_error_reported()) failed ...
iveresov
parents:
2426
diff
changeset
|
576 |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
577 ttyLocker ttyl; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
578 tty->print("### sweeper: %s ", msg); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
579 if (format != NULL) { |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
580 va_list ap; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
581 va_start(ap, format); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
582 tty->vprint(format, ap); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
583 va_end(ap); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
584 } |
2482
dbccacb79c63
7036236: VM crashes assert((!inside_attrs()) || is_error_reported()) failed ...
iveresov
parents:
2426
diff
changeset
|
585 tty->print_cr(s.as_string()); |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
586 } |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
587 |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
588 if (LogCompilation && (xtty != NULL)) { |
2482
dbccacb79c63
7036236: VM crashes assert((!inside_attrs()) || is_error_reported()) failed ...
iveresov
parents:
2426
diff
changeset
|
589 stringStream s; |
dbccacb79c63
7036236: VM crashes assert((!inside_attrs()) || is_error_reported()) failed ...
iveresov
parents:
2426
diff
changeset
|
590 // Dump code cache state into a buffer before locking the tty, |
dbccacb79c63
7036236: VM crashes assert((!inside_attrs()) || is_error_reported()) failed ...
iveresov
parents:
2426
diff
changeset
|
591 // because log_state() will use locks causing lock conflicts. |
dbccacb79c63
7036236: VM crashes assert((!inside_attrs()) || is_error_reported()) failed ...
iveresov
parents:
2426
diff
changeset
|
592 CodeCache::log_state(&s); |
dbccacb79c63
7036236: VM crashes assert((!inside_attrs()) || is_error_reported()) failed ...
iveresov
parents:
2426
diff
changeset
|
593 |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
594 ttyLocker ttyl; |
1646 | 595 xtty->begin_elem("sweeper state='%s' traversals='" INTX_FORMAT "' ", msg, (intx)traversal_count()); |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
596 if (format != NULL) { |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
597 va_list ap; |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
598 va_start(ap, format); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
599 xtty->vprint(format, ap); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
600 va_end(ap); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
601 } |
2482
dbccacb79c63
7036236: VM crashes assert((!inside_attrs()) || is_error_reported()) failed ...
iveresov
parents:
2426
diff
changeset
|
602 xtty->print(s.as_string()); |
1644
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
603 xtty->stamp(); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
604 xtty->end_elem(); |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
605 } |
2a47bd84841f
6965184: possible races in make_not_entrant_or_zombie
never
parents:
1615
diff
changeset
|
606 } |