221 } |
221 } |
222 } // unlocking constantPool |
222 } // unlocking constantPool |
223 |
223 |
224 |
224 |
225 // The original attempt to resolve this constant pool entry failed so find the |
225 // The original attempt to resolve this constant pool entry failed so find the |
226 // original error and throw it again (JVMS 5.4.3). |
226 // class of the original error and throw another error of the same class (JVMS 5.4.3). |
|
227 // If there is a detail message, pass that detail message to the error constructor. |
|
228 // The JVMS does not strictly require us to duplicate the same detail message, |
|
229 // or any internal exception fields such as cause or stacktrace. But since the |
|
230 // detail message is often a class name or other literal string, we will repeat it if |
|
231 // we can find it in the symbol table. |
227 if (in_error) { |
232 if (in_error) { |
228 Symbol* error = SystemDictionary::find_resolution_error(this_cp, which); |
233 throw_resolution_error(this_cp, which, CHECK_0); |
229 guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table"); |
|
230 ResourceMark rm; |
|
231 // exception text will be the class name |
|
232 const char* className = this_cp->unresolved_klass_at(which)->as_C_string(); |
|
233 THROW_MSG_0(error, className); |
|
234 } |
234 } |
235 |
235 |
236 if (do_resolve) { |
236 if (do_resolve) { |
237 // this_cp must be unlocked during resolve_or_fail |
237 // this_cp must be unlocked during resolve_or_fail |
238 oop protection_domain = this_cp->pool_holder()->protection_domain(); |
238 oop protection_domain = this_cp->pool_holder()->protection_domain(); |
248 } |
248 } |
249 |
249 |
250 // Failed to resolve class. We must record the errors so that subsequent attempts |
250 // Failed to resolve class. We must record the errors so that subsequent attempts |
251 // to resolve this constant pool entry fail with the same error (JVMS 5.4.3). |
251 // to resolve this constant pool entry fail with the same error (JVMS 5.4.3). |
252 if (HAS_PENDING_EXCEPTION) { |
252 if (HAS_PENDING_EXCEPTION) { |
253 ResourceMark rm; |
|
254 Symbol* error = PENDING_EXCEPTION->klass()->name(); |
|
255 |
|
256 bool throw_orig_error = false; |
|
257 { |
|
258 MonitorLockerEx ml(this_cp->lock()); |
253 MonitorLockerEx ml(this_cp->lock()); |
259 |
254 |
260 // some other thread has beaten us and has resolved the class. |
255 // some other thread has beaten us and has resolved the class. |
261 if (this_cp->tag_at(which).is_klass()) { |
256 if (this_cp->tag_at(which).is_klass()) { |
262 CLEAR_PENDING_EXCEPTION; |
257 CLEAR_PENDING_EXCEPTION; |
263 entry = this_cp->resolved_klass_at(which); |
258 entry = this_cp->resolved_klass_at(which); |
264 return entry.get_klass(); |
259 return entry.get_klass(); |
265 } |
260 } |
266 |
261 |
267 if (!PENDING_EXCEPTION-> |
262 // The tag could have changed to in-error before the lock but we have to |
268 is_a(SystemDictionary::LinkageError_klass())) { |
263 // handle that here for the class case. |
269 // Just throw the exception and don't prevent these classes from |
264 save_and_throw_exception(this_cp, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_0); |
270 // being loaded due to virtual machine errors like StackOverflow |
|
271 // and OutOfMemoryError, etc, or if the thread was hit by stop() |
|
272 // Needs clarification to section 5.4.3 of the VM spec (see 6308271) |
|
273 } |
|
274 else if (!this_cp->tag_at(which).is_unresolved_klass_in_error()) { |
|
275 SystemDictionary::add_resolution_error(this_cp, which, error); |
|
276 this_cp->tag_at_put(which, JVM_CONSTANT_UnresolvedClassInError); |
|
277 } else { |
|
278 // some other thread has put the class in error state. |
|
279 error = SystemDictionary::find_resolution_error(this_cp, which); |
|
280 assert(error != NULL, "checking"); |
|
281 throw_orig_error = true; |
|
282 } |
|
283 } // unlocked |
|
284 |
|
285 if (throw_orig_error) { |
|
286 CLEAR_PENDING_EXCEPTION; |
|
287 ResourceMark rm; |
|
288 const char* className = this_cp->unresolved_klass_at(which)->as_C_string(); |
|
289 THROW_MSG_0(error, className); |
|
290 } |
|
291 |
|
292 return 0; |
|
293 } |
265 } |
294 |
266 |
295 if (TraceClassResolution && !k()->oop_is_array()) { |
267 if (TraceClassResolution && !k()->oop_is_array()) { |
296 // skip resolving the constant pool so that this code get's |
268 // skip resolving the constant pool so that this code get's |
297 // called the next time some bytecodes refer to this class. |
269 // called the next time some bytecodes refer to this class. |
585 } |
557 } |
586 // set_preresolution(); or some bit for future use |
558 // set_preresolution(); or some bit for future use |
587 return true; |
559 return true; |
588 } |
560 } |
589 |
561 |
590 // If resolution for MethodHandle or MethodType fails, save the exception |
562 Symbol* ConstantPool::exception_message(constantPoolHandle this_cp, int which, constantTag tag, oop pending_exception) { |
|
563 // Dig out the detailed message to reuse if possible |
|
564 Symbol* message = NULL; |
|
565 oop detailed_message = java_lang_Throwable::message(pending_exception); |
|
566 if (detailed_message != NULL) { |
|
567 message = java_lang_String::as_symbol_or_null(detailed_message); |
|
568 if (message != NULL) { |
|
569 return message; |
|
570 } |
|
571 } |
|
572 |
|
573 // Return specific message for the tag |
|
574 switch (tag.value()) { |
|
575 case JVM_CONSTANT_UnresolvedClass: |
|
576 // return the class name in the error message |
|
577 message = this_cp->unresolved_klass_at(which); |
|
578 break; |
|
579 case JVM_CONSTANT_MethodHandle: |
|
580 // return the method handle name in the error message |
|
581 message = this_cp->method_handle_name_ref_at(which); |
|
582 break; |
|
583 case JVM_CONSTANT_MethodType: |
|
584 // return the method type signature in the error message |
|
585 message = this_cp->method_type_signature_at(which); |
|
586 break; |
|
587 default: |
|
588 ShouldNotReachHere(); |
|
589 } |
|
590 |
|
591 return message; |
|
592 } |
|
593 |
|
594 void ConstantPool::throw_resolution_error(constantPoolHandle this_cp, int which, TRAPS) { |
|
595 Symbol* message = NULL; |
|
596 Symbol* error = SystemDictionary::find_resolution_error(this_cp, which, &message); |
|
597 assert(error != NULL && message != NULL, "checking"); |
|
598 CLEAR_PENDING_EXCEPTION; |
|
599 ResourceMark rm; |
|
600 THROW_MSG(error, message->as_C_string()); |
|
601 } |
|
602 |
|
603 // If resolution for Class, MethodHandle or MethodType fails, save the exception |
591 // in the resolution error table, so that the same exception is thrown again. |
604 // in the resolution error table, so that the same exception is thrown again. |
592 void ConstantPool::save_and_throw_exception(constantPoolHandle this_cp, int which, |
605 void ConstantPool::save_and_throw_exception(constantPoolHandle this_cp, int which, |
593 int tag, TRAPS) { |
606 constantTag tag, TRAPS) { |
594 ResourceMark rm; |
607 assert(this_cp->lock()->is_locked(), "constant pool lock should be held"); |
595 Symbol* error = PENDING_EXCEPTION->klass()->name(); |
608 Symbol* error = PENDING_EXCEPTION->klass()->name(); |
596 MonitorLockerEx ml(this_cp->lock()); // lock cpool to change tag. |
609 |
597 |
610 int error_tag = tag.error_value(); |
598 int error_tag = (tag == JVM_CONSTANT_MethodHandle) ? |
|
599 JVM_CONSTANT_MethodHandleInError : JVM_CONSTANT_MethodTypeInError; |
|
600 |
611 |
601 if (!PENDING_EXCEPTION-> |
612 if (!PENDING_EXCEPTION-> |
602 is_a(SystemDictionary::LinkageError_klass())) { |
613 is_a(SystemDictionary::LinkageError_klass())) { |
603 // Just throw the exception and don't prevent these classes from |
614 // Just throw the exception and don't prevent these classes from |
604 // being loaded due to virtual machine errors like StackOverflow |
615 // being loaded due to virtual machine errors like StackOverflow |
605 // and OutOfMemoryError, etc, or if the thread was hit by stop() |
616 // and OutOfMemoryError, etc, or if the thread was hit by stop() |
606 // Needs clarification to section 5.4.3 of the VM spec (see 6308271) |
617 // Needs clarification to section 5.4.3 of the VM spec (see 6308271) |
607 |
|
608 } else if (this_cp->tag_at(which).value() != error_tag) { |
618 } else if (this_cp->tag_at(which).value() != error_tag) { |
609 SystemDictionary::add_resolution_error(this_cp, which, error); |
619 Symbol* message = exception_message(this_cp, which, tag, PENDING_EXCEPTION); |
|
620 SystemDictionary::add_resolution_error(this_cp, which, error, message); |
610 this_cp->tag_at_put(which, error_tag); |
621 this_cp->tag_at_put(which, error_tag); |
611 } else { |
622 } else { |
612 // some other thread has put the class in error state. |
623 // some other thread put this in error state |
613 error = SystemDictionary::find_resolution_error(this_cp, which); |
624 throw_resolution_error(this_cp, which, CHECK); |
614 assert(error != NULL, "checking"); |
625 } |
615 CLEAR_PENDING_EXCEPTION; |
626 |
616 THROW_MSG(error, ""); |
627 // This exits with some pending exception |
617 } |
628 assert(HAS_PENDING_EXCEPTION, "should not be cleared"); |
618 } |
629 } |
|
630 |
619 |
631 |
620 |
632 |
621 // Called to resolve constants in the constant pool and return an oop. |
633 // Called to resolve constants in the constant pool and return an oop. |
622 // Some constant pool entries cache their resolved oop. This is also |
634 // Some constant pool entries cache their resolved oop. This is also |
623 // called to create oops from constants to use in arguments for invokedynamic |
635 // called to create oops from constants to use in arguments for invokedynamic |
713 signature->as_C_string()); |
723 signature->as_C_string()); |
714 KlassHandle klass(THREAD, this_cp->pool_holder()); |
724 KlassHandle klass(THREAD, this_cp->pool_holder()); |
715 Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD); |
725 Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD); |
716 result_oop = value(); |
726 result_oop = value(); |
717 if (HAS_PENDING_EXCEPTION) { |
727 if (HAS_PENDING_EXCEPTION) { |
718 save_and_throw_exception(this_cp, index, tag_value, CHECK_NULL); |
728 MonitorLockerEx ml(this_cp->lock()); // lock cpool to change tag. |
|
729 save_and_throw_exception(this_cp, index, tag, CHECK_NULL); |
719 } |
730 } |
720 break; |
731 break; |
721 } |
732 } |
722 |
733 |
723 case JVM_CONSTANT_Integer: |
734 case JVM_CONSTANT_Integer: |