Mercurial > hg > truffle
annotate src/share/vm/oops/methodKlass.cpp @ 3762:5c0a3c1858b1
7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
Summary: The LNC array is sized before the start of a scavenge, while the heap may expand during a scavenge. With CMS, the last block of an arbitrary suffice of the LNC array may expand due to coalition with the expansion delta. We now take care not to attempt access past the end of the LNC array. LNC array code will be cleaned up and suitably encapsulated as part of the forthcoming performance RFE 7043675.
Reviewed-by: brutisso
author | ysr |
---|---|
date | Thu, 02 Jun 2011 10:23:36 -0700 |
parents | 5d8f5a6dced7 |
children | f00918f35c7f 94ec88ca68e2 |
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:
1507
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1507
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:
1507
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/javaClasses.hpp" | |
27 #include "gc_implementation/shared/markSweep.inline.hpp" | |
28 #include "gc_interface/collectedHeap.inline.hpp" | |
29 #include "interpreter/interpreter.hpp" | |
30 #include "memory/gcLocker.hpp" | |
31 #include "memory/resourceArea.hpp" | |
32 #include "memory/universe.inline.hpp" | |
33 #include "oops/constMethodKlass.hpp" | |
34 #include "oops/klassOop.hpp" | |
35 #include "oops/methodDataOop.hpp" | |
36 #include "oops/methodKlass.hpp" | |
37 #include "oops/oop.inline.hpp" | |
38 #include "oops/oop.inline2.hpp" | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
39 #include "oops/symbol.hpp" |
1972 | 40 #include "runtime/handles.inline.hpp" |
0 | 41 |
42 klassOop methodKlass::create_klass(TRAPS) { | |
43 methodKlass o; | |
44 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj()); | |
45 KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL); | |
46 // Make sure size calculation is right | |
47 assert(k()->size() == align_object_size(header_size()), "wrong size for object"); | |
48 java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror | |
49 return k(); | |
50 } | |
51 | |
52 | |
53 int methodKlass::oop_size(oop obj) const { | |
54 assert(obj->is_method(), "must be method oop"); | |
55 return methodOop(obj)->object_size(); | |
56 } | |
57 | |
58 | |
59 bool methodKlass::oop_is_parsable(oop obj) const { | |
60 assert(obj->is_method(), "must be method oop"); | |
61 return methodOop(obj)->object_is_parsable(); | |
62 } | |
63 | |
64 | |
65 methodOop methodKlass::allocate(constMethodHandle xconst, | |
66 AccessFlags access_flags, TRAPS) { | |
67 int size = methodOopDesc::object_size(access_flags.is_native()); | |
68 KlassHandle h_k(THREAD, as_klassOop()); | |
69 assert(xconst()->is_parsable(), "possible publication protocol violation"); | |
70 methodOop m = (methodOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); | |
71 assert(!m->is_parsable(), "not expecting parsability yet."); | |
72 | |
73 No_Safepoint_Verifier no_safepoint; // until m becomes parsable below | |
74 m->set_constMethod(xconst()); | |
75 m->set_access_flags(access_flags); | |
76 m->set_method_size(size); | |
77 m->set_name_index(0); | |
78 m->set_signature_index(0); | |
79 #ifdef CC_INTERP | |
80 m->set_result_index(T_VOID); | |
81 #endif | |
82 m->set_constants(NULL); | |
83 m->set_max_stack(0); | |
84 m->set_max_locals(0); | |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
710
diff
changeset
|
85 m->set_intrinsic_id(vmIntrinsics::_none); |
0 | 86 m->set_method_data(NULL); |
87 m->set_interpreter_throwout_count(0); | |
88 m->set_vtable_index(methodOopDesc::garbage_vtable_index); | |
89 | |
90 // Fix and bury in methodOop | |
91 m->set_interpreter_entry(NULL); // sets i2i entry and from_int | |
92 m->set_adapter_entry(NULL); | |
93 m->clear_code(); // from_c/from_i get set to c2i/i2i | |
94 | |
95 if (access_flags.is_native()) { | |
96 m->clear_native_function(); | |
97 m->set_signature_handler(NULL); | |
98 } | |
99 | |
100 NOT_PRODUCT(m->set_compiled_invocation_count(0);) | |
101 m->set_interpreter_invocation_count(0); | |
102 m->invocation_counter()->init(); | |
103 m->backedge_counter()->init(); | |
104 m->clear_number_of_breakpoints(); | |
1783 | 105 |
2348
5d8f5a6dced7
7020403: Add AdvancedCompilationPolicy for tiered
iveresov
parents:
2227
diff
changeset
|
106 #ifdef TIERED |
5d8f5a6dced7
7020403: Add AdvancedCompilationPolicy for tiered
iveresov
parents:
2227
diff
changeset
|
107 m->set_rate(0); |
5d8f5a6dced7
7020403: Add AdvancedCompilationPolicy for tiered
iveresov
parents:
2227
diff
changeset
|
108 m->set_prev_event_count(0); |
5d8f5a6dced7
7020403: Add AdvancedCompilationPolicy for tiered
iveresov
parents:
2227
diff
changeset
|
109 m->set_prev_time(0); |
5d8f5a6dced7
7020403: Add AdvancedCompilationPolicy for tiered
iveresov
parents:
2227
diff
changeset
|
110 #endif |
5d8f5a6dced7
7020403: Add AdvancedCompilationPolicy for tiered
iveresov
parents:
2227
diff
changeset
|
111 |
0 | 112 assert(m->is_parsable(), "must be parsable here."); |
113 assert(m->size() == size, "wrong size for object"); | |
114 // We should not publish an uprasable object's reference | |
115 // into one that is parsable, since that presents problems | |
116 // for the concurrent parallel marking and precleaning phases | |
117 // of concurrent gc (CMS). | |
118 xconst->set_method(m); | |
119 return m; | |
120 } | |
121 | |
122 | |
123 void methodKlass::oop_follow_contents(oop obj) { | |
124 assert (obj->is_method(), "object must be method"); | |
125 methodOop m = methodOop(obj); | |
126 // Performance tweak: We skip iterating over the klass pointer since we | |
127 // know that Universe::methodKlassObj never moves. | |
128 MarkSweep::mark_and_push(m->adr_constMethod()); | |
129 MarkSweep::mark_and_push(m->adr_constants()); | |
130 if (m->method_data() != NULL) { | |
131 MarkSweep::mark_and_push(m->adr_method_data()); | |
132 } | |
133 } | |
134 | |
135 #ifndef SERIALGC | |
136 void methodKlass::oop_follow_contents(ParCompactionManager* cm, | |
137 oop obj) { | |
138 assert (obj->is_method(), "object must be method"); | |
139 methodOop m = methodOop(obj); | |
140 // Performance tweak: We skip iterating over the klass pointer since we | |
141 // know that Universe::methodKlassObj never moves. | |
142 PSParallelCompact::mark_and_push(cm, m->adr_constMethod()); | |
143 PSParallelCompact::mark_and_push(cm, m->adr_constants()); | |
144 #ifdef COMPILER2 | |
145 if (m->method_data() != NULL) { | |
146 PSParallelCompact::mark_and_push(cm, m->adr_method_data()); | |
147 } | |
148 #endif // COMPILER2 | |
149 } | |
150 #endif // SERIALGC | |
151 | |
152 int methodKlass::oop_oop_iterate(oop obj, OopClosure* blk) { | |
153 assert (obj->is_method(), "object must be method"); | |
154 methodOop m = methodOop(obj); | |
155 // Get size before changing pointers. | |
156 // Don't call size() or oop_size() since that is a virtual call. | |
157 int size = m->object_size(); | |
158 // Performance tweak: We skip iterating over the klass pointer since we | |
159 // know that Universe::methodKlassObj never moves | |
160 blk->do_oop(m->adr_constMethod()); | |
161 blk->do_oop(m->adr_constants()); | |
162 if (m->method_data() != NULL) { | |
163 blk->do_oop(m->adr_method_data()); | |
164 } | |
165 return size; | |
166 } | |
167 | |
168 | |
169 int methodKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { | |
170 assert (obj->is_method(), "object must be method"); | |
171 methodOop m = methodOop(obj); | |
172 // Get size before changing pointers. | |
173 // Don't call size() or oop_size() since that is a virtual call. | |
174 int size = m->object_size(); | |
175 // Performance tweak: We skip iterating over the klass pointer since we | |
176 // know that Universe::methodKlassObj never moves. | |
177 oop* adr; | |
178 adr = m->adr_constMethod(); | |
179 if (mr.contains(adr)) blk->do_oop(adr); | |
180 adr = m->adr_constants(); | |
181 if (mr.contains(adr)) blk->do_oop(adr); | |
182 if (m->method_data() != NULL) { | |
183 adr = m->adr_method_data(); | |
184 if (mr.contains(adr)) blk->do_oop(adr); | |
185 } | |
186 return size; | |
187 } | |
188 | |
189 | |
190 int methodKlass::oop_adjust_pointers(oop obj) { | |
191 assert(obj->is_method(), "should be method"); | |
192 methodOop m = methodOop(obj); | |
193 // Get size before changing pointers. | |
194 // Don't call size() or oop_size() since that is a virtual call. | |
195 int size = m->object_size(); | |
196 // Performance tweak: We skip iterating over the klass pointer since we | |
197 // know that Universe::methodKlassObj never moves. | |
198 MarkSweep::adjust_pointer(m->adr_constMethod()); | |
199 MarkSweep::adjust_pointer(m->adr_constants()); | |
200 if (m->method_data() != NULL) { | |
201 MarkSweep::adjust_pointer(m->adr_method_data()); | |
202 } | |
203 return size; | |
204 } | |
205 | |
206 #ifndef SERIALGC | |
207 void methodKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { | |
208 assert(obj->is_method(), "should be method"); | |
209 } | |
210 | |
211 int methodKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { | |
212 assert(obj->is_method(), "should be method"); | |
213 methodOop m = methodOop(obj); | |
214 PSParallelCompact::adjust_pointer(m->adr_constMethod()); | |
215 PSParallelCompact::adjust_pointer(m->adr_constants()); | |
216 #ifdef COMPILER2 | |
217 if (m->method_data() != NULL) { | |
218 PSParallelCompact::adjust_pointer(m->adr_method_data()); | |
219 } | |
220 #endif // COMPILER2 | |
221 return m->object_size(); | |
222 } | |
223 #endif // SERIALGC | |
224 | |
225 #ifndef PRODUCT | |
226 | |
227 // Printing | |
228 | |
229 void methodKlass::oop_print_on(oop obj, outputStream* st) { | |
230 ResourceMark rm; | |
231 assert(obj->is_method(), "must be method"); | |
232 Klass::oop_print_on(obj, st); | |
233 methodOop m = methodOop(obj); | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1155
diff
changeset
|
234 // get the effect of PrintOopAddress, always, for methods: |
1573
beb77f0d41b3
6957004: MethodComparator uses the wrong CP index accessor
jrose
parents:
1507
diff
changeset
|
235 st->print_cr(" - this oop: "INTPTR_FORMAT, (intptr_t)m); |
0 | 236 st->print (" - method holder: "); m->method_holder()->print_value_on(st); st->cr(); |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1155
diff
changeset
|
237 st->print (" - constants: "INTPTR_FORMAT" ", (address)m->constants()); |
0 | 238 m->constants()->print_value_on(st); st->cr(); |
239 st->print (" - access: 0x%x ", m->access_flags().as_int()); m->access_flags().print_on(st); st->cr(); | |
240 st->print (" - name: "); m->name()->print_value_on(st); st->cr(); | |
241 st->print (" - signature: "); m->signature()->print_value_on(st); st->cr(); | |
242 st->print_cr(" - max stack: %d", m->max_stack()); | |
243 st->print_cr(" - max locals: %d", m->max_locals()); | |
244 st->print_cr(" - size of params: %d", m->size_of_parameters()); | |
245 st->print_cr(" - method size: %d", m->method_size()); | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1155
diff
changeset
|
246 if (m->intrinsic_id() != vmIntrinsics::_none) |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1155
diff
changeset
|
247 st->print_cr(" - intrinsic id: %d %s", m->intrinsic_id(), vmIntrinsics::name_at(m->intrinsic_id())); |
1783 | 248 if (m->highest_comp_level() != CompLevel_none) |
249 st->print_cr(" - highest level: %d", m->highest_comp_level()); | |
0 | 250 st->print_cr(" - vtable index: %d", m->_vtable_index); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
251 st->print_cr(" - i2i entry: " INTPTR_FORMAT, m->interpreter_entry()); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
252 st->print_cr(" - adapter: " INTPTR_FORMAT, m->adapter()); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
253 st->print_cr(" - compiled entry " INTPTR_FORMAT, m->from_compiled_entry()); |
0 | 254 st->print_cr(" - code size: %d", m->code_size()); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
255 if (m->code_size() != 0) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
256 st->print_cr(" - code start: " INTPTR_FORMAT, m->code_base()); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
257 st->print_cr(" - code end (excl): " INTPTR_FORMAT, m->code_base() + m->code_size()); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
258 } |
0 | 259 if (m->method_data() != NULL) { |
260 st->print_cr(" - method data: " INTPTR_FORMAT, (address)m->method_data()); | |
261 } | |
262 st->print_cr(" - checked ex length: %d", m->checked_exceptions_length()); | |
263 if (m->checked_exceptions_length() > 0) { | |
264 CheckedExceptionElement* table = m->checked_exceptions_start(); | |
265 st->print_cr(" - checked ex start: " INTPTR_FORMAT, table); | |
266 if (Verbose) { | |
267 for (int i = 0; i < m->checked_exceptions_length(); i++) { | |
268 st->print_cr(" - throws %s", m->constants()->printable_name_at(table[i].class_cp_index)); | |
269 } | |
270 } | |
271 } | |
272 if (m->has_linenumber_table()) { | |
273 u_char* table = m->compressed_linenumber_table(); | |
274 st->print_cr(" - linenumber start: " INTPTR_FORMAT, table); | |
275 if (Verbose) { | |
276 CompressedLineNumberReadStream stream(table); | |
277 while (stream.read_pair()) { | |
278 st->print_cr(" - line %d: %d", stream.line(), stream.bci()); | |
279 } | |
280 } | |
281 } | |
282 st->print_cr(" - localvar length: %d", m->localvariable_table_length()); | |
283 if (m->localvariable_table_length() > 0) { | |
284 LocalVariableTableElement* table = m->localvariable_table_start(); | |
285 st->print_cr(" - localvar start: " INTPTR_FORMAT, table); | |
286 if (Verbose) { | |
287 for (int i = 0; i < m->localvariable_table_length(); i++) { | |
288 int bci = table[i].start_bci; | |
289 int len = table[i].length; | |
290 const char* name = m->constants()->printable_name_at(table[i].name_cp_index); | |
291 const char* desc = m->constants()->printable_name_at(table[i].descriptor_cp_index); | |
292 int slot = table[i].slot; | |
293 st->print_cr(" - %s %s bci=%d len=%d slot=%d", desc, name, bci, len, slot); | |
294 } | |
295 } | |
296 } | |
297 if (m->code() != NULL) { | |
298 st->print (" - compiled code: "); | |
299 m->code()->print_value_on(st); | |
300 st->cr(); | |
301 } | |
710 | 302 if (m->is_method_handle_invoke()) { |
303 st->print_cr(" - invoke method type: " INTPTR_FORMAT, (address) m->method_handle_type()); | |
304 // m is classified as native, but it does not have an interesting | |
305 // native_function or signature handler | |
306 } else if (m->is_native()) { | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
307 st->print_cr(" - native function: " INTPTR_FORMAT, m->native_function()); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
308 st->print_cr(" - signature handler: " INTPTR_FORMAT, m->signature_handler()); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
309 } |
0 | 310 } |
311 | |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
856
diff
changeset
|
312 #endif //PRODUCT |
0 | 313 |
314 void methodKlass::oop_print_value_on(oop obj, outputStream* st) { | |
315 assert(obj->is_method(), "must be method"); | |
316 Klass::oop_print_value_on(obj, st); | |
317 methodOop m = methodOop(obj); | |
318 st->print(" "); | |
319 m->name()->print_value_on(st); | |
320 st->print(" "); | |
321 m->signature()->print_value_on(st); | |
322 st->print(" in "); | |
323 m->method_holder()->print_value_on(st); | |
324 if (WizardMode) st->print("[%d,%d]", m->size_of_parameters(), m->max_locals()); | |
325 if (WizardMode && m->code() != NULL) st->print(" ((nmethod*)%p)", m->code()); | |
326 } | |
327 | |
328 const char* methodKlass::internal_name() const { | |
329 return "{method}"; | |
330 } | |
331 | |
332 | |
333 // Verification | |
334 | |
335 void methodKlass::oop_verify_on(oop obj, outputStream* st) { | |
336 Klass::oop_verify_on(obj, st); | |
337 guarantee(obj->is_method(), "object must be method"); | |
338 if (!obj->partially_loaded()) { | |
339 methodOop m = methodOop(obj); | |
340 guarantee(m->is_perm(), "should be in permspace"); | |
341 guarantee(m->constants()->is_perm(), "should be in permspace"); | |
342 guarantee(m->constants()->is_constantPool(), "should be constant pool"); | |
343 guarantee(m->constMethod()->is_constMethod(), "should be constMethodOop"); | |
344 guarantee(m->constMethod()->is_perm(), "should be in permspace"); | |
345 methodDataOop method_data = m->method_data(); | |
346 guarantee(method_data == NULL || | |
347 method_data->is_perm(), "should be in permspace"); | |
348 guarantee(method_data == NULL || | |
349 method_data->is_methodData(), "should be method data"); | |
350 } | |
351 } | |
352 | |
353 bool methodKlass::oop_partially_loaded(oop obj) const { | |
354 assert(obj->is_method(), "object must be method"); | |
355 methodOop m = methodOop(obj); | |
356 constMethodOop xconst = m->constMethod(); | |
357 assert(xconst != NULL, "const method must be set"); | |
358 constMethodKlass* ck = constMethodKlass::cast(xconst->klass()); | |
359 return ck->oop_partially_loaded(xconst); | |
360 } | |
361 | |
362 | |
363 void methodKlass::oop_set_partially_loaded(oop obj) { | |
364 assert(obj->is_method(), "object must be method"); | |
365 methodOop m = methodOop(obj); | |
366 constMethodOop xconst = m->constMethod(); | |
367 assert(xconst != NULL, "const method must be set"); | |
368 constMethodKlass* ck = constMethodKlass::cast(xconst->klass()); | |
369 ck->oop_set_partially_loaded(xconst); | |
370 } |