Mercurial > hg > graal-jvmci-8
annotate src/share/vm/oops/methodKlass.cpp @ 3011:f00918f35c7f
inlining and runtime interface related changes:
added codeSize() and compilerStorage() to RiMethod
HotSpotMethodResolved uses reflective methods instead of vmIds and survives compilations
HotSpotResolvedType.isInitialized not represented as field (can change)
inlining stores graphs into method objects and reuses them
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Thu, 16 Jun 2011 20:36:17 +0200 |
parents | 5d8f5a6dced7 |
children | 63cd21fda79b |
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(); | |
3011
f00918f35c7f
inlining and runtime interface related changes:
Lukas Stadler <lukas.stadler@jku.at>
parents:
2348
diff
changeset
|
105 m->set_graal_mirror(NULL); |
1783 | 106 |
2348
5d8f5a6dced7
7020403: Add AdvancedCompilationPolicy for tiered
iveresov
parents:
2227
diff
changeset
|
107 #ifdef TIERED |
5d8f5a6dced7
7020403: Add AdvancedCompilationPolicy for tiered
iveresov
parents:
2227
diff
changeset
|
108 m->set_rate(0); |
5d8f5a6dced7
7020403: Add AdvancedCompilationPolicy for tiered
iveresov
parents:
2227
diff
changeset
|
109 m->set_prev_event_count(0); |
5d8f5a6dced7
7020403: Add AdvancedCompilationPolicy for tiered
iveresov
parents:
2227
diff
changeset
|
110 m->set_prev_time(0); |
5d8f5a6dced7
7020403: Add AdvancedCompilationPolicy for tiered
iveresov
parents:
2227
diff
changeset
|
111 #endif |
5d8f5a6dced7
7020403: Add AdvancedCompilationPolicy for tiered
iveresov
parents:
2227
diff
changeset
|
112 |
0 | 113 assert(m->is_parsable(), "must be parsable here."); |
114 assert(m->size() == size, "wrong size for object"); | |
115 // We should not publish an uprasable object's reference | |
116 // into one that is parsable, since that presents problems | |
117 // for the concurrent parallel marking and precleaning phases | |
118 // of concurrent gc (CMS). | |
119 xconst->set_method(m); | |
120 return m; | |
121 } | |
122 | |
123 | |
124 void methodKlass::oop_follow_contents(oop obj) { | |
125 assert (obj->is_method(), "object must be method"); | |
126 methodOop m = methodOop(obj); | |
127 // Performance tweak: We skip iterating over the klass pointer since we | |
128 // know that Universe::methodKlassObj never moves. | |
129 MarkSweep::mark_and_push(m->adr_constMethod()); | |
130 MarkSweep::mark_and_push(m->adr_constants()); | |
3011
f00918f35c7f
inlining and runtime interface related changes:
Lukas Stadler <lukas.stadler@jku.at>
parents:
2348
diff
changeset
|
131 MarkSweep::mark_and_push(m->adr_graal_mirror()); |
0 | 132 if (m->method_data() != NULL) { |
133 MarkSweep::mark_and_push(m->adr_method_data()); | |
134 } | |
135 } | |
136 | |
137 #ifndef SERIALGC | |
138 void methodKlass::oop_follow_contents(ParCompactionManager* cm, | |
139 oop obj) { | |
140 assert (obj->is_method(), "object must be method"); | |
141 methodOop m = methodOop(obj); | |
142 // Performance tweak: We skip iterating over the klass pointer since we | |
143 // know that Universe::methodKlassObj never moves. | |
144 PSParallelCompact::mark_and_push(cm, m->adr_constMethod()); | |
145 PSParallelCompact::mark_and_push(cm, m->adr_constants()); | |
3011
f00918f35c7f
inlining and runtime interface related changes:
Lukas Stadler <lukas.stadler@jku.at>
parents:
2348
diff
changeset
|
146 PSParallelCompact::mark_and_push(cm, m->adr_graal_mirror()); |
0 | 147 #ifdef COMPILER2 |
148 if (m->method_data() != NULL) { | |
149 PSParallelCompact::mark_and_push(cm, m->adr_method_data()); | |
150 } | |
151 #endif // COMPILER2 | |
152 } | |
153 #endif // SERIALGC | |
154 | |
155 int methodKlass::oop_oop_iterate(oop obj, OopClosure* blk) { | |
156 assert (obj->is_method(), "object must be method"); | |
157 methodOop m = methodOop(obj); | |
158 // Get size before changing pointers. | |
159 // Don't call size() or oop_size() since that is a virtual call. | |
160 int size = m->object_size(); | |
161 // Performance tweak: We skip iterating over the klass pointer since we | |
162 // know that Universe::methodKlassObj never moves | |
163 blk->do_oop(m->adr_constMethod()); | |
164 blk->do_oop(m->adr_constants()); | |
3011
f00918f35c7f
inlining and runtime interface related changes:
Lukas Stadler <lukas.stadler@jku.at>
parents:
2348
diff
changeset
|
165 blk->do_oop(m->adr_graal_mirror()); |
0 | 166 if (m->method_data() != NULL) { |
167 blk->do_oop(m->adr_method_data()); | |
168 } | |
169 return size; | |
170 } | |
171 | |
172 | |
173 int methodKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { | |
174 assert (obj->is_method(), "object must be method"); | |
175 methodOop m = methodOop(obj); | |
176 // Get size before changing pointers. | |
177 // Don't call size() or oop_size() since that is a virtual call. | |
178 int size = m->object_size(); | |
179 // Performance tweak: We skip iterating over the klass pointer since we | |
180 // know that Universe::methodKlassObj never moves. | |
181 oop* adr; | |
182 adr = m->adr_constMethod(); | |
183 if (mr.contains(adr)) blk->do_oop(adr); | |
184 adr = m->adr_constants(); | |
185 if (mr.contains(adr)) blk->do_oop(adr); | |
3011
f00918f35c7f
inlining and runtime interface related changes:
Lukas Stadler <lukas.stadler@jku.at>
parents:
2348
diff
changeset
|
186 adr = m->adr_graal_mirror(); |
f00918f35c7f
inlining and runtime interface related changes:
Lukas Stadler <lukas.stadler@jku.at>
parents:
2348
diff
changeset
|
187 if (mr.contains(adr)) blk->do_oop(adr); |
0 | 188 if (m->method_data() != NULL) { |
189 adr = m->adr_method_data(); | |
190 if (mr.contains(adr)) blk->do_oop(adr); | |
191 } | |
192 return size; | |
193 } | |
194 | |
195 | |
196 int methodKlass::oop_adjust_pointers(oop obj) { | |
197 assert(obj->is_method(), "should be method"); | |
198 methodOop m = methodOop(obj); | |
199 // Get size before changing pointers. | |
200 // Don't call size() or oop_size() since that is a virtual call. | |
201 int size = m->object_size(); | |
202 // Performance tweak: We skip iterating over the klass pointer since we | |
203 // know that Universe::methodKlassObj never moves. | |
204 MarkSweep::adjust_pointer(m->adr_constMethod()); | |
205 MarkSweep::adjust_pointer(m->adr_constants()); | |
3011
f00918f35c7f
inlining and runtime interface related changes:
Lukas Stadler <lukas.stadler@jku.at>
parents:
2348
diff
changeset
|
206 MarkSweep::adjust_pointer(m->adr_graal_mirror()); |
0 | 207 if (m->method_data() != NULL) { |
208 MarkSweep::adjust_pointer(m->adr_method_data()); | |
209 } | |
210 return size; | |
211 } | |
212 | |
213 #ifndef SERIALGC | |
214 void methodKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { | |
215 assert(obj->is_method(), "should be method"); | |
216 } | |
217 | |
218 int methodKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { | |
219 assert(obj->is_method(), "should be method"); | |
220 methodOop m = methodOop(obj); | |
221 PSParallelCompact::adjust_pointer(m->adr_constMethod()); | |
222 PSParallelCompact::adjust_pointer(m->adr_constants()); | |
3011
f00918f35c7f
inlining and runtime interface related changes:
Lukas Stadler <lukas.stadler@jku.at>
parents:
2348
diff
changeset
|
223 PSParallelCompact::adjust_pointer(m->adr_graal_mirror()); |
0 | 224 #ifdef COMPILER2 |
225 if (m->method_data() != NULL) { | |
226 PSParallelCompact::adjust_pointer(m->adr_method_data()); | |
227 } | |
228 #endif // COMPILER2 | |
229 return m->object_size(); | |
230 } | |
231 #endif // SERIALGC | |
232 | |
233 #ifndef PRODUCT | |
234 | |
235 // Printing | |
236 | |
237 void methodKlass::oop_print_on(oop obj, outputStream* st) { | |
238 ResourceMark rm; | |
239 assert(obj->is_method(), "must be method"); | |
240 Klass::oop_print_on(obj, st); | |
241 methodOop m = methodOop(obj); | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1155
diff
changeset
|
242 // get the effect of PrintOopAddress, always, for methods: |
1573
beb77f0d41b3
6957004: MethodComparator uses the wrong CP index accessor
jrose
parents:
1507
diff
changeset
|
243 st->print_cr(" - this oop: "INTPTR_FORMAT, (intptr_t)m); |
0 | 244 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
|
245 st->print (" - constants: "INTPTR_FORMAT" ", (address)m->constants()); |
0 | 246 m->constants()->print_value_on(st); st->cr(); |
247 st->print (" - access: 0x%x ", m->access_flags().as_int()); m->access_flags().print_on(st); st->cr(); | |
248 st->print (" - name: "); m->name()->print_value_on(st); st->cr(); | |
249 st->print (" - signature: "); m->signature()->print_value_on(st); st->cr(); | |
250 st->print_cr(" - max stack: %d", m->max_stack()); | |
251 st->print_cr(" - max locals: %d", m->max_locals()); | |
252 st->print_cr(" - size of params: %d", m->size_of_parameters()); | |
253 st->print_cr(" - method size: %d", m->method_size()); | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1155
diff
changeset
|
254 if (m->intrinsic_id() != vmIntrinsics::_none) |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1155
diff
changeset
|
255 st->print_cr(" - intrinsic id: %d %s", m->intrinsic_id(), vmIntrinsics::name_at(m->intrinsic_id())); |
1783 | 256 if (m->highest_comp_level() != CompLevel_none) |
257 st->print_cr(" - highest level: %d", m->highest_comp_level()); | |
0 | 258 st->print_cr(" - vtable index: %d", m->_vtable_index); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
259 st->print_cr(" - i2i entry: " INTPTR_FORMAT, m->interpreter_entry()); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
260 st->print_cr(" - adapter: " INTPTR_FORMAT, m->adapter()); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
261 st->print_cr(" - compiled entry " INTPTR_FORMAT, m->from_compiled_entry()); |
0 | 262 st->print_cr(" - code size: %d", m->code_size()); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
263 if (m->code_size() != 0) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
264 st->print_cr(" - code start: " INTPTR_FORMAT, m->code_base()); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
265 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
|
266 } |
0 | 267 if (m->method_data() != NULL) { |
268 st->print_cr(" - method data: " INTPTR_FORMAT, (address)m->method_data()); | |
269 } | |
270 st->print_cr(" - checked ex length: %d", m->checked_exceptions_length()); | |
271 if (m->checked_exceptions_length() > 0) { | |
272 CheckedExceptionElement* table = m->checked_exceptions_start(); | |
273 st->print_cr(" - checked ex start: " INTPTR_FORMAT, table); | |
274 if (Verbose) { | |
275 for (int i = 0; i < m->checked_exceptions_length(); i++) { | |
276 st->print_cr(" - throws %s", m->constants()->printable_name_at(table[i].class_cp_index)); | |
277 } | |
278 } | |
279 } | |
280 if (m->has_linenumber_table()) { | |
281 u_char* table = m->compressed_linenumber_table(); | |
282 st->print_cr(" - linenumber start: " INTPTR_FORMAT, table); | |
283 if (Verbose) { | |
284 CompressedLineNumberReadStream stream(table); | |
285 while (stream.read_pair()) { | |
286 st->print_cr(" - line %d: %d", stream.line(), stream.bci()); | |
287 } | |
288 } | |
289 } | |
290 st->print_cr(" - localvar length: %d", m->localvariable_table_length()); | |
291 if (m->localvariable_table_length() > 0) { | |
292 LocalVariableTableElement* table = m->localvariable_table_start(); | |
293 st->print_cr(" - localvar start: " INTPTR_FORMAT, table); | |
294 if (Verbose) { | |
295 for (int i = 0; i < m->localvariable_table_length(); i++) { | |
296 int bci = table[i].start_bci; | |
297 int len = table[i].length; | |
298 const char* name = m->constants()->printable_name_at(table[i].name_cp_index); | |
299 const char* desc = m->constants()->printable_name_at(table[i].descriptor_cp_index); | |
300 int slot = table[i].slot; | |
301 st->print_cr(" - %s %s bci=%d len=%d slot=%d", desc, name, bci, len, slot); | |
302 } | |
303 } | |
304 } | |
305 if (m->code() != NULL) { | |
306 st->print (" - compiled code: "); | |
307 m->code()->print_value_on(st); | |
308 st->cr(); | |
309 } | |
710 | 310 if (m->is_method_handle_invoke()) { |
311 st->print_cr(" - invoke method type: " INTPTR_FORMAT, (address) m->method_handle_type()); | |
312 // m is classified as native, but it does not have an interesting | |
313 // native_function or signature handler | |
314 } else if (m->is_native()) { | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
315 st->print_cr(" - native function: " INTPTR_FORMAT, m->native_function()); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
316 st->print_cr(" - signature handler: " INTPTR_FORMAT, m->signature_handler()); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
317 } |
0 | 318 } |
319 | |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
856
diff
changeset
|
320 #endif //PRODUCT |
0 | 321 |
322 void methodKlass::oop_print_value_on(oop obj, outputStream* st) { | |
323 assert(obj->is_method(), "must be method"); | |
324 Klass::oop_print_value_on(obj, st); | |
325 methodOop m = methodOop(obj); | |
326 st->print(" "); | |
327 m->name()->print_value_on(st); | |
328 st->print(" "); | |
329 m->signature()->print_value_on(st); | |
330 st->print(" in "); | |
331 m->method_holder()->print_value_on(st); | |
332 if (WizardMode) st->print("[%d,%d]", m->size_of_parameters(), m->max_locals()); | |
333 if (WizardMode && m->code() != NULL) st->print(" ((nmethod*)%p)", m->code()); | |
334 } | |
335 | |
336 const char* methodKlass::internal_name() const { | |
337 return "{method}"; | |
338 } | |
339 | |
340 | |
341 // Verification | |
342 | |
343 void methodKlass::oop_verify_on(oop obj, outputStream* st) { | |
344 Klass::oop_verify_on(obj, st); | |
345 guarantee(obj->is_method(), "object must be method"); | |
346 if (!obj->partially_loaded()) { | |
347 methodOop m = methodOop(obj); | |
348 guarantee(m->is_perm(), "should be in permspace"); | |
349 guarantee(m->constants()->is_perm(), "should be in permspace"); | |
350 guarantee(m->constants()->is_constantPool(), "should be constant pool"); | |
351 guarantee(m->constMethod()->is_constMethod(), "should be constMethodOop"); | |
352 guarantee(m->constMethod()->is_perm(), "should be in permspace"); | |
353 methodDataOop method_data = m->method_data(); | |
354 guarantee(method_data == NULL || | |
355 method_data->is_perm(), "should be in permspace"); | |
356 guarantee(method_data == NULL || | |
357 method_data->is_methodData(), "should be method data"); | |
358 } | |
359 } | |
360 | |
361 bool methodKlass::oop_partially_loaded(oop obj) const { | |
362 assert(obj->is_method(), "object must be method"); | |
363 methodOop m = methodOop(obj); | |
364 constMethodOop xconst = m->constMethod(); | |
365 assert(xconst != NULL, "const method must be set"); | |
366 constMethodKlass* ck = constMethodKlass::cast(xconst->klass()); | |
367 return ck->oop_partially_loaded(xconst); | |
368 } | |
369 | |
370 | |
371 void methodKlass::oop_set_partially_loaded(oop obj) { | |
372 assert(obj->is_method(), "object must be method"); | |
373 methodOop m = methodOop(obj); | |
374 constMethodOop xconst = m->constMethod(); | |
375 assert(xconst != NULL, "const method must be set"); | |
376 constMethodKlass* ck = constMethodKlass::cast(xconst->klass()); | |
377 ck->oop_set_partially_loaded(xconst); | |
378 } |