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