Mercurial > hg > truffle
annotate src/share/vm/oops/methodOop.cpp @ 4181:319860ae697a
Simplify FrameMap: make offsets of spill slots and outgoing parameters independent so that they can be allocated at the same time, eliminating the separate phases. This makes the separate StackBlock unnecesary. Change CiStackSlot to use byte offsets instead of spill slot index. This makes CiTarget.spillSlotSize unnecessary.
author | Christian Wimmer <Christian.Wimmer@Oracle.com> |
---|---|
date | Mon, 02 Jan 2012 14:16:08 -0800 |
parents | 04b9a2566eec |
children | 33df1aeaebbf |
rev | line source |
---|---|
0 | 1 /* |
2142 | 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:
1515
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1515
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:
1515
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "code/debugInfoRec.hpp" | |
28 #include "gc_interface/collectedHeap.inline.hpp" | |
29 #include "interpreter/bytecodeStream.hpp" | |
30 #include "interpreter/bytecodeTracer.hpp" | |
31 #include "interpreter/bytecodes.hpp" | |
32 #include "interpreter/interpreter.hpp" | |
33 #include "interpreter/oopMapCache.hpp" | |
34 #include "memory/gcLocker.hpp" | |
35 #include "memory/generation.hpp" | |
36 #include "memory/oopFactory.hpp" | |
37 #include "oops/klassOop.hpp" | |
38 #include "oops/methodDataOop.hpp" | |
39 #include "oops/methodOop.hpp" | |
40 #include "oops/oop.inline.hpp" | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
41 #include "oops/symbol.hpp" |
1972 | 42 #include "prims/jvmtiExport.hpp" |
43 #include "prims/methodHandleWalk.hpp" | |
44 #include "prims/nativeLookup.hpp" | |
45 #include "runtime/arguments.hpp" | |
46 #include "runtime/compilationPolicy.hpp" | |
47 #include "runtime/frame.inline.hpp" | |
48 #include "runtime/handles.inline.hpp" | |
49 #include "runtime/relocator.hpp" | |
50 #include "runtime/sharedRuntime.hpp" | |
51 #include "runtime/signature.hpp" | |
3779 | 52 #include "utilities/quickSort.hpp" |
1972 | 53 #include "utilities/xmlstream.hpp" |
0 | 54 |
55 | |
56 // Implementation of methodOopDesc | |
57 | |
58 address methodOopDesc::get_i2c_entry() { | |
59 assert(_adapter != NULL, "must have"); | |
60 return _adapter->get_i2c_entry(); | |
61 } | |
62 | |
63 address methodOopDesc::get_c2i_entry() { | |
64 assert(_adapter != NULL, "must have"); | |
65 return _adapter->get_c2i_entry(); | |
66 } | |
67 | |
68 address methodOopDesc::get_c2i_unverified_entry() { | |
69 assert(_adapter != NULL, "must have"); | |
70 return _adapter->get_c2i_unverified_entry(); | |
71 } | |
72 | |
73 char* methodOopDesc::name_and_sig_as_C_string() { | |
74 return name_and_sig_as_C_string(Klass::cast(constants()->pool_holder()), name(), signature()); | |
75 } | |
76 | |
77 char* methodOopDesc::name_and_sig_as_C_string(char* buf, int size) { | |
78 return name_and_sig_as_C_string(Klass::cast(constants()->pool_holder()), name(), signature(), buf, size); | |
79 } | |
80 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
81 char* methodOopDesc::name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature) { |
0 | 82 const char* klass_name = klass->external_name(); |
83 int klass_name_len = (int)strlen(klass_name); | |
84 int method_name_len = method_name->utf8_length(); | |
85 int len = klass_name_len + 1 + method_name_len + signature->utf8_length(); | |
86 char* dest = NEW_RESOURCE_ARRAY(char, len + 1); | |
87 strcpy(dest, klass_name); | |
88 dest[klass_name_len] = '.'; | |
89 strcpy(&dest[klass_name_len + 1], method_name->as_C_string()); | |
90 strcpy(&dest[klass_name_len + 1 + method_name_len], signature->as_C_string()); | |
91 dest[len] = 0; | |
92 return dest; | |
93 } | |
94 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
95 char* methodOopDesc::name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature, char* buf, int size) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
96 Symbol* klass_name = klass->name(); |
0 | 97 klass_name->as_klass_external_name(buf, size); |
98 int len = (int)strlen(buf); | |
99 | |
100 if (len < size - 1) { | |
101 buf[len++] = '.'; | |
102 | |
103 method_name->as_C_string(&(buf[len]), size - len); | |
104 len = (int)strlen(buf); | |
105 | |
106 signature->as_C_string(&(buf[len]), size - len); | |
107 } | |
108 | |
109 return buf; | |
110 } | |
111 | |
112 int methodOopDesc::fast_exception_handler_bci_for(KlassHandle ex_klass, int throw_bci, TRAPS) { | |
113 // exception table holds quadruple entries of the form (beg_bci, end_bci, handler_bci, klass_index) | |
114 const int beg_bci_offset = 0; | |
115 const int end_bci_offset = 1; | |
116 const int handler_bci_offset = 2; | |
117 const int klass_index_offset = 3; | |
118 const int entry_size = 4; | |
119 // access exception table | |
120 typeArrayHandle table (THREAD, constMethod()->exception_table()); | |
121 int length = table->length(); | |
122 assert(length % entry_size == 0, "exception table format has changed"); | |
123 // iterate through all entries sequentially | |
124 constantPoolHandle pool(THREAD, constants()); | |
125 for (int i = 0; i < length; i += entry_size) { | |
126 int beg_bci = table->int_at(i + beg_bci_offset); | |
127 int end_bci = table->int_at(i + end_bci_offset); | |
128 assert(beg_bci <= end_bci, "inconsistent exception table"); | |
129 if (beg_bci <= throw_bci && throw_bci < end_bci) { | |
130 // exception handler bci range covers throw_bci => investigate further | |
131 int handler_bci = table->int_at(i + handler_bci_offset); | |
132 int klass_index = table->int_at(i + klass_index_offset); | |
133 if (klass_index == 0) { | |
134 return handler_bci; | |
135 } else if (ex_klass.is_null()) { | |
136 return handler_bci; | |
137 } else { | |
138 // we know the exception class => get the constraint class | |
139 // this may require loading of the constraint class; if verification | |
140 // fails or some other exception occurs, return handler_bci | |
141 klassOop k = pool->klass_at(klass_index, CHECK_(handler_bci)); | |
142 KlassHandle klass = KlassHandle(THREAD, k); | |
143 assert(klass.not_null(), "klass not loaded"); | |
144 if (ex_klass->is_subtype_of(klass())) { | |
145 return handler_bci; | |
146 } | |
147 } | |
148 } | |
149 } | |
150 | |
151 return -1; | |
152 } | |
153 | |
154 void methodOopDesc::mask_for(int bci, InterpreterOopMap* mask) { | |
155 | |
156 Thread* myThread = Thread::current(); | |
157 methodHandle h_this(myThread, this); | |
158 #ifdef ASSERT | |
159 bool has_capability = myThread->is_VM_thread() || | |
160 myThread->is_ConcurrentGC_thread() || | |
161 myThread->is_GC_task_thread(); | |
162 | |
163 if (!has_capability) { | |
164 if (!VerifyStack && !VerifyLastFrame) { | |
165 // verify stack calls this outside VM thread | |
166 warning("oopmap should only be accessed by the " | |
167 "VM, GC task or CMS threads (or during debugging)"); | |
168 InterpreterOopMap local_mask; | |
169 instanceKlass::cast(method_holder())->mask_for(h_this, bci, &local_mask); | |
170 local_mask.print(); | |
171 } | |
172 } | |
173 #endif | |
174 instanceKlass::cast(method_holder())->mask_for(h_this, bci, mask); | |
175 return; | |
176 } | |
177 | |
178 | |
179 int methodOopDesc::bci_from(address bcp) const { | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
180 assert(is_native() && bcp == code_base() || contains(bcp) || is_error_reported(), "bcp doesn't belong to this method"); |
0 | 181 return bcp - code_base(); |
182 } | |
183 | |
184 | |
185 // Return (int)bcx if it appears to be a valid BCI. | |
186 // Return bci_from((address)bcx) if it appears to be a valid BCP. | |
187 // Return -1 otherwise. | |
188 // Used by profiling code, when invalid data is a possibility. | |
189 // The caller is responsible for validating the methodOop itself. | |
190 int methodOopDesc::validate_bci_from_bcx(intptr_t bcx) const { | |
191 // keep bci as -1 if not a valid bci | |
192 int bci = -1; | |
193 if (bcx == 0 || (address)bcx == code_base()) { | |
194 // code_size() may return 0 and we allow 0 here | |
195 // the method may be native | |
196 bci = 0; | |
197 } else if (frame::is_bci(bcx)) { | |
198 if (bcx < code_size()) { | |
199 bci = (int)bcx; | |
200 } | |
201 } else if (contains((address)bcx)) { | |
202 bci = (address)bcx - code_base(); | |
203 } | |
204 // Assert that if we have dodged any asserts, bci is negative. | |
205 assert(bci == -1 || bci == bci_from(bcp_from(bci)), "sane bci if >=0"); | |
206 return bci; | |
207 } | |
208 | |
209 address methodOopDesc::bcp_from(int bci) const { | |
2935
9b8f30608e62
deoptimization action (invalidate, reprofile, ...)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2478
diff
changeset
|
210 #ifdef ASSERT |
9b8f30608e62
deoptimization action (invalidate, reprofile, ...)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2478
diff
changeset
|
211 if (!((is_native() && bci == 0) || (!is_native() && 0 <= bci && bci < code_size()))) { |
9b8f30608e62
deoptimization action (invalidate, reprofile, ...)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2478
diff
changeset
|
212 char buf[1024]; |
9b8f30608e62
deoptimization action (invalidate, reprofile, ...)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2478
diff
changeset
|
213 tty->print_cr("bci: %i, size: %i, method: %s", bci, code_size(), const_cast<methodOop>(this)->name_and_sig_as_C_string(buf, 1024)); |
9b8f30608e62
deoptimization action (invalidate, reprofile, ...)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2478
diff
changeset
|
214 } |
9b8f30608e62
deoptimization action (invalidate, reprofile, ...)
Lukas Stadler <lukas.stadler@jku.at>
parents:
2478
diff
changeset
|
215 #endif // ASSERT |
0 | 216 assert((is_native() && bci == 0) || (!is_native() && 0 <= bci && bci < code_size()), "illegal bci"); |
217 address bcp = code_base() + bci; | |
218 assert(is_native() && bcp == code_base() || contains(bcp), "bcp doesn't belong to this method"); | |
219 return bcp; | |
220 } | |
221 | |
222 | |
223 int methodOopDesc::object_size(bool is_native) { | |
224 // If native, then include pointers for native_function and signature_handler | |
225 int extra_bytes = (is_native) ? 2*sizeof(address*) : 0; | |
226 int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord; | |
227 return align_object_size(header_size() + extra_words); | |
228 } | |
229 | |
230 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
231 Symbol* methodOopDesc::klass_name() const { |
0 | 232 klassOop k = method_holder(); |
233 assert(k->is_klass(), "must be klass"); | |
234 instanceKlass* ik = (instanceKlass*) k->klass_part(); | |
235 return ik->name(); | |
236 } | |
237 | |
238 | |
239 void methodOopDesc::set_interpreter_kind() { | |
240 int kind = Interpreter::method_kind(methodOop(this)); | |
241 assert(kind != Interpreter::invalid, | |
242 "interpreter entry must be valid"); | |
243 set_interpreter_kind(kind); | |
244 } | |
245 | |
246 | |
247 // Attempt to return method oop to original state. Clear any pointers | |
248 // (to objects outside the shared spaces). We won't be able to predict | |
249 // where they should point in a new JVM. Further initialize some | |
250 // entries now in order allow them to be write protected later. | |
251 | |
252 void methodOopDesc::remove_unshareable_info() { | |
253 unlink_method(); | |
254 set_interpreter_kind(); | |
255 } | |
256 | |
257 | |
1783 | 258 bool methodOopDesc::was_executed_more_than(int n) { |
0 | 259 // Invocation counter is reset when the methodOop is compiled. |
260 // If the method has compiled code we therefore assume it has | |
261 // be excuted more than n times. | |
262 if (is_accessor() || is_empty_method() || (code() != NULL)) { | |
263 // interpreter doesn't bump invocation counter of trivial methods | |
264 // compiler does not bump invocation counter of compiled methods | |
265 return true; | |
1783 | 266 } |
267 else if (_invocation_counter.carry() || (method_data() != NULL && method_data()->invocation_counter()->carry())) { | |
0 | 268 // The carry bit is set when the counter overflows and causes |
269 // a compilation to occur. We don't know how many times | |
270 // the counter has been reset, so we simply assume it has | |
271 // been executed more than n times. | |
272 return true; | |
273 } else { | |
274 return invocation_count() > n; | |
275 } | |
276 } | |
277 | |
278 #ifndef PRODUCT | |
1783 | 279 void methodOopDesc::print_invocation_count() { |
0 | 280 if (is_static()) tty->print("static "); |
281 if (is_final()) tty->print("final "); | |
282 if (is_synchronized()) tty->print("synchronized "); | |
283 if (is_native()) tty->print("native "); | |
284 method_holder()->klass_part()->name()->print_symbol_on(tty); | |
285 tty->print("."); | |
286 name()->print_symbol_on(tty); | |
287 signature()->print_symbol_on(tty); | |
288 | |
289 if (WizardMode) { | |
290 // dump the size of the byte codes | |
291 tty->print(" {%d}", code_size()); | |
292 } | |
293 tty->cr(); | |
294 | |
295 tty->print_cr (" interpreter_invocation_count: %8d ", interpreter_invocation_count()); | |
296 tty->print_cr (" invocation_counter: %8d ", invocation_count()); | |
297 tty->print_cr (" backedge_counter: %8d ", backedge_count()); | |
298 if (CountCompiledCalls) { | |
299 tty->print_cr (" compiled_invocation_count: %8d ", compiled_invocation_count()); | |
300 } | |
301 | |
302 } | |
303 #endif | |
304 | |
305 // Build a methodDataOop object to hold information about this method | |
306 // collected in the interpreter. | |
307 void methodOopDesc::build_interpreter_method_data(methodHandle method, TRAPS) { | |
2021
7cf1a74771e8
6988439: Parallel Class Loading test deadlock involving MethodData_lock and Pending List Lock
coleenp
parents:
1972
diff
changeset
|
308 // Do not profile method if current thread holds the pending list lock, |
7cf1a74771e8
6988439: Parallel Class Loading test deadlock involving MethodData_lock and Pending List Lock
coleenp
parents:
1972
diff
changeset
|
309 // which avoids deadlock for acquiring the MethodData_lock. |
7cf1a74771e8
6988439: Parallel Class Loading test deadlock involving MethodData_lock and Pending List Lock
coleenp
parents:
1972
diff
changeset
|
310 if (instanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) { |
7cf1a74771e8
6988439: Parallel Class Loading test deadlock involving MethodData_lock and Pending List Lock
coleenp
parents:
1972
diff
changeset
|
311 return; |
7cf1a74771e8
6988439: Parallel Class Loading test deadlock involving MethodData_lock and Pending List Lock
coleenp
parents:
1972
diff
changeset
|
312 } |
7cf1a74771e8
6988439: Parallel Class Loading test deadlock involving MethodData_lock and Pending List Lock
coleenp
parents:
1972
diff
changeset
|
313 |
0 | 314 // Grab a lock here to prevent multiple |
315 // methodDataOops from being created. | |
316 MutexLocker ml(MethodData_lock, THREAD); | |
317 if (method->method_data() == NULL) { | |
318 methodDataOop method_data = oopFactory::new_methodData(method, CHECK); | |
319 method->set_method_data(method_data); | |
320 if (PrintMethodData && (Verbose || WizardMode)) { | |
321 ResourceMark rm(THREAD); | |
322 tty->print("build_interpreter_method_data for "); | |
323 method->print_name(tty); | |
324 tty->cr(); | |
325 // At the end of the run, the MDO, full of data, will be dumped. | |
326 } | |
327 } | |
328 } | |
329 | |
330 void methodOopDesc::cleanup_inline_caches() { | |
331 // The current system doesn't use inline caches in the interpreter | |
332 // => nothing to do (keep this method around for future use) | |
333 } | |
334 | |
335 | |
710 | 336 int methodOopDesc::extra_stack_words() { |
337 // not an inline function, to avoid a header dependency on Interpreter | |
1506 | 338 return extra_stack_entries() * Interpreter::stackElementSize; |
710 | 339 } |
340 | |
341 | |
0 | 342 void methodOopDesc::compute_size_of_parameters(Thread *thread) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
343 ArgumentSizeComputer asc(signature()); |
0 | 344 set_size_of_parameters(asc.size() + (is_static() ? 0 : 1)); |
345 } | |
346 | |
347 #ifdef CC_INTERP | |
348 void methodOopDesc::set_result_index(BasicType type) { | |
349 _result_index = Interpreter::BasicType_as_index(type); | |
350 } | |
351 #endif | |
352 | |
353 BasicType methodOopDesc::result_type() const { | |
354 ResultTypeFinder rtf(signature()); | |
355 return rtf.type(); | |
356 } | |
357 | |
358 | |
359 bool methodOopDesc::is_empty_method() const { | |
360 return code_size() == 1 | |
361 && *code_base() == Bytecodes::_return; | |
362 } | |
363 | |
364 | |
365 bool methodOopDesc::is_vanilla_constructor() const { | |
366 // Returns true if this method is a vanilla constructor, i.e. an "<init>" "()V" method | |
367 // which only calls the superclass vanilla constructor and possibly does stores of | |
368 // zero constants to local fields: | |
369 // | |
370 // aload_0 | |
371 // invokespecial | |
372 // indexbyte1 | |
373 // indexbyte2 | |
374 // | |
375 // followed by an (optional) sequence of: | |
376 // | |
377 // aload_0 | |
378 // aconst_null / iconst_0 / fconst_0 / dconst_0 | |
379 // putfield | |
380 // indexbyte1 | |
381 // indexbyte2 | |
382 // | |
383 // followed by: | |
384 // | |
385 // return | |
386 | |
387 assert(name() == vmSymbols::object_initializer_name(), "Should only be called for default constructors"); | |
388 assert(signature() == vmSymbols::void_method_signature(), "Should only be called for default constructors"); | |
389 int size = code_size(); | |
390 // Check if size match | |
391 if (size == 0 || size % 5 != 0) return false; | |
392 address cb = code_base(); | |
393 int last = size - 1; | |
394 if (cb[0] != Bytecodes::_aload_0 || cb[1] != Bytecodes::_invokespecial || cb[last] != Bytecodes::_return) { | |
395 // Does not call superclass default constructor | |
396 return false; | |
397 } | |
398 // Check optional sequence | |
399 for (int i = 4; i < last; i += 5) { | |
400 if (cb[i] != Bytecodes::_aload_0) return false; | |
401 if (!Bytecodes::is_zero_const(Bytecodes::cast(cb[i+1]))) return false; | |
402 if (cb[i+2] != Bytecodes::_putfield) return false; | |
403 } | |
404 return true; | |
405 } | |
406 | |
407 | |
408 bool methodOopDesc::compute_has_loops_flag() { | |
409 BytecodeStream bcs(methodOop(this)); | |
410 Bytecodes::Code bc; | |
411 | |
412 while ((bc = bcs.next()) >= 0) { | |
413 switch( bc ) { | |
414 case Bytecodes::_ifeq: | |
415 case Bytecodes::_ifnull: | |
416 case Bytecodes::_iflt: | |
417 case Bytecodes::_ifle: | |
418 case Bytecodes::_ifne: | |
419 case Bytecodes::_ifnonnull: | |
420 case Bytecodes::_ifgt: | |
421 case Bytecodes::_ifge: | |
422 case Bytecodes::_if_icmpeq: | |
423 case Bytecodes::_if_icmpne: | |
424 case Bytecodes::_if_icmplt: | |
425 case Bytecodes::_if_icmpgt: | |
426 case Bytecodes::_if_icmple: | |
427 case Bytecodes::_if_icmpge: | |
428 case Bytecodes::_if_acmpeq: | |
429 case Bytecodes::_if_acmpne: | |
430 case Bytecodes::_goto: | |
431 case Bytecodes::_jsr: | |
432 if( bcs.dest() < bcs.next_bci() ) _access_flags.set_has_loops(); | |
433 break; | |
434 | |
435 case Bytecodes::_goto_w: | |
436 case Bytecodes::_jsr_w: | |
437 if( bcs.dest_w() < bcs.next_bci() ) _access_flags.set_has_loops(); | |
438 break; | |
439 } | |
440 } | |
441 _access_flags.set_loops_flag_init(); | |
442 return _access_flags.has_loops(); | |
443 } | |
444 | |
445 | |
446 bool methodOopDesc::is_final_method() const { | |
447 // %%% Should return true for private methods also, | |
448 // since there is no way to override them. | |
449 return is_final() || Klass::cast(method_holder())->is_final(); | |
450 } | |
451 | |
452 | |
453 bool methodOopDesc::is_strict_method() const { | |
454 return is_strict(); | |
455 } | |
456 | |
457 | |
458 bool methodOopDesc::can_be_statically_bound() const { | |
459 if (is_final_method()) return true; | |
460 return vtable_index() == nonvirtual_vtable_index; | |
461 } | |
462 | |
463 | |
464 bool methodOopDesc::is_accessor() const { | |
465 if (code_size() != 5) return false; | |
466 if (size_of_parameters() != 1) return false; | |
2142 | 467 if (java_code_at(0) != Bytecodes::_aload_0 ) return false; |
468 if (java_code_at(1) != Bytecodes::_getfield) return false; | |
469 if (java_code_at(4) != Bytecodes::_areturn && | |
470 java_code_at(4) != Bytecodes::_ireturn ) return false; | |
0 | 471 return true; |
472 } | |
473 | |
474 | |
475 bool methodOopDesc::is_initializer() const { | |
2334
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
476 return name() == vmSymbols::object_initializer_name() || is_static_initializer(); |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
477 } |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
478 |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
479 bool methodOopDesc::has_valid_initializer_flags() const { |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
480 return (is_static() || |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
481 instanceKlass::cast(method_holder())->major_version() < 51); |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
482 } |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
483 |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
484 bool methodOopDesc::is_static_initializer() const { |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
485 // For classfiles version 51 or greater, ensure that the clinit method is |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
486 // static. Non-static methods with the name "<clinit>" are not static |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
487 // initializers. (older classfiles exempted for backward compatibility) |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
488 return name() == vmSymbols::class_initializer_name() && |
dbad0519a1c4
6845426: non-static <clinit> method with no args is called during the class initialization process
kamg
parents:
2264
diff
changeset
|
489 has_valid_initializer_flags(); |
0 | 490 } |
491 | |
492 | |
493 objArrayHandle methodOopDesc::resolved_checked_exceptions_impl(methodOop this_oop, TRAPS) { | |
494 int length = this_oop->checked_exceptions_length(); | |
495 if (length == 0) { // common case | |
496 return objArrayHandle(THREAD, Universe::the_empty_class_klass_array()); | |
497 } else { | |
498 methodHandle h_this(THREAD, this_oop); | |
1142 | 499 objArrayOop m_oop = oopFactory::new_objArray(SystemDictionary::Class_klass(), length, CHECK_(objArrayHandle())); |
0 | 500 objArrayHandle mirrors (THREAD, m_oop); |
501 for (int i = 0; i < length; i++) { | |
502 CheckedExceptionElement* table = h_this->checked_exceptions_start(); // recompute on each iteration, not gc safe | |
503 klassOop k = h_this->constants()->klass_at(table[i].class_cp_index, CHECK_(objArrayHandle())); | |
1142 | 504 assert(Klass::cast(k)->is_subclass_of(SystemDictionary::Throwable_klass()), "invalid exception class"); |
0 | 505 mirrors->obj_at_put(i, Klass::cast(k)->java_mirror()); |
506 } | |
507 return mirrors; | |
508 } | |
509 }; | |
510 | |
511 | |
512 int methodOopDesc::line_number_from_bci(int bci) const { | |
513 if (bci == SynchronizationEntryBCI) bci = 0; | |
514 assert(bci == 0 || 0 <= bci && bci < code_size(), "illegal bci"); | |
515 int best_bci = 0; | |
516 int best_line = -1; | |
517 | |
518 if (has_linenumber_table()) { | |
519 // The line numbers are a short array of 2-tuples [start_pc, line_number]. | |
520 // Not necessarily sorted and not necessarily one-to-one. | |
521 CompressedLineNumberReadStream stream(compressed_linenumber_table()); | |
522 while (stream.read_pair()) { | |
523 if (stream.bci() == bci) { | |
524 // perfect match | |
525 return stream.line(); | |
526 } else { | |
527 // update best_bci/line | |
528 if (stream.bci() < bci && stream.bci() >= best_bci) { | |
529 best_bci = stream.bci(); | |
530 best_line = stream.line(); | |
531 } | |
532 } | |
533 } | |
534 } | |
535 return best_line; | |
536 } | |
537 | |
538 | |
539 bool methodOopDesc::is_klass_loaded_by_klass_index(int klass_index) const { | |
540 if( _constants->tag_at(klass_index).is_unresolved_klass() ) { | |
541 Thread *thread = Thread::current(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
542 Symbol* klass_name = _constants->klass_name_at(klass_index); |
0 | 543 Handle loader(thread, instanceKlass::cast(method_holder())->class_loader()); |
544 Handle prot (thread, Klass::cast(method_holder())->protection_domain()); | |
545 return SystemDictionary::find(klass_name, loader, prot, thread) != NULL; | |
546 } else { | |
547 return true; | |
548 } | |
549 } | |
550 | |
551 | |
552 bool methodOopDesc::is_klass_loaded(int refinfo_index, bool must_be_resolved) const { | |
553 int klass_index = _constants->klass_ref_index_at(refinfo_index); | |
554 if (must_be_resolved) { | |
555 // Make sure klass is resolved in constantpool. | |
556 if (constants()->tag_at(klass_index).is_unresolved_klass()) return false; | |
557 } | |
558 return is_klass_loaded_by_klass_index(klass_index); | |
559 } | |
560 | |
561 | |
562 void methodOopDesc::set_native_function(address function, bool post_event_flag) { | |
563 assert(function != NULL, "use clear_native_function to unregister natives"); | |
564 address* native_function = native_function_addr(); | |
565 | |
566 // We can see racers trying to place the same native function into place. Once | |
567 // is plenty. | |
568 address current = *native_function; | |
569 if (current == function) return; | |
570 if (post_event_flag && JvmtiExport::should_post_native_method_bind() && | |
571 function != NULL) { | |
572 // native_method_throw_unsatisfied_link_error_entry() should only | |
573 // be passed when post_event_flag is false. | |
574 assert(function != | |
575 SharedRuntime::native_method_throw_unsatisfied_link_error_entry(), | |
576 "post_event_flag mis-match"); | |
577 | |
578 // post the bind event, and possible change the bind function | |
579 JvmtiExport::post_native_method_bind(this, &function); | |
580 } | |
581 *native_function = function; | |
582 // This function can be called more than once. We must make sure that we always | |
583 // use the latest registered method -> check if a stub already has been generated. | |
584 // If so, we have to make it not_entrant. | |
585 nmethod* nm = code(); // Put it into local variable to guard against concurrent updates | |
586 if (nm != NULL) { | |
587 nm->make_not_entrant(); | |
588 } | |
589 } | |
590 | |
591 | |
592 bool methodOopDesc::has_native_function() const { | |
593 address func = native_function(); | |
594 return (func != NULL && func != SharedRuntime::native_method_throw_unsatisfied_link_error_entry()); | |
595 } | |
596 | |
597 | |
598 void methodOopDesc::clear_native_function() { | |
599 set_native_function( | |
600 SharedRuntime::native_method_throw_unsatisfied_link_error_entry(), | |
601 !native_bind_event_is_interesting); | |
602 clear_code(); | |
603 } | |
604 | |
605 | |
606 void methodOopDesc::set_signature_handler(address handler) { | |
607 address* signature_handler = signature_handler_addr(); | |
608 *signature_handler = handler; | |
609 } | |
610 | |
611 | |
612 bool methodOopDesc::is_not_compilable(int comp_level) const { | |
710 | 613 if (is_method_handle_invoke()) { |
614 // compilers must recognize this method specially, or not at all | |
615 return true; | |
616 } | |
1783 | 617 if (number_of_breakpoints() > 0) { |
618 return true; | |
619 } | |
620 if (comp_level == CompLevel_any) { | |
621 return is_not_c1_compilable() || is_not_c2_compilable(); | |
0 | 622 } |
1783 | 623 if (is_c1_compile(comp_level)) { |
624 return is_not_c1_compilable(); | |
625 } | |
626 if (is_c2_compile(comp_level)) { | |
627 return is_not_c2_compilable(); | |
628 } | |
629 return false; | |
0 | 630 } |
631 | |
632 // call this when compiler finds that this method is not compilable | |
1208
cef333a48af6
6923043: failed nightly tests which use -XX:+PrintCompilation -Xcomp -XX:CompileOnly
kvn
parents:
1206
diff
changeset
|
633 void methodOopDesc::set_not_compilable(int comp_level, bool report) { |
cef333a48af6
6923043: failed nightly tests which use -XX:+PrintCompilation -Xcomp -XX:CompileOnly
kvn
parents:
1206
diff
changeset
|
634 if (PrintCompilation && report) { |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1202
diff
changeset
|
635 ttyLocker ttyl; |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1202
diff
changeset
|
636 tty->print("made not compilable "); |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1202
diff
changeset
|
637 this->print_short_name(tty); |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1202
diff
changeset
|
638 int size = this->code_size(); |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1202
diff
changeset
|
639 if (size > 0) |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1202
diff
changeset
|
640 tty->print(" (%d bytes)", size); |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1202
diff
changeset
|
641 tty->cr(); |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1202
diff
changeset
|
642 } |
0 | 643 if ((TraceDeoptimization || LogCompilation) && (xtty != NULL)) { |
644 ttyLocker ttyl; | |
645 xtty->begin_elem("make_not_compilable thread='%d'", (int) os::current_thread_id()); | |
646 xtty->method(methodOop(this)); | |
647 xtty->stamp(); | |
648 xtty->end_elem(); | |
649 } | |
1783 | 650 if (comp_level == CompLevel_all) { |
651 set_not_c1_compilable(); | |
652 set_not_c2_compilable(); | |
653 } else { | |
654 if (is_c1_compile(comp_level)) { | |
655 set_not_c1_compilable(); | |
656 } else | |
657 if (is_c2_compile(comp_level)) { | |
658 set_not_c2_compilable(); | |
659 } | |
0 | 660 } |
1783 | 661 CompilationPolicy::policy()->disable_compilation(this); |
0 | 662 } |
663 | |
664 // Revert to using the interpreter and clear out the nmethod | |
665 void methodOopDesc::clear_code() { | |
666 | |
667 // this may be NULL if c2i adapters have not been made yet | |
668 // Only should happen at allocate time. | |
669 if (_adapter == NULL) { | |
670 _from_compiled_entry = NULL; | |
671 } else { | |
672 _from_compiled_entry = _adapter->get_c2i_entry(); | |
673 } | |
674 OrderAccess::storestore(); | |
675 _from_interpreted_entry = _i2i_entry; | |
676 OrderAccess::storestore(); | |
677 _code = NULL; | |
678 } | |
679 | |
680 // Called by class data sharing to remove any entry points (which are not shared) | |
681 void methodOopDesc::unlink_method() { | |
682 _code = NULL; | |
683 _i2i_entry = NULL; | |
684 _from_interpreted_entry = NULL; | |
685 if (is_native()) { | |
686 *native_function_addr() = NULL; | |
687 set_signature_handler(NULL); | |
688 } | |
689 NOT_PRODUCT(set_compiled_invocation_count(0);) | |
690 invocation_counter()->reset(); | |
691 backedge_counter()->reset(); | |
692 _adapter = NULL; | |
693 _from_compiled_entry = NULL; | |
694 assert(_method_data == NULL, "unexpected method data?"); | |
695 set_method_data(NULL); | |
696 set_interpreter_throwout_count(0); | |
697 set_interpreter_invocation_count(0); | |
698 } | |
699 | |
700 // Called when the method_holder is getting linked. Setup entrypoints so the method | |
701 // is ready to be called from interpreter, compiler, and vtables. | |
702 void methodOopDesc::link_method(methodHandle h_method, TRAPS) { | |
3404 | 703 // If the code cache is full, we may reenter this function for the |
704 // leftover methods that weren't linked. | |
705 if (_i2i_entry != NULL) return; | |
706 | |
0 | 707 assert(_adapter == NULL, "init'd to NULL" ); |
708 assert( _code == NULL, "nothing compiled yet" ); | |
709 | |
710 // Setup interpreter entrypoint | |
711 assert(this == h_method(), "wrong h_method()" ); | |
712 address entry = Interpreter::entry_for_method(h_method); | |
713 assert(entry != NULL, "interpreter entry must be non-null"); | |
714 // Sets both _i2i_entry and _from_interpreted_entry | |
715 set_interpreter_entry(entry); | |
710 | 716 if (is_native() && !is_method_handle_invoke()) { |
0 | 717 set_native_function( |
718 SharedRuntime::native_method_throw_unsatisfied_link_error_entry(), | |
719 !native_bind_event_is_interesting); | |
720 } | |
721 | |
722 // Setup compiler entrypoint. This is made eagerly, so we do not need | |
723 // special handling of vtables. An alternative is to make adapters more | |
724 // lazily by calling make_adapter() from from_compiled_entry() for the | |
725 // normal calls. For vtable calls life gets more complicated. When a | |
726 // call-site goes mega-morphic we need adapters in all methods which can be | |
727 // called from the vtable. We need adapters on such methods that get loaded | |
728 // later. Ditto for mega-morphic itable calls. If this proves to be a | |
729 // problem we'll make these lazily later. | |
3419
deaa3ce90583
7049928: VM crashes with "assert(_adapter != NULL) failed: must have" at methodOop.cpp:63
coleenp
parents:
3404
diff
changeset
|
730 (void) make_adapters(h_method, CHECK); |
0 | 731 |
732 // ONLY USE the h_method now as make_adapter may have blocked | |
733 | |
734 } | |
735 | |
736 address methodOopDesc::make_adapters(methodHandle mh, TRAPS) { | |
737 // Adapters for compiled code are made eagerly here. They are fairly | |
738 // small (generally < 100 bytes) and quick to make (and cached and shared) | |
739 // so making them eagerly shouldn't be too expensive. | |
740 AdapterHandlerEntry* adapter = AdapterHandlerLibrary::get_adapter(mh); | |
741 if (adapter == NULL ) { | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1152
diff
changeset
|
742 THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), "out of space in CodeCache for adapters"); |
0 | 743 } |
744 | |
745 mh->set_adapter_entry(adapter); | |
746 mh->_from_compiled_entry = adapter->get_c2i_entry(); | |
747 return adapter->get_c2i_entry(); | |
748 } | |
749 | |
750 // The verified_code_entry() must be called when a invoke is resolved | |
751 // on this method. | |
752 | |
753 // It returns the compiled code entry point, after asserting not null. | |
754 // This function is called after potential safepoints so that nmethod | |
755 // or adapter that it points to is still live and valid. | |
756 // This function must not hit a safepoint! | |
757 address methodOopDesc::verified_code_entry() { | |
758 debug_only(No_Safepoint_Verifier nsv;) | |
1202 | 759 nmethod *code = (nmethod *)OrderAccess::load_ptr_acquire(&_code); |
760 if (code == NULL && UseCodeCacheFlushing) { | |
761 nmethod *saved_code = CodeCache::find_and_remove_saved_code(this); | |
762 if (saved_code != NULL) { | |
763 methodHandle method(this); | |
764 assert( ! saved_code->is_osr_method(), "should not get here for osr" ); | |
765 set_code( method, saved_code ); | |
766 } | |
767 } | |
768 | |
0 | 769 assert(_from_compiled_entry != NULL, "must be set"); |
770 return _from_compiled_entry; | |
771 } | |
772 | |
773 // Check that if an nmethod ref exists, it has a backlink to this or no backlink at all | |
774 // (could be racing a deopt). | |
775 // Not inline to avoid circular ref. | |
776 bool methodOopDesc::check_code() const { | |
777 // cached in a register or local. There's a race on the value of the field. | |
778 nmethod *code = (nmethod *)OrderAccess::load_ptr_acquire(&_code); | |
779 return code == NULL || (code->method() == NULL) || (code->method() == (methodOop)this && !code->is_osr_method()); | |
780 } | |
781 | |
782 // Install compiled code. Instantly it can execute. | |
783 void methodOopDesc::set_code(methodHandle mh, nmethod *code) { | |
784 assert( code, "use clear_code to remove code" ); | |
785 assert( mh->check_code(), "" ); | |
786 | |
787 guarantee(mh->adapter() != NULL, "Adapter blob must already exist!"); | |
788 | |
789 // These writes must happen in this order, because the interpreter will | |
790 // directly jump to from_interpreted_entry which jumps to an i2c adapter | |
791 // which jumps to _from_compiled_entry. | |
792 mh->_code = code; // Assign before allowing compiled code to exec | |
793 | |
794 int comp_level = code->comp_level(); | |
795 // In theory there could be a race here. In practice it is unlikely | |
796 // and not worth worrying about. | |
1783 | 797 if (comp_level > mh->highest_comp_level()) { |
798 mh->set_highest_comp_level(comp_level); | |
0 | 799 } |
800 | |
801 OrderAccess::storestore(); | |
1692 | 802 #ifdef SHARK |
1845
a222fcfba398
6990549: Zero and Shark fixes after 6978355 and 6953144
twisti
parents:
1793
diff
changeset
|
803 mh->_from_interpreted_entry = code->insts_begin(); |
1692 | 804 #else |
0 | 805 mh->_from_compiled_entry = code->verified_entry_point(); |
806 OrderAccess::storestore(); | |
807 // Instantly compiled code can execute. | |
808 mh->_from_interpreted_entry = mh->get_i2c_entry(); | |
1692 | 809 #endif // SHARK |
0 | 810 |
811 } | |
812 | |
813 | |
814 bool methodOopDesc::is_overridden_in(klassOop k) const { | |
815 instanceKlass* ik = instanceKlass::cast(k); | |
816 | |
817 if (ik->is_interface()) return false; | |
818 | |
819 // If method is an interface, we skip it - except if it | |
820 // is a miranda method | |
821 if (instanceKlass::cast(method_holder())->is_interface()) { | |
822 // Check that method is not a miranda method | |
823 if (ik->lookup_method(name(), signature()) == NULL) { | |
824 // No implementation exist - so miranda method | |
825 return false; | |
826 } | |
827 return true; | |
828 } | |
829 | |
830 assert(ik->is_subclass_of(method_holder()), "should be subklass"); | |
831 assert(ik->vtable() != NULL, "vtable should exist"); | |
832 if (vtable_index() == nonvirtual_vtable_index) { | |
833 return false; | |
834 } else { | |
835 methodOop vt_m = ik->method_at_vtable(vtable_index()); | |
836 return vt_m != methodOop(this); | |
837 } | |
838 } | |
839 | |
840 | |
48
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
841 // give advice about whether this methodOop should be cached or not |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
842 bool methodOopDesc::should_not_be_cached() const { |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
843 if (is_old()) { |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
844 // This method has been redefined. It is either EMCP or obsolete |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
845 // and we don't want to cache it because that would pin the method |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
846 // down and prevent it from being collectible if and when it |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
847 // finishes executing. |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
848 return true; |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
849 } |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
850 |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
851 if (mark()->should_not_be_cached()) { |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
852 // It is either not safe or not a good idea to cache this |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
853 // method at this time because of the state of the embedded |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
854 // markOop. See markOop.cpp for the gory details. |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
855 return true; |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
856 } |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
857 |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
858 // caching this method should be just fine |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
859 return false; |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
860 } |
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
861 |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
862 bool methodOopDesc::is_method_handle_invoke_name(vmSymbols::SID name_sid) { |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
863 switch (name_sid) { |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
864 case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name): |
2460 | 865 case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name): |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
866 return true; |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
867 } |
2460 | 868 if (AllowInvokeGeneric |
869 && name_sid == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name)) | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
870 return true; |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
871 return false; |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
872 } |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
873 |
710 | 874 // Constant pool structure for invoke methods: |
875 enum { | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
876 _imcp_invoke_name = 1, // utf8: 'invokeExact' or 'invokeGeneric' |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
877 _imcp_invoke_signature, // utf8: (variable Symbol*) |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
878 _imcp_method_type_value, // string: (variable java/lang/invoke/MethodType, sic) |
710 | 879 _imcp_limit |
880 }; | |
881 | |
882 oop methodOopDesc::method_handle_type() const { | |
883 if (!is_method_handle_invoke()) { assert(false, "caller resp."); return NULL; } | |
884 oop mt = constants()->resolved_string_at(_imcp_method_type_value); | |
885 assert(mt->klass() == SystemDictionary::MethodType_klass(), ""); | |
886 return mt; | |
887 } | |
888 | |
889 jint* methodOopDesc::method_type_offsets_chain() { | |
890 static jint pchase[] = { -1, -1, -1 }; | |
891 if (pchase[0] == -1) { | |
892 jint step0 = in_bytes(constants_offset()); | |
893 jint step1 = (constantPoolOopDesc::header_size() + _imcp_method_type_value) * HeapWordSize; | |
894 // do this in reverse to avoid races: | |
895 OrderAccess::release_store(&pchase[1], step1); | |
896 OrderAccess::release_store(&pchase[0], step0); | |
897 } | |
898 return pchase; | |
899 } | |
900 | |
1152
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1142
diff
changeset
|
901 //------------------------------------------------------------------------------ |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1142
diff
changeset
|
902 // methodOopDesc::is_method_handle_adapter |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1142
diff
changeset
|
903 // |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1142
diff
changeset
|
904 // Tests if this method is an internal adapter frame from the |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1142
diff
changeset
|
905 // MethodHandleCompiler. |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
906 // Must be consistent with MethodHandleCompiler::get_method_oop(). |
1152
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1142
diff
changeset
|
907 bool methodOopDesc::is_method_handle_adapter() const { |
1662
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1552
diff
changeset
|
908 if (is_synthetic() && |
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1552
diff
changeset
|
909 !is_native() && // has code from MethodHandleCompiler |
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1552
diff
changeset
|
910 is_method_handle_invoke_name(name()) && |
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1552
diff
changeset
|
911 MethodHandleCompiler::klass_is_method_handle_adapter_holder(method_holder())) { |
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1552
diff
changeset
|
912 assert(!is_method_handle_invoke(), "disjoint"); |
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1552
diff
changeset
|
913 return true; |
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1552
diff
changeset
|
914 } else { |
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1552
diff
changeset
|
915 return false; |
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1552
diff
changeset
|
916 } |
1152
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1142
diff
changeset
|
917 } |
cd37471eaecc
6914206: change way of permission checking for generated MethodHandle adapters
twisti
parents:
1142
diff
changeset
|
918 |
710 | 919 methodHandle methodOopDesc::make_invoke_method(KlassHandle holder, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
920 Symbol* name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
921 Symbol* signature, |
710 | 922 Handle method_type, TRAPS) { |
3891
ac8738449b6f
7082949: JSR 292: missing ResourceMark in methodOopDesc::make_invoke_method
never
parents:
3795
diff
changeset
|
923 ResourceMark rm; |
710 | 924 methodHandle empty; |
925 | |
926 assert(holder() == SystemDictionary::MethodHandle_klass(), | |
927 "must be a JSR 292 magic type"); | |
928 | |
929 if (TraceMethodHandles) { | |
930 tty->print("Creating invoke method for "); | |
931 signature->print_value(); | |
932 tty->cr(); | |
933 } | |
934 | |
2478
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
935 // invariant: cp->symbol_at_put is preceded by a refcount increment (more usually a lookup) |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
936 name->increment_refcount(); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
937 signature->increment_refcount(); |
328926869b15
6987991: JSR 292 phpreboot test/testtracefun2.phpr segfaults
jrose
parents:
2460
diff
changeset
|
938 |
3461
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
939 // record non-BCP method types in the constant pool |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
940 GrowableArray<KlassHandle>* extra_klasses = NULL; |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
941 for (int i = -1, len = java_lang_invoke_MethodType::ptype_count(method_type()); i < len; i++) { |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
942 oop ptype = (i == -1 |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
943 ? java_lang_invoke_MethodType::rtype(method_type()) |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
944 : java_lang_invoke_MethodType::ptype(method_type(), i)); |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
945 klassOop klass = check_non_bcp_klass(java_lang_Class::as_klassOop(ptype)); |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
946 if (klass != NULL) { |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
947 if (extra_klasses == NULL) |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
948 extra_klasses = new GrowableArray<KlassHandle>(len+1); |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
949 bool dup = false; |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
950 for (int j = 0; j < extra_klasses->length(); j++) { |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
951 if (extra_klasses->at(j) == klass) { dup = true; break; } |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
952 } |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
953 if (!dup) |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
954 extra_klasses->append(KlassHandle(THREAD, klass)); |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
955 } |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
956 } |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
957 |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
958 int extra_klass_count = (extra_klasses == NULL ? 0 : extra_klasses->length()); |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
959 int cp_length = _imcp_limit + extra_klass_count; |
710 | 960 constantPoolHandle cp; |
961 { | |
3461
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
962 constantPoolOop cp_oop = oopFactory::new_constantPool(cp_length, IsSafeConc, CHECK_(empty)); |
710 | 963 cp = constantPoolHandle(THREAD, cp_oop); |
964 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
965 cp->symbol_at_put(_imcp_invoke_name, name); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
966 cp->symbol_at_put(_imcp_invoke_signature, signature); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
967 cp->string_at_put(_imcp_method_type_value, Universe::the_null_string()); |
3461
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
968 for (int j = 0; j < extra_klass_count; j++) { |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
969 KlassHandle klass = extra_klasses->at(j); |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
970 cp->klass_at_put(_imcp_limit + j, klass()); |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
971 } |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
972 cp->set_preresolution(); |
710 | 973 cp->set_pool_holder(holder()); |
974 | |
975 // set up the fancy stuff: | |
976 cp->pseudo_string_at_put(_imcp_method_type_value, method_type()); | |
977 methodHandle m; | |
978 { | |
979 int flags_bits = (JVM_MH_INVOKE_BITS | JVM_ACC_PUBLIC | JVM_ACC_FINAL); | |
980 methodOop m_oop = oopFactory::new_method(0, accessFlags_from(flags_bits), | |
981 0, 0, 0, IsSafeConc, CHECK_(empty)); | |
982 m = methodHandle(THREAD, m_oop); | |
983 } | |
984 m->set_constants(cp()); | |
985 m->set_name_index(_imcp_invoke_name); | |
986 m->set_signature_index(_imcp_invoke_signature); | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
987 assert(is_method_handle_invoke_name(m->name()), ""); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
988 assert(m->signature() == signature, ""); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
989 assert(m->is_method_handle_invoke(), ""); |
710 | 990 #ifdef CC_INTERP |
2256
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
2177
diff
changeset
|
991 ResultTypeFinder rtf(signature); |
710 | 992 m->set_result_index(rtf.type()); |
993 #endif | |
994 m->compute_size_of_parameters(THREAD); | |
995 m->set_exception_table(Universe::the_empty_int_array()); | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
996 m->init_intrinsic_id(); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
997 assert(m->intrinsic_id() == vmIntrinsics::_invokeExact || |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
998 m->intrinsic_id() == vmIntrinsics::_invokeGeneric, "must be an invoker"); |
710 | 999 |
1000 // Finally, set up its entry points. | |
1001 assert(m->method_handle_type() == method_type(), ""); | |
1002 assert(m->can_be_statically_bound(), ""); | |
1003 m->set_vtable_index(methodOopDesc::nonvirtual_vtable_index); | |
1004 m->link_method(m, CHECK_(empty)); | |
1005 | |
1006 #ifdef ASSERT | |
1007 // Make sure the pointer chase works. | |
1008 address p = (address) m(); | |
1009 for (jint* pchase = method_type_offsets_chain(); (*pchase) != -1; pchase++) { | |
1010 p = *(address*)(p + (*pchase)); | |
1011 } | |
1012 assert((oop)p == method_type(), "pointer chase is correct"); | |
1013 #endif | |
1014 | |
1039
987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
jrose
parents:
856
diff
changeset
|
1015 if (TraceMethodHandles && (Verbose || WizardMode)) |
710 | 1016 m->print_on(tty); |
1017 | |
1018 return m; | |
1019 } | |
1020 | |
3461
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
1021 klassOop methodOopDesc::check_non_bcp_klass(klassOop klass) { |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
1022 if (klass != NULL && Klass::cast(klass)->class_loader() != NULL) { |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
1023 if (Klass::cast(klass)->oop_is_objArray()) |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
1024 klass = objArrayKlass::cast(klass)->bottom_klass(); |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
1025 return klass; |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
1026 } |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
1027 return NULL; |
81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3419
diff
changeset
|
1028 } |
710 | 1029 |
48
d8b3ef7ee3e5
6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure
dcubed
parents:
0
diff
changeset
|
1030 |
0 | 1031 methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length, |
1032 u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS) { | |
1033 // Code below does not work for native methods - they should never get rewritten anyway | |
1034 assert(!m->is_native(), "cannot rewrite native methods"); | |
1035 // Allocate new methodOop | |
1036 AccessFlags flags = m->access_flags(); | |
1037 int checked_exceptions_len = m->checked_exceptions_length(); | |
1038 int localvariable_len = m->localvariable_table_length(); | |
518
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1039 // Allocate newm_oop with the is_conc_safe parameter set |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1040 // to IsUnsafeConc to indicate that newm_oop is not yet |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1041 // safe for concurrent processing by a GC. |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1042 methodOop newm_oop = oopFactory::new_method(new_code_length, |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1043 flags, |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1044 new_compressed_linenumber_size, |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1045 localvariable_len, |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1046 checked_exceptions_len, |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1047 IsUnsafeConc, |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1048 CHECK_(methodHandle())); |
0 | 1049 methodHandle newm (THREAD, newm_oop); |
2226
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1050 NOT_PRODUCT(int nmsz = newm->is_parsable() ? newm->size() : -1;) |
0 | 1051 int new_method_size = newm->method_size(); |
1052 // Create a shallow copy of methodOopDesc part, but be careful to preserve the new constMethodOop | |
1053 constMethodOop newcm = newm->constMethod(); | |
2226
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1054 NOT_PRODUCT(int ncmsz = newcm->is_parsable() ? newcm->size() : -1;) |
0 | 1055 int new_const_method_size = newm->constMethod()->object_size(); |
518
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1056 |
0 | 1057 memcpy(newm(), m(), sizeof(methodOopDesc)); |
1058 // Create shallow copy of constMethodOopDesc, but be careful to preserve the methodOop | |
518
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1059 // is_conc_safe is set to false because that is the value of |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1060 // is_conc_safe initialzied into newcm and the copy should |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1061 // not overwrite that value. During the window during which it is |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1062 // tagged as unsafe, some extra work could be needed during precleaning |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1063 // or concurrent marking but those phases will be correct. Setting and |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1064 // resetting is done in preference to a careful copying into newcm to |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1065 // avoid having to know the precise layout of a constMethodOop. |
2226
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1066 m->constMethod()->set_is_conc_safe(oopDesc::IsUnsafeConc); |
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1067 assert(m->constMethod()->is_parsable(), "Should remain parsable"); |
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1068 |
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1069 // NOTE: this is a reachable object that transiently signals "conc_unsafe" |
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1070 // However, no allocations are done during this window |
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1071 // during which it is tagged conc_unsafe, so we are assured that any concurrent |
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1072 // thread will not wait forever for the object to revert to "conc_safe". |
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1073 // Further, any such conc_unsafe object will indicate a stable size |
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1074 // through the transition. |
0 | 1075 memcpy(newcm, m->constMethod(), sizeof(constMethodOopDesc)); |
2226
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1076 m->constMethod()->set_is_conc_safe(oopDesc::IsSafeConc); |
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1077 assert(m->constMethod()->is_parsable(), "Should remain parsable"); |
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1078 |
0 | 1079 // Reset correct method/const method, method size, and parameter info |
1080 newcm->set_method(newm()); | |
1081 newm->set_constMethod(newcm); | |
1082 assert(newcm->method() == newm(), "check"); | |
1083 newm->constMethod()->set_code_size(new_code_length); | |
1084 newm->constMethod()->set_constMethod_size(new_const_method_size); | |
1085 newm->set_method_size(new_method_size); | |
1086 assert(newm->code_size() == new_code_length, "check"); | |
1087 assert(newm->checked_exceptions_length() == checked_exceptions_len, "check"); | |
1088 assert(newm->localvariable_table_length() == localvariable_len, "check"); | |
1089 // Copy new byte codes | |
1090 memcpy(newm->code_base(), new_code, new_code_length); | |
1091 // Copy line number table | |
1092 if (new_compressed_linenumber_size > 0) { | |
1093 memcpy(newm->compressed_linenumber_table(), | |
1094 new_compressed_linenumber_table, | |
1095 new_compressed_linenumber_size); | |
1096 } | |
1097 // Copy checked_exceptions | |
1098 if (checked_exceptions_len > 0) { | |
1099 memcpy(newm->checked_exceptions_start(), | |
1100 m->checked_exceptions_start(), | |
1101 checked_exceptions_len * sizeof(CheckedExceptionElement)); | |
1102 } | |
1103 // Copy local variable number table | |
1104 if (localvariable_len > 0) { | |
1105 memcpy(newm->localvariable_table_start(), | |
1106 m->localvariable_table_start(), | |
1107 localvariable_len * sizeof(LocalVariableTableElement)); | |
1108 } | |
518
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1109 |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1110 // Only set is_conc_safe to true when changes to newcm are |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1111 // complete. |
2226
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1112 assert(!newm->is_parsable() || nmsz < 0 || newm->size() == nmsz, "newm->size() inconsistency"); |
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1113 assert(!newcm->is_parsable() || ncmsz < 0 || newcm->size() == ncmsz, "newcm->size() inconsistency"); |
518
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
196
diff
changeset
|
1114 newcm->set_is_conc_safe(true); |
0 | 1115 return newm; |
1116 } | |
1117 | |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1118 vmSymbols::SID methodOopDesc::klass_id_for_intrinsics(klassOop holder) { |
0 | 1119 // if loader is not the default loader (i.e., != NULL), we can't know the intrinsics |
1120 // because we are not loading from core libraries | |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1121 if (instanceKlass::cast(holder)->class_loader() != NULL) |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1122 return vmSymbols::NO_SID; // regardless of name, no intrinsics here |
0 | 1123 |
1124 // see if the klass name is well-known: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1125 Symbol* klass_name = instanceKlass::cast(holder)->name(); |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1126 return vmSymbols::find_sid(klass_name); |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1127 } |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1128 |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1129 void methodOopDesc::init_intrinsic_id() { |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1130 assert(_intrinsic_id == vmIntrinsics::_none, "do this just once"); |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1131 const uintptr_t max_id_uint = right_n_bits((int)(sizeof(_intrinsic_id) * BitsPerByte)); |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1132 assert((uintptr_t)vmIntrinsics::ID_LIMIT <= max_id_uint, "else fix size"); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
1133 assert(intrinsic_id_size_in_bytes() == sizeof(_intrinsic_id), ""); |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1134 |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1135 // the klass name is well-known: |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1136 vmSymbols::SID klass_id = klass_id_for_intrinsics(method_holder()); |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1137 assert(klass_id != vmSymbols::NO_SID, "caller responsibility"); |
0 | 1138 |
1139 // ditto for method and signature: | |
1140 vmSymbols::SID name_id = vmSymbols::find_sid(name()); | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
1141 if (name_id == vmSymbols::NO_SID) return; |
0 | 1142 vmSymbols::SID sig_id = vmSymbols::find_sid(signature()); |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1143 if (klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle) |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
1144 && sig_id == vmSymbols::NO_SID) return; |
0 | 1145 jshort flags = access_flags().as_short(); |
1146 | |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1147 vmIntrinsics::ID id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags); |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1148 if (id != vmIntrinsics::_none) { |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1149 set_intrinsic_id(id); |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1150 return; |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1151 } |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1152 |
0 | 1153 // A few slightly irregular cases: |
1154 switch (klass_id) { | |
1155 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_StrictMath): | |
1156 // Second chance: check in regular Math. | |
1157 switch (name_id) { | |
1158 case vmSymbols::VM_SYMBOL_ENUM_NAME(min_name): | |
1159 case vmSymbols::VM_SYMBOL_ENUM_NAME(max_name): | |
1160 case vmSymbols::VM_SYMBOL_ENUM_NAME(sqrt_name): | |
1161 // pretend it is the corresponding method in the non-strict class: | |
1162 klass_id = vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Math); | |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1163 id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags); |
0 | 1164 break; |
1165 } | |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
1166 break; |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
1167 |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
1168 // Signature-polymorphic methods: MethodHandle.invoke*, InvokeDynamic.*. |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1169 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle): |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
1170 if (is_static() || !is_native()) break; |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
1171 switch (name_id) { |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
1172 case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name): |
2460 | 1173 if (!AllowInvokeGeneric) break; |
1174 case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name): | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
1175 id = vmIntrinsics::_invokeGeneric; |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
1176 break; |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
1177 case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name): |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
1178 id = vmIntrinsics::_invokeExact; |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
1179 break; |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
1180 } |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
1181 break; |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
1182 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_InvokeDynamic): |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
1183 if (!is_static() || !is_native()) break; |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
1184 id = vmIntrinsics::_invokeDynamic; |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
1185 break; |
0 | 1186 } |
1187 | |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1188 if (id != vmIntrinsics::_none) { |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1189 // Set up its iid. It is an alias method. |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1190 set_intrinsic_id(id); |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1191 return; |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
1192 } |
0 | 1193 } |
1194 | |
1195 // These two methods are static since a GC may move the methodOopDesc | |
1196 bool methodOopDesc::load_signature_classes(methodHandle m, TRAPS) { | |
1197 bool sig_is_loaded = true; | |
1198 Handle class_loader(THREAD, instanceKlass::cast(m->method_holder())->class_loader()); | |
1199 Handle protection_domain(THREAD, Klass::cast(m->method_holder())->protection_domain()); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1200 ResourceMark rm(THREAD); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1201 Symbol* signature = m->signature(); |
0 | 1202 for(SignatureStream ss(signature); !ss.is_done(); ss.next()) { |
1203 if (ss.is_object()) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1204 Symbol* sym = ss.as_symbol(CHECK_(false)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1205 Symbol* name = sym; |
0 | 1206 klassOop klass = SystemDictionary::resolve_or_null(name, class_loader, |
1207 protection_domain, THREAD); | |
104
541929da62d2
6624474: Server compiler generates unexpected LinkageError
rasbold
parents:
48
diff
changeset
|
1208 // We are loading classes eagerly. If a ClassNotFoundException or |
541929da62d2
6624474: Server compiler generates unexpected LinkageError
rasbold
parents:
48
diff
changeset
|
1209 // a LinkageError was generated, be sure to ignore it. |
0 | 1210 if (HAS_PENDING_EXCEPTION) { |
1142 | 1211 if (PENDING_EXCEPTION->is_a(SystemDictionary::ClassNotFoundException_klass()) || |
1212 PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) { | |
0 | 1213 CLEAR_PENDING_EXCEPTION; |
1214 } else { | |
1215 return false; | |
1216 } | |
1217 } | |
1218 if( klass == NULL) { sig_is_loaded = false; } | |
1219 } | |
1220 } | |
1221 return sig_is_loaded; | |
1222 } | |
1223 | |
1224 bool methodOopDesc::has_unloaded_classes_in_signature(methodHandle m, TRAPS) { | |
1225 Handle class_loader(THREAD, instanceKlass::cast(m->method_holder())->class_loader()); | |
1226 Handle protection_domain(THREAD, Klass::cast(m->method_holder())->protection_domain()); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1227 ResourceMark rm(THREAD); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1228 Symbol* signature = m->signature(); |
0 | 1229 for(SignatureStream ss(signature); !ss.is_done(); ss.next()) { |
1230 if (ss.type() == T_OBJECT) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1231 Symbol* name = ss.as_symbol_or_null(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1232 if (name == NULL) return true; |
0 | 1233 klassOop klass = SystemDictionary::find(name, class_loader, protection_domain, THREAD); |
1234 if (klass == NULL) return true; | |
1235 } | |
1236 } | |
1237 return false; | |
1238 } | |
1239 | |
1240 // Exposed so field engineers can debug VM | |
1241 void methodOopDesc::print_short_name(outputStream* st) { | |
1242 ResourceMark rm; | |
1243 #ifdef PRODUCT | |
1244 st->print(" %s::", method_holder()->klass_part()->external_name()); | |
1245 #else | |
1246 st->print(" %s::", method_holder()->klass_part()->internal_name()); | |
1247 #endif | |
1248 name()->print_symbol_on(st); | |
1249 if (WizardMode) signature()->print_symbol_on(st); | |
1250 } | |
1251 | |
1252 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array | |
1253 static void reorder_based_on_method_index(objArrayOop methods, | |
1254 objArrayOop annotations, | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
104
diff
changeset
|
1255 GrowableArray<oop>* temp_array) { |
0 | 1256 if (annotations == NULL) { |
1257 return; | |
1258 } | |
1259 | |
1260 int length = methods->length(); | |
1261 int i; | |
1262 // Copy to temp array | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
104
diff
changeset
|
1263 temp_array->clear(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
104
diff
changeset
|
1264 for (i = 0; i < length; i++) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
104
diff
changeset
|
1265 temp_array->append(annotations->obj_at(i)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
104
diff
changeset
|
1266 } |
0 | 1267 |
1268 // Copy back using old method indices | |
1269 for (i = 0; i < length; i++) { | |
1270 methodOop m = (methodOop) methods->obj_at(i); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
104
diff
changeset
|
1271 annotations->obj_at_put(i, temp_array->at(m->method_idnum())); |
0 | 1272 } |
1273 } | |
1274 | |
3779 | 1275 // Comparer for sorting an object array containing |
1276 // methodOops. | |
3929
f94227b6117b
7090259: Fix hotspot sources to build with old compilers
kvn
parents:
3891
diff
changeset
|
1277 // Used non-template method_comparator methods since |
f94227b6117b
7090259: Fix hotspot sources to build with old compilers
kvn
parents:
3891
diff
changeset
|
1278 // Visual Studio 2003 compiler generates incorrect |
f94227b6117b
7090259: Fix hotspot sources to build with old compilers
kvn
parents:
3891
diff
changeset
|
1279 // optimized code for it. |
f94227b6117b
7090259: Fix hotspot sources to build with old compilers
kvn
parents:
3891
diff
changeset
|
1280 static int method_comparator_narrowOop(narrowOop a, narrowOop b) { |
3779 | 1281 methodOop m = (methodOop)oopDesc::decode_heap_oop_not_null(a); |
1282 methodOop n = (methodOop)oopDesc::decode_heap_oop_not_null(b); | |
1283 return m->name()->fast_compare(n->name()); | |
1284 } | |
3929
f94227b6117b
7090259: Fix hotspot sources to build with old compilers
kvn
parents:
3891
diff
changeset
|
1285 static int method_comparator_oop(oop a, oop b) { |
f94227b6117b
7090259: Fix hotspot sources to build with old compilers
kvn
parents:
3891
diff
changeset
|
1286 methodOop m = (methodOop)a; |
f94227b6117b
7090259: Fix hotspot sources to build with old compilers
kvn
parents:
3891
diff
changeset
|
1287 methodOop n = (methodOop)b; |
f94227b6117b
7090259: Fix hotspot sources to build with old compilers
kvn
parents:
3891
diff
changeset
|
1288 return m->name()->fast_compare(n->name()); |
f94227b6117b
7090259: Fix hotspot sources to build with old compilers
kvn
parents:
3891
diff
changeset
|
1289 } |
0 | 1290 |
1291 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array | |
1292 void methodOopDesc::sort_methods(objArrayOop methods, | |
1293 objArrayOop methods_annotations, | |
1294 objArrayOop methods_parameter_annotations, | |
1295 objArrayOop methods_default_annotations, | |
1296 bool idempotent) { | |
1297 int length = methods->length(); | |
1298 if (length > 1) { | |
1299 bool do_annotations = false; | |
1300 if (methods_annotations != NULL || | |
1301 methods_parameter_annotations != NULL || | |
1302 methods_default_annotations != NULL) { | |
1303 do_annotations = true; | |
1304 } | |
1305 if (do_annotations) { | |
1306 // Remember current method ordering so we can reorder annotations | |
1307 for (int i = 0; i < length; i++) { | |
1308 methodOop m = (methodOop) methods->obj_at(i); | |
1309 m->set_method_idnum(i); | |
1310 } | |
1311 } | |
3779 | 1312 { |
1313 No_Safepoint_Verifier nsv; | |
1314 if (UseCompressedOops) { | |
3929
f94227b6117b
7090259: Fix hotspot sources to build with old compilers
kvn
parents:
3891
diff
changeset
|
1315 QuickSort::sort<narrowOop>((narrowOop*)(methods->base()), length, method_comparator_narrowOop, idempotent); |
3779 | 1316 } else { |
3929
f94227b6117b
7090259: Fix hotspot sources to build with old compilers
kvn
parents:
3891
diff
changeset
|
1317 QuickSort::sort<oop>((oop*)(methods->base()), length, method_comparator_oop, idempotent); |
0 | 1318 } |
3779 | 1319 if (UseConcMarkSweepGC) { |
1320 // For CMS we need to dirty the cards for the array | |
1321 BarrierSet* bs = Universe::heap()->barrier_set(); | |
1322 assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); | |
1323 bs->write_ref_array(methods->base(), length); | |
1324 } | |
0 | 1325 } |
1326 | |
1327 // Sort annotations if necessary | |
1328 assert(methods_annotations == NULL || methods_annotations->length() == methods->length(), ""); | |
1329 assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), ""); | |
1330 assert(methods_default_annotations == NULL || methods_default_annotations->length() == methods->length(), ""); | |
1331 if (do_annotations) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
104
diff
changeset
|
1332 ResourceMark rm; |
0 | 1333 // Allocate temporary storage |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
104
diff
changeset
|
1334 GrowableArray<oop>* temp_array = new GrowableArray<oop>(length); |
0 | 1335 reorder_based_on_method_index(methods, methods_annotations, temp_array); |
1336 reorder_based_on_method_index(methods, methods_parameter_annotations, temp_array); | |
1337 reorder_based_on_method_index(methods, methods_default_annotations, temp_array); | |
1338 } | |
1339 | |
1340 // Reset method ordering | |
1341 for (int i = 0; i < length; i++) { | |
1342 methodOop m = (methodOop) methods->obj_at(i); | |
1343 m->set_method_idnum(i); | |
1344 } | |
1345 } | |
1346 } | |
1347 | |
1348 | |
1349 //----------------------------------------------------------------------------------- | |
1350 // Non-product code | |
1351 | |
1352 #ifndef PRODUCT | |
1353 class SignatureTypePrinter : public SignatureTypeNames { | |
1354 private: | |
1355 outputStream* _st; | |
1356 bool _use_separator; | |
1357 | |
1358 void type_name(const char* name) { | |
1359 if (_use_separator) _st->print(", "); | |
1360 _st->print(name); | |
1361 _use_separator = true; | |
1362 } | |
1363 | |
1364 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1365 SignatureTypePrinter(Symbol* signature, outputStream* st) : SignatureTypeNames(signature) { |
0 | 1366 _st = st; |
1367 _use_separator = false; | |
1368 } | |
1369 | |
1370 void print_parameters() { _use_separator = false; iterate_parameters(); } | |
1371 void print_returntype() { _use_separator = false; iterate_returntype(); } | |
1372 }; | |
1373 | |
1374 | |
1375 void methodOopDesc::print_name(outputStream* st) { | |
1376 Thread *thread = Thread::current(); | |
1377 ResourceMark rm(thread); | |
1378 SignatureTypePrinter sig(signature(), st); | |
1379 st->print("%s ", is_static() ? "static" : "virtual"); | |
1380 sig.print_returntype(); | |
1381 st->print(" %s.", method_holder()->klass_part()->internal_name()); | |
1382 name()->print_symbol_on(st); | |
1383 st->print("("); | |
1384 sig.print_parameters(); | |
1385 st->print(")"); | |
1386 } | |
1387 | |
1388 | |
1389 void methodOopDesc::print_codes_on(outputStream* st) const { | |
1390 print_codes_on(0, code_size(), st); | |
1391 } | |
1392 | |
1393 void methodOopDesc::print_codes_on(int from, int to, outputStream* st) const { | |
1394 Thread *thread = Thread::current(); | |
1395 ResourceMark rm(thread); | |
1396 methodHandle mh (thread, (methodOop)this); | |
1397 BytecodeStream s(mh); | |
1398 s.set_interval(from, to); | |
1399 BytecodeTracer::set_closure(BytecodeTracer::std_closure()); | |
1400 while (s.next() >= 0) BytecodeTracer::trace(mh, s.bcp(), st); | |
1401 } | |
1402 #endif // not PRODUCT | |
1403 | |
1404 | |
1405 // Simple compression of line number tables. We use a regular compressed stream, except that we compress deltas | |
1406 // between (bci,line) pairs since they are smaller. If (bci delta, line delta) fits in (5-bit unsigned, 3-bit unsigned) | |
1407 // we save it as one byte, otherwise we write a 0xFF escape character and use regular compression. 0x0 is used | |
1408 // as end-of-stream terminator. | |
1409 | |
1410 void CompressedLineNumberWriteStream::write_pair_regular(int bci_delta, int line_delta) { | |
1411 // bci and line number does not compress into single byte. | |
1412 // Write out escape character and use regular compression for bci and line number. | |
1413 write_byte((jubyte)0xFF); | |
1414 write_signed_int(bci_delta); | |
1415 write_signed_int(line_delta); | |
1416 } | |
1417 | |
1418 // See comment in methodOop.hpp which explains why this exists. | |
2233
15d6977f04b0
7017824: Add support for creating 64-bit Visual Studio projects
sla
parents:
2177
diff
changeset
|
1419 #if defined(_M_AMD64) && _MSC_VER >= 1400 |
0 | 1420 #pragma optimize("", off) |
1421 void CompressedLineNumberWriteStream::write_pair(int bci, int line) { | |
1422 write_pair_inline(bci, line); | |
1423 } | |
1424 #pragma optimize("", on) | |
1425 #endif | |
1426 | |
1427 CompressedLineNumberReadStream::CompressedLineNumberReadStream(u_char* buffer) : CompressedReadStream(buffer) { | |
1428 _bci = 0; | |
1429 _line = 0; | |
1430 }; | |
1431 | |
1432 | |
1433 bool CompressedLineNumberReadStream::read_pair() { | |
1434 jubyte next = read_byte(); | |
1435 // Check for terminator | |
1436 if (next == 0) return false; | |
1437 if (next == 0xFF) { | |
1438 // Escape character, regular compression used | |
1439 _bci += read_signed_int(); | |
1440 _line += read_signed_int(); | |
1441 } else { | |
1442 // Single byte compression used | |
1443 _bci += next >> 3; | |
1444 _line += next & 0x7; | |
1445 } | |
1446 return true; | |
1447 } | |
1448 | |
1449 | |
2142 | 1450 Bytecodes::Code methodOopDesc::orig_bytecode_at(int bci) const { |
0 | 1451 BreakpointInfo* bp = instanceKlass::cast(method_holder())->breakpoints(); |
1452 for (; bp != NULL; bp = bp->next()) { | |
1453 if (bp->match(this, bci)) { | |
1454 return bp->orig_bytecode(); | |
1455 } | |
1456 } | |
1457 ShouldNotReachHere(); | |
1458 return Bytecodes::_shouldnotreachhere; | |
1459 } | |
1460 | |
1461 void methodOopDesc::set_orig_bytecode_at(int bci, Bytecodes::Code code) { | |
1462 assert(code != Bytecodes::_breakpoint, "cannot patch breakpoints this way"); | |
1463 BreakpointInfo* bp = instanceKlass::cast(method_holder())->breakpoints(); | |
1464 for (; bp != NULL; bp = bp->next()) { | |
1465 if (bp->match(this, bci)) { | |
1466 bp->set_orig_bytecode(code); | |
1467 // and continue, in case there is more than one | |
1468 } | |
1469 } | |
1470 } | |
1471 | |
1472 void methodOopDesc::set_breakpoint(int bci) { | |
1473 instanceKlass* ik = instanceKlass::cast(method_holder()); | |
1474 BreakpointInfo *bp = new BreakpointInfo(this, bci); | |
1475 bp->set_next(ik->breakpoints()); | |
1476 ik->set_breakpoints(bp); | |
1477 // do this last: | |
1478 bp->set(this); | |
1479 } | |
1480 | |
1481 static void clear_matches(methodOop m, int bci) { | |
1482 instanceKlass* ik = instanceKlass::cast(m->method_holder()); | |
1483 BreakpointInfo* prev_bp = NULL; | |
1484 BreakpointInfo* next_bp; | |
1485 for (BreakpointInfo* bp = ik->breakpoints(); bp != NULL; bp = next_bp) { | |
1486 next_bp = bp->next(); | |
1487 // bci value of -1 is used to delete all breakpoints in method m (ex: clear_all_breakpoint). | |
1488 if (bci >= 0 ? bp->match(m, bci) : bp->match(m)) { | |
1489 // do this first: | |
1490 bp->clear(m); | |
1491 // unhook it | |
1492 if (prev_bp != NULL) | |
1493 prev_bp->set_next(next_bp); | |
1494 else | |
1495 ik->set_breakpoints(next_bp); | |
1496 delete bp; | |
1497 // When class is redefined JVMTI sets breakpoint in all versions of EMCP methods | |
1498 // at same location. So we have multiple matching (method_index and bci) | |
1499 // BreakpointInfo nodes in BreakpointInfo list. We should just delete one | |
1500 // breakpoint for clear_breakpoint request and keep all other method versions | |
1501 // BreakpointInfo for future clear_breakpoint request. | |
1502 // bcivalue of -1 is used to clear all breakpoints (see clear_all_breakpoints) | |
1503 // which is being called when class is unloaded. We delete all the Breakpoint | |
1504 // information for all versions of method. We may not correctly restore the original | |
1505 // bytecode in all method versions, but that is ok. Because the class is being unloaded | |
1506 // so these methods won't be used anymore. | |
1507 if (bci >= 0) { | |
1508 break; | |
1509 } | |
1510 } else { | |
1511 // This one is a keeper. | |
1512 prev_bp = bp; | |
1513 } | |
1514 } | |
1515 } | |
1516 | |
1517 void methodOopDesc::clear_breakpoint(int bci) { | |
1518 assert(bci >= 0, ""); | |
1519 clear_matches(this, bci); | |
1520 } | |
1521 | |
1522 void methodOopDesc::clear_all_breakpoints() { | |
1523 clear_matches(this, -1); | |
1524 } | |
1525 | |
1526 | |
1783 | 1527 int methodOopDesc::invocation_count() { |
1528 if (TieredCompilation) { | |
1529 const methodDataOop mdo = method_data(); | |
1530 if (invocation_counter()->carry() || ((mdo != NULL) ? mdo->invocation_counter()->carry() : false)) { | |
1531 return InvocationCounter::count_limit; | |
1532 } else { | |
1533 return invocation_counter()->count() + ((mdo != NULL) ? mdo->invocation_counter()->count() : 0); | |
1534 } | |
1535 } else { | |
1536 return invocation_counter()->count(); | |
1537 } | |
1538 } | |
1539 | |
1540 int methodOopDesc::backedge_count() { | |
1541 if (TieredCompilation) { | |
1542 const methodDataOop mdo = method_data(); | |
1543 if (backedge_counter()->carry() || ((mdo != NULL) ? mdo->backedge_counter()->carry() : false)) { | |
1544 return InvocationCounter::count_limit; | |
1545 } else { | |
1546 return backedge_counter()->count() + ((mdo != NULL) ? mdo->backedge_counter()->count() : 0); | |
1547 } | |
1548 } else { | |
1549 return backedge_counter()->count(); | |
1550 } | |
1551 } | |
1552 | |
1553 int methodOopDesc::highest_comp_level() const { | |
1554 methodDataOop mdo = method_data(); | |
1555 if (mdo != NULL) { | |
1556 return mdo->highest_comp_level(); | |
1557 } else { | |
1558 return CompLevel_none; | |
1559 } | |
1560 } | |
1561 | |
1562 int methodOopDesc::highest_osr_comp_level() const { | |
1563 methodDataOop mdo = method_data(); | |
1564 if (mdo != NULL) { | |
1565 return mdo->highest_osr_comp_level(); | |
1566 } else { | |
1567 return CompLevel_none; | |
1568 } | |
1569 } | |
1570 | |
1571 void methodOopDesc::set_highest_comp_level(int level) { | |
1572 methodDataOop mdo = method_data(); | |
1573 if (mdo != NULL) { | |
1574 mdo->set_highest_comp_level(level); | |
1575 } | |
1576 } | |
1577 | |
1578 void methodOopDesc::set_highest_osr_comp_level(int level) { | |
1579 methodDataOop mdo = method_data(); | |
1580 if (mdo != NULL) { | |
1581 mdo->set_highest_osr_comp_level(level); | |
1582 } | |
1583 } | |
1584 | |
0 | 1585 BreakpointInfo::BreakpointInfo(methodOop m, int bci) { |
1586 _bci = bci; | |
1587 _name_index = m->name_index(); | |
1588 _signature_index = m->signature_index(); | |
1589 _orig_bytecode = (Bytecodes::Code) *m->bcp_from(_bci); | |
1590 if (_orig_bytecode == Bytecodes::_breakpoint) | |
1591 _orig_bytecode = m->orig_bytecode_at(_bci); | |
1592 _next = NULL; | |
1593 } | |
1594 | |
1595 void BreakpointInfo::set(methodOop method) { | |
1596 #ifdef ASSERT | |
1597 { | |
1598 Bytecodes::Code code = (Bytecodes::Code) *method->bcp_from(_bci); | |
1599 if (code == Bytecodes::_breakpoint) | |
1600 code = method->orig_bytecode_at(_bci); | |
1601 assert(orig_bytecode() == code, "original bytecode must be the same"); | |
1602 } | |
1603 #endif | |
1604 *method->bcp_from(_bci) = Bytecodes::_breakpoint; | |
1605 method->incr_number_of_breakpoints(); | |
1606 SystemDictionary::notice_modification(); | |
1607 { | |
1608 // Deoptimize all dependents on this method | |
1609 Thread *thread = Thread::current(); | |
1610 HandleMark hm(thread); | |
1611 methodHandle mh(thread, method); | |
1612 Universe::flush_dependents_on_method(mh); | |
1613 } | |
1614 } | |
1615 | |
1616 void BreakpointInfo::clear(methodOop method) { | |
1617 *method->bcp_from(_bci) = orig_bytecode(); | |
1618 assert(method->number_of_breakpoints() > 0, "must not go negative"); | |
1619 method->decr_number_of_breakpoints(); | |
1620 } |