hotspot/src/share/vm/oops/constantPool.cpp
changeset 24334 36096f7271f4
parent 23872 536c66fc43d3
child 24426 0a69c8cdfca9
child 24337 ddce5dcb6be1
equal deleted inserted replaced
24333:c7214442139d 24334:36096f7271f4
   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
   643     index = this_cp->object_to_cp_index(cache_index);
   655     index = this_cp->object_to_cp_index(cache_index);
   644   }
   656   }
   645 
   657 
   646   jvalue prim_value;  // temp used only in a few cases below
   658   jvalue prim_value;  // temp used only in a few cases below
   647 
   659 
   648   int tag_value = this_cp->tag_at(index).value();
   660   constantTag tag = this_cp->tag_at(index);
   649 
   661 
   650   switch (tag_value) {
   662   switch (tag.value()) {
   651 
   663 
   652   case JVM_CONSTANT_UnresolvedClass:
   664   case JVM_CONSTANT_UnresolvedClass:
   653   case JVM_CONSTANT_UnresolvedClassInError:
   665   case JVM_CONSTANT_UnresolvedClassInError:
   654   case JVM_CONSTANT_Class:
   666   case JVM_CONSTANT_Class:
   655     {
   667     {
   670     break;
   682     break;
   671 
   683 
   672   case JVM_CONSTANT_MethodHandleInError:
   684   case JVM_CONSTANT_MethodHandleInError:
   673   case JVM_CONSTANT_MethodTypeInError:
   685   case JVM_CONSTANT_MethodTypeInError:
   674     {
   686     {
   675       Symbol* error = SystemDictionary::find_resolution_error(this_cp, index);
   687       throw_resolution_error(this_cp, index, CHECK_NULL);
   676       guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table");
       
   677       ResourceMark rm;
       
   678       THROW_MSG_0(error, "");
       
   679       break;
   688       break;
   680     }
   689     }
   681 
   690 
   682   case JVM_CONSTANT_MethodHandle:
   691   case JVM_CONSTANT_MethodHandle:
   683     {
   692     {
   697       Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind,
   706       Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind,
   698                                                                    callee, name, signature,
   707                                                                    callee, name, signature,
   699                                                                    THREAD);
   708                                                                    THREAD);
   700       result_oop = value();
   709       result_oop = value();
   701       if (HAS_PENDING_EXCEPTION) {
   710       if (HAS_PENDING_EXCEPTION) {
   702         save_and_throw_exception(this_cp, index, tag_value, CHECK_NULL);
   711         MonitorLockerEx ml(this_cp->lock());  // lock cpool to change tag.
       
   712         save_and_throw_exception(this_cp, index, tag, CHECK_NULL);
   703       }
   713       }
   704       break;
   714       break;
   705     }
   715     }
   706 
   716 
   707   case JVM_CONSTANT_MethodType:
   717   case JVM_CONSTANT_MethodType:
   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:
   744     result_oop = java_lang_boxing_object::create(T_DOUBLE, &prim_value, CHECK_NULL);
   755     result_oop = java_lang_boxing_object::create(T_DOUBLE, &prim_value, CHECK_NULL);
   745     break;
   756     break;
   746 
   757 
   747   default:
   758   default:
   748     DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d",
   759     DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d",
   749                               this_cp(), index, cache_index, tag_value) );
   760                               this_cp(), index, cache_index, tag.value()));
   750     assert(false, "unexpected constant tag");
   761     assert(false, "unexpected constant tag");
   751     break;
   762     break;
   752   }
   763   }
   753 
   764 
   754   if (cache_index >= 0) {
   765   if (cache_index >= 0) {