< prev index next >

src/hotspot/share/classfile/verifier.cpp

Print this page
rev 54022 : 8220366: Optimize Symbol handling in ClassVerifier and SignatureStream
Reviewed-by: TBD


 147     klass->java_mirror()->identity_hash();
 148   }
 149 
 150   if (!is_eligible_for_verification(klass, should_verify_class)) {
 151     return true;
 152   }
 153 
 154   // Timer includes any side effects of class verification (resolution,
 155   // etc), but not recursive calls to Verifier::verify().
 156   JavaThread* jt = (JavaThread*)THREAD;
 157   PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(),
 158                            ClassLoader::perf_class_verify_selftime(),
 159                            ClassLoader::perf_classes_verified(),
 160                            jt->get_thread_stat()->perf_recursion_counts_addr(),
 161                            jt->get_thread_stat()->perf_timers_addr(),
 162                            PerfClassTraceTime::CLASS_VERIFY);
 163 
 164   // If the class should be verified, first see if we can use the split
 165   // verifier.  If not, or if verification fails and FailOverToOldVerifier
 166   // is set, then call the inference verifier.
 167 
 168   Symbol* exception_name = NULL;
 169   const size_t message_buffer_len = klass->name()->utf8_length() + 1024;
 170   char* message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len);
 171   char* exception_message = message_buffer;
 172 
 173   const char* klassName = klass->external_name();
 174   bool can_failover = FailOverToOldVerifier &&
 175      klass->major_version() < NOFAILOVER_MAJOR_VERSION;
 176 
 177   log_info(class, init)("Start class verification for: %s", klassName);
 178   if (klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) {
 179     ClassVerifier split_verifier(klass, THREAD);
 180     split_verifier.verify_class(THREAD);
 181     exception_name = split_verifier.result();
 182     if (can_failover && !HAS_PENDING_EXCEPTION &&
 183         (exception_name == vmSymbols::java_lang_VerifyError() ||
 184          exception_name == vmSymbols::java_lang_ClassFormatError())) {
 185       log_info(verification)("Fail over class verification to old verifier for: %s", klassName);
 186       log_info(class, init)("Fail over class verification to old verifier for: %s", klassName);


 187       exception_name = inference_verify(
 188         klass, message_buffer, message_buffer_len, THREAD);
 189     }
 190     if (exception_name != NULL) {
 191       exception_message = split_verifier.exception_message();
 192     }
 193   } else {


 194     exception_name = inference_verify(
 195         klass, message_buffer, message_buffer_len, THREAD);
 196   }
 197 
 198   LogTarget(Info, class, init) lt1;
 199   if (lt1.is_enabled()) {
 200     LogStream ls(lt1);
 201     log_end_verification(&ls, klassName, exception_name, THREAD);
 202   }
 203   LogTarget(Info, verification) lt2;
 204   if (lt2.is_enabled()) {
 205     LogStream ls(lt2);
 206     log_end_verification(&ls, klassName, exception_name, THREAD);
 207   }
 208 
 209   if (HAS_PENDING_EXCEPTION) {
 210     return false; // use the existing exception
 211   } else if (exception_name == NULL) {
 212     return true; // verifcation succeeded
 213   } else { // VerifyError or ClassFormatError to be created and thrown
 214     ResourceMark rm(THREAD);
 215     Klass* kls =
 216       SystemDictionary::resolve_or_fail(exception_name, true, CHECK_false);
 217     if (log_is_enabled(Debug, class, resolve)) {
 218       Verifier::trace_class_resolution(kls, klass);
 219     }
 220 
 221     while (kls != NULL) {
 222       if (kls == klass) {
 223         // If the class being verified is the exception we're creating
 224         // or one of it's superclasses, we're in trouble and are going
 225         // to infinitely recurse when we try to initialize the exception.
 226         // So bail out here by throwing the preallocated VM error.
 227         THROW_OOP_(Universe::virtual_machine_error_instance(), false);
 228       }
 229       kls = kls->super();
 230     }

 231     message_buffer[message_buffer_len - 1] = '\0'; // just to be sure


 232     THROW_MSG_(exception_name, exception_message, false);
 233   }
 234 }
 235 
 236 bool Verifier::is_eligible_for_verification(InstanceKlass* klass, bool should_verify_class) {
 237   Symbol* name = klass->name();
 238   Klass* refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass();
 239 
 240   bool is_reflect = refl_magic_klass != NULL && klass->is_subtype_of(refl_magic_klass);
 241 
 242   return (should_verify_for(klass->class_loader(), should_verify_class) &&
 243     // return if the class is a bootstrapping class
 244     // or defineClass specified not to verify by default (flags override passed arg)
 245     // We need to skip the following four for bootstraping
 246     name != vmSymbols::java_lang_Object() &&
 247     name != vmSymbols::java_lang_Class() &&
 248     name != vmSymbols::java_lang_String() &&
 249     name != vmSymbols::java_lang_Throwable() &&
 250 
 251     // Can not verify the bytecodes for shared classes because they have


 552     int current_offset = -1;
 553     address end_of_sm_table = (address)sm_table + method->stackmap_data()->length();
 554     for (u2 i = 0; i < sm_table->number_of_entries(); ++i) {
 555       ss->indent();
 556       if (!sm_frame->verify((address)sm_frame, end_of_sm_table)) {
 557         sm_frame->print_truncated(ss, current_offset);
 558         return;
 559       }
 560       sm_frame->print_on(ss, current_offset);
 561       ss->cr();
 562       current_offset += sm_frame->offset_delta();
 563       sm_frame = sm_frame->next();
 564     }
 565   }
 566 }
 567 
 568 // Methods in ClassVerifier
 569 
 570 ClassVerifier::ClassVerifier(
 571     InstanceKlass* klass, TRAPS)
 572     : _thread(THREAD), _exception_type(NULL), _message(NULL), _klass(klass) {

 573   _this_type = VerificationType::reference_type(klass->name());
 574   // Create list to hold symbols in reference area.
 575   _symbols = new GrowableArray<Symbol*>(100, 0, NULL);
 576 }
 577 
 578 ClassVerifier::~ClassVerifier() {
 579   // Decrement the reference count for any symbols created.

 580   for (int i = 0; i < _symbols->length(); i++) {
 581     Symbol* s = _symbols->at(i);
 582     s->decrement_refcount();
 583   }

 584 }
 585 
 586 VerificationType ClassVerifier::object_type() const {
 587   return VerificationType::reference_type(vmSymbols::java_lang_Object());
 588 }
 589 
 590 TypeOrigin ClassVerifier::ref_ctx(const char* sig, TRAPS) {
 591   VerificationType vt = VerificationType::reference_type(
 592       create_temporary_symbol(sig, (int)strlen(sig), THREAD));
 593   return TypeOrigin::implicit(vt);
 594 }
 595 
 596 void ClassVerifier::verify_class(TRAPS) {
 597   log_info(verification)("Verifying class %s with new format", _klass->external_name());
 598 
 599   Array<Method*>* methods = _klass->methods();
 600   int num_methods = methods->length();
 601 
 602   for (int index = 0; index < num_methods; index++) {
 603     // Check for recursive re-verification before each method.


3085   if (return_type == VerificationType::bogus_type()) {
3086     verify_error(ErrorContext::bad_type(bci,
3087         current_frame->stack_top_ctx(), TypeOrigin::signature(return_type)),
3088         "Method expects a return value");
3089     return;
3090   }
3091   bool match = return_type.is_assignable_from(type, this, false, CHECK_VERIFY(this));
3092   if (!match) {
3093     verify_error(ErrorContext::bad_type(bci,
3094         current_frame->stack_top_ctx(), TypeOrigin::signature(return_type)),
3095         "Bad return type");
3096     return;
3097   }
3098 }
3099 
3100 // The verifier creates symbols which are substrings of Symbols.
3101 // These are stored in the verifier until the end of verification so that
3102 // they can be reference counted.
3103 Symbol* ClassVerifier::create_temporary_symbol(const Symbol *s, int begin,
3104                                                int end, TRAPS) {
3105   Symbol* sym = SymbolTable::new_symbol(s, begin, end, CHECK_NULL);











3106   _symbols->push(sym);


3107   return sym;
3108 }
3109 
3110 Symbol* ClassVerifier::create_temporary_symbol(const char *s, int length, TRAPS) {
3111   Symbol* sym = SymbolTable::new_symbol(s, length, CHECK_NULL);








3112   _symbols->push(sym);


3113   return sym;
3114 }


 147     klass->java_mirror()->identity_hash();
 148   }
 149 
 150   if (!is_eligible_for_verification(klass, should_verify_class)) {
 151     return true;
 152   }
 153 
 154   // Timer includes any side effects of class verification (resolution,
 155   // etc), but not recursive calls to Verifier::verify().
 156   JavaThread* jt = (JavaThread*)THREAD;
 157   PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(),
 158                            ClassLoader::perf_class_verify_selftime(),
 159                            ClassLoader::perf_classes_verified(),
 160                            jt->get_thread_stat()->perf_recursion_counts_addr(),
 161                            jt->get_thread_stat()->perf_timers_addr(),
 162                            PerfClassTraceTime::CLASS_VERIFY);
 163 
 164   // If the class should be verified, first see if we can use the split
 165   // verifier.  If not, or if verification fails and FailOverToOldVerifier
 166   // is set, then call the inference verifier.

 167   Symbol* exception_name = NULL;
 168   const size_t message_buffer_len = klass->name()->utf8_length() + 1024;
 169   char* message_buffer = NULL;
 170   char* exception_message = NULL;
 171 

 172   bool can_failover = FailOverToOldVerifier &&
 173      klass->major_version() < NOFAILOVER_MAJOR_VERSION;
 174 
 175   log_info(class, init)("Start class verification for: %s", klass->external_name());
 176   if (klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) {
 177     ClassVerifier split_verifier(klass, THREAD);
 178     split_verifier.verify_class(THREAD);
 179     exception_name = split_verifier.result();
 180     if (can_failover && !HAS_PENDING_EXCEPTION &&
 181         (exception_name == vmSymbols::java_lang_VerifyError() ||
 182          exception_name == vmSymbols::java_lang_ClassFormatError())) {
 183       log_info(verification)("Fail over class verification to old verifier for: %s", klass->external_name());
 184       log_info(class, init)("Fail over class verification to old verifier for: %s", klass->external_name());
 185       message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len);
 186       exception_message = message_buffer;
 187       exception_name = inference_verify(
 188         klass, message_buffer, message_buffer_len, THREAD);
 189     }
 190     if (exception_name != NULL) {
 191       exception_message = split_verifier.exception_message();
 192     }
 193   } else {
 194     message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len);
 195     exception_message = message_buffer;
 196     exception_name = inference_verify(
 197         klass, message_buffer, message_buffer_len, THREAD);
 198   }
 199 
 200   LogTarget(Info, class, init) lt1;
 201   if (lt1.is_enabled()) {
 202     LogStream ls(lt1);
 203     log_end_verification(&ls, klass->external_name(), exception_name, THREAD);
 204   }
 205   LogTarget(Info, verification) lt2;
 206   if (lt2.is_enabled()) {
 207     LogStream ls(lt2);
 208     log_end_verification(&ls, klass->external_name(), exception_name, THREAD);
 209   }
 210 
 211   if (HAS_PENDING_EXCEPTION) {
 212     return false; // use the existing exception
 213   } else if (exception_name == NULL) {
 214     return true; // verification succeeded
 215   } else { // VerifyError or ClassFormatError to be created and thrown

 216     Klass* kls =
 217       SystemDictionary::resolve_or_fail(exception_name, true, CHECK_false);
 218     if (log_is_enabled(Debug, class, resolve)) {
 219       Verifier::trace_class_resolution(kls, klass);
 220     }
 221 
 222     while (kls != NULL) {
 223       if (kls == klass) {
 224         // If the class being verified is the exception we're creating
 225         // or one of it's superclasses, we're in trouble and are going
 226         // to infinitely recurse when we try to initialize the exception.
 227         // So bail out here by throwing the preallocated VM error.
 228         THROW_OOP_(Universe::virtual_machine_error_instance(), false);
 229       }
 230       kls = kls->super();
 231     }
 232     if (message_buffer != NULL) {
 233       message_buffer[message_buffer_len - 1] = '\0'; // just to be sure
 234     }
 235     assert(exception_message != NULL, "");
 236     THROW_MSG_(exception_name, exception_message, false);
 237   }
 238 }
 239 
 240 bool Verifier::is_eligible_for_verification(InstanceKlass* klass, bool should_verify_class) {
 241   Symbol* name = klass->name();
 242   Klass* refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass();
 243 
 244   bool is_reflect = refl_magic_klass != NULL && klass->is_subtype_of(refl_magic_klass);
 245 
 246   return (should_verify_for(klass->class_loader(), should_verify_class) &&
 247     // return if the class is a bootstrapping class
 248     // or defineClass specified not to verify by default (flags override passed arg)
 249     // We need to skip the following four for bootstraping
 250     name != vmSymbols::java_lang_Object() &&
 251     name != vmSymbols::java_lang_Class() &&
 252     name != vmSymbols::java_lang_String() &&
 253     name != vmSymbols::java_lang_Throwable() &&
 254 
 255     // Can not verify the bytecodes for shared classes because they have


 556     int current_offset = -1;
 557     address end_of_sm_table = (address)sm_table + method->stackmap_data()->length();
 558     for (u2 i = 0; i < sm_table->number_of_entries(); ++i) {
 559       ss->indent();
 560       if (!sm_frame->verify((address)sm_frame, end_of_sm_table)) {
 561         sm_frame->print_truncated(ss, current_offset);
 562         return;
 563       }
 564       sm_frame->print_on(ss, current_offset);
 565       ss->cr();
 566       current_offset += sm_frame->offset_delta();
 567       sm_frame = sm_frame->next();
 568     }
 569   }
 570 }
 571 
 572 // Methods in ClassVerifier
 573 
 574 ClassVerifier::ClassVerifier(
 575     InstanceKlass* klass, TRAPS)
 576     : _thread(THREAD), _previous_symbol(NULL), _symbols(NULL), _exception_type(NULL),
 577       _message(NULL), _klass(klass) {
 578   _this_type = VerificationType::reference_type(klass->name());


 579 }
 580 
 581 ClassVerifier::~ClassVerifier() {
 582   // Decrement the reference count for any symbols created.
 583   if (_symbols != NULL) {
 584     for (int i = 0; i < _symbols->length(); i++) {
 585       Symbol* s = _symbols->at(i);
 586       s->decrement_refcount();
 587     }
 588   }
 589 }
 590 
 591 VerificationType ClassVerifier::object_type() const {
 592   return VerificationType::reference_type(vmSymbols::java_lang_Object());
 593 }
 594 
 595 TypeOrigin ClassVerifier::ref_ctx(const char* sig, TRAPS) {
 596   VerificationType vt = VerificationType::reference_type(
 597       create_temporary_symbol(sig, (int)strlen(sig), THREAD));
 598   return TypeOrigin::implicit(vt);
 599 }
 600 
 601 void ClassVerifier::verify_class(TRAPS) {
 602   log_info(verification)("Verifying class %s with new format", _klass->external_name());
 603 
 604   Array<Method*>* methods = _klass->methods();
 605   int num_methods = methods->length();
 606 
 607   for (int index = 0; index < num_methods; index++) {
 608     // Check for recursive re-verification before each method.


3090   if (return_type == VerificationType::bogus_type()) {
3091     verify_error(ErrorContext::bad_type(bci,
3092         current_frame->stack_top_ctx(), TypeOrigin::signature(return_type)),
3093         "Method expects a return value");
3094     return;
3095   }
3096   bool match = return_type.is_assignable_from(type, this, false, CHECK_VERIFY(this));
3097   if (!match) {
3098     verify_error(ErrorContext::bad_type(bci,
3099         current_frame->stack_top_ctx(), TypeOrigin::signature(return_type)),
3100         "Bad return type");
3101     return;
3102   }
3103 }
3104 
3105 // The verifier creates symbols which are substrings of Symbols.
3106 // These are stored in the verifier until the end of verification so that
3107 // they can be reference counted.
3108 Symbol* ClassVerifier::create_temporary_symbol(const Symbol *s, int begin,
3109                                                int end, TRAPS) {
3110   const char* name = (const char*)s->base() + begin;
3111   int length = end - begin;
3112 
3113   // Quick deduplication check
3114   if (_previous_symbol != NULL && _previous_symbol->equals(name, length)) {
3115     return _previous_symbol;
3116   }
3117   Symbol* sym = SymbolTable::new_symbol(name, length, CHECK_NULL);
3118   if (!sym->is_permanent()) {
3119     if (_symbols == NULL) {
3120       _symbols = new GrowableArray<Symbol*>(50, 0, NULL);
3121     }
3122     _symbols->push(sym);
3123   }
3124   _previous_symbol = sym;
3125   return sym;
3126 }
3127 
3128 Symbol* ClassVerifier::create_temporary_symbol(const char *name, int length, TRAPS) {
3129   // Quick deduplication check
3130   if (_previous_symbol != NULL && _previous_symbol->equals(name, length)) {
3131     return _previous_symbol;
3132   }
3133   Symbol* sym = SymbolTable::new_symbol(name, length, CHECK_NULL);
3134   if (!sym->is_permanent()) {
3135     if (_symbols == NULL) {
3136       _symbols = new GrowableArray<Symbol*>(50, 0, NULL);
3137     }
3138     _symbols->push(sym);
3139   }
3140   _previous_symbol = sym;
3141   return sym;
3142 }
< prev index next >