Mercurial > hg > truffle
annotate src/share/vm/oops/instanceKlass.cpp @ 3917:eca1193ca245
4965777: GC changes to support use of discovered field for pending references
Summary: If and when the reference handler thread is able to use the discovered field to link reference objects in its pending list, so will GC. In that case, GC will scan through this field once a reference object has been placed on the pending list, but not scan that field before that stage, as the field is used by the concurrent GC thread to link discovered objects. When ReferenceHandleR thread does not use the discovered field for the purpose of linking the elements in the pending list, as would be the case in older JDKs, the JVM will fall back to the old behaviour of using the next field for that purpose.
Reviewed-by: jcoomes, mchung, stefank
author | ysr |
---|---|
date | Wed, 07 Sep 2011 13:55:42 -0700 |
parents | fdb992d83a87 |
children | e6b1331a51d2 |
rev | line source |
---|---|
0 | 1 /* |
2227 | 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:
1490
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
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:
1490
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/javaClasses.hpp" | |
27 #include "classfile/systemDictionary.hpp" | |
28 #include "classfile/verifier.hpp" | |
29 #include "classfile/vmSymbols.hpp" | |
30 #include "compiler/compileBroker.hpp" | |
31 #include "gc_implementation/shared/markSweep.inline.hpp" | |
32 #include "gc_interface/collectedHeap.inline.hpp" | |
33 #include "interpreter/oopMapCache.hpp" | |
34 #include "interpreter/rewriter.hpp" | |
35 #include "jvmtifiles/jvmti.h" | |
36 #include "memory/genOopClosures.inline.hpp" | |
37 #include "memory/oopFactory.hpp" | |
38 #include "memory/permGen.hpp" | |
39 #include "oops/instanceKlass.hpp" | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
40 #include "oops/instanceMirrorKlass.hpp" |
1972 | 41 #include "oops/instanceOop.hpp" |
42 #include "oops/methodOop.hpp" | |
43 #include "oops/objArrayKlassKlass.hpp" | |
44 #include "oops/oop.inline.hpp" | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
45 #include "oops/symbol.hpp" |
1972 | 46 #include "prims/jvmtiExport.hpp" |
47 #include "prims/jvmtiRedefineClassesTrace.hpp" | |
48 #include "runtime/fieldDescriptor.hpp" | |
49 #include "runtime/handles.inline.hpp" | |
50 #include "runtime/javaCalls.hpp" | |
51 #include "runtime/mutexLocker.hpp" | |
52 #include "services/threadService.hpp" | |
53 #include "utilities/dtrace.hpp" | |
54 #ifdef TARGET_OS_FAMILY_linux | |
55 # include "thread_linux.inline.hpp" | |
56 #endif | |
57 #ifdef TARGET_OS_FAMILY_solaris | |
58 # include "thread_solaris.inline.hpp" | |
59 #endif | |
60 #ifdef TARGET_OS_FAMILY_windows | |
61 # include "thread_windows.inline.hpp" | |
62 #endif | |
63 #ifndef SERIALGC | |
64 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" | |
65 #include "gc_implementation/g1/g1OopClosures.inline.hpp" | |
66 #include "gc_implementation/g1/g1RemSet.inline.hpp" | |
67 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" | |
68 #include "gc_implementation/parNew/parOopClosures.inline.hpp" | |
69 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" | |
70 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" | |
71 #include "oops/oop.pcgc.inline.hpp" | |
72 #endif | |
73 #ifdef COMPILER1 | |
74 #include "c1/c1_Compiler.hpp" | |
75 #endif | |
0 | 76 |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
77 #ifdef DTRACE_ENABLED |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
78 |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
79 HS_DTRACE_PROBE_DECL4(hotspot, class__initialization__required, |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
80 char*, intptr_t, oop, intptr_t); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
81 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__recursive, |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
82 char*, intptr_t, oop, intptr_t, int); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
83 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__concurrent, |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
84 char*, intptr_t, oop, intptr_t, int); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
85 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__erroneous, |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
86 char*, intptr_t, oop, intptr_t, int); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
87 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__super__failed, |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
88 char*, intptr_t, oop, intptr_t, int); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
89 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__clinit, |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
90 char*, intptr_t, oop, intptr_t, int); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
91 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__error, |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
92 char*, intptr_t, oop, intptr_t, int); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
93 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end, |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
94 char*, intptr_t, oop, intptr_t, int); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
95 |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
96 #define DTRACE_CLASSINIT_PROBE(type, clss, thread_type) \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
97 { \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
98 char* data = NULL; \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
99 int len = 0; \ |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
100 Symbol* name = (clss)->name(); \ |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
101 if (name != NULL) { \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
102 data = (char*)name->bytes(); \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
103 len = name->utf8_length(); \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
104 } \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
105 HS_DTRACE_PROBE4(hotspot, class__initialization__##type, \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
106 data, len, (clss)->class_loader(), thread_type); \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
107 } |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
108 |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
109 #define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
110 { \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
111 char* data = NULL; \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
112 int len = 0; \ |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
113 Symbol* name = (clss)->name(); \ |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
114 if (name != NULL) { \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
115 data = (char*)name->bytes(); \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
116 len = name->utf8_length(); \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
117 } \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
118 HS_DTRACE_PROBE5(hotspot, class__initialization__##type, \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
119 data, len, (clss)->class_loader(), thread_type, wait); \ |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
120 } |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
121 |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
122 #else // ndef DTRACE_ENABLED |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
123 |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
124 #define DTRACE_CLASSINIT_PROBE(type, clss, thread_type) |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
125 #define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
126 |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
127 #endif // ndef DTRACE_ENABLED |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
128 |
0 | 129 bool instanceKlass::should_be_initialized() const { |
130 return !is_initialized(); | |
131 } | |
132 | |
133 klassVtable* instanceKlass::vtable() const { | |
134 return new klassVtable(as_klassOop(), start_of_vtable(), vtable_length() / vtableEntry::size()); | |
135 } | |
136 | |
137 klassItable* instanceKlass::itable() const { | |
138 return new klassItable(as_klassOop()); | |
139 } | |
140 | |
141 void instanceKlass::eager_initialize(Thread *thread) { | |
142 if (!EagerInitialization) return; | |
143 | |
144 if (this->is_not_initialized()) { | |
145 // abort if the the class has a class initializer | |
146 if (this->class_initializer() != NULL) return; | |
147 | |
148 // abort if it is java.lang.Object (initialization is handled in genesis) | |
149 klassOop super = this->super(); | |
150 if (super == NULL) return; | |
151 | |
152 // abort if the super class should be initialized | |
153 if (!instanceKlass::cast(super)->is_initialized()) return; | |
154 | |
155 // call body to expose the this pointer | |
156 instanceKlassHandle this_oop(thread, this->as_klassOop()); | |
157 eager_initialize_impl(this_oop); | |
158 } | |
159 } | |
160 | |
161 | |
162 void instanceKlass::eager_initialize_impl(instanceKlassHandle this_oop) { | |
163 EXCEPTION_MARK; | |
164 ObjectLocker ol(this_oop, THREAD); | |
165 | |
166 // abort if someone beat us to the initialization | |
167 if (!this_oop->is_not_initialized()) return; // note: not equivalent to is_initialized() | |
168 | |
169 ClassState old_state = this_oop->_init_state; | |
170 link_class_impl(this_oop, true, THREAD); | |
171 if (HAS_PENDING_EXCEPTION) { | |
172 CLEAR_PENDING_EXCEPTION; | |
173 // Abort if linking the class throws an exception. | |
174 | |
175 // Use a test to avoid redundantly resetting the state if there's | |
176 // no change. Set_init_state() asserts that state changes make | |
177 // progress, whereas here we might just be spinning in place. | |
178 if( old_state != this_oop->_init_state ) | |
179 this_oop->set_init_state (old_state); | |
180 } else { | |
181 // linking successfull, mark class as initialized | |
182 this_oop->set_init_state (fully_initialized); | |
183 // trace | |
184 if (TraceClassInitialization) { | |
185 ResourceMark rm(THREAD); | |
186 tty->print_cr("[Initialized %s without side effects]", this_oop->external_name()); | |
187 } | |
188 } | |
189 } | |
190 | |
191 | |
192 // See "The Virtual Machine Specification" section 2.16.5 for a detailed explanation of the class initialization | |
193 // process. The step comments refers to the procedure described in that section. | |
194 // Note: implementation moved to static method to expose the this pointer. | |
195 void instanceKlass::initialize(TRAPS) { | |
196 if (this->should_be_initialized()) { | |
197 HandleMark hm(THREAD); | |
198 instanceKlassHandle this_oop(THREAD, this->as_klassOop()); | |
199 initialize_impl(this_oop, CHECK); | |
200 // Note: at this point the class may be initialized | |
201 // OR it may be in the state of being initialized | |
202 // in case of recursive initialization! | |
203 } else { | |
204 assert(is_initialized(), "sanity check"); | |
205 } | |
206 } | |
207 | |
208 | |
209 bool instanceKlass::verify_code( | |
210 instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS) { | |
211 // 1) Verify the bytecodes | |
212 Verifier::Mode mode = | |
213 throw_verifyerror ? Verifier::ThrowException : Verifier::NoException; | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
964
diff
changeset
|
214 return Verifier::verify(this_oop, mode, this_oop->should_verify_class(), CHECK_false); |
0 | 215 } |
216 | |
217 | |
218 // Used exclusively by the shared spaces dump mechanism to prevent | |
219 // classes mapped into the shared regions in new VMs from appearing linked. | |
220 | |
221 void instanceKlass::unlink_class() { | |
222 assert(is_linked(), "must be linked"); | |
223 _init_state = loaded; | |
224 } | |
225 | |
226 void instanceKlass::link_class(TRAPS) { | |
227 assert(is_loaded(), "must be loaded"); | |
228 if (!is_linked()) { | |
229 instanceKlassHandle this_oop(THREAD, this->as_klassOop()); | |
230 link_class_impl(this_oop, true, CHECK); | |
231 } | |
232 } | |
233 | |
234 // Called to verify that a class can link during initialization, without | |
235 // throwing a VerifyError. | |
236 bool instanceKlass::link_class_or_fail(TRAPS) { | |
237 assert(is_loaded(), "must be loaded"); | |
238 if (!is_linked()) { | |
239 instanceKlassHandle this_oop(THREAD, this->as_klassOop()); | |
240 link_class_impl(this_oop, false, CHECK_false); | |
241 } | |
242 return is_linked(); | |
243 } | |
244 | |
245 bool instanceKlass::link_class_impl( | |
246 instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS) { | |
247 // check for error state | |
248 if (this_oop->is_in_error_state()) { | |
249 ResourceMark rm(THREAD); | |
250 THROW_MSG_(vmSymbols::java_lang_NoClassDefFoundError(), | |
251 this_oop->external_name(), false); | |
252 } | |
253 // return if already verified | |
254 if (this_oop->is_linked()) { | |
255 return true; | |
256 } | |
257 | |
258 // Timing | |
259 // timer handles recursion | |
260 assert(THREAD->is_Java_thread(), "non-JavaThread in link_class_impl"); | |
261 JavaThread* jt = (JavaThread*)THREAD; | |
262 | |
263 // link super class before linking this class | |
264 instanceKlassHandle super(THREAD, this_oop->super()); | |
265 if (super.not_null()) { | |
266 if (super->is_interface()) { // check if super class is an interface | |
267 ResourceMark rm(THREAD); | |
268 Exceptions::fthrow( | |
269 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
270 vmSymbols::java_lang_IncompatibleClassChangeError(), |
0 | 271 "class %s has interface %s as super class", |
272 this_oop->external_name(), | |
273 super->external_name() | |
274 ); | |
275 return false; | |
276 } | |
277 | |
278 link_class_impl(super, throw_verifyerror, CHECK_false); | |
279 } | |
280 | |
281 // link all interfaces implemented by this class before linking this class | |
282 objArrayHandle interfaces (THREAD, this_oop->local_interfaces()); | |
283 int num_interfaces = interfaces->length(); | |
284 for (int index = 0; index < num_interfaces; index++) { | |
285 HandleMark hm(THREAD); | |
286 instanceKlassHandle ih(THREAD, klassOop(interfaces->obj_at(index))); | |
287 link_class_impl(ih, throw_verifyerror, CHECK_false); | |
288 } | |
289 | |
290 // in case the class is linked in the process of linking its superclasses | |
291 if (this_oop->is_linked()) { | |
292 return true; | |
293 } | |
294 | |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
295 // trace only the link time for this klass that includes |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
296 // the verification time |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
297 PerfClassTraceTime vmtimer(ClassLoader::perf_class_link_time(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
298 ClassLoader::perf_class_link_selftime(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
299 ClassLoader::perf_classes_linked(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
300 jt->get_thread_stat()->perf_recursion_counts_addr(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
301 jt->get_thread_stat()->perf_timers_addr(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
302 PerfClassTraceTime::CLASS_LINK); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
303 |
0 | 304 // verification & rewriting |
305 { | |
306 ObjectLocker ol(this_oop, THREAD); | |
307 // rewritten will have been set if loader constraint error found | |
308 // on an earlier link attempt | |
309 // don't verify or rewrite if already rewritten | |
310 if (!this_oop->is_linked()) { | |
311 if (!this_oop->is_rewritten()) { | |
312 { | |
313 // Timer includes any side effects of class verification (resolution, | |
314 // etc), but not recursive entry into verify_code(). | |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
315 PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
316 ClassLoader::perf_class_verify_selftime(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
317 ClassLoader::perf_classes_verified(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
318 jt->get_thread_stat()->perf_recursion_counts_addr(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
319 jt->get_thread_stat()->perf_timers_addr(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
320 PerfClassTraceTime::CLASS_VERIFY); |
0 | 321 bool verify_ok = verify_code(this_oop, throw_verifyerror, THREAD); |
322 if (!verify_ok) { | |
323 return false; | |
324 } | |
325 } | |
326 | |
327 // Just in case a side-effect of verify linked this class already | |
328 // (which can sometimes happen since the verifier loads classes | |
329 // using custom class loaders, which are free to initialize things) | |
330 if (this_oop->is_linked()) { | |
331 return true; | |
332 } | |
333 | |
334 // also sets rewritten | |
335 this_oop->rewrite_class(CHECK_false); | |
336 } | |
337 | |
3748 | 338 // relocate jsrs and link methods after they are all rewritten |
339 this_oop->relocate_and_link_methods(CHECK_false); | |
340 | |
0 | 341 // Initialize the vtable and interface table after |
342 // methods have been rewritten since rewrite may | |
343 // fabricate new methodOops. | |
344 // also does loader constraint checking | |
345 if (!this_oop()->is_shared()) { | |
346 ResourceMark rm(THREAD); | |
347 this_oop->vtable()->initialize_vtable(true, CHECK_false); | |
348 this_oop->itable()->initialize_itable(true, CHECK_false); | |
349 } | |
350 #ifdef ASSERT | |
351 else { | |
352 ResourceMark rm(THREAD); | |
353 this_oop->vtable()->verify(tty, true); | |
354 // In case itable verification is ever added. | |
355 // this_oop->itable()->verify(tty, true); | |
356 } | |
357 #endif | |
358 this_oop->set_init_state(linked); | |
359 if (JvmtiExport::should_post_class_prepare()) { | |
360 Thread *thread = THREAD; | |
361 assert(thread->is_Java_thread(), "thread->is_Java_thread()"); | |
362 JvmtiExport::post_class_prepare((JavaThread *) thread, this_oop()); | |
363 } | |
364 } | |
365 } | |
366 return true; | |
367 } | |
368 | |
369 | |
370 // Rewrite the byte codes of all of the methods of a class. | |
371 // The rewriter must be called exactly once. Rewriting must happen after | |
372 // verification but before the first method of the class is executed. | |
373 void instanceKlass::rewrite_class(TRAPS) { | |
374 assert(is_loaded(), "must be loaded"); | |
375 instanceKlassHandle this_oop(THREAD, this->as_klassOop()); | |
376 if (this_oop->is_rewritten()) { | |
377 assert(this_oop()->is_shared(), "rewriting an unshared class?"); | |
378 return; | |
379 } | |
3748 | 380 Rewriter::rewrite(this_oop, CHECK); |
0 | 381 this_oop->set_rewritten(); |
382 } | |
383 | |
3748 | 384 // Now relocate and link method entry points after class is rewritten. |
385 // This is outside is_rewritten flag. In case of an exception, it can be | |
386 // executed more than once. | |
387 void instanceKlass::relocate_and_link_methods(TRAPS) { | |
388 assert(is_loaded(), "must be loaded"); | |
389 instanceKlassHandle this_oop(THREAD, this->as_klassOop()); | |
390 Rewriter::relocate_and_link(this_oop, CHECK); | |
391 } | |
392 | |
0 | 393 |
394 void instanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) { | |
395 // Make sure klass is linked (verified) before initialization | |
396 // A class could already be verified, since it has been reflected upon. | |
397 this_oop->link_class(CHECK); | |
398 | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
399 DTRACE_CLASSINIT_PROBE(required, instanceKlass::cast(this_oop()), -1); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
400 |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
401 bool wait = false; |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
402 |
0 | 403 // refer to the JVM book page 47 for description of steps |
404 // Step 1 | |
405 { ObjectLocker ol(this_oop, THREAD); | |
406 | |
407 Thread *self = THREAD; // it's passed the current thread | |
408 | |
409 // Step 2 | |
410 // If we were to use wait() instead of waitInterruptibly() then | |
411 // we might end up throwing IE from link/symbol resolution sites | |
412 // that aren't expected to throw. This would wreak havoc. See 6320309. | |
413 while(this_oop->is_being_initialized() && !this_oop->is_reentrant_initialization(self)) { | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
414 wait = true; |
0 | 415 ol.waitUninterruptibly(CHECK); |
416 } | |
417 | |
418 // Step 3 | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
419 if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self)) { |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
420 DTRACE_CLASSINIT_PROBE_WAIT(recursive, instanceKlass::cast(this_oop()), -1,wait); |
0 | 421 return; |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
422 } |
0 | 423 |
424 // Step 4 | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
425 if (this_oop->is_initialized()) { |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
426 DTRACE_CLASSINIT_PROBE_WAIT(concurrent, instanceKlass::cast(this_oop()), -1,wait); |
0 | 427 return; |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
428 } |
0 | 429 |
430 // Step 5 | |
431 if (this_oop->is_in_error_state()) { | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
432 DTRACE_CLASSINIT_PROBE_WAIT(erroneous, instanceKlass::cast(this_oop()), -1,wait); |
0 | 433 ResourceMark rm(THREAD); |
434 const char* desc = "Could not initialize class "; | |
435 const char* className = this_oop->external_name(); | |
436 size_t msglen = strlen(desc) + strlen(className) + 1; | |
1751
2528b5bd749c
6980262: Memory leak when exception is thrown in static initializer
kamg
parents:
1706
diff
changeset
|
437 char* message = NEW_RESOURCE_ARRAY(char, msglen); |
0 | 438 if (NULL == message) { |
439 // Out of memory: can't create detailed error message | |
440 THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), className); | |
441 } else { | |
442 jio_snprintf(message, msglen, "%s%s", desc, className); | |
443 THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), message); | |
444 } | |
445 } | |
446 | |
447 // Step 6 | |
448 this_oop->set_init_state(being_initialized); | |
449 this_oop->set_init_thread(self); | |
450 } | |
451 | |
452 // Step 7 | |
453 klassOop super_klass = this_oop->super(); | |
454 if (super_klass != NULL && !this_oop->is_interface() && Klass::cast(super_klass)->should_be_initialized()) { | |
455 Klass::cast(super_klass)->initialize(THREAD); | |
456 | |
457 if (HAS_PENDING_EXCEPTION) { | |
458 Handle e(THREAD, PENDING_EXCEPTION); | |
459 CLEAR_PENDING_EXCEPTION; | |
460 { | |
461 EXCEPTION_MARK; | |
462 this_oop->set_initialization_state_and_notify(initialization_error, THREAD); // Locks object, set state, and notify all waiting threads | |
463 CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, superclass initialization error is thrown below | |
464 } | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
465 DTRACE_CLASSINIT_PROBE_WAIT(super__failed, instanceKlass::cast(this_oop()), -1,wait); |
0 | 466 THROW_OOP(e()); |
467 } | |
468 } | |
469 | |
470 // Step 8 | |
471 { | |
472 assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl"); | |
473 JavaThread* jt = (JavaThread*)THREAD; | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
474 DTRACE_CLASSINIT_PROBE_WAIT(clinit, instanceKlass::cast(this_oop()), -1,wait); |
0 | 475 // Timer includes any side effects of class initialization (resolution, |
476 // etc), but not recursive entry into call_class_initializer(). | |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
477 PerfClassTraceTime timer(ClassLoader::perf_class_init_time(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
478 ClassLoader::perf_class_init_selftime(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
479 ClassLoader::perf_classes_inited(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
480 jt->get_thread_stat()->perf_recursion_counts_addr(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
481 jt->get_thread_stat()->perf_timers_addr(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
676
diff
changeset
|
482 PerfClassTraceTime::CLASS_CLINIT); |
0 | 483 this_oop->call_class_initializer(THREAD); |
484 } | |
485 | |
486 // Step 9 | |
487 if (!HAS_PENDING_EXCEPTION) { | |
488 this_oop->set_initialization_state_and_notify(fully_initialized, CHECK); | |
489 { ResourceMark rm(THREAD); | |
490 debug_only(this_oop->vtable()->verify(tty, true);) | |
491 } | |
492 } | |
493 else { | |
494 // Step 10 and 11 | |
495 Handle e(THREAD, PENDING_EXCEPTION); | |
496 CLEAR_PENDING_EXCEPTION; | |
497 { | |
498 EXCEPTION_MARK; | |
499 this_oop->set_initialization_state_and_notify(initialization_error, THREAD); | |
500 CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, class initialization error is thrown below | |
501 } | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
502 DTRACE_CLASSINIT_PROBE_WAIT(error, instanceKlass::cast(this_oop()), -1,wait); |
1142 | 503 if (e->is_a(SystemDictionary::Error_klass())) { |
0 | 504 THROW_OOP(e()); |
505 } else { | |
506 JavaCallArguments args(e); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
507 THROW_ARG(vmSymbols::java_lang_ExceptionInInitializerError(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
508 vmSymbols::throwable_void_signature(), |
0 | 509 &args); |
510 } | |
511 } | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
1155
diff
changeset
|
512 DTRACE_CLASSINIT_PROBE_WAIT(end, instanceKlass::cast(this_oop()), -1,wait); |
0 | 513 } |
514 | |
515 | |
516 // Note: implementation moved to static method to expose the this pointer. | |
517 void instanceKlass::set_initialization_state_and_notify(ClassState state, TRAPS) { | |
518 instanceKlassHandle kh(THREAD, this->as_klassOop()); | |
519 set_initialization_state_and_notify_impl(kh, state, CHECK); | |
520 } | |
521 | |
522 void instanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle this_oop, ClassState state, TRAPS) { | |
523 ObjectLocker ol(this_oop, THREAD); | |
524 this_oop->set_init_state(state); | |
525 ol.notify_all(CHECK); | |
526 } | |
527 | |
528 void instanceKlass::add_implementor(klassOop k) { | |
529 assert(Compile_lock->owned_by_self(), ""); | |
530 // Filter out my subinterfaces. | |
531 // (Note: Interfaces are never on the subklass list.) | |
532 if (instanceKlass::cast(k)->is_interface()) return; | |
533 | |
534 // Filter out subclasses whose supers already implement me. | |
535 // (Note: CHA must walk subclasses of direct implementors | |
536 // in order to locate indirect implementors.) | |
537 klassOop sk = instanceKlass::cast(k)->super(); | |
538 if (sk != NULL && instanceKlass::cast(sk)->implements_interface(as_klassOop())) | |
539 // We only need to check one immediate superclass, since the | |
540 // implements_interface query looks at transitive_interfaces. | |
541 // Any supers of the super have the same (or fewer) transitive_interfaces. | |
542 return; | |
543 | |
544 // Update number of implementors | |
545 int i = _nof_implementors++; | |
546 | |
547 // Record this implementor, if there are not too many already | |
548 if (i < implementors_limit) { | |
549 assert(_implementors[i] == NULL, "should be exactly one implementor"); | |
550 oop_store_without_check((oop*)&_implementors[i], k); | |
551 } else if (i == implementors_limit) { | |
552 // clear out the list on first overflow | |
553 for (int i2 = 0; i2 < implementors_limit; i2++) | |
554 oop_store_without_check((oop*)&_implementors[i2], NULL); | |
555 } | |
556 | |
557 // The implementor also implements the transitive_interfaces | |
558 for (int index = 0; index < local_interfaces()->length(); index++) { | |
559 instanceKlass::cast(klassOop(local_interfaces()->obj_at(index)))->add_implementor(k); | |
560 } | |
561 } | |
562 | |
563 void instanceKlass::init_implementor() { | |
564 for (int i = 0; i < implementors_limit; i++) | |
565 oop_store_without_check((oop*)&_implementors[i], NULL); | |
566 _nof_implementors = 0; | |
567 } | |
568 | |
569 | |
570 void instanceKlass::process_interfaces(Thread *thread) { | |
571 // link this class into the implementors list of every interface it implements | |
572 KlassHandle this_as_oop (thread, this->as_klassOop()); | |
573 for (int i = local_interfaces()->length() - 1; i >= 0; i--) { | |
574 assert(local_interfaces()->obj_at(i)->is_klass(), "must be a klass"); | |
575 instanceKlass* interf = instanceKlass::cast(klassOop(local_interfaces()->obj_at(i))); | |
576 assert(interf->is_interface(), "expected interface"); | |
577 interf->add_implementor(this_as_oop()); | |
578 } | |
579 } | |
580 | |
581 bool instanceKlass::can_be_primary_super_slow() const { | |
582 if (is_interface()) | |
583 return false; | |
584 else | |
585 return Klass::can_be_primary_super_slow(); | |
586 } | |
587 | |
588 objArrayOop instanceKlass::compute_secondary_supers(int num_extra_slots, TRAPS) { | |
589 // The secondaries are the implemented interfaces. | |
590 instanceKlass* ik = instanceKlass::cast(as_klassOop()); | |
591 objArrayHandle interfaces (THREAD, ik->transitive_interfaces()); | |
592 int num_secondaries = num_extra_slots + interfaces->length(); | |
593 if (num_secondaries == 0) { | |
594 return Universe::the_empty_system_obj_array(); | |
595 } else if (num_extra_slots == 0) { | |
596 return interfaces(); | |
597 } else { | |
598 // a mix of both | |
599 objArrayOop secondaries = oopFactory::new_system_objArray(num_secondaries, CHECK_NULL); | |
600 for (int i = 0; i < interfaces->length(); i++) { | |
601 secondaries->obj_at_put(num_extra_slots+i, interfaces->obj_at(i)); | |
602 } | |
603 return secondaries; | |
604 } | |
605 } | |
606 | |
607 bool instanceKlass::compute_is_subtype_of(klassOop k) { | |
608 if (Klass::cast(k)->is_interface()) { | |
609 return implements_interface(k); | |
610 } else { | |
611 return Klass::compute_is_subtype_of(k); | |
612 } | |
613 } | |
614 | |
615 bool instanceKlass::implements_interface(klassOop k) const { | |
616 if (as_klassOop() == k) return true; | |
617 assert(Klass::cast(k)->is_interface(), "should be an interface class"); | |
618 for (int i = 0; i < transitive_interfaces()->length(); i++) { | |
619 if (transitive_interfaces()->obj_at(i) == k) { | |
620 return true; | |
621 } | |
622 } | |
623 return false; | |
624 } | |
625 | |
626 objArrayOop instanceKlass::allocate_objArray(int n, int length, TRAPS) { | |
627 if (length < 0) THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); | |
628 if (length > arrayOopDesc::max_array_length(T_OBJECT)) { | |
876
1413494da700
6850957: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
875
diff
changeset
|
629 report_java_out_of_memory("Requested array size exceeds VM limit"); |
0 | 630 THROW_OOP_0(Universe::out_of_memory_error_array_size()); |
631 } | |
632 int size = objArrayOopDesc::object_size(length); | |
633 klassOop ak = array_klass(n, CHECK_NULL); | |
634 KlassHandle h_ak (THREAD, ak); | |
635 objArrayOop o = | |
636 (objArrayOop)CollectedHeap::array_allocate(h_ak, size, length, CHECK_NULL); | |
637 return o; | |
638 } | |
639 | |
640 instanceOop instanceKlass::register_finalizer(instanceOop i, TRAPS) { | |
641 if (TraceFinalizerRegistration) { | |
642 tty->print("Registered "); | |
643 i->print_value_on(tty); | |
644 tty->print_cr(" (" INTPTR_FORMAT ") as finalizable", (address)i); | |
645 } | |
646 instanceHandle h_i(THREAD, i); | |
647 // Pass the handle as argument, JavaCalls::call expects oop as jobjects | |
648 JavaValue result(T_VOID); | |
649 JavaCallArguments args(h_i); | |
650 methodHandle mh (THREAD, Universe::finalizer_register_method()); | |
651 JavaCalls::call(&result, mh, &args, CHECK_NULL); | |
652 return h_i(); | |
653 } | |
654 | |
655 instanceOop instanceKlass::allocate_instance(TRAPS) { | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
656 assert(!oop_is_instanceMirror(), "wrong allocation path"); |
0 | 657 bool has_finalizer_flag = has_finalizer(); // Query before possible GC |
658 int size = size_helper(); // Query before forming handle. | |
659 | |
660 KlassHandle h_k(THREAD, as_klassOop()); | |
661 | |
662 instanceOop i; | |
663 | |
664 i = (instanceOop)CollectedHeap::obj_allocate(h_k, size, CHECK_NULL); | |
665 if (has_finalizer_flag && !RegisterFinalizersAtInit) { | |
666 i = register_finalizer(i, CHECK_NULL); | |
667 } | |
668 return i; | |
669 } | |
670 | |
671 instanceOop instanceKlass::allocate_permanent_instance(TRAPS) { | |
672 // Finalizer registration occurs in the Object.<init> constructor | |
673 // and constructors normally aren't run when allocating perm | |
674 // instances so simply disallow finalizable perm objects. This can | |
675 // be relaxed if a need for it is found. | |
676 assert(!has_finalizer(), "perm objects not allowed to have finalizers"); | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
677 assert(!oop_is_instanceMirror(), "wrong allocation path"); |
0 | 678 int size = size_helper(); // Query before forming handle. |
679 KlassHandle h_k(THREAD, as_klassOop()); | |
680 instanceOop i = (instanceOop) | |
681 CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); | |
682 return i; | |
683 } | |
684 | |
685 void instanceKlass::check_valid_for_instantiation(bool throwError, TRAPS) { | |
686 if (is_interface() || is_abstract()) { | |
687 ResourceMark rm(THREAD); | |
688 THROW_MSG(throwError ? vmSymbols::java_lang_InstantiationError() | |
689 : vmSymbols::java_lang_InstantiationException(), external_name()); | |
690 } | |
1142 | 691 if (as_klassOop() == SystemDictionary::Class_klass()) { |
0 | 692 ResourceMark rm(THREAD); |
693 THROW_MSG(throwError ? vmSymbols::java_lang_IllegalAccessError() | |
694 : vmSymbols::java_lang_IllegalAccessException(), external_name()); | |
695 } | |
696 } | |
697 | |
698 klassOop instanceKlass::array_klass_impl(bool or_null, int n, TRAPS) { | |
699 instanceKlassHandle this_oop(THREAD, as_klassOop()); | |
700 return array_klass_impl(this_oop, or_null, n, THREAD); | |
701 } | |
702 | |
703 klassOop instanceKlass::array_klass_impl(instanceKlassHandle this_oop, bool or_null, int n, TRAPS) { | |
704 if (this_oop->array_klasses() == NULL) { | |
705 if (or_null) return NULL; | |
706 | |
707 ResourceMark rm; | |
708 JavaThread *jt = (JavaThread *)THREAD; | |
709 { | |
710 // Atomic creation of array_klasses | |
711 MutexLocker mc(Compile_lock, THREAD); // for vtables | |
712 MutexLocker ma(MultiArray_lock, THREAD); | |
713 | |
714 // Check if update has already taken place | |
715 if (this_oop->array_klasses() == NULL) { | |
716 objArrayKlassKlass* oakk = | |
717 (objArrayKlassKlass*)Universe::objArrayKlassKlassObj()->klass_part(); | |
718 | |
719 klassOop k = oakk->allocate_objArray_klass(1, this_oop, CHECK_NULL); | |
720 this_oop->set_array_klasses(k); | |
721 } | |
722 } | |
723 } | |
724 // _this will always be set at this point | |
725 objArrayKlass* oak = (objArrayKlass*)this_oop->array_klasses()->klass_part(); | |
726 if (or_null) { | |
727 return oak->array_klass_or_null(n); | |
728 } | |
729 return oak->array_klass(n, CHECK_NULL); | |
730 } | |
731 | |
732 klassOop instanceKlass::array_klass_impl(bool or_null, TRAPS) { | |
733 return array_klass_impl(or_null, 1, THREAD); | |
734 } | |
735 | |
736 void instanceKlass::call_class_initializer(TRAPS) { | |
737 instanceKlassHandle ik (THREAD, as_klassOop()); | |
738 call_class_initializer_impl(ik, THREAD); | |
739 } | |
740 | |
741 static int call_class_initializer_impl_counter = 0; // for debugging | |
742 | |
743 methodOop instanceKlass::class_initializer() { | |
2334
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2227
diff
changeset
|
744 methodOop clinit = find_method( |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2227
diff
changeset
|
745 vmSymbols::class_initializer_name(), vmSymbols::void_method_signature()); |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2227
diff
changeset
|
746 if (clinit != NULL && clinit->has_valid_initializer_flags()) { |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2227
diff
changeset
|
747 return clinit; |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2227
diff
changeset
|
748 } |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2227
diff
changeset
|
749 return NULL; |
0 | 750 } |
751 | |
752 void instanceKlass::call_class_initializer_impl(instanceKlassHandle this_oop, TRAPS) { | |
753 methodHandle h_method(THREAD, this_oop->class_initializer()); | |
754 assert(!this_oop->is_initialized(), "we cannot initialize twice"); | |
755 if (TraceClassInitialization) { | |
756 tty->print("%d Initializing ", call_class_initializer_impl_counter++); | |
757 this_oop->name()->print_value(); | |
758 tty->print_cr("%s (" INTPTR_FORMAT ")", h_method() == NULL ? "(no method)" : "", (address)this_oop()); | |
759 } | |
760 if (h_method() != NULL) { | |
761 JavaCallArguments args; // No arguments | |
762 JavaValue result(T_VOID); | |
763 JavaCalls::call(&result, h_method, &args, CHECK); // Static call (no args) | |
764 } | |
765 } | |
766 | |
767 | |
768 void instanceKlass::mask_for(methodHandle method, int bci, | |
769 InterpreterOopMap* entry_for) { | |
770 // Dirty read, then double-check under a lock. | |
771 if (_oop_map_cache == NULL) { | |
772 // Otherwise, allocate a new one. | |
773 MutexLocker x(OopMapCacheAlloc_lock); | |
774 // First time use. Allocate a cache in C heap | |
775 if (_oop_map_cache == NULL) { | |
776 _oop_map_cache = new OopMapCache(); | |
777 } | |
778 } | |
779 // _oop_map_cache is constant after init; lookup below does is own locking. | |
780 _oop_map_cache->lookup(method, bci, entry_for); | |
781 } | |
782 | |
783 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
784 bool instanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const { |
0 | 785 const int n = fields()->length(); |
786 for (int i = 0; i < n; i += next_offset ) { | |
787 int name_index = fields()->ushort_at(i + name_index_offset); | |
788 int sig_index = fields()->ushort_at(i + signature_index_offset); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
789 Symbol* f_name = constants()->symbol_at(name_index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
790 Symbol* f_sig = constants()->symbol_at(sig_index); |
0 | 791 if (f_name == name && f_sig == sig) { |
792 fd->initialize(as_klassOop(), i); | |
793 return true; | |
794 } | |
795 } | |
796 return false; | |
797 } | |
798 | |
799 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
800 void instanceKlass::shared_symbols_iterate(SymbolClosure* closure) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
801 Klass::shared_symbols_iterate(closure); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
802 closure->do_symbol(&_generic_signature); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
803 closure->do_symbol(&_source_file_name); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
804 closure->do_symbol(&_source_debug_extension); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
805 |
0 | 806 const int n = fields()->length(); |
807 for (int i = 0; i < n; i += next_offset ) { | |
808 int name_index = fields()->ushort_at(i + name_index_offset); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
809 closure->do_symbol(constants()->symbol_at_addr(name_index)); |
0 | 810 int sig_index = fields()->ushort_at(i + signature_index_offset); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
811 closure->do_symbol(constants()->symbol_at_addr(sig_index)); |
0 | 812 } |
813 } | |
814 | |
815 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
816 klassOop instanceKlass::find_interface_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const { |
0 | 817 const int n = local_interfaces()->length(); |
818 for (int i = 0; i < n; i++) { | |
819 klassOop intf1 = klassOop(local_interfaces()->obj_at(i)); | |
820 assert(Klass::cast(intf1)->is_interface(), "just checking type"); | |
821 // search for field in current interface | |
822 if (instanceKlass::cast(intf1)->find_local_field(name, sig, fd)) { | |
823 assert(fd->is_static(), "interface field must be static"); | |
824 return intf1; | |
825 } | |
826 // search for field in direct superinterfaces | |
827 klassOop intf2 = instanceKlass::cast(intf1)->find_interface_field(name, sig, fd); | |
828 if (intf2 != NULL) return intf2; | |
829 } | |
830 // otherwise field lookup fails | |
831 return NULL; | |
832 } | |
833 | |
834 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
835 klassOop instanceKlass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const { |
0 | 836 // search order according to newest JVM spec (5.4.3.2, p.167). |
837 // 1) search for field in current klass | |
838 if (find_local_field(name, sig, fd)) { | |
839 return as_klassOop(); | |
840 } | |
841 // 2) search for field recursively in direct superinterfaces | |
842 { klassOop intf = find_interface_field(name, sig, fd); | |
843 if (intf != NULL) return intf; | |
844 } | |
845 // 3) apply field lookup recursively if superclass exists | |
846 { klassOop supr = super(); | |
847 if (supr != NULL) return instanceKlass::cast(supr)->find_field(name, sig, fd); | |
848 } | |
849 // 4) otherwise field lookup fails | |
850 return NULL; | |
851 } | |
852 | |
853 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
854 klassOop instanceKlass::find_field(Symbol* name, Symbol* sig, bool is_static, fieldDescriptor* fd) const { |
0 | 855 // search order according to newest JVM spec (5.4.3.2, p.167). |
856 // 1) search for field in current klass | |
857 if (find_local_field(name, sig, fd)) { | |
858 if (fd->is_static() == is_static) return as_klassOop(); | |
859 } | |
860 // 2) search for field recursively in direct superinterfaces | |
861 if (is_static) { | |
862 klassOop intf = find_interface_field(name, sig, fd); | |
863 if (intf != NULL) return intf; | |
864 } | |
865 // 3) apply field lookup recursively if superclass exists | |
866 { klassOop supr = super(); | |
867 if (supr != NULL) return instanceKlass::cast(supr)->find_field(name, sig, is_static, fd); | |
868 } | |
869 // 4) otherwise field lookup fails | |
870 return NULL; | |
871 } | |
872 | |
873 | |
874 bool instanceKlass::find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const { | |
875 int length = fields()->length(); | |
876 for (int i = 0; i < length; i += next_offset) { | |
877 if (offset_from_fields( i ) == offset) { | |
878 fd->initialize(as_klassOop(), i); | |
879 if (fd->is_static() == is_static) return true; | |
880 } | |
881 } | |
882 return false; | |
883 } | |
884 | |
885 | |
886 bool instanceKlass::find_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const { | |
887 klassOop klass = as_klassOop(); | |
888 while (klass != NULL) { | |
889 if (instanceKlass::cast(klass)->find_local_field_from_offset(offset, is_static, fd)) { | |
890 return true; | |
891 } | |
892 klass = Klass::cast(klass)->super(); | |
893 } | |
894 return false; | |
895 } | |
896 | |
897 | |
898 void instanceKlass::methods_do(void f(methodOop method)) { | |
899 int len = methods()->length(); | |
900 for (int index = 0; index < len; index++) { | |
901 methodOop m = methodOop(methods()->obj_at(index)); | |
902 assert(m->is_method(), "must be method"); | |
903 f(m); | |
904 } | |
905 } | |
906 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
907 |
0 | 908 void instanceKlass::do_local_static_fields(FieldClosure* cl) { |
909 fieldDescriptor fd; | |
910 int length = fields()->length(); | |
911 for (int i = 0; i < length; i += next_offset) { | |
912 fd.initialize(as_klassOop(), i); | |
913 if (fd.is_static()) cl->do_field(&fd); | |
914 } | |
915 } | |
916 | |
917 | |
918 void instanceKlass::do_local_static_fields(void f(fieldDescriptor*, TRAPS), TRAPS) { | |
919 instanceKlassHandle h_this(THREAD, as_klassOop()); | |
920 do_local_static_fields_impl(h_this, f, CHECK); | |
921 } | |
922 | |
923 | |
924 void instanceKlass::do_local_static_fields_impl(instanceKlassHandle this_oop, void f(fieldDescriptor* fd, TRAPS), TRAPS) { | |
925 fieldDescriptor fd; | |
926 int length = this_oop->fields()->length(); | |
927 for (int i = 0; i < length; i += next_offset) { | |
928 fd.initialize(this_oop(), i); | |
929 if (fd.is_static()) { f(&fd, CHECK); } // Do NOT remove {}! (CHECK macro expands into several statements) | |
930 } | |
931 } | |
932 | |
933 | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
934 static int compare_fields_by_offset(int* a, int* b) { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
935 return a[0] - b[0]; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
936 } |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
937 |
0 | 938 void instanceKlass::do_nonstatic_fields(FieldClosure* cl) { |
939 instanceKlass* super = superklass(); | |
940 if (super != NULL) { | |
941 super->do_nonstatic_fields(cl); | |
942 } | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
943 fieldDescriptor fd; |
0 | 944 int length = fields()->length(); |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
945 // In DebugInfo nonstatic fields are sorted by offset. |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
946 int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1)); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
947 int j = 0; |
0 | 948 for (int i = 0; i < length; i += next_offset) { |
949 fd.initialize(as_klassOop(), i); | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
950 if (!fd.is_static()) { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
951 fields_sorted[j + 0] = fd.offset(); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
952 fields_sorted[j + 1] = i; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
953 j += 2; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
954 } |
0 | 955 } |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
956 if (j > 0) { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
957 length = j; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
958 // _sort_Fn is defined in growableArray.hpp. |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
959 qsort(fields_sorted, length/2, 2*sizeof(int), (_sort_Fn)compare_fields_by_offset); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
960 for (int i = 0; i < length; i += 2) { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
961 fd.initialize(as_klassOop(), fields_sorted[i + 1]); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
962 assert(!fd.is_static() && fd.offset() == fields_sorted[i], "only nonstatic fields"); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
963 cl->do_field(&fd); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
964 } |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
965 } |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
966 FREE_C_HEAP_ARRAY(int, fields_sorted); |
0 | 967 } |
968 | |
969 | |
970 void instanceKlass::array_klasses_do(void f(klassOop k)) { | |
971 if (array_klasses() != NULL) | |
972 arrayKlass::cast(array_klasses())->array_klasses_do(f); | |
973 } | |
974 | |
975 | |
976 void instanceKlass::with_array_klasses_do(void f(klassOop k)) { | |
977 f(as_klassOop()); | |
978 array_klasses_do(f); | |
979 } | |
980 | |
981 #ifdef ASSERT | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
982 static int linear_search(objArrayOop methods, Symbol* name, Symbol* signature) { |
0 | 983 int len = methods->length(); |
984 for (int index = 0; index < len; index++) { | |
985 methodOop m = (methodOop)(methods->obj_at(index)); | |
986 assert(m->is_method(), "must be method"); | |
987 if (m->signature() == signature && m->name() == name) { | |
988 return index; | |
989 } | |
990 } | |
991 return -1; | |
992 } | |
993 #endif | |
994 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
995 methodOop instanceKlass::find_method(Symbol* name, Symbol* signature) const { |
0 | 996 return instanceKlass::find_method(methods(), name, signature); |
997 } | |
998 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
999 methodOop instanceKlass::find_method(objArrayOop methods, Symbol* name, Symbol* signature) { |
0 | 1000 int len = methods->length(); |
1001 // methods are sorted, so do binary search | |
1002 int l = 0; | |
1003 int h = len - 1; | |
1004 while (l <= h) { | |
1005 int mid = (l + h) >> 1; | |
1006 methodOop m = (methodOop)methods->obj_at(mid); | |
1007 assert(m->is_method(), "must be method"); | |
1008 int res = m->name()->fast_compare(name); | |
1009 if (res == 0) { | |
1010 // found matching name; do linear search to find matching signature | |
1011 // first, quick check for common case | |
1012 if (m->signature() == signature) return m; | |
1013 // search downwards through overloaded methods | |
1014 int i; | |
1015 for (i = mid - 1; i >= l; i--) { | |
1016 methodOop m = (methodOop)methods->obj_at(i); | |
1017 assert(m->is_method(), "must be method"); | |
1018 if (m->name() != name) break; | |
1019 if (m->signature() == signature) return m; | |
1020 } | |
1021 // search upwards | |
1022 for (i = mid + 1; i <= h; i++) { | |
1023 methodOop m = (methodOop)methods->obj_at(i); | |
1024 assert(m->is_method(), "must be method"); | |
1025 if (m->name() != name) break; | |
1026 if (m->signature() == signature) return m; | |
1027 } | |
1028 // not found | |
1029 #ifdef ASSERT | |
1030 int index = linear_search(methods, name, signature); | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1324
diff
changeset
|
1031 assert(index == -1, err_msg("binary search should have found entry %d", index)); |
0 | 1032 #endif |
1033 return NULL; | |
1034 } else if (res < 0) { | |
1035 l = mid + 1; | |
1036 } else { | |
1037 h = mid - 1; | |
1038 } | |
1039 } | |
1040 #ifdef ASSERT | |
1041 int index = linear_search(methods, name, signature); | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1324
diff
changeset
|
1042 assert(index == -1, err_msg("binary search should have found entry %d", index)); |
0 | 1043 #endif |
1044 return NULL; | |
1045 } | |
1046 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1047 methodOop instanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const { |
0 | 1048 klassOop klass = as_klassOop(); |
1049 while (klass != NULL) { | |
1050 methodOop method = instanceKlass::cast(klass)->find_method(name, signature); | |
1051 if (method != NULL) return method; | |
1052 klass = instanceKlass::cast(klass)->super(); | |
1053 } | |
1054 return NULL; | |
1055 } | |
1056 | |
1057 // lookup a method in all the interfaces that this class implements | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1058 methodOop instanceKlass::lookup_method_in_all_interfaces(Symbol* name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1059 Symbol* signature) const { |
0 | 1060 objArrayOop all_ifs = instanceKlass::cast(as_klassOop())->transitive_interfaces(); |
1061 int num_ifs = all_ifs->length(); | |
1062 instanceKlass *ik = NULL; | |
1063 for (int i = 0; i < num_ifs; i++) { | |
1064 ik = instanceKlass::cast(klassOop(all_ifs->obj_at(i))); | |
1065 methodOop m = ik->lookup_method(name, signature); | |
1066 if (m != NULL) { | |
1067 return m; | |
1068 } | |
1069 } | |
1070 return NULL; | |
1071 } | |
1072 | |
1073 /* jni_id_for_impl for jfieldIds only */ | |
1074 JNIid* instanceKlass::jni_id_for_impl(instanceKlassHandle this_oop, int offset) { | |
1075 MutexLocker ml(JfieldIdCreation_lock); | |
1076 // Retry lookup after we got the lock | |
1077 JNIid* probe = this_oop->jni_ids() == NULL ? NULL : this_oop->jni_ids()->find(offset); | |
1078 if (probe == NULL) { | |
1079 // Slow case, allocate new static field identifier | |
1080 probe = new JNIid(this_oop->as_klassOop(), offset, this_oop->jni_ids()); | |
1081 this_oop->set_jni_ids(probe); | |
1082 } | |
1083 return probe; | |
1084 } | |
1085 | |
1086 | |
1087 /* jni_id_for for jfieldIds only */ | |
1088 JNIid* instanceKlass::jni_id_for(int offset) { | |
1089 JNIid* probe = jni_ids() == NULL ? NULL : jni_ids()->find(offset); | |
1090 if (probe == NULL) { | |
1091 probe = jni_id_for_impl(this->as_klassOop(), offset); | |
1092 } | |
1093 return probe; | |
1094 } | |
1095 | |
1096 | |
1097 // Lookup or create a jmethodID. | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1098 // This code is called by the VMThread and JavaThreads so the |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1099 // locking has to be done very carefully to avoid deadlocks |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1100 // and/or other cache consistency problems. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1101 // |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1102 jmethodID instanceKlass::get_jmethod_id(instanceKlassHandle ik_h, methodHandle method_h) { |
0 | 1103 size_t idnum = (size_t)method_h->method_idnum(); |
1104 jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire(); | |
1105 size_t length = 0; | |
1106 jmethodID id = NULL; | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1107 |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1108 // We use a double-check locking idiom here because this cache is |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1109 // performance sensitive. In the normal system, this cache only |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1110 // transitions from NULL to non-NULL which is safe because we use |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1111 // release_set_methods_jmethod_ids() to advertise the new cache. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1112 // A partially constructed cache should never be seen by a racing |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1113 // thread. We also use release_store_ptr() to save a new jmethodID |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1114 // in the cache so a partially constructed jmethodID should never be |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1115 // seen either. Cache reads of existing jmethodIDs proceed without a |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1116 // lock, but cache writes of a new jmethodID requires uniqueness and |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1117 // creation of the cache itself requires no leaks so a lock is |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1118 // generally acquired in those two cases. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1119 // |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1120 // If the RedefineClasses() API has been used, then this cache can |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1121 // grow and we'll have transitions from non-NULL to bigger non-NULL. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1122 // Cache creation requires no leaks and we require safety between all |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1123 // cache accesses and freeing of the old cache so a lock is generally |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1124 // acquired when the RedefineClasses() API has been used. |
0 | 1125 |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1126 if (jmeths != NULL) { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1127 // the cache already exists |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1128 if (!ik_h->idnum_can_increment()) { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1129 // the cache can't grow so we can just get the current values |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1130 get_jmethod_id_length_value(jmeths, idnum, &length, &id); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1131 } else { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1132 // cache can grow so we have to be more careful |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1133 if (Threads::number_of_threads() == 0 || |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1134 SafepointSynchronize::is_at_safepoint()) { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1135 // we're single threaded or at a safepoint - no locking needed |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1136 get_jmethod_id_length_value(jmeths, idnum, &length, &id); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1137 } else { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1138 MutexLocker ml(JmethodIdCreation_lock); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1139 get_jmethod_id_length_value(jmeths, idnum, &length, &id); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1140 } |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1141 } |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1142 } |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1143 // implied else: |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1144 // we need to allocate a cache so default length and id values are good |
0 | 1145 |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1146 if (jmeths == NULL || // no cache yet |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1147 length <= idnum || // cache is too short |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1148 id == NULL) { // cache doesn't contain entry |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1149 |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1150 // This function can be called by the VMThread so we have to do all |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1151 // things that might block on a safepoint before grabbing the lock. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1152 // Otherwise, we can deadlock with the VMThread or have a cache |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1153 // consistency issue. These vars keep track of what we might have |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1154 // to free after the lock is dropped. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1155 jmethodID to_dealloc_id = NULL; |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1156 jmethodID* to_dealloc_jmeths = NULL; |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1157 |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1158 // may not allocate new_jmeths or use it if we allocate it |
0 | 1159 jmethodID* new_jmeths = NULL; |
1160 if (length <= idnum) { | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1161 // allocate a new cache that might be used |
0 | 1162 size_t size = MAX2(idnum+1, (size_t)ik_h->idnum_allocated_count()); |
1163 new_jmeths = NEW_C_HEAP_ARRAY(jmethodID, size+1); | |
1164 memset(new_jmeths, 0, (size+1)*sizeof(jmethodID)); | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1165 // cache size is stored in element[0], other elements offset by one |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1166 new_jmeths[0] = (jmethodID)size; |
0 | 1167 } |
1168 | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1169 // allocate a new jmethodID that might be used |
0 | 1170 jmethodID new_id = NULL; |
1171 if (method_h->is_old() && !method_h->is_obsolete()) { | |
1172 // The method passed in is old (but not obsolete), we need to use the current version | |
1173 methodOop current_method = ik_h->method_with_idnum((int)idnum); | |
1174 assert(current_method != NULL, "old and but not obsolete, so should exist"); | |
1175 methodHandle current_method_h(current_method == NULL? method_h() : current_method); | |
1176 new_id = JNIHandles::make_jmethod_id(current_method_h); | |
1177 } else { | |
1178 // It is the current version of the method or an obsolete method, | |
1179 // use the version passed in | |
1180 new_id = JNIHandles::make_jmethod_id(method_h); | |
1181 } | |
1182 | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1183 if (Threads::number_of_threads() == 0 || |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1184 SafepointSynchronize::is_at_safepoint()) { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1185 // we're single threaded or at a safepoint - no locking needed |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1186 id = get_jmethod_id_fetch_or_update(ik_h, idnum, new_id, new_jmeths, |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1187 &to_dealloc_id, &to_dealloc_jmeths); |
49
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1188 } else { |
0 | 1189 MutexLocker ml(JmethodIdCreation_lock); |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1190 id = get_jmethod_id_fetch_or_update(ik_h, idnum, new_id, new_jmeths, |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1191 &to_dealloc_id, &to_dealloc_jmeths); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1192 } |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1193 |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1194 // The lock has been dropped so we can free resources. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1195 // Free up either the old cache or the new cache if we allocated one. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1196 if (to_dealloc_jmeths != NULL) { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1197 FreeHeap(to_dealloc_jmeths); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1198 } |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1199 // free up the new ID since it wasn't needed |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1200 if (to_dealloc_id != NULL) { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1201 JNIHandles::destroy_jmethod_id(to_dealloc_id); |
49
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1202 } |
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1203 } |
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1204 return id; |
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1205 } |
0 | 1206 |
49
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1207 |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1208 // Common code to fetch the jmethodID from the cache or update the |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1209 // cache with the new jmethodID. This function should never do anything |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1210 // that causes the caller to go to a safepoint or we can deadlock with |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1211 // the VMThread or have cache consistency issues. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1212 // |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1213 jmethodID instanceKlass::get_jmethod_id_fetch_or_update( |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1214 instanceKlassHandle ik_h, size_t idnum, jmethodID new_id, |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1215 jmethodID* new_jmeths, jmethodID* to_dealloc_id_p, |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1216 jmethodID** to_dealloc_jmeths_p) { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1217 assert(new_id != NULL, "sanity check"); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1218 assert(to_dealloc_id_p != NULL, "sanity check"); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1219 assert(to_dealloc_jmeths_p != NULL, "sanity check"); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1220 assert(Threads::number_of_threads() == 0 || |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1221 SafepointSynchronize::is_at_safepoint() || |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1222 JmethodIdCreation_lock->owned_by_self(), "sanity check"); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1223 |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1224 // reacquire the cache - we are locked, single threaded or at a safepoint |
49
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1225 jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire(); |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1226 jmethodID id = NULL; |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1227 size_t length = 0; |
0 | 1228 |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1229 if (jmeths == NULL || // no cache yet |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1230 (length = (size_t)jmeths[0]) <= idnum) { // cache is too short |
49
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1231 if (jmeths != NULL) { |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1232 // copy any existing entries from the old cache |
49
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1233 for (size_t index = 0; index < length; index++) { |
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1234 new_jmeths[index+1] = jmeths[index+1]; |
0 | 1235 } |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1236 *to_dealloc_jmeths_p = jmeths; // save old cache for later delete |
0 | 1237 } |
49
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1238 ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths); |
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1239 } else { |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1240 // fetch jmethodID (if any) from the existing cache |
49
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1241 id = jmeths[idnum+1]; |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1242 *to_dealloc_jmeths_p = new_jmeths; // save new cache for later delete |
49
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1243 } |
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1244 if (id == NULL) { |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1245 // No matching jmethodID in the existing cache or we have a new |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1246 // cache or we just grew the cache. This cache write is done here |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1247 // by the first thread to win the foot race because a jmethodID |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1248 // needs to be unique once it is generally available. |
49
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1249 id = new_id; |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1250 |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1251 // The jmethodID cache can be read while unlocked so we have to |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1252 // make sure the new jmethodID is complete before installing it |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1253 // in the cache. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1254 OrderAccess::release_store_ptr(&jmeths[idnum+1], id); |
49
31000d79ec71
6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents:
47
diff
changeset
|
1255 } else { |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1256 *to_dealloc_id_p = new_id; // save new id for later delete |
0 | 1257 } |
1258 return id; | |
1259 } | |
1260 | |
1261 | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1262 // Common code to get the jmethodID cache length and the jmethodID |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1263 // value at index idnum if there is one. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1264 // |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1265 void instanceKlass::get_jmethod_id_length_value(jmethodID* cache, |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1266 size_t idnum, size_t *length_p, jmethodID* id_p) { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1267 assert(cache != NULL, "sanity check"); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1268 assert(length_p != NULL, "sanity check"); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1269 assert(id_p != NULL, "sanity check"); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1270 |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1271 // cache size is stored in element[0], other elements offset by one |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1272 *length_p = (size_t)cache[0]; |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1273 if (*length_p <= idnum) { // cache is too short |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1274 *id_p = NULL; |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1275 } else { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1276 *id_p = cache[idnum+1]; // fetch jmethodID (if any) |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1277 } |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1278 } |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1279 |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1280 |
0 | 1281 // Lookup a jmethodID, NULL if not found. Do no blocking, no allocations, no handles |
1282 jmethodID instanceKlass::jmethod_id_or_null(methodOop method) { | |
1283 size_t idnum = (size_t)method->method_idnum(); | |
1284 jmethodID* jmeths = methods_jmethod_ids_acquire(); | |
1285 size_t length; // length assigned as debugging crumb | |
1286 jmethodID id = NULL; | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1287 if (jmeths != NULL && // If there is a cache |
0 | 1288 (length = (size_t)jmeths[0]) > idnum) { // and if it is long enough, |
1289 id = jmeths[idnum+1]; // Look up the id (may be NULL) | |
1290 } | |
1291 return id; | |
1292 } | |
1293 | |
1294 | |
1295 // Cache an itable index | |
1296 void instanceKlass::set_cached_itable_index(size_t idnum, int index) { | |
1297 int* indices = methods_cached_itable_indices_acquire(); | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1298 int* to_dealloc_indices = NULL; |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1299 |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1300 // We use a double-check locking idiom here because this cache is |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1301 // performance sensitive. In the normal system, this cache only |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1302 // transitions from NULL to non-NULL which is safe because we use |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1303 // release_set_methods_cached_itable_indices() to advertise the |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1304 // new cache. A partially constructed cache should never be seen |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1305 // by a racing thread. Cache reads and writes proceed without a |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1306 // lock, but creation of the cache itself requires no leaks so a |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1307 // lock is generally acquired in that case. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1308 // |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1309 // If the RedefineClasses() API has been used, then this cache can |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1310 // grow and we'll have transitions from non-NULL to bigger non-NULL. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1311 // Cache creation requires no leaks and we require safety between all |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1312 // cache accesses and freeing of the old cache so a lock is generally |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1313 // acquired when the RedefineClasses() API has been used. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1314 |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1315 if (indices == NULL || idnum_can_increment()) { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1316 // we need a cache or the cache can grow |
0 | 1317 MutexLocker ml(JNICachedItableIndex_lock); |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1318 // reacquire the cache to see if another thread already did the work |
0 | 1319 indices = methods_cached_itable_indices_acquire(); |
1320 size_t length = 0; | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1321 // cache size is stored in element[0], other elements offset by one |
0 | 1322 if (indices == NULL || (length = (size_t)indices[0]) <= idnum) { |
1323 size_t size = MAX2(idnum+1, (size_t)idnum_allocated_count()); | |
1324 int* new_indices = NEW_C_HEAP_ARRAY(int, size+1); | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1325 new_indices[0] = (int)size; |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1326 // copy any existing entries |
0 | 1327 size_t i; |
1328 for (i = 0; i < length; i++) { | |
1329 new_indices[i+1] = indices[i+1]; | |
1330 } | |
1331 // Set all the rest to -1 | |
1332 for (i = length; i < size; i++) { | |
1333 new_indices[i+1] = -1; | |
1334 } | |
1335 if (indices != NULL) { | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1336 // We have an old cache to delete so save it for after we |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1337 // drop the lock. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1338 to_dealloc_indices = indices; |
0 | 1339 } |
1340 release_set_methods_cached_itable_indices(indices = new_indices); | |
1341 } | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1342 |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1343 if (idnum_can_increment()) { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1344 // this cache can grow so we have to write to it safely |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1345 indices[idnum+1] = index; |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1346 } |
0 | 1347 } else { |
1348 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); | |
1349 } | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1350 |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1351 if (!idnum_can_increment()) { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1352 // The cache cannot grow and this JNI itable index value does not |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1353 // have to be unique like a jmethodID. If there is a race to set it, |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1354 // it doesn't matter. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1355 indices[idnum+1] = index; |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1356 } |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1357 |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1358 if (to_dealloc_indices != NULL) { |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1359 // we allocated a new cache so free the old one |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1360 FreeHeap(to_dealloc_indices); |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
1361 } |
0 | 1362 } |
1363 | |
1364 | |
1365 // Retrieve a cached itable index | |
1366 int instanceKlass::cached_itable_index(size_t idnum) { | |
1367 int* indices = methods_cached_itable_indices_acquire(); | |
1368 if (indices != NULL && ((size_t)indices[0]) > idnum) { | |
1369 // indices exist and are long enough, retrieve possible cached | |
1370 return indices[idnum+1]; | |
1371 } | |
1372 return -1; | |
1373 } | |
1374 | |
1375 | |
1376 // | |
1377 // nmethodBucket is used to record dependent nmethods for | |
1378 // deoptimization. nmethod dependencies are actually <klass, method> | |
1379 // pairs but we really only care about the klass part for purposes of | |
1380 // finding nmethods which might need to be deoptimized. Instead of | |
1381 // recording the method, a count of how many times a particular nmethod | |
1382 // was recorded is kept. This ensures that any recording errors are | |
1383 // noticed since an nmethod should be removed as many times are it's | |
1384 // added. | |
1385 // | |
1386 class nmethodBucket { | |
1387 private: | |
1388 nmethod* _nmethod; | |
1389 int _count; | |
1390 nmethodBucket* _next; | |
1391 | |
1392 public: | |
1393 nmethodBucket(nmethod* nmethod, nmethodBucket* next) { | |
1394 _nmethod = nmethod; | |
1395 _next = next; | |
1396 _count = 1; | |
1397 } | |
1398 int count() { return _count; } | |
1399 int increment() { _count += 1; return _count; } | |
1400 int decrement() { _count -= 1; assert(_count >= 0, "don't underflow"); return _count; } | |
1401 nmethodBucket* next() { return _next; } | |
1402 void set_next(nmethodBucket* b) { _next = b; } | |
1403 nmethod* get_nmethod() { return _nmethod; } | |
1404 }; | |
1405 | |
1406 | |
1407 // | |
1408 // Walk the list of dependent nmethods searching for nmethods which | |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3748
diff
changeset
|
1409 // are dependent on the changes that were passed in and mark them for |
0 | 1410 // deoptimization. Returns the number of nmethods found. |
1411 // | |
1412 int instanceKlass::mark_dependent_nmethods(DepChange& changes) { | |
1413 assert_locked_or_safepoint(CodeCache_lock); | |
1414 int found = 0; | |
1415 nmethodBucket* b = _dependencies; | |
1416 while (b != NULL) { | |
1417 nmethod* nm = b->get_nmethod(); | |
1418 // since dependencies aren't removed until an nmethod becomes a zombie, | |
1419 // the dependency list may contain nmethods which aren't alive. | |
1420 if (nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) { | |
1421 if (TraceDependencies) { | |
1422 ResourceMark rm; | |
1423 tty->print_cr("Marked for deoptimization"); | |
1424 tty->print_cr(" context = %s", this->external_name()); | |
1425 changes.print(); | |
1426 nm->print(); | |
1427 nm->print_dependencies(); | |
1428 } | |
1429 nm->mark_for_deoptimization(); | |
1430 found++; | |
1431 } | |
1432 b = b->next(); | |
1433 } | |
1434 return found; | |
1435 } | |
1436 | |
1437 | |
1438 // | |
1439 // Add an nmethodBucket to the list of dependencies for this nmethod. | |
1440 // It's possible that an nmethod has multiple dependencies on this klass | |
1441 // so a count is kept for each bucket to guarantee that creation and | |
1442 // deletion of dependencies is consistent. | |
1443 // | |
1444 void instanceKlass::add_dependent_nmethod(nmethod* nm) { | |
1445 assert_locked_or_safepoint(CodeCache_lock); | |
1446 nmethodBucket* b = _dependencies; | |
1447 nmethodBucket* last = NULL; | |
1448 while (b != NULL) { | |
1449 if (nm == b->get_nmethod()) { | |
1450 b->increment(); | |
1451 return; | |
1452 } | |
1453 b = b->next(); | |
1454 } | |
1455 _dependencies = new nmethodBucket(nm, _dependencies); | |
1456 } | |
1457 | |
1458 | |
1459 // | |
1460 // Decrement count of the nmethod in the dependency list and remove | |
1461 // the bucket competely when the count goes to 0. This method must | |
1462 // find a corresponding bucket otherwise there's a bug in the | |
1463 // recording of dependecies. | |
1464 // | |
1465 void instanceKlass::remove_dependent_nmethod(nmethod* nm) { | |
1466 assert_locked_or_safepoint(CodeCache_lock); | |
1467 nmethodBucket* b = _dependencies; | |
1468 nmethodBucket* last = NULL; | |
1469 while (b != NULL) { | |
1470 if (nm == b->get_nmethod()) { | |
1471 if (b->decrement() == 0) { | |
1472 if (last == NULL) { | |
1473 _dependencies = b->next(); | |
1474 } else { | |
1475 last->set_next(b->next()); | |
1476 } | |
1477 delete b; | |
1478 } | |
1479 return; | |
1480 } | |
1481 last = b; | |
1482 b = b->next(); | |
1483 } | |
1484 #ifdef ASSERT | |
1485 tty->print_cr("### %s can't find dependent nmethod:", this->external_name()); | |
1486 nm->print(); | |
1487 #endif // ASSERT | |
1488 ShouldNotReachHere(); | |
1489 } | |
1490 | |
1491 | |
1492 #ifndef PRODUCT | |
1493 void instanceKlass::print_dependent_nmethods(bool verbose) { | |
1494 nmethodBucket* b = _dependencies; | |
1495 int idx = 0; | |
1496 while (b != NULL) { | |
1497 nmethod* nm = b->get_nmethod(); | |
1498 tty->print("[%d] count=%d { ", idx++, b->count()); | |
1499 if (!verbose) { | |
1500 nm->print_on(tty, "nmethod"); | |
1501 tty->print_cr(" } "); | |
1502 } else { | |
1503 nm->print(); | |
1504 nm->print_dependencies(); | |
1505 tty->print_cr("--- } "); | |
1506 } | |
1507 b = b->next(); | |
1508 } | |
1509 } | |
1510 | |
1511 | |
1512 bool instanceKlass::is_dependent_nmethod(nmethod* nm) { | |
1513 nmethodBucket* b = _dependencies; | |
1514 while (b != NULL) { | |
1515 if (nm == b->get_nmethod()) { | |
1516 return true; | |
1517 } | |
1518 b = b->next(); | |
1519 } | |
1520 return false; | |
1521 } | |
1522 #endif //PRODUCT | |
1523 | |
1524 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1525 #ifdef ASSERT |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1526 template <class T> void assert_is_in(T *p) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1527 T heap_oop = oopDesc::load_heap_oop(p); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1528 if (!oopDesc::is_null(heap_oop)) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1529 oop o = oopDesc::decode_heap_oop_not_null(heap_oop); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1530 assert(Universe::heap()->is_in(o), "should be in heap"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1531 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1532 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1533 template <class T> void assert_is_in_closed_subset(T *p) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1534 T heap_oop = oopDesc::load_heap_oop(p); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1535 if (!oopDesc::is_null(heap_oop)) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1536 oop o = oopDesc::decode_heap_oop_not_null(heap_oop); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1537 assert(Universe::heap()->is_in_closed_subset(o), "should be in closed"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1538 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1539 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1540 template <class T> void assert_is_in_reserved(T *p) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1541 T heap_oop = oopDesc::load_heap_oop(p); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1542 if (!oopDesc::is_null(heap_oop)) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1543 oop o = oopDesc::decode_heap_oop_not_null(heap_oop); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1544 assert(Universe::heap()->is_in_reserved(o), "should be in reserved"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1545 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1546 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1547 template <class T> void assert_nothing(T *p) {} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1548 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1549 #else |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1550 template <class T> void assert_is_in(T *p) {} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1551 template <class T> void assert_is_in_closed_subset(T *p) {} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1552 template <class T> void assert_is_in_reserved(T *p) {} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1553 template <class T> void assert_nothing(T *p) {} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1554 #endif // ASSERT |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1555 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1556 // |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1557 // Macros that iterate over areas of oops which are specialized on type of |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1558 // oop pointer either narrow or wide, depending on UseCompressedOops |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1559 // |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1560 // Parameters are: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1561 // T - type of oop to point to (either oop or narrowOop) |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1562 // start_p - starting pointer for region to iterate over |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1563 // count - number of oops or narrowOops to iterate over |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1564 // do_oop - action to perform on each oop (it's arbitrary C code which |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1565 // makes it more efficient to put in a macro rather than making |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1566 // it a template function) |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1567 // assert_fn - assert function which is template function because performance |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1568 // doesn't matter when enabled. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1569 #define InstanceKlass_SPECIALIZED_OOP_ITERATE( \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1570 T, start_p, count, do_oop, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1571 assert_fn) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1572 { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1573 T* p = (T*)(start_p); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1574 T* const end = p + (count); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1575 while (p < end) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1576 (assert_fn)(p); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1577 do_oop; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1578 ++p; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1579 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1580 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1581 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1582 #define InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE( \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1583 T, start_p, count, do_oop, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1584 assert_fn) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1585 { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1586 T* const start = (T*)(start_p); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1587 T* p = start + (count); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1588 while (start < p) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1589 --p; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1590 (assert_fn)(p); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1591 do_oop; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1592 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1593 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1594 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1595 #define InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE( \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1596 T, start_p, count, low, high, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1597 do_oop, assert_fn) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1598 { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1599 T* const l = (T*)(low); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1600 T* const h = (T*)(high); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1601 assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 && \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1602 mask_bits((intptr_t)h, sizeof(T)-1) == 0, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1603 "bounded region must be properly aligned"); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1604 T* p = (T*)(start_p); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1605 T* end = p + (count); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1606 if (p < l) p = l; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1607 if (end > h) end = h; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1608 while (p < end) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1609 (assert_fn)(p); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1610 do_oop; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1611 ++p; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1612 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1613 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1614 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1615 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1616 // The following macros call specialized macros, passing either oop or |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1617 // narrowOop as the specialization type. These test the UseCompressedOops |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1618 // flag. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1619 #define InstanceKlass_OOP_MAP_ITERATE(obj, do_oop, assert_fn) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1620 { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1621 /* Compute oopmap block range. The common case \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1622 is nonstatic_oop_map_size == 1. */ \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1623 OopMapBlock* map = start_of_nonstatic_oop_maps(); \ |
938 | 1624 OopMapBlock* const end_map = map + nonstatic_oop_map_count(); \ |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1625 if (UseCompressedOops) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1626 while (map < end_map) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1627 InstanceKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \ |
938 | 1628 obj->obj_field_addr<narrowOop>(map->offset()), map->count(), \ |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1629 do_oop, assert_fn) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1630 ++map; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1631 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1632 } else { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1633 while (map < end_map) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1634 InstanceKlass_SPECIALIZED_OOP_ITERATE(oop, \ |
938 | 1635 obj->obj_field_addr<oop>(map->offset()), map->count(), \ |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1636 do_oop, assert_fn) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1637 ++map; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1638 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1639 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1640 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1641 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1642 #define InstanceKlass_OOP_MAP_REVERSE_ITERATE(obj, do_oop, assert_fn) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1643 { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1644 OopMapBlock* const start_map = start_of_nonstatic_oop_maps(); \ |
938 | 1645 OopMapBlock* map = start_map + nonstatic_oop_map_count(); \ |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1646 if (UseCompressedOops) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1647 while (start_map < map) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1648 --map; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1649 InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE(narrowOop, \ |
938 | 1650 obj->obj_field_addr<narrowOop>(map->offset()), map->count(), \ |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1651 do_oop, assert_fn) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1652 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1653 } else { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1654 while (start_map < map) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1655 --map; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1656 InstanceKlass_SPECIALIZED_OOP_REVERSE_ITERATE(oop, \ |
938 | 1657 obj->obj_field_addr<oop>(map->offset()), map->count(), \ |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1658 do_oop, assert_fn) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1659 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1660 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1661 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1662 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1663 #define InstanceKlass_BOUNDED_OOP_MAP_ITERATE(obj, low, high, do_oop, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1664 assert_fn) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1665 { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1666 /* Compute oopmap block range. The common case is \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1667 nonstatic_oop_map_size == 1, so we accept the \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1668 usually non-existent extra overhead of examining \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1669 all the maps. */ \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1670 OopMapBlock* map = start_of_nonstatic_oop_maps(); \ |
938 | 1671 OopMapBlock* const end_map = map + nonstatic_oop_map_count(); \ |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1672 if (UseCompressedOops) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1673 while (map < end_map) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1674 InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \ |
938 | 1675 obj->obj_field_addr<narrowOop>(map->offset()), map->count(), \ |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1676 low, high, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1677 do_oop, assert_fn) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1678 ++map; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1679 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1680 } else { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1681 while (map < end_map) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1682 InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop, \ |
938 | 1683 obj->obj_field_addr<oop>(map->offset()), map->count(), \ |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1684 low, high, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1685 do_oop, assert_fn) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1686 ++map; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1687 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1688 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1689 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1690 |
0 | 1691 void instanceKlass::oop_follow_contents(oop obj) { |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1692 assert(obj != NULL, "can't follow the content of NULL object"); |
0 | 1693 obj->follow_header(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1694 InstanceKlass_OOP_MAP_ITERATE( \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1695 obj, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1696 MarkSweep::mark_and_push(p), \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1697 assert_is_in_closed_subset) |
0 | 1698 } |
1699 | |
1700 #ifndef SERIALGC | |
1701 void instanceKlass::oop_follow_contents(ParCompactionManager* cm, | |
1702 oop obj) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1703 assert(obj != NULL, "can't follow the content of NULL object"); |
0 | 1704 obj->follow_header(cm); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1705 InstanceKlass_OOP_MAP_ITERATE( \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1706 obj, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1707 PSParallelCompact::mark_and_push(cm, p), \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1708 assert_is_in) |
0 | 1709 } |
1710 #endif // SERIALGC | |
1711 | |
1712 // closure's do_header() method dicates whether the given closure should be | |
1713 // applied to the klass ptr in the object header. | |
1714 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1715 #define InstanceKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1716 \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1717 int instanceKlass::oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \ |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1718 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik);\ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1719 /* header */ \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1720 if (closure->do_header()) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1721 obj->oop_iterate_header(closure); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1722 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1723 InstanceKlass_OOP_MAP_ITERATE( \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1724 obj, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1725 SpecializationStats:: \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1726 record_do_oop_call##nv_suffix(SpecializationStats::ik); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1727 (closure)->do_oop##nv_suffix(p), \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1728 assert_is_in_closed_subset) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1729 return size_helper(); \ |
0 | 1730 } |
1731 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1732 #ifndef SERIALGC |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1733 #define InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1734 \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1735 int instanceKlass::oop_oop_iterate_backwards##nv_suffix(oop obj, \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1736 OopClosureType* closure) { \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1737 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik); \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1738 /* header */ \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1739 if (closure->do_header()) { \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1740 obj->oop_iterate_header(closure); \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1741 } \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1742 /* instance variables */ \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1743 InstanceKlass_OOP_MAP_REVERSE_ITERATE( \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1744 obj, \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1745 SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::ik);\ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1746 (closure)->do_oop##nv_suffix(p), \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1747 assert_is_in_closed_subset) \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1748 return size_helper(); \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1749 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1750 #endif // !SERIALGC |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1751 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1752 #define InstanceKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1753 \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1754 int instanceKlass::oop_oop_iterate##nv_suffix##_m(oop obj, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1755 OopClosureType* closure, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1756 MemRegion mr) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1757 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik);\ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1758 if (closure->do_header()) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1759 obj->oop_iterate_header(closure, mr); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1760 } \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1761 InstanceKlass_BOUNDED_OOP_MAP_ITERATE( \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1762 obj, mr.start(), mr.end(), \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1763 (closure)->do_oop##nv_suffix(p), \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1764 assert_is_in_closed_subset) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1765 return size_helper(); \ |
0 | 1766 } |
1767 | |
1768 ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN) | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1769 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN) |
0 | 1770 ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_DEFN_m) |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1771 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_DEFN_m) |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1772 #ifndef SERIALGC |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1773 ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1774 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
1775 #endif // !SERIALGC |
0 | 1776 |
1777 int instanceKlass::oop_adjust_pointers(oop obj) { | |
1778 int size = size_helper(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1779 InstanceKlass_OOP_MAP_ITERATE( \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1780 obj, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1781 MarkSweep::adjust_pointer(p), \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1782 assert_is_in) |
0 | 1783 obj->adjust_header(); |
1784 return size; | |
1785 } | |
1786 | |
1787 #ifndef SERIALGC | |
1788 void instanceKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1789 InstanceKlass_OOP_MAP_REVERSE_ITERATE( \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1790 obj, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1791 if (PSScavenge::should_scavenge(p)) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1792 pm->claim_or_forward_depth(p); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1793 }, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1794 assert_nothing ) |
0 | 1795 } |
1796 | |
1797 int instanceKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1798 InstanceKlass_OOP_MAP_ITERATE( \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1799 obj, \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1800 PSParallelCompact::adjust_pointer(p), \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
1801 assert_nothing) |
0 | 1802 return size_helper(); |
1803 } | |
1804 | |
1805 #endif // SERIALGC | |
1806 | |
1807 // This klass is alive but the implementor link is not followed/updated. | |
1808 // Subklass and sibling links are handled by Klass::follow_weak_klass_links | |
1809 | |
1810 void instanceKlass::follow_weak_klass_links( | |
1811 BoolObjectClosure* is_alive, OopClosure* keep_alive) { | |
1812 assert(is_alive->do_object_b(as_klassOop()), "this oop should be live"); | |
1813 if (ClassUnloading) { | |
1814 for (int i = 0; i < implementors_limit; i++) { | |
1815 klassOop impl = _implementors[i]; | |
1816 if (impl == NULL) break; // no more in the list | |
1817 if (!is_alive->do_object_b(impl)) { | |
1818 // remove this guy from the list by overwriting him with the tail | |
1819 int lasti = --_nof_implementors; | |
1820 assert(lasti >= i && lasti < implementors_limit, "just checking"); | |
1821 _implementors[i] = _implementors[lasti]; | |
1822 _implementors[lasti] = NULL; | |
1823 --i; // rerun the loop at this index | |
1824 } | |
1825 } | |
1826 } else { | |
1827 for (int i = 0; i < implementors_limit; i++) { | |
1828 keep_alive->do_oop(&adr_implementors()[i]); | |
1829 } | |
1830 } | |
1831 Klass::follow_weak_klass_links(is_alive, keep_alive); | |
1832 } | |
1833 | |
1834 void instanceKlass::remove_unshareable_info() { | |
1835 Klass::remove_unshareable_info(); | |
1836 init_implementor(); | |
1837 } | |
1838 | |
1839 static void clear_all_breakpoints(methodOop m) { | |
1840 m->clear_all_breakpoints(); | |
1841 } | |
1842 | |
1843 void instanceKlass::release_C_heap_structures() { | |
1844 // Deallocate oop map cache | |
1845 if (_oop_map_cache != NULL) { | |
1846 delete _oop_map_cache; | |
1847 _oop_map_cache = NULL; | |
1848 } | |
1849 | |
1850 // Deallocate JNI identifiers for jfieldIDs | |
1851 JNIid::deallocate(jni_ids()); | |
1852 set_jni_ids(NULL); | |
1853 | |
1854 jmethodID* jmeths = methods_jmethod_ids_acquire(); | |
1855 if (jmeths != (jmethodID*)NULL) { | |
1856 release_set_methods_jmethod_ids(NULL); | |
1857 FreeHeap(jmeths); | |
1858 } | |
1859 | |
1860 int* indices = methods_cached_itable_indices_acquire(); | |
1861 if (indices != (int*)NULL) { | |
1862 release_set_methods_cached_itable_indices(NULL); | |
1863 FreeHeap(indices); | |
1864 } | |
1865 | |
1866 // release dependencies | |
1867 nmethodBucket* b = _dependencies; | |
1868 _dependencies = NULL; | |
1869 while (b != NULL) { | |
1870 nmethodBucket* next = b->next(); | |
1871 delete b; | |
1872 b = next; | |
1873 } | |
1874 | |
1875 // Deallocate breakpoint records | |
1876 if (breakpoints() != 0x0) { | |
1877 methods_do(clear_all_breakpoints); | |
1878 assert(breakpoints() == 0x0, "should have cleared breakpoints"); | |
1879 } | |
1880 | |
1881 // deallocate information about previous versions | |
1882 if (_previous_versions != NULL) { | |
1883 for (int i = _previous_versions->length() - 1; i >= 0; i--) { | |
1884 PreviousVersionNode * pv_node = _previous_versions->at(i); | |
1885 delete pv_node; | |
1886 } | |
1887 delete _previous_versions; | |
1888 _previous_versions = NULL; | |
1889 } | |
1890 | |
1891 // deallocate the cached class file | |
1892 if (_cached_class_file_bytes != NULL) { | |
1893 os::free(_cached_class_file_bytes); | |
1894 _cached_class_file_bytes = NULL; | |
1895 _cached_class_file_len = 0; | |
1896 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1897 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1898 // Decrement symbol reference counts associated with the unloaded class. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1899 if (_name != NULL) _name->decrement_refcount(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1900 // unreference array name derived from this class name (arrays of an unloaded |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1901 // class can't be referenced anymore). |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1902 if (_array_name != NULL) _array_name->decrement_refcount(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1903 if (_source_file_name != NULL) _source_file_name->decrement_refcount(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1904 if (_source_debug_extension != NULL) _source_debug_extension->decrement_refcount(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1905 // walk constant pool and decrement symbol reference counts |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1906 _constants->unreference_symbols(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1907 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1908 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1909 void instanceKlass::set_source_file_name(Symbol* n) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1910 _source_file_name = n; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1911 if (_source_file_name != NULL) _source_file_name->increment_refcount(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1912 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1913 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1914 void instanceKlass::set_source_debug_extension(Symbol* n) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1915 _source_debug_extension = n; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1916 if (_source_debug_extension != NULL) _source_debug_extension->increment_refcount(); |
0 | 1917 } |
1918 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
1919 address instanceKlass::static_field_addr(int offset) { |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
1920 return (address)(offset + instanceMirrorKlass::offset_of_static_fields() + (intptr_t)java_mirror()); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
1921 } |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
1922 |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
1923 |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
997
diff
changeset
|
1924 const char* instanceKlass::signature_name() const { |
0 | 1925 const char* src = (const char*) (name()->as_C_string()); |
1926 const int src_length = (int)strlen(src); | |
1927 char* dest = NEW_RESOURCE_ARRAY(char, src_length + 3); | |
1928 int src_index = 0; | |
1929 int dest_index = 0; | |
1930 dest[dest_index++] = 'L'; | |
1931 while (src_index < src_length) { | |
1932 dest[dest_index++] = src[src_index++]; | |
1933 } | |
1934 dest[dest_index++] = ';'; | |
1935 dest[dest_index] = '\0'; | |
1936 return dest; | |
1937 } | |
1938 | |
1939 // different verisons of is_same_class_package | |
1940 bool instanceKlass::is_same_class_package(klassOop class2) { | |
1941 klassOop class1 = as_klassOop(); | |
1942 oop classloader1 = instanceKlass::cast(class1)->class_loader(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1943 Symbol* classname1 = Klass::cast(class1)->name(); |
0 | 1944 |
1945 if (Klass::cast(class2)->oop_is_objArray()) { | |
1946 class2 = objArrayKlass::cast(class2)->bottom_klass(); | |
1947 } | |
1948 oop classloader2; | |
1949 if (Klass::cast(class2)->oop_is_instance()) { | |
1950 classloader2 = instanceKlass::cast(class2)->class_loader(); | |
1951 } else { | |
1952 assert(Klass::cast(class2)->oop_is_typeArray(), "should be type array"); | |
1953 classloader2 = NULL; | |
1954 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1955 Symbol* classname2 = Klass::cast(class2)->name(); |
0 | 1956 |
1957 return instanceKlass::is_same_class_package(classloader1, classname1, | |
1958 classloader2, classname2); | |
1959 } | |
1960 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1961 bool instanceKlass::is_same_class_package(oop classloader2, Symbol* classname2) { |
0 | 1962 klassOop class1 = as_klassOop(); |
1963 oop classloader1 = instanceKlass::cast(class1)->class_loader(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1964 Symbol* classname1 = Klass::cast(class1)->name(); |
0 | 1965 |
1966 return instanceKlass::is_same_class_package(classloader1, classname1, | |
1967 classloader2, classname2); | |
1968 } | |
1969 | |
1970 // return true if two classes are in the same package, classloader | |
1971 // and classname information is enough to determine a class's package | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1972 bool instanceKlass::is_same_class_package(oop class_loader1, Symbol* class_name1, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1973 oop class_loader2, Symbol* class_name2) { |
0 | 1974 if (class_loader1 != class_loader2) { |
1975 return false; | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
1976 } else if (class_name1 == class_name2) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
1977 return true; // skip painful bytewise comparison |
0 | 1978 } else { |
1979 ResourceMark rm; | |
1980 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1981 // The Symbol*'s are in UTF8 encoding. Since we only need to check explicitly |
0 | 1982 // for ASCII characters ('/', 'L', '['), we can keep them in UTF8 encoding. |
1983 // Otherwise, we just compare jbyte values between the strings. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1984 const jbyte *name1 = class_name1->base(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1985 const jbyte *name2 = class_name2->base(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1986 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1987 const jbyte *last_slash1 = UTF8::strrchr(name1, class_name1->utf8_length(), '/'); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1988 const jbyte *last_slash2 = UTF8::strrchr(name2, class_name2->utf8_length(), '/'); |
0 | 1989 |
1990 if ((last_slash1 == NULL) || (last_slash2 == NULL)) { | |
1991 // One of the two doesn't have a package. Only return true | |
1992 // if the other one also doesn't have a package. | |
1993 return last_slash1 == last_slash2; | |
1994 } else { | |
1995 // Skip over '['s | |
1996 if (*name1 == '[') { | |
1997 do { | |
1998 name1++; | |
1999 } while (*name1 == '['); | |
2000 if (*name1 != 'L') { | |
2001 // Something is terribly wrong. Shouldn't be here. | |
2002 return false; | |
2003 } | |
2004 } | |
2005 if (*name2 == '[') { | |
2006 do { | |
2007 name2++; | |
2008 } while (*name2 == '['); | |
2009 if (*name2 != 'L') { | |
2010 // Something is terribly wrong. Shouldn't be here. | |
2011 return false; | |
2012 } | |
2013 } | |
2014 | |
2015 // Check that package part is identical | |
2016 int length1 = last_slash1 - name1; | |
2017 int length2 = last_slash2 - name2; | |
2018 | |
2019 return UTF8::equal(name1, length1, name2, length2); | |
2020 } | |
2021 } | |
2022 } | |
2023 | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2024 // Returns true iff super_method can be overridden by a method in targetclassname |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2025 // See JSL 3rd edition 8.4.6.1 |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2026 // Assumes name-signature match |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2027 // "this" is instanceKlass of super_method which must exist |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2028 // note that the instanceKlass of the method in the targetclassname has not always been created yet |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
2029 bool instanceKlass::is_override(methodHandle super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS) { |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2030 // Private methods can not be overridden |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2031 if (super_method->is_private()) { |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2032 return false; |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2033 } |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2034 // If super method is accessible, then override |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2035 if ((super_method->is_protected()) || |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2036 (super_method->is_public())) { |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2037 return true; |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2038 } |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2039 // Package-private methods are not inherited outside of package |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2040 assert(super_method->is_package_private(), "must be package private"); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
2041 return(is_same_class_package(targetclassloader(), targetclassname)); |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
605
diff
changeset
|
2042 } |
0 | 2043 |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2044 /* defined for now in jvm.cpp, for historical reasons *-- |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2045 klassOop instanceKlass::compute_enclosing_class_impl(instanceKlassHandle self, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
2046 Symbol*& simple_name_result, TRAPS) { |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2047 ... |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2048 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2049 */ |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2050 |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2051 // tell if two classes have the same enclosing class (at package level) |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2052 bool instanceKlass::is_same_package_member_impl(instanceKlassHandle class1, |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2053 klassOop class2_oop, TRAPS) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2054 if (class2_oop == class1->as_klassOop()) return true; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2055 if (!Klass::cast(class2_oop)->oop_is_instance()) return false; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2056 instanceKlassHandle class2(THREAD, class2_oop); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2057 |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2058 // must be in same package before we try anything else |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2059 if (!class1->is_same_class_package(class2->class_loader(), class2->name())) |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2060 return false; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2061 |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2062 // As long as there is an outer1.getEnclosingClass, |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2063 // shift the search outward. |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2064 instanceKlassHandle outer1 = class1; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2065 for (;;) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2066 // As we walk along, look for equalities between outer1 and class2. |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2067 // Eventually, the walks will terminate as outer1 stops |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2068 // at the top-level class around the original class. |
1126
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1039
diff
changeset
|
2069 bool ignore_inner_is_member; |
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1039
diff
changeset
|
2070 klassOop next = outer1->compute_enclosing_class(&ignore_inner_is_member, |
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1039
diff
changeset
|
2071 CHECK_false); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2072 if (next == NULL) break; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2073 if (next == class2()) return true; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2074 outer1 = instanceKlassHandle(THREAD, next); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2075 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2076 |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2077 // Now do the same for class2. |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2078 instanceKlassHandle outer2 = class2; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2079 for (;;) { |
1126
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1039
diff
changeset
|
2080 bool ignore_inner_is_member; |
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1039
diff
changeset
|
2081 klassOop next = outer2->compute_enclosing_class(&ignore_inner_is_member, |
933a3e806ce6
6895168: JCK api/signaturetest/sigtest.basic.html#basic test fails for jdk 5.0 with HS 16 in nightly build
xlu
parents:
1039
diff
changeset
|
2082 CHECK_false); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2083 if (next == NULL) break; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2084 // Might as well check the new outer against all available values. |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2085 if (next == class1()) return true; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2086 if (next == outer1()) return true; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2087 outer2 = instanceKlassHandle(THREAD, next); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2088 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2089 |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2090 // If by this point we have not found an equality between the |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2091 // two classes, we know they are in separate package members. |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2092 return false; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2093 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2094 |
0 | 2095 |
2096 jint instanceKlass::compute_modifier_flags(TRAPS) const { | |
2097 klassOop k = as_klassOop(); | |
2098 jint access = access_flags().as_int(); | |
2099 | |
2100 // But check if it happens to be member class. | |
2101 typeArrayOop inner_class_list = inner_classes(); | |
2102 int length = (inner_class_list == NULL) ? 0 : inner_class_list->length(); | |
2103 assert (length % instanceKlass::inner_class_next_offset == 0, "just checking"); | |
2104 if (length > 0) { | |
2105 typeArrayHandle inner_class_list_h(THREAD, inner_class_list); | |
2106 instanceKlassHandle ik(THREAD, k); | |
2107 for (int i = 0; i < length; i += instanceKlass::inner_class_next_offset) { | |
2108 int ioff = inner_class_list_h->ushort_at( | |
2109 i + instanceKlass::inner_class_inner_class_info_offset); | |
2110 | |
2111 // Inner class attribute can be zero, skip it. | |
2112 // Strange but true: JVM spec. allows null inner class refs. | |
2113 if (ioff == 0) continue; | |
2114 | |
2115 // only look at classes that are already loaded | |
2116 // since we are looking for the flags for our self. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
2117 Symbol* inner_name = ik->constants()->klass_name_at(ioff); |
0 | 2118 if ((ik->name() == inner_name)) { |
2119 // This is really a member class. | |
2120 access = inner_class_list_h->ushort_at(i + instanceKlass::inner_class_access_flags_offset); | |
2121 break; | |
2122 } | |
2123 } | |
2124 } | |
2125 // Remember to strip ACC_SUPER bit | |
2126 return (access & (~JVM_ACC_SUPER)) & JVM_ACC_WRITTEN_FLAGS; | |
2127 } | |
2128 | |
2129 jint instanceKlass::jvmti_class_status() const { | |
2130 jint result = 0; | |
2131 | |
2132 if (is_linked()) { | |
2133 result |= JVMTI_CLASS_STATUS_VERIFIED | JVMTI_CLASS_STATUS_PREPARED; | |
2134 } | |
2135 | |
2136 if (is_initialized()) { | |
2137 assert(is_linked(), "Class status is not consistent"); | |
2138 result |= JVMTI_CLASS_STATUS_INITIALIZED; | |
2139 } | |
2140 if (is_in_error_state()) { | |
2141 result |= JVMTI_CLASS_STATUS_ERROR; | |
2142 } | |
2143 return result; | |
2144 } | |
2145 | |
2146 methodOop instanceKlass::method_at_itable(klassOop holder, int index, TRAPS) { | |
2147 itableOffsetEntry* ioe = (itableOffsetEntry*)start_of_itable(); | |
2148 int method_table_offset_in_words = ioe->offset()/wordSize; | |
2149 int nof_interfaces = (method_table_offset_in_words - itable_offset_in_words()) | |
2150 / itableOffsetEntry::size(); | |
2151 | |
2152 for (int cnt = 0 ; ; cnt ++, ioe ++) { | |
605 | 2153 // If the interface isn't implemented by the receiver class, |
0 | 2154 // the VM should throw IncompatibleClassChangeError. |
2155 if (cnt >= nof_interfaces) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
2156 THROW_0(vmSymbols::java_lang_IncompatibleClassChangeError()); |
0 | 2157 } |
2158 | |
2159 klassOop ik = ioe->interface_klass(); | |
2160 if (ik == holder) break; | |
2161 } | |
2162 | |
2163 itableMethodEntry* ime = ioe->first_method_entry(as_klassOop()); | |
2164 methodOop m = ime[index].method(); | |
2165 if (m == NULL) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
2166 THROW_0(vmSymbols::java_lang_AbstractMethodError()); |
0 | 2167 } |
2168 return m; | |
2169 } | |
2170 | |
2171 // On-stack replacement stuff | |
2172 void instanceKlass::add_osr_nmethod(nmethod* n) { | |
2173 // only one compilation can be active | |
2174 NEEDS_CLEANUP | |
2175 // This is a short non-blocking critical region, so the no safepoint check is ok. | |
2176 OsrList_lock->lock_without_safepoint_check(); | |
2177 assert(n->is_osr_method(), "wrong kind of nmethod"); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
876
diff
changeset
|
2178 n->set_osr_link(osr_nmethods_head()); |
0 | 2179 set_osr_nmethods_head(n); |
1783 | 2180 // Raise the highest osr level if necessary |
2181 if (TieredCompilation) { | |
2182 methodOop m = n->method(); | |
2183 m->set_highest_osr_comp_level(MAX2(m->highest_osr_comp_level(), n->comp_level())); | |
2184 } | |
0 | 2185 // Remember to unlock again |
2186 OsrList_lock->unlock(); | |
1783 | 2187 |
2188 // Get rid of the osr methods for the same bci that have lower levels. | |
2189 if (TieredCompilation) { | |
2190 for (int l = CompLevel_limited_profile; l < n->comp_level(); l++) { | |
2191 nmethod *inv = lookup_osr_nmethod(n->method(), n->osr_entry_bci(), l, true); | |
2192 if (inv != NULL && inv->is_in_use()) { | |
2193 inv->make_not_entrant(); | |
2194 } | |
2195 } | |
2196 } | |
0 | 2197 } |
2198 | |
2199 | |
2200 void instanceKlass::remove_osr_nmethod(nmethod* n) { | |
2201 // This is a short non-blocking critical region, so the no safepoint check is ok. | |
2202 OsrList_lock->lock_without_safepoint_check(); | |
2203 assert(n->is_osr_method(), "wrong kind of nmethod"); | |
2204 nmethod* last = NULL; | |
2205 nmethod* cur = osr_nmethods_head(); | |
1783 | 2206 int max_level = CompLevel_none; // Find the max comp level excluding n |
2207 methodOop m = n->method(); | |
0 | 2208 // Search for match |
2209 while(cur != NULL && cur != n) { | |
1783 | 2210 if (TieredCompilation) { |
2211 // Find max level before n | |
2212 max_level = MAX2(max_level, cur->comp_level()); | |
2213 } | |
0 | 2214 last = cur; |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
876
diff
changeset
|
2215 cur = cur->osr_link(); |
0 | 2216 } |
1783 | 2217 nmethod* next = NULL; |
0 | 2218 if (cur == n) { |
1783 | 2219 next = cur->osr_link(); |
0 | 2220 if (last == NULL) { |
2221 // Remove first element | |
1783 | 2222 set_osr_nmethods_head(next); |
0 | 2223 } else { |
1783 | 2224 last->set_osr_link(next); |
0 | 2225 } |
2226 } | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
876
diff
changeset
|
2227 n->set_osr_link(NULL); |
1783 | 2228 if (TieredCompilation) { |
2229 cur = next; | |
2230 while (cur != NULL) { | |
2231 // Find max level after n | |
2232 max_level = MAX2(max_level, cur->comp_level()); | |
2233 cur = cur->osr_link(); | |
2234 } | |
2235 m->set_highest_osr_comp_level(max_level); | |
2236 } | |
0 | 2237 // Remember to unlock again |
2238 OsrList_lock->unlock(); | |
2239 } | |
2240 | |
1783 | 2241 nmethod* instanceKlass::lookup_osr_nmethod(const methodOop m, int bci, int comp_level, bool match_level) const { |
0 | 2242 // This is a short non-blocking critical region, so the no safepoint check is ok. |
2243 OsrList_lock->lock_without_safepoint_check(); | |
2244 nmethod* osr = osr_nmethods_head(); | |
1783 | 2245 nmethod* best = NULL; |
0 | 2246 while (osr != NULL) { |
2247 assert(osr->is_osr_method(), "wrong kind of nmethod found in chain"); | |
1783 | 2248 // There can be a time when a c1 osr method exists but we are waiting |
2249 // for a c2 version. When c2 completes its osr nmethod we will trash | |
2250 // the c1 version and only be able to find the c2 version. However | |
2251 // while we overflow in the c1 code at back branches we don't want to | |
2252 // try and switch to the same code as we are already running | |
2253 | |
0 | 2254 if (osr->method() == m && |
2255 (bci == InvocationEntryBci || osr->osr_entry_bci() == bci)) { | |
1783 | 2256 if (match_level) { |
2257 if (osr->comp_level() == comp_level) { | |
2258 // Found a match - return it. | |
2259 OsrList_lock->unlock(); | |
2260 return osr; | |
2261 } | |
2262 } else { | |
2263 if (best == NULL || (osr->comp_level() > best->comp_level())) { | |
2264 if (osr->comp_level() == CompLevel_highest_tier) { | |
2265 // Found the best possible - return it. | |
2266 OsrList_lock->unlock(); | |
2267 return osr; | |
2268 } | |
2269 best = osr; | |
2270 } | |
2271 } | |
0 | 2272 } |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
876
diff
changeset
|
2273 osr = osr->osr_link(); |
0 | 2274 } |
2275 OsrList_lock->unlock(); | |
1783 | 2276 if (best != NULL && best->comp_level() >= comp_level && match_level == false) { |
2277 return best; | |
2278 } | |
0 | 2279 return NULL; |
2280 } | |
2281 | |
2282 // ----------------------------------------------------------------------------------------------------- | |
2283 #ifndef PRODUCT | |
2284 | |
2285 // Printing | |
2286 | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2287 #define BULLET " - " |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2288 |
0 | 2289 void FieldPrinter::do_field(fieldDescriptor* fd) { |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2290 _st->print(BULLET); |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
2291 if (_obj == NULL) { |
0 | 2292 fd->print_on(_st); |
2293 _st->cr(); | |
2294 } else { | |
2295 fd->print_on_for(_st, _obj); | |
2296 _st->cr(); | |
2297 } | |
2298 } | |
2299 | |
2300 | |
2301 void instanceKlass::oop_print_on(oop obj, outputStream* st) { | |
2302 Klass::oop_print_on(obj, st); | |
2303 | |
1142 | 2304 if (as_klassOop() == SystemDictionary::String_klass()) { |
0 | 2305 typeArrayOop value = java_lang_String::value(obj); |
2306 juint offset = java_lang_String::offset(obj); | |
2307 juint length = java_lang_String::length(obj); | |
2308 if (value != NULL && | |
2309 value->is_typeArray() && | |
2310 offset <= (juint) value->length() && | |
2311 offset + length <= (juint) value->length()) { | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2312 st->print(BULLET"string: "); |
0 | 2313 Handle h_obj(obj); |
2314 java_lang_String::print(h_obj, st); | |
2315 st->cr(); | |
2316 if (!WizardMode) return; // that is enough | |
2317 } | |
2318 } | |
2319 | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2320 st->print_cr(BULLET"---- fields (total size %d words):", oop_size(obj)); |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
2321 FieldPrinter print_field(st, obj); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
2322 do_nonstatic_fields(&print_field); |
0 | 2323 |
1142 | 2324 if (as_klassOop() == SystemDictionary::Class_klass()) { |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2325 st->print(BULLET"signature: "); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2326 java_lang_Class::print_signature(obj, st); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2327 st->cr(); |
0 | 2328 klassOop mirrored_klass = java_lang_Class::as_klassOop(obj); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2329 st->print(BULLET"fake entry for mirror: "); |
0 | 2330 mirrored_klass->print_value_on(st); |
2331 st->cr(); | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2332 st->print(BULLET"fake entry resolved_constructor: "); |
0 | 2333 methodOop ctor = java_lang_Class::resolved_constructor(obj); |
2334 ctor->print_value_on(st); | |
2335 klassOop array_klass = java_lang_Class::array_klass(obj); | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2336 st->cr(); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2337 st->print(BULLET"fake entry for array: "); |
0 | 2338 array_klass->print_value_on(st); |
2339 st->cr(); | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
2340 st->print_cr(BULLET"fake entry for oop_size: %d", java_lang_Class::oop_size(obj)); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
2341 st->print_cr(BULLET"fake entry for static_oop_field_count: %d", java_lang_Class::static_oop_field_count(obj)); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
2342 klassOop real_klass = java_lang_Class::as_klassOop(obj); |
2408
2cd0180da6e1
7032306: Fastdebug build failure on Solaris with SS11 compilers
never
parents:
2376
diff
changeset
|
2343 if (real_klass != NULL && real_klass->klass_part()->oop_is_instance()) { |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
2344 instanceKlass::cast(real_klass)->do_local_static_fields(&print_field); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
2345 } |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
997
diff
changeset
|
2346 } else if (as_klassOop() == SystemDictionary::MethodType_klass()) { |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
997
diff
changeset
|
2347 st->print(BULLET"signature: "); |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2334
diff
changeset
|
2348 java_lang_invoke_MethodType::print_signature(obj, st); |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
997
diff
changeset
|
2349 st->cr(); |
0 | 2350 } |
2351 } | |
2352 | |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1144
diff
changeset
|
2353 #endif //PRODUCT |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1144
diff
changeset
|
2354 |
0 | 2355 void instanceKlass::oop_print_value_on(oop obj, outputStream* st) { |
2356 st->print("a "); | |
2357 name()->print_value_on(st); | |
2358 obj->print_address_on(st); | |
1142 | 2359 if (as_klassOop() == SystemDictionary::String_klass() |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2360 && java_lang_String::value(obj) != NULL) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2361 ResourceMark rm; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2362 int len = java_lang_String::length(obj); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2363 int plen = (len < 24 ? len : 12); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2364 char* str = java_lang_String::as_utf8_string(obj, 0, plen); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2365 st->print(" = \"%s\"", str); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2366 if (len > plen) |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2367 st->print("...[%d]", len); |
1142 | 2368 } else if (as_klassOop() == SystemDictionary::Class_klass()) { |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2369 klassOop k = java_lang_Class::as_klassOop(obj); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2370 st->print(" = "); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2371 if (k != NULL) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2372 k->print_value_on(st); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2373 } else { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2374 const char* tname = type2name(java_lang_Class::primitive_type(obj)); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2375 st->print("%s", tname ? tname : "type?"); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2376 } |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
997
diff
changeset
|
2377 } else if (as_klassOop() == SystemDictionary::MethodType_klass()) { |
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
997
diff
changeset
|
2378 st->print(" = "); |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2334
diff
changeset
|
2379 java_lang_invoke_MethodType::print_signature(obj, st); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2380 } else if (java_lang_boxing_object::is_instance(obj)) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2381 st->print(" = "); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2382 java_lang_boxing_object::print(obj, st); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
605
diff
changeset
|
2383 } |
0 | 2384 } |
2385 | |
2386 const char* instanceKlass::internal_name() const { | |
2387 return external_name(); | |
2388 } | |
2389 | |
2390 // Verification | |
2391 | |
2392 class VerifyFieldClosure: public OopClosure { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2393 protected: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2394 template <class T> void do_oop_work(T* p) { |
0 | 2395 guarantee(Universe::heap()->is_in_closed_subset(p), "should be in heap"); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2396 oop obj = oopDesc::load_decode_heap_oop(p); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2397 if (!obj->is_oop_or_null()) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2398 tty->print_cr("Failed: " PTR_FORMAT " -> " PTR_FORMAT, p, (address)obj); |
0 | 2399 Universe::print(); |
2400 guarantee(false, "boom"); | |
2401 } | |
2402 } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2403 public: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2404 virtual void do_oop(oop* p) { VerifyFieldClosure::do_oop_work(p); } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2405 virtual void do_oop(narrowOop* p) { VerifyFieldClosure::do_oop_work(p); } |
0 | 2406 }; |
2407 | |
2408 void instanceKlass::oop_verify_on(oop obj, outputStream* st) { | |
2409 Klass::oop_verify_on(obj, st); | |
2410 VerifyFieldClosure blk; | |
2411 oop_oop_iterate(obj, &blk); | |
2412 } | |
2413 | |
2414 #ifndef PRODUCT | |
2415 | |
2416 void instanceKlass::verify_class_klass_nonstatic_oop_maps(klassOop k) { | |
2417 // This verification code is disabled. JDK_Version::is_gte_jdk14x_version() | |
2418 // cannot be called since this function is called before the VM is | |
2419 // able to determine what JDK version is running with. | |
2420 // The check below always is false since 1.4. | |
2421 return; | |
2422 | |
2423 // This verification code temporarily disabled for the 1.4 | |
2424 // reflection implementation since java.lang.Class now has | |
2425 // Java-level instance fields. Should rewrite this to handle this | |
2426 // case. | |
2427 if (!(JDK_Version::is_gte_jdk14x_version() && UseNewReflection)) { | |
2428 // Verify that java.lang.Class instances have a fake oop field added. | |
2429 instanceKlass* ik = instanceKlass::cast(k); | |
2430 | |
2431 // Check that we have the right class | |
2432 static bool first_time = true; | |
1142 | 2433 guarantee(k == SystemDictionary::Class_klass() && first_time, "Invalid verify of maps"); |
0 | 2434 first_time = false; |
2435 const int extra = java_lang_Class::number_of_fake_oop_fields; | |
2436 guarantee(ik->nonstatic_field_size() == extra, "just checking"); | |
938 | 2437 guarantee(ik->nonstatic_oop_map_count() == 1, "just checking"); |
0 | 2438 guarantee(ik->size_helper() == align_object_size(instanceOopDesc::header_size() + extra), "just checking"); |
2439 | |
2440 // Check that the map is (2,extra) | |
2441 int offset = java_lang_Class::klass_offset; | |
2442 | |
2443 OopMapBlock* map = ik->start_of_nonstatic_oop_maps(); | |
939
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
2444 guarantee(map->offset() == offset && map->count() == (unsigned int) extra, |
9eebd3ac74cf
6845368: large objects cause a crash or unexpected exception
jcoomes
parents:
938
diff
changeset
|
2445 "sanity"); |
0 | 2446 } |
2447 } | |
2448 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2449 #endif // ndef PRODUCT |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2450 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2451 // JNIid class for jfieldIDs only |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2452 // Note to reviewers: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2453 // These JNI functions are just moved over to column 1 and not changed |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2454 // in the compressed oops workspace. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2455 JNIid::JNIid(klassOop holder, int offset, JNIid* next) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2456 _holder = holder; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2457 _offset = offset; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2458 _next = next; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2459 debug_only(_is_static_field_id = false;) |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2460 } |
0 | 2461 |
2462 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2463 JNIid* JNIid::find(int offset) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2464 JNIid* current = this; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2465 while (current != NULL) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2466 if (current->offset() == offset) return current; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2467 current = current->next(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2468 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2469 return NULL; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2470 } |
0 | 2471 |
2472 void JNIid::oops_do(OopClosure* f) { | |
2473 for (JNIid* cur = this; cur != NULL; cur = cur->next()) { | |
2474 f->do_oop(cur->holder_addr()); | |
2475 } | |
2476 } | |
2477 | |
2478 void JNIid::deallocate(JNIid* current) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2479 while (current != NULL) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2480 JNIid* next = current->next(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2481 delete current; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2482 current = next; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2483 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2484 } |
0 | 2485 |
2486 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2487 void JNIid::verify(klassOop holder) { |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
2488 int first_field_offset = instanceMirrorKlass::offset_of_static_fields(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2489 int end_field_offset; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2490 end_field_offset = first_field_offset + (instanceKlass::cast(holder)->static_field_size() * wordSize); |
0 | 2491 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2492 JNIid* current = this; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2493 while (current != NULL) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2494 guarantee(current->holder() == holder, "Invalid klass in JNIid"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2495 #ifdef ASSERT |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2496 int o = current->offset(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2497 if (current->is_static_field_id()) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2498 guarantee(o >= first_field_offset && o < end_field_offset, "Invalid static field offset in JNIid"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2499 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2500 #endif |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2501 current = current->next(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2502 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2503 } |
0 | 2504 |
2505 | |
2506 #ifdef ASSERT | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2507 void instanceKlass::set_init_state(ClassState state) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2508 bool good_state = as_klassOop()->is_shared() ? (_init_state <= state) |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2509 : (_init_state < state); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2510 assert(good_state || state == allocated, "illegal state transition"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2511 _init_state = state; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2512 } |
0 | 2513 #endif |
2514 | |
2515 | |
2516 // RedefineClasses() support for previous versions: | |
2517 | |
2518 // Add an information node that contains weak references to the | |
2519 // interesting parts of the previous version of the_class. | |
977
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
2520 // This is also where we clean out any unused weak references. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
2521 // Note that while we delete nodes from the _previous_versions |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
2522 // array, we never delete the array itself until the klass is |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
2523 // unloaded. The has_been_redefined() query depends on that fact. |
74a5db69c1fe
6419370: 4/4 new jmethodID code has tiny holes in synchronization
dcubed
parents:
974
diff
changeset
|
2524 // |
0 | 2525 void instanceKlass::add_previous_version(instanceKlassHandle ikh, |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2526 BitMap* emcp_methods, int emcp_method_count) { |
0 | 2527 assert(Thread::current()->is_VM_thread(), |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
52
diff
changeset
|
2528 "only VMThread can add previous versions"); |
0 | 2529 |
2530 if (_previous_versions == NULL) { | |
2531 // This is the first previous version so make some space. | |
2532 // Start with 2 elements under the assumption that the class | |
2533 // won't be redefined much. | |
2534 _previous_versions = new (ResourceObj::C_HEAP) | |
2535 GrowableArray<PreviousVersionNode *>(2, true); | |
2536 } | |
2537 | |
2538 // RC_TRACE macro has an embedded ResourceMark | |
2539 RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d", | |
2540 ikh->external_name(), _previous_versions->length(), emcp_method_count)); | |
2541 constantPoolHandle cp_h(ikh->constants()); | |
47
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2542 jobject cp_ref; |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2543 if (cp_h->is_shared()) { |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2544 // a shared ConstantPool requires a regular reference; a weak |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2545 // reference would be collectible |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2546 cp_ref = JNIHandles::make_global(cp_h); |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2547 } else { |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2548 cp_ref = JNIHandles::make_weak_global(cp_h); |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2549 } |
0 | 2550 PreviousVersionNode * pv_node = NULL; |
2551 objArrayOop old_methods = ikh->methods(); | |
2552 | |
2553 if (emcp_method_count == 0) { | |
47
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2554 // non-shared ConstantPool gets a weak reference |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2555 pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), NULL); |
0 | 2556 RC_TRACE(0x00000400, |
2557 ("add: all methods are obsolete; flushing any EMCP weak refs")); | |
2558 } else { | |
2559 int local_count = 0; | |
2560 GrowableArray<jweak>* method_refs = new (ResourceObj::C_HEAP) | |
2561 GrowableArray<jweak>(emcp_method_count, true); | |
2562 for (int i = 0; i < old_methods->length(); i++) { | |
2563 if (emcp_methods->at(i)) { | |
2564 // this old method is EMCP so save a weak ref | |
2565 methodOop old_method = (methodOop) old_methods->obj_at(i); | |
2566 methodHandle old_method_h(old_method); | |
2567 jweak method_ref = JNIHandles::make_weak_global(old_method_h); | |
2568 method_refs->append(method_ref); | |
2569 if (++local_count >= emcp_method_count) { | |
2570 // no more EMCP methods so bail out now | |
2571 break; | |
2572 } | |
2573 } | |
2574 } | |
47
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2575 // non-shared ConstantPool gets a weak reference |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2576 pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), method_refs); |
0 | 2577 } |
2578 | |
2579 _previous_versions->append(pv_node); | |
2580 | |
2581 // Using weak references allows the interesting parts of previous | |
2582 // classes to be GC'ed when they are no longer needed. Since the | |
2583 // caller is the VMThread and we are at a safepoint, this is a good | |
2584 // time to clear out unused weak references. | |
2585 | |
2586 RC_TRACE(0x00000400, ("add: previous version length=%d", | |
2587 _previous_versions->length())); | |
2588 | |
2589 // skip the last entry since we just added it | |
2590 for (int i = _previous_versions->length() - 2; i >= 0; i--) { | |
2591 // check the previous versions array for a GC'ed weak refs | |
2592 pv_node = _previous_versions->at(i); | |
2593 cp_ref = pv_node->prev_constant_pool(); | |
47
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2594 assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); |
0 | 2595 if (cp_ref == NULL) { |
2596 delete pv_node; | |
2597 _previous_versions->remove_at(i); | |
2598 // Since we are traversing the array backwards, we don't have to | |
2599 // do anything special with the index. | |
2600 continue; // robustness | |
2601 } | |
2602 | |
2603 constantPoolOop cp = (constantPoolOop)JNIHandles::resolve(cp_ref); | |
2604 if (cp == NULL) { | |
2605 // this entry has been GC'ed so remove it | |
2606 delete pv_node; | |
2607 _previous_versions->remove_at(i); | |
2608 // Since we are traversing the array backwards, we don't have to | |
2609 // do anything special with the index. | |
2610 continue; | |
2611 } else { | |
2612 RC_TRACE(0x00000400, ("add: previous version @%d is alive", i)); | |
2613 } | |
2614 | |
2615 GrowableArray<jweak>* method_refs = pv_node->prev_EMCP_methods(); | |
2616 if (method_refs != NULL) { | |
2617 RC_TRACE(0x00000400, ("add: previous methods length=%d", | |
2618 method_refs->length())); | |
2619 for (int j = method_refs->length() - 1; j >= 0; j--) { | |
2620 jweak method_ref = method_refs->at(j); | |
2621 assert(method_ref != NULL, "weak method ref was unexpectedly cleared"); | |
2622 if (method_ref == NULL) { | |
2623 method_refs->remove_at(j); | |
2624 // Since we are traversing the array backwards, we don't have to | |
2625 // do anything special with the index. | |
2626 continue; // robustness | |
2627 } | |
2628 | |
2629 methodOop method = (methodOop)JNIHandles::resolve(method_ref); | |
2630 if (method == NULL || emcp_method_count == 0) { | |
2631 // This method entry has been GC'ed or the current | |
2632 // RedefineClasses() call has made all methods obsolete | |
2633 // so remove it. | |
2634 JNIHandles::destroy_weak_global(method_ref); | |
2635 method_refs->remove_at(j); | |
2636 } else { | |
2637 // RC_TRACE macro has an embedded ResourceMark | |
2638 RC_TRACE(0x00000400, | |
2639 ("add: %s(%s): previous method @%d in version @%d is alive", | |
2640 method->name()->as_C_string(), method->signature()->as_C_string(), | |
2641 j, i)); | |
2642 } | |
2643 } | |
2644 } | |
2645 } | |
2646 | |
2647 int obsolete_method_count = old_methods->length() - emcp_method_count; | |
2648 | |
2649 if (emcp_method_count != 0 && obsolete_method_count != 0 && | |
2650 _previous_versions->length() > 1) { | |
2651 // We have a mix of obsolete and EMCP methods. If there is more | |
2652 // than the previous version that we just added, then we have to | |
2653 // clear out any matching EMCP method entries the hard way. | |
2654 int local_count = 0; | |
2655 for (int i = 0; i < old_methods->length(); i++) { | |
2656 if (!emcp_methods->at(i)) { | |
2657 // only obsolete methods are interesting | |
2658 methodOop old_method = (methodOop) old_methods->obj_at(i); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
2659 Symbol* m_name = old_method->name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
2660 Symbol* m_signature = old_method->signature(); |
0 | 2661 |
2662 // skip the last entry since we just added it | |
2663 for (int j = _previous_versions->length() - 2; j >= 0; j--) { | |
2664 // check the previous versions array for a GC'ed weak refs | |
2665 pv_node = _previous_versions->at(j); | |
2666 cp_ref = pv_node->prev_constant_pool(); | |
47
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2667 assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); |
0 | 2668 if (cp_ref == NULL) { |
2669 delete pv_node; | |
2670 _previous_versions->remove_at(j); | |
2671 // Since we are traversing the array backwards, we don't have to | |
2672 // do anything special with the index. | |
2673 continue; // robustness | |
2674 } | |
2675 | |
2676 constantPoolOop cp = (constantPoolOop)JNIHandles::resolve(cp_ref); | |
2677 if (cp == NULL) { | |
2678 // this entry has been GC'ed so remove it | |
2679 delete pv_node; | |
2680 _previous_versions->remove_at(j); | |
2681 // Since we are traversing the array backwards, we don't have to | |
2682 // do anything special with the index. | |
2683 continue; | |
2684 } | |
2685 | |
2686 GrowableArray<jweak>* method_refs = pv_node->prev_EMCP_methods(); | |
2687 if (method_refs == NULL) { | |
2688 // We have run into a PreviousVersion generation where | |
2689 // all methods were made obsolete during that generation's | |
2690 // RedefineClasses() operation. At the time of that | |
2691 // operation, all EMCP methods were flushed so we don't | |
2692 // have to go back any further. | |
2693 // | |
2694 // A NULL method_refs is different than an empty method_refs. | |
2695 // We cannot infer any optimizations about older generations | |
2696 // from an empty method_refs for the current generation. | |
2697 break; | |
2698 } | |
2699 | |
2700 for (int k = method_refs->length() - 1; k >= 0; k--) { | |
2701 jweak method_ref = method_refs->at(k); | |
2702 assert(method_ref != NULL, | |
2703 "weak method ref was unexpectedly cleared"); | |
2704 if (method_ref == NULL) { | |
2705 method_refs->remove_at(k); | |
2706 // Since we are traversing the array backwards, we don't | |
2707 // have to do anything special with the index. | |
2708 continue; // robustness | |
2709 } | |
2710 | |
2711 methodOop method = (methodOop)JNIHandles::resolve(method_ref); | |
2712 if (method == NULL) { | |
2713 // this method entry has been GC'ed so skip it | |
2714 JNIHandles::destroy_weak_global(method_ref); | |
2715 method_refs->remove_at(k); | |
2716 continue; | |
2717 } | |
2718 | |
2719 if (method->name() == m_name && | |
2720 method->signature() == m_signature) { | |
2721 // The current RedefineClasses() call has made all EMCP | |
2722 // versions of this method obsolete so mark it as obsolete | |
2723 // and remove the weak ref. | |
2724 RC_TRACE(0x00000400, | |
2725 ("add: %s(%s): flush obsolete method @%d in version @%d", | |
2726 m_name->as_C_string(), m_signature->as_C_string(), k, j)); | |
2727 | |
2728 method->set_is_obsolete(); | |
2729 JNIHandles::destroy_weak_global(method_ref); | |
2730 method_refs->remove_at(k); | |
2731 break; | |
2732 } | |
2733 } | |
2734 | |
2735 // The previous loop may not find a matching EMCP method, but | |
2736 // that doesn't mean that we can optimize and not go any | |
2737 // further back in the PreviousVersion generations. The EMCP | |
2738 // method for this generation could have already been GC'ed, | |
2739 // but there still may be an older EMCP method that has not | |
2740 // been GC'ed. | |
2741 } | |
2742 | |
2743 if (++local_count >= obsolete_method_count) { | |
2744 // no more obsolete methods so bail out now | |
2745 break; | |
2746 } | |
2747 } | |
2748 } | |
2749 } | |
2750 } // end add_previous_version() | |
2751 | |
2752 | |
2753 // Determine if instanceKlass has a previous version. | |
2754 bool instanceKlass::has_previous_version() const { | |
2755 if (_previous_versions == NULL) { | |
2756 // no previous versions array so answer is easy | |
2757 return false; | |
2758 } | |
2759 | |
2760 for (int i = _previous_versions->length() - 1; i >= 0; i--) { | |
2761 // Check the previous versions array for an info node that hasn't | |
2762 // been GC'ed | |
2763 PreviousVersionNode * pv_node = _previous_versions->at(i); | |
2764 | |
47
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2765 jobject cp_ref = pv_node->prev_constant_pool(); |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2766 assert(cp_ref != NULL, "cp reference was unexpectedly cleared"); |
0 | 2767 if (cp_ref == NULL) { |
2768 continue; // robustness | |
2769 } | |
2770 | |
2771 constantPoolOop cp = (constantPoolOop)JNIHandles::resolve(cp_ref); | |
2772 if (cp != NULL) { | |
2773 // we have at least one previous version | |
2774 return true; | |
2775 } | |
2776 | |
2777 // We don't have to check the method refs. If the constant pool has | |
2778 // been GC'ed then so have the methods. | |
2779 } | |
2780 | |
2781 // all of the underlying nodes' info has been GC'ed | |
2782 return false; | |
2783 } // end has_previous_version() | |
2784 | |
2785 methodOop instanceKlass::method_with_idnum(int idnum) { | |
2786 methodOop m = NULL; | |
2787 if (idnum < methods()->length()) { | |
2788 m = (methodOop) methods()->obj_at(idnum); | |
2789 } | |
2790 if (m == NULL || m->method_idnum() != idnum) { | |
2791 for (int index = 0; index < methods()->length(); ++index) { | |
2792 m = (methodOop) methods()->obj_at(index); | |
2793 if (m->method_idnum() == idnum) { | |
2794 return m; | |
2795 } | |
2796 } | |
2797 } | |
2798 return m; | |
2799 } | |
2800 | |
2801 | |
2802 // Set the annotation at 'idnum' to 'anno'. | |
2803 // We don't want to create or extend the array if 'anno' is NULL, since that is the | |
2804 // default value. However, if the array exists and is long enough, we must set NULL values. | |
2805 void instanceKlass::set_methods_annotations_of(int idnum, typeArrayOop anno, objArrayOop* md_p) { | |
2806 objArrayOop md = *md_p; | |
2807 if (md != NULL && md->length() > idnum) { | |
2808 md->obj_at_put(idnum, anno); | |
2809 } else if (anno != NULL) { | |
2810 // create the array | |
2811 int length = MAX2(idnum+1, (int)_idnum_allocated_count); | |
2812 md = oopFactory::new_system_objArray(length, Thread::current()); | |
2813 if (*md_p != NULL) { | |
2814 // copy the existing entries | |
2815 for (int index = 0; index < (*md_p)->length(); index++) { | |
2816 md->obj_at_put(index, (*md_p)->obj_at(index)); | |
2817 } | |
2818 } | |
2819 set_annotations(md, md_p); | |
2820 md->obj_at_put(idnum, anno); | |
2821 } // if no array and idnum isn't included there is nothing to do | |
2822 } | |
2823 | |
2824 // Construct a PreviousVersionNode entry for the array hung off | |
2825 // the instanceKlass. | |
47
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2826 PreviousVersionNode::PreviousVersionNode(jobject prev_constant_pool, |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2827 bool prev_cp_is_weak, GrowableArray<jweak>* prev_EMCP_methods) { |
0 | 2828 |
2829 _prev_constant_pool = prev_constant_pool; | |
47
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2830 _prev_cp_is_weak = prev_cp_is_weak; |
0 | 2831 _prev_EMCP_methods = prev_EMCP_methods; |
2832 } | |
2833 | |
2834 | |
2835 // Destroy a PreviousVersionNode | |
2836 PreviousVersionNode::~PreviousVersionNode() { | |
2837 if (_prev_constant_pool != NULL) { | |
47
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2838 if (_prev_cp_is_weak) { |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2839 JNIHandles::destroy_weak_global(_prev_constant_pool); |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2840 } else { |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2841 JNIHandles::destroy_global(_prev_constant_pool); |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2842 } |
0 | 2843 } |
2844 | |
2845 if (_prev_EMCP_methods != NULL) { | |
2846 for (int i = _prev_EMCP_methods->length() - 1; i >= 0; i--) { | |
2847 jweak method_ref = _prev_EMCP_methods->at(i); | |
2848 if (method_ref != NULL) { | |
2849 JNIHandles::destroy_weak_global(method_ref); | |
2850 } | |
2851 } | |
2852 delete _prev_EMCP_methods; | |
2853 } | |
2854 } | |
2855 | |
2856 | |
2857 // Construct a PreviousVersionInfo entry | |
2858 PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) { | |
2859 _prev_constant_pool_handle = constantPoolHandle(); // NULL handle | |
2860 _prev_EMCP_method_handles = NULL; | |
2861 | |
47
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2862 jobject cp_ref = pv_node->prev_constant_pool(); |
2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
dcubed
parents:
0
diff
changeset
|
2863 assert(cp_ref != NULL, "constant pool ref was unexpectedly cleared"); |
0 | 2864 if (cp_ref == NULL) { |
2865 return; // robustness | |
2866 } | |
2867 | |
2868 constantPoolOop cp = (constantPoolOop)JNIHandles::resolve(cp_ref); | |
2869 if (cp == NULL) { | |
2870 // Weak reference has been GC'ed. Since the constant pool has been | |
2871 // GC'ed, the methods have also been GC'ed. | |
2872 return; | |
2873 } | |
2874 | |
2875 // make the constantPoolOop safe to return | |
2876 _prev_constant_pool_handle = constantPoolHandle(cp); | |
2877 | |
2878 GrowableArray<jweak>* method_refs = pv_node->prev_EMCP_methods(); | |
2879 if (method_refs == NULL) { | |
2880 // the instanceKlass did not have any EMCP methods | |
2881 return; | |
2882 } | |
2883 | |
2884 _prev_EMCP_method_handles = new GrowableArray<methodHandle>(10); | |
2885 | |
2886 int n_methods = method_refs->length(); | |
2887 for (int i = 0; i < n_methods; i++) { | |
2888 jweak method_ref = method_refs->at(i); | |
2889 assert(method_ref != NULL, "weak method ref was unexpectedly cleared"); | |
2890 if (method_ref == NULL) { | |
2891 continue; // robustness | |
2892 } | |
2893 | |
2894 methodOop method = (methodOop)JNIHandles::resolve(method_ref); | |
2895 if (method == NULL) { | |
2896 // this entry has been GC'ed so skip it | |
2897 continue; | |
2898 } | |
2899 | |
2900 // make the methodOop safe to return | |
2901 _prev_EMCP_method_handles->append(methodHandle(method)); | |
2902 } | |
2903 } | |
2904 | |
2905 | |
2906 // Destroy a PreviousVersionInfo | |
2907 PreviousVersionInfo::~PreviousVersionInfo() { | |
2908 // Since _prev_EMCP_method_handles is not C-heap allocated, we | |
2909 // don't have to delete it. | |
2910 } | |
2911 | |
2912 | |
2913 // Construct a helper for walking the previous versions array | |
2914 PreviousVersionWalker::PreviousVersionWalker(instanceKlass *ik) { | |
2915 _previous_versions = ik->previous_versions(); | |
2916 _current_index = 0; | |
2917 // _hm needs no initialization | |
2918 _current_p = NULL; | |
2919 } | |
2920 | |
2921 | |
2922 // Destroy a PreviousVersionWalker | |
2923 PreviousVersionWalker::~PreviousVersionWalker() { | |
2924 // Delete the current info just in case the caller didn't walk to | |
2925 // the end of the previous versions list. No harm if _current_p is | |
2926 // already NULL. | |
2927 delete _current_p; | |
2928 | |
2929 // When _hm is destroyed, all the Handles returned in | |
2930 // PreviousVersionInfo objects will be destroyed. | |
2931 // Also, after this destructor is finished it will be | |
2932 // safe to delete the GrowableArray allocated in the | |
2933 // PreviousVersionInfo objects. | |
2934 } | |
2935 | |
2936 | |
2937 // Return the interesting information for the next previous version | |
2938 // of the klass. Returns NULL if there are no more previous versions. | |
2939 PreviousVersionInfo* PreviousVersionWalker::next_previous_version() { | |
2940 if (_previous_versions == NULL) { | |
2941 // no previous versions so nothing to return | |
2942 return NULL; | |
2943 } | |
2944 | |
2945 delete _current_p; // cleanup the previous info for the caller | |
2946 _current_p = NULL; // reset to NULL so we don't delete same object twice | |
2947 | |
2948 int length = _previous_versions->length(); | |
2949 | |
2950 while (_current_index < length) { | |
2951 PreviousVersionNode * pv_node = _previous_versions->at(_current_index++); | |
2952 PreviousVersionInfo * pv_info = new (ResourceObj::C_HEAP) | |
2953 PreviousVersionInfo(pv_node); | |
2954 | |
2955 constantPoolHandle cp_h = pv_info->prev_constant_pool_handle(); | |
2956 if (cp_h.is_null()) { | |
2957 delete pv_info; | |
2958 | |
2959 // The underlying node's info has been GC'ed so try the next one. | |
2960 // We don't have to check the methods. If the constant pool has | |
2961 // GC'ed then so have the methods. | |
2962 continue; | |
2963 } | |
2964 | |
2965 // Found a node with non GC'ed info so return it. The caller will | |
2966 // need to delete pv_info when they are done with it. | |
2967 _current_p = pv_info; | |
2968 return pv_info; | |
2969 } | |
2970 | |
2971 // all of the underlying nodes' info has been GC'ed | |
2972 return NULL; | |
2973 } // end next_previous_version() |