< prev index next >

src/share/vm/oops/methodOop.cpp

Print this page
rev 4134 : 7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
Summary: Change constMethodOop::_exception_table to optionally inlined u2 table.
Reviewed-by: bdelsart, coleenp, kamg
rev 4135 : 7181632: nsk classLoad001_14 failure and CompileTheWorld crash after 7178145.
Summary: Need to copy the inlined exception table to the new constMethodOop during method rewriting.
Reviewed-by: coleenp, dholmes


  94 
  95 char* methodOopDesc::name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature, char* buf, int size) {
  96   Symbol* klass_name = klass->name();
  97   klass_name->as_klass_external_name(buf, size);
  98   int len = (int)strlen(buf);
  99 
 100   if (len < size - 1) {
 101     buf[len++] = '.';
 102 
 103     method_name->as_C_string(&(buf[len]), size - len);
 104     len = (int)strlen(buf);
 105 
 106     signature->as_C_string(&(buf[len]), size - len);
 107   }
 108 
 109   return buf;
 110 }
 111 
 112 int  methodOopDesc::fast_exception_handler_bci_for(KlassHandle ex_klass, int throw_bci, TRAPS) {
 113   // exception table holds quadruple entries of the form (beg_bci, end_bci, handler_bci, klass_index)
 114   const int beg_bci_offset     = 0;
 115   const int end_bci_offset     = 1;
 116   const int handler_bci_offset = 2;
 117   const int klass_index_offset = 3;
 118   const int entry_size         = 4;
 119   // access exception table
 120   typeArrayHandle table (THREAD, constMethod()->exception_table());
 121   int length = table->length();
 122   assert(length % entry_size == 0, "exception table format has changed");
 123   // iterate through all entries sequentially
 124   constantPoolHandle pool(THREAD, constants());
 125   for (int i = 0; i < length; i += entry_size) {
 126     int beg_bci = table->int_at(i + beg_bci_offset);
 127     int end_bci = table->int_at(i + end_bci_offset);


 128     assert(beg_bci <= end_bci, "inconsistent exception table");
 129     if (beg_bci <= throw_bci && throw_bci < end_bci) {
 130       // exception handler bci range covers throw_bci => investigate further
 131       int handler_bci = table->int_at(i + handler_bci_offset);
 132       int klass_index = table->int_at(i + klass_index_offset);
 133       if (klass_index == 0) {
 134         return handler_bci;
 135       } else if (ex_klass.is_null()) {
 136         return handler_bci;
 137       } else {
 138         // we know the exception class => get the constraint class
 139         // this may require loading of the constraint class; if verification
 140         // fails or some other exception occurs, return handler_bci
 141         klassOop k = pool->klass_at(klass_index, CHECK_(handler_bci));
 142         KlassHandle klass = KlassHandle(THREAD, k);
 143         assert(klass.not_null(), "klass not loaded");
 144         if (ex_klass->is_subtype_of(klass())) {
 145           return handler_bci;
 146         }
 147       }
 148     }
 149   }
 150 
 151   return -1;
 152 }


 961   {
 962     constantPoolOop cp_oop = oopFactory::new_constantPool(cp_length, IsSafeConc, CHECK_(empty));
 963     cp = constantPoolHandle(THREAD, cp_oop);
 964   }
 965   cp->symbol_at_put(_imcp_invoke_name,       name);
 966   cp->symbol_at_put(_imcp_invoke_signature,  signature);
 967   cp->string_at_put(_imcp_method_type_value, Universe::the_null_string());
 968   for (int j = 0; j < extra_klass_count; j++) {
 969     KlassHandle klass = extra_klasses->at(j);
 970     cp->klass_at_put(_imcp_limit + j, klass());
 971   }
 972   cp->set_preresolution();
 973   cp->set_pool_holder(holder());
 974 
 975   // set up the fancy stuff:
 976   cp->pseudo_string_at_put(_imcp_method_type_value, method_type());
 977   methodHandle m;
 978   {
 979     int flags_bits = (JVM_MH_INVOKE_BITS | JVM_ACC_PUBLIC | JVM_ACC_FINAL);
 980     methodOop m_oop = oopFactory::new_method(0, accessFlags_from(flags_bits),
 981                                              0, 0, 0, IsSafeConc, CHECK_(empty));
 982     m = methodHandle(THREAD, m_oop);
 983   }
 984   m->set_constants(cp());
 985   m->set_name_index(_imcp_invoke_name);
 986   m->set_signature_index(_imcp_invoke_signature);
 987   assert(is_method_handle_invoke_name(m->name()), "");
 988   assert(m->signature() == signature, "");
 989   assert(m->is_method_handle_invoke(), "");
 990 #ifdef CC_INTERP
 991   ResultTypeFinder rtf(signature);
 992   m->set_result_index(rtf.type());
 993 #endif
 994   m->compute_size_of_parameters(THREAD);
 995   m->set_exception_table(Universe::the_empty_int_array());
 996   m->init_intrinsic_id();
 997   assert(m->intrinsic_id() == vmIntrinsics::_invokeExact ||
 998          m->intrinsic_id() == vmIntrinsics::_invokeGeneric, "must be an invoker");
 999 
