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