src/share/vm/oops/method.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8161987 Sdiff src/share/vm/oops

src/share/vm/oops/method.cpp

Print this page
rev 8156 : 8157181: Compilers accept modification of final fields outside initializer methods
Summary: Track initialized final field updates; disable constant folding if an update is detected.
Reviewed-by: vlivanov, dnsimon, forax, never, kvn, coleenp


 573   if (code_size() != 5) return false;
 574   if (size_of_parameters() != 1) return false;
 575   if (java_code_at(0) != Bytecodes::_aload_0 ) return false;
 576   if (java_code_at(1) != Bytecodes::_getfield) return false;
 577   if (java_code_at(4) != Bytecodes::_areturn &&
 578       java_code_at(4) != Bytecodes::_ireturn ) return false;
 579   return true;
 580 }
 581 
 582 bool Method::is_constant_getter() const {
 583   int last_index = code_size() - 1;
 584   // Check if the first 1-3 bytecodes are a constant push
 585   // and the last bytecode is a return.
 586   return (2 <= code_size() && code_size() <= 4 &&
 587           Bytecodes::is_const(java_code_at(0)) &&
 588           Bytecodes::length_for(java_code_at(0)) == last_index &&
 589           Bytecodes::is_return(java_code_at(last_index)));
 590 }
 591 
 592 bool Method::is_initializer() const {
 593   return name() == vmSymbols::object_initializer_name() || is_static_initializer();
 594 }
 595 
 596 bool Method::has_valid_initializer_flags() const {
 597   return (is_static() ||
 598           method_holder()->major_version() < 51);
 599 }
 600 
 601 bool Method::is_static_initializer() const {
 602   // For classfiles version 51 or greater, ensure that the clinit method is
 603   // static.  Non-static methods with the name "<clinit>" are not static
 604   // initializers. (older classfiles exempted for backward compatibility)
 605   return name() == vmSymbols::class_initializer_name() &&
 606          has_valid_initializer_flags();
 607 }
 608 



 609 
 610 objArrayHandle Method::resolved_checked_exceptions_impl(Method* this_oop, TRAPS) {
 611   int length = this_oop->checked_exceptions_length();
 612   if (length == 0) {  // common case
 613     return objArrayHandle(THREAD, Universe::the_empty_class_klass_array());
 614   } else {
 615     methodHandle h_this(THREAD, this_oop);
 616     objArrayOop m_oop = oopFactory::new_objArray(SystemDictionary::Class_klass(), length, CHECK_(objArrayHandle()));
 617     objArrayHandle mirrors (THREAD, m_oop);
 618     for (int i = 0; i < length; i++) {
 619       CheckedExceptionElement* table = h_this->checked_exceptions_start(); // recompute on each iteration, not gc safe
 620       Klass* k = h_this->constants()->klass_at(table[i].class_cp_index, CHECK_(objArrayHandle()));
 621       assert(k->is_subclass_of(SystemDictionary::Throwable_klass()), "invalid exception class");
 622       mirrors->obj_at_put(i, k->java_mirror());
 623     }
 624     return mirrors;
 625   }
 626 };
 627 
 628 




 573   if (code_size() != 5) return false;
 574   if (size_of_parameters() != 1) return false;
 575   if (java_code_at(0) != Bytecodes::_aload_0 ) return false;
 576   if (java_code_at(1) != Bytecodes::_getfield) return false;
 577   if (java_code_at(4) != Bytecodes::_areturn &&
 578       java_code_at(4) != Bytecodes::_ireturn ) return false;
 579   return true;
 580 }
 581 
 582 bool Method::is_constant_getter() const {
 583   int last_index = code_size() - 1;
 584   // Check if the first 1-3 bytecodes are a constant push
 585   // and the last bytecode is a return.
 586   return (2 <= code_size() && code_size() <= 4 &&
 587           Bytecodes::is_const(java_code_at(0)) &&
 588           Bytecodes::length_for(java_code_at(0)) == last_index &&
 589           Bytecodes::is_return(java_code_at(last_index)));
 590 }
 591 
 592 bool Method::is_initializer() const {
 593   return is_object_initializer() || is_static_initializer();
 594 }
 595 
 596 bool Method::has_valid_initializer_flags() const {
 597   return (is_static() ||
 598           method_holder()->major_version() < 51);
 599 }
 600 
 601 bool Method::is_static_initializer() const {
 602   // For classfiles version 51 or greater, ensure that the clinit method is
 603   // static.  Non-static methods with the name "<clinit>" are not static
 604   // initializers. (older classfiles exempted for backward compatibility)
 605   return name() == vmSymbols::class_initializer_name() &&
 606          has_valid_initializer_flags();
 607 }
 608 
 609 bool Method::is_object_initializer() const {
 610    return name() == vmSymbols::object_initializer_name();
 611 }
 612 
 613 objArrayHandle Method::resolved_checked_exceptions_impl(Method* this_oop, TRAPS) {
 614   int length = this_oop->checked_exceptions_length();
 615   if (length == 0) {  // common case
 616     return objArrayHandle(THREAD, Universe::the_empty_class_klass_array());
 617   } else {
 618     methodHandle h_this(THREAD, this_oop);
 619     objArrayOop m_oop = oopFactory::new_objArray(SystemDictionary::Class_klass(), length, CHECK_(objArrayHandle()));
 620     objArrayHandle mirrors (THREAD, m_oop);
 621     for (int i = 0; i < length; i++) {
 622       CheckedExceptionElement* table = h_this->checked_exceptions_start(); // recompute on each iteration, not gc safe
 623       Klass* k = h_this->constants()->klass_at(table[i].class_cp_index, CHECK_(objArrayHandle()));
 624       assert(k->is_subclass_of(SystemDictionary::Throwable_klass()), "invalid exception class");
 625       mirrors->obj_at_put(i, k->java_mirror());
 626     }
 627     return mirrors;
 628   }
 629 };
 630 
 631 


src/share/vm/oops/method.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File