1000   // Finally, set up its entry points.
1001   assert(m->method_handle_type() == method_type(), "");
1002   assert(m->can_be_statically_bound(), "");
1003   m->set_vtable_index(methodOopDesc::nonvirtual_vtable_index);
1004   m->link_method(m, CHECK_(empty));
1005 
1006 #ifdef ASSERT
1007   // Make sure the pointer chase works.
1008   address p = (address) m();
1009   for (jint* pchase = method_type_offsets_chain(); (*pchase) != -1; pchase++) {
1010     p = *(address*)(p + (*pchase));
1011   }
1012   assert((oop)p == method_type(), "pointer chase is correct");
1013 #endif
1014 
1015   if (TraceMethodHandles && (Verbose || WizardMode))


1019 }
1020 
1021 klassOop methodOopDesc::check_non_bcp_klass(klassOop klass) {
1022   if (klass != NULL && Klass::cast(klass)->class_loader() != NULL) {
1023     if (Klass::cast(klass)->oop_is_objArray())
1024       klass = objArrayKlass::cast(klass)->bottom_klass();
1025     return klass;
1026   }
1027   return NULL;
1028 }
1029 
1030 
1031 methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length,
1032                                                 u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS) {
1033   // Code below does not work for native methods - they should never get rewritten anyway
1034   assert(!m->is_native(), "cannot rewrite native methods");
1035   // Allocate new methodOop
1036   AccessFlags flags = m->access_flags();
1037   int checked_exceptions_len = m->checked_exceptions_length();
1038   int localvariable_len = m->localvariable_table_length();

1039   // Allocate newm_oop with the is_conc_safe parameter set
1040   // to IsUnsafeConc to indicate that newm_oop is not yet
1041   // safe for concurrent processing by a GC.
1042   methodOop newm_oop = oopFactory::new_method(new_code_length,
1043                                               flags,
1044                                               new_compressed_linenumber_size,
1045                                               localvariable_len,

1046                                               checked_exceptions_len,
1047                                               IsUnsafeConc,
1048                                               CHECK_(methodHandle()));
1049   methodHandle newm (THREAD, newm_oop);
1050   NOT_PRODUCT(int nmsz = newm->is_parsable() ? newm->size() : -1;)
1051   int new_method_size = newm->method_size();
1052   // Create a shallow copy of methodOopDesc part, but be careful to preserve the new constMethodOop
1053   constMethodOop newcm = newm->constMethod();
1054   NOT_PRODUCT(int ncmsz = newcm->is_parsable() ? newcm->size() : -1;)
1055   int new_const_method_size = newm->constMethod()->object_size();
1056 
1057   memcpy(newm(), m(), sizeof(methodOopDesc));
1058   // Create shallow copy of constMethodOopDesc, but be careful to preserve the methodOop
1059   // is_conc_safe is set to false because that is the value of
1060   // is_conc_safe initialzied into newcm and the copy should
1061   // not overwrite that value.  During the window during which it is
1062   // tagged as unsafe, some extra work could be needed during precleaning
1063   // or concurrent marking but those phases will be correct.  Setting and
1064   // resetting is done in preference to a careful copying into newcm to
1065   // avoid having to know the precise layout of a constMethodOop.


1068 
1069   // NOTE: this is a reachable object that transiently signals "conc_unsafe"
1070   // However, no allocations are done during this window
1071   // during which it is tagged conc_unsafe, so we are assured that any concurrent
1072   // thread will not wait forever for the object to revert to "conc_safe".
1073   // Further, any such conc_unsafe object will indicate a stable size
1074   // through the transition.
1075   memcpy(newcm, m->constMethod(), sizeof(constMethodOopDesc));
1076   m->constMethod()->set_is_conc_safe(oopDesc::IsSafeConc);
1077   assert(m->constMethod()->is_parsable(), "Should remain parsable");
1078 
1079   // Reset correct method/const method, method size, and parameter info
1080   newcm->set_method(newm());
1081   newm->set_constMethod(newcm);
1082   assert(newcm->method() == newm(), "check");
1083   newm->constMethod()->set_code_size(new_code_length);
1084   newm->constMethod()->set_constMethod_size(new_const_method_size);
1085   newm->set_method_size(new_method_size);
1086   assert(newm->code_size() == new_code_length, "check");
1087   assert(newm->checked_exceptions_length() == checked_exceptions_len, "check");

1088   assert(newm->localvariable_table_length() == localvariable_len, "check");
1089   // Copy new byte codes
1090   memcpy(newm->code_base(), new_code, new_code_length);
1091   // Copy line number table
1092   if (new_compressed_linenumber_size > 0) {
1093     memcpy(newm->compressed_linenumber_table(),
1094            new_compressed_linenumber_table,
1095            new_compressed_linenumber_size);
1096   }
1097   // Copy checked_exceptions
1098   if (checked_exceptions_len > 0) {
1099     memcpy(newm->checked_exceptions_start(),
1100            m->checked_exceptions_start(),
1101            checked_exceptions_len * sizeof(CheckedExceptionElement));






1102   }
1103   // Copy local variable number table
1104   if (localvariable_len > 0) {
1105     memcpy(newm->localvariable_table_start(),
1106            m->localvariable_table_start(),
1107            localvariable_len * sizeof(LocalVariableTableElement));
1108   }
1109 
1110   // Only set is_conc_safe to true when changes to newcm are
1111   // complete.
1112   assert(!newm->is_parsable()  || nmsz  < 0 || newm->size()  == nmsz,  "newm->size()  inconsistency");
1113   assert(!newcm->is_parsable() || ncmsz < 0 || newcm->size() == ncmsz, "newcm->size() inconsistency");
1114   newcm->set_is_conc_safe(true);
1115   return newm;
1116 }
1117 
1118 vmSymbols::SID methodOopDesc::klass_id_for_intrinsics(klassOop holder) {
1119   // if loader is not the default loader (i.e., != NULL), we can't know the intrinsics
1120   // because we are not loading from core libraries
1121   if (instanceKlass::cast(holder)->class_loader() != NULL)




  94 
  95 char* methodOopDesc::name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature, char* buf, int size) {
  96   Symbol* klass_name = klass->name();
  97   klass_name->as_klass_external_name(buf, size);
  98   int len = (int)strlen(buf);
  99 
 100   if (len < size - 1) {
 101     buf[len++] = '.';
 102 
 103     method_name->as_C_string(&(buf[len]), size - len);
 104     len = (int)strlen(buf);
 105 
 106     signature->as_C_string(&(buf[len]), size - len);
 107   }
 108 
 109   return buf;
 110 }
 111 
 112 int  methodOopDesc::fast_exception_handler_bci_for(KlassHandle ex_klass, int throw_bci, TRAPS) {
 113   // exception table holds quadruple entries of the form (beg_bci, end_bci, handler_bci, klass_index)





 114   // access exception table
 115   ExceptionTable table(this);
 116   int length = table.length();

 117   // iterate through all entries sequentially
 118   constantPoolHandle pool(THREAD, constants());
 119   for (int i = 0; i < length; i ++) {
 120     //reacquire the table in case a GC happened
 121     ExceptionTable table(this);
 122     int beg_bci = table.start_pc(i);
 123     int end_bci = table.end_pc(i);
 124     assert(beg_bci <= end_bci, "inconsistent exception table");
 125     if (beg_bci <= throw_bci && throw_bci < end_bci) {
 126       // exception handler bci range covers throw_bci => investigate further
 127       int handler_bci = table.handler_pc(i);
 128       int klass_index = table.catch_type_index(i);
 129       if (klass_index == 0) {
 130         return handler_bci;
 131       } else if (ex_klass.is_null()) {
 132         return handler_bci;
 133       } else {
 134         // we know the exception class => get the constraint class
 135         // this may require loading of the constraint class; if verification
 136         // fails or some other exception occurs, return handler_bci
 137         klassOop k = pool->klass_at(klass_index, CHECK_(handler_bci));
 138         KlassHandle klass = KlassHandle(THREAD, k);
 139         assert(klass.not_null(), "klass not loaded");
 140         if (ex_klass->is_subtype_of(klass())) {
 141           return handler_bci;
 142         }
 143       }
 144     }
 145   }
 146 
 147   return -1;
 148 }


 957   {
 958     constantPoolOop cp_oop = oopFactory::new_constantPool(cp_length, IsSafeConc, CHECK_(empty));
 959     cp = constantPoolHandle(THREAD, cp_oop);
 960   }
 961   cp->symbol_at_put(_imcp_invoke_name,       name);
 962   cp->symbol_at_put(_imcp_invoke_signature,  signature);
 963   cp->string_at_put(_imcp_method_type_value, Universe::the_null_string());
 964   for (int j = 0; j < extra_klass_count; j++) {
 965     KlassHandle klass = extra_klasses->at(j);
 966     cp->klass_at_put(_imcp_limit + j, klass());
 967   }
 968   cp->set_preresolution();
 969   cp->set_pool_holder(holder());
 970 
 971   // set up the fancy stuff:
 972   cp->pseudo_string_at_put(_imcp_method_type_value, method_type());
 973   methodHandle m;
 974   {
 975     int flags_bits = (JVM_MH_INVOKE_BITS | JVM_ACC_PUBLIC | JVM_ACC_FINAL);
 976     methodOop m_oop = oopFactory::new_method(0, accessFlags_from(flags_bits),
 977                                              0, 0, 0, 0, IsSafeConc, CHECK_(empty));
 978     m = methodHandle(THREAD, m_oop);
 979   }
 980   m->set_constants(cp());
 981   m->set_name_index(_imcp_invoke_name);
 982   m->set_signature_index(_imcp_invoke_signature);
 983   assert(is_method_handle_invoke_name(m->name()), "");
 984   assert(m->signature() == signature, "");
 985   assert(m->is_method_handle_invoke(), "");
 986 #ifdef CC_INTERP
 987   ResultTypeFinder rtf(signature);
 988   m->set_result_index(rtf.type());
 989 #endif
 990   m->compute_size_of_parameters(THREAD);

 991   m->init_intrinsic_id();
 992   assert(m->intrinsic_id() == vmIntrinsics::_invokeExact ||
 993          m->intrinsic_id() == vmIntrinsics::_invokeGeneric, "must be an invoker");
 994 
 995   // Finally, set up its entry points.
 996   assert(m->method_handle_type() == method_type(), "");
 997   assert(m->can_be_statically_bound(), "");
 998   m->set_vtable_index(methodOopDesc::nonvirtual_vtable_index);
 999   m->link_method(m, CHECK_(empty));
