src/share/vm/oops/methodOop.cpp

Print this page




  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 }


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


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

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

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




  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 }


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

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


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