src/share/vm/oops/constantPool.cpp

changeset 9966
baf9f57c9b46
parent 9550
270570f695e0
child 9970
f614bd5c9561
equal deleted inserted replaced
9965:c39172598323 9966:baf9f57c9b46
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
653 index = this_oop->object_to_cp_index(cache_index); 665 index = this_oop->object_to_cp_index(cache_index);
654 } 666 }
655 667
656 jvalue prim_value; // temp used only in a few cases below 668 jvalue prim_value; // temp used only in a few cases below
657 669
658 int tag_value = this_oop->tag_at(index).value(); 670 constantTag tag = this_oop->tag_at(index);
659 671
660 switch (tag_value) { 672 switch (tag.value()) {
661 673
662 case JVM_CONSTANT_UnresolvedClass: 674 case JVM_CONSTANT_UnresolvedClass:
663 case JVM_CONSTANT_UnresolvedClassInError: 675 case JVM_CONSTANT_UnresolvedClassInError:
664 case JVM_CONSTANT_Class: 676 case JVM_CONSTANT_Class:
665 { 677 {
680 break; 692 break;
681 693
682 case JVM_CONSTANT_MethodHandleInError: 694 case JVM_CONSTANT_MethodHandleInError:
683 case JVM_CONSTANT_MethodTypeInError: 695 case JVM_CONSTANT_MethodTypeInError:
684 { 696 {
685 Symbol* error = SystemDictionary::find_resolution_error(this_oop, index); 697 throw_resolution_error(this_oop, index, CHECK_NULL);
686 guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table");
687 ResourceMark rm;
688 THROW_MSG_0(error, "");
689 break; 698 break;
690 } 699 }
691 700
692 case JVM_CONSTANT_MethodHandle: 701 case JVM_CONSTANT_MethodHandle:
693 { 702 {
707 Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind, 716 Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind,
708 callee, name, signature, 717 callee, name, signature,
709 THREAD); 718 THREAD);
710 result_oop = value(); 719 result_oop = value();
711 if (HAS_PENDING_EXCEPTION) { 720 if (HAS_PENDING_EXCEPTION) {
712 save_and_throw_exception(this_oop, index, tag_value, CHECK_NULL); 721 MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag.
722 save_and_throw_exception(this_oop, index, tag, CHECK_NULL);
713 } 723 }
714 break; 724 break;
715 } 725 }
716 726
717 case JVM_CONSTANT_MethodType: 727 case JVM_CONSTANT_MethodType:
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:
754 result_oop = java_lang_boxing_object::create(T_DOUBLE, &prim_value, CHECK_NULL); 765 result_oop = java_lang_boxing_object::create(T_DOUBLE, &prim_value, CHECK_NULL);
755 break; 766 break;
756 767
757 default: 768 default:
758 DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d", 769 DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d",
759 this_oop(), index, cache_index, tag_value) ); 770 this_oop(), index, cache_index, tag.value()));
760 assert(false, "unexpected constant tag"); 771 assert(false, "unexpected constant tag");
761 break; 772 break;
762 } 773 }
763 774
764 if (cache_index >= 0) { 775 if (cache_index >= 0) {

mercurial