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