1000 
1001 #ifdef ASSERT
1002   // Make sure the pointer chase works.
1003   address p = (address) m();
1004   for (jint* pchase = method_type_offsets_chain(); (*pchase) != -1; pchase++) {
1005     p = *(address*)(p + (*pchase));
1006   }
1007   assert((oop)p == method_type(), "pointer chase is correct");
1008 #endif
1009 
1010   if (TraceMethodHandles && (Verbose || WizardMode))


1014 }
1015 
1016 klassOop methodOopDesc::check_non_bcp_klass(klassOop klass) {
1017   if (klass != NULL && Klass::cast(klass)->class_loader() != NULL) {
1018     if (Klass::cast(klass)->oop_is_objArray())
1019       klass = objArrayKlass::cast(klass)->bottom_klass();
1020     return klass;
1021   }
1022   return NULL;
1023 }
1024 
1025 
1026 methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length,
1027                                                 u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS) {
1028   // Code below does not work for native methods - they should never get rewritten anyway
1029   assert(!m->is_native(), "cannot rewrite native methods");
1030   // Allocate new methodOop
1031   AccessFlags flags = m->access_flags();
1032   int checked_exceptions_len = m->checked_exceptions_length();
1033   int localvariable_len = m->localvariable_table_length();
1034   int exception_table_len = m->exception_table_length();
1035   // Allocate newm_oop with the is_conc_safe parameter set
1036   // to IsUnsafeConc to indicate that newm_oop is not yet
1037   // safe for concurrent processing by a GC.
1038   methodOop newm_oop = oopFactory::new_method(new_code_length,
1039                                               flags,
1040                                               new_compressed_linenumber_size,
1041                                               localvariable_len,
1042                                               exception_table_len,
1043                                               checked_exceptions_len,
1044                                               IsUnsafeConc,
1045                                               CHECK_(methodHandle()));
1046   methodHandle newm (THREAD, newm_oop);
1047   NOT_PRODUCT(int nmsz = newm->is_parsable() ? newm->size() : -1;)
1048   int new_method_size = newm->method_size();
1049   // Create a shallow copy of methodOopDesc part, but be careful to preserve the new constMethodOop
1050   constMethodOop newcm = newm->constMethod();
1051   NOT_PRODUCT(int ncmsz = newcm->is_parsable() ? newcm->size() : -1;)
1052   int new_const_method_size = newm->constMethod()->object_size();
1053 
1054   memcpy(newm(), m(), sizeof(methodOopDesc));
1055   // Create shallow copy of constMethodOopDesc, but be careful to preserve the methodOop
1056   // is_conc_safe is set to false because that is the value of
1057   // is_conc_safe initialzied into newcm and the copy should
1058   // not overwrite that value.  During the window during which it is
1059   // tagged as unsafe, some extra work could be needed during precleaning
1060   // or concurrent marking but those phases will be correct.  Setting and
1061   // resetting is done in preference to a careful copying into newcm to
1062   // avoid having to know the precise layout of a constMethodOop.


1065 
1066   // NOTE: this is a reachable object that transiently signals "conc_unsafe"
1067   // However, no allocations are done during this window
1068   // during which it is tagged conc_unsafe, so we are assured that any concurrent
1069   // thread will not wait forever for the object to revert to "conc_safe".
1070   // Further, any such conc_unsafe object will indicate a stable size
1071   // through the transition.
1072   memcpy(newcm, m->constMethod(), sizeof(constMethodOopDesc));
1073   m->constMethod()->set_is_conc_safe(oopDesc::IsSafeConc);
1074   assert(m->constMethod()->is_parsable(), "Should remain parsable");
1075 
1076   // Reset correct method/const method, method size, and parameter info
1077   newcm->set_method(newm());
1078   newm->set_constMethod(newcm);
1079   assert(newcm->method() == newm(), "check");
1080   newm->constMethod()->set_code_size(new_code_length);
1081   newm->constMethod()->set_constMethod_size(new_const_method_size);
1082   newm->set_method_size(new_method_size);
1083   assert(newm->code_size() == new_code_length, "check");
1084   assert(newm->checked_exceptions_length() == checked_exceptions_len, "check");
1085   assert(newm->exception_table_length() == exception_table_len, "check");
1086   assert(newm->localvariable_table_length() == localvariable_len, "check");
1087   // Copy new byte codes
1088   memcpy(newm->code_base(), new_code, new_code_length);
1089   // Copy line number table
1090   if (new_compressed_linenumber_size > 0) {
1091     memcpy(newm->compressed_linenumber_table(),
1092            new_compressed_linenumber_table,
1093            new_compressed_linenumber_size);
1094   }
1095   // Copy checked_exceptions
1096   if (checked_exceptions_len > 0) {
1097     memcpy(newm->checked_exceptions_start(),
1098            m->checked_exceptions_start(),
1099            checked_exceptions_len * sizeof(CheckedExceptionElement));
1100   }
1101   // Copy exception table
1102   if (exception_table_len > 0) {
1103     memcpy(newm->exception_table_start(),
1104            m->exception_table_start(),
1105            exception_table_len * sizeof(ExceptionTableElement));
1106   }
1107   // Copy local variable number table
1108   if (localvariable_len > 0) {
1109     memcpy(newm->localvariable_table_start(),
1110            m->localvariable_table_start(),
1111            localvariable_len * sizeof(LocalVariableTableElement));
1112   }
1113 
1114   // Only set is_conc_safe to true when changes to newcm are
1115   // complete.
1116   assert(!newm->is_parsable()  || nmsz  < 0 || newm->size()  == nmsz,  "newm->size()  inconsistency");
1117   assert(!newcm->is_parsable() || ncmsz < 0 || newcm->size() == ncmsz, "newcm->size() inconsistency");
1118   newcm->set_is_conc_safe(true);
1119   return newm;
1120 }
1121 
1122 vmSymbols::SID methodOopDesc::klass_id_for_intrinsics(klassOop holder) {
1123   // if loader is not the default loader (i.e., != NULL), we can't know the intrinsics
1124   // because we are not loading from core libraries
1125   if (instanceKlass::cast(holder)->class_loader() != NULL)


< prev index next >