< prev index next >

src/hotspot/share/oops/method.cpp

Print this page

        

@@ -46,10 +46,11 @@
 #include "oops/method.inline.hpp"
 #include "oops/methodData.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
+#include "oops/valueKlass.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "prims/methodHandles.hpp"
 #include "prims/nativeLookup.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/compilationPolicy.hpp"

@@ -105,11 +106,10 @@
 
   if (access_flags.is_native()) {
     clear_native_function();
     set_signature_handler(NULL);
   }
-
   NOT_PRODUCT(set_compiled_invocation_count(0);)
 }
 
 // Release Method*.  The nmethod will be gone when we get here because
 // we've walked the code cache.

@@ -465,10 +465,30 @@
 BasicType Method::result_type() const {
   ResultTypeFinder rtf(signature());
   return rtf.type();
 }
 
+#ifdef ASSERT
+// ValueKlass the method is declared to return. This must not
+// safepoint as it is called with references live on the stack at
+// locations the GC is unaware of.
+ValueKlass* Method::returned_value_type(Thread* thread) const {
+  SignatureStream ss(signature());
+  while (!ss.at_return_type()) {
+    ss.next();
+  }
+  Handle class_loader(thread, method_holder()->class_loader());
+  Handle protection_domain(thread, method_holder()->protection_domain());
+  Klass* k = NULL;
+  {
+    NoSafepointVerifier nsv;
+    k = ss.as_klass(class_loader, protection_domain, SignatureStream::ReturnNull, thread);
+  }
+  assert(k != NULL && !thread->has_pending_exception(), "can't resolve klass");
+  return ValueKlass::cast(k);
+}
+#endif
 
 bool Method::is_empty_method() const {
   return  code_size() == 1
       && *code_base() == Bytecodes::_return;
 }

@@ -715,11 +735,11 @@
   return best_line;
 }
 
 
 bool Method::is_klass_loaded_by_klass_index(int klass_index) const {
-  if( constants()->tag_at(klass_index).is_unresolved_klass() ) {
+  if( constants()->tag_at(klass_index).is_unresolved_klass()) {
     Thread *thread = Thread::current();
     Symbol* klass_name = constants()->klass_name_at(klass_index);
     Handle loader(thread, method_holder()->class_loader());
     Handle prot  (thread, method_holder()->protection_domain());
     return SystemDictionary::find(klass_name, loader, prot, thread) != NULL;

@@ -731,11 +751,13 @@
 
 bool Method::is_klass_loaded(int refinfo_index, bool must_be_resolved) const {
   int klass_index = constants()->klass_ref_index_at(refinfo_index);
   if (must_be_resolved) {
     // Make sure klass is resolved in constantpool.
-    if (constants()->tag_at(klass_index).is_unresolved_klass()) return false;
+    if (constants()->tag_at(klass_index).is_unresolved_klass()) {
+      return false;
+    }
   }
   return is_klass_loaded_by_klass_index(klass_index);
 }
 
 

@@ -910,12 +932,16 @@
   MutexLockerEx pl(acquire_lock ? Patching_lock : NULL, Mutex::_no_safepoint_check_flag);
   // this may be NULL if c2i adapters have not been made yet
   // Only should happen at allocate time.
   if (adapter() == NULL) {
     _from_compiled_entry    = NULL;
+    _from_compiled_value_entry = NULL;
+    _from_compiled_value_ro_entry = NULL;
   } else {
     _from_compiled_entry    = adapter()->get_c2i_entry();
+    _from_compiled_value_entry = adapter()->get_c2i_value_entry();
+    _from_compiled_value_ro_entry = adapter()->get_c2i_value_ro_entry();
   }
   OrderAccess::storestore();
   _from_interpreted_entry = _i2i_entry;
   OrderAccess::storestore();
   _code = NULL;

@@ -940,10 +966,14 @@
 
   CDSAdapterHandlerEntry* cds_adapter = (CDSAdapterHandlerEntry*)adapter();
   constMethod()->set_adapter_trampoline(cds_adapter->get_adapter_trampoline());
   _from_compiled_entry = cds_adapter->get_c2i_entry_trampoline();
   assert(*((int*)_from_compiled_entry) == 0, "must be NULL during dump time, to be initialized at run time");
+  _from_compiled_value_entry = cds_adapter->get_c2i_entry_trampoline();
+  assert(*((int*)_from_compiled_value_entry) == 0, "must be NULL during dump time, to be initialized at run time");
+  _from_compiled_value_ro_entry = cds_adapter->get_c2i_entry_trampoline();
+  assert(*((int*)_from_compiled_value_ro_entry) == 0, "must be NULL during dump time, to be initialized at run time");
 
   set_method_data(NULL);
   clear_method_counters();
 }
 #endif

@@ -1087,13 +1117,17 @@
   }
 
   if (mh->is_shared()) {
     assert(mh->adapter() == adapter, "must be");
     assert(mh->_from_compiled_entry != NULL, "must be");
+    assert(mh->_from_compiled_value_entry != NULL, "must be");
+    assert(mh->_from_compiled_value_ro_entry != NULL, "must be");
   } else {
     mh->set_adapter_entry(adapter);
     mh->_from_compiled_entry = adapter->get_c2i_entry();
+    mh->_from_compiled_value_entry = adapter->get_c2i_value_entry();
+    mh->_from_compiled_value_ro_entry = adapter->get_c2i_value_ro_entry();
   }
   return adapter->get_c2i_entry();
 }
 
 void Method::restore_unshareable_info(TRAPS) {

@@ -1127,10 +1161,16 @@
   debug_only(NoSafepointVerifier nsv;)
   assert(_from_compiled_entry != NULL, "must be set");
   return _from_compiled_entry;
 }
 
+address Method::verified_value_ro_code_entry() {
+  debug_only(NoSafepointVerifier nsv;)
+  assert(_from_compiled_value_ro_entry != NULL, "must be set");
+  return _from_compiled_value_ro_entry;
+}
+
 // Check that if an nmethod ref exists, it has a backlink to this or no backlink at all
 // (could be racing a deopt).
 // Not inline to avoid circular ref.
 bool Method::check_code() const {
   // cached in a register or local.  There's a race on the value of the field.

@@ -1158,10 +1198,12 @@
     mh->set_highest_comp_level(comp_level);
   }
 
   OrderAccess::storestore();
   mh->_from_compiled_entry = code->verified_entry_point();
+  mh->_from_compiled_value_entry = code->verified_value_entry_point();
+  mh->_from_compiled_value_ro_entry = code->verified_value_ro_entry_point();
   OrderAccess::storestore();
   // Instantly compiled code can execute.
   if (!mh->is_method_handle_intrinsic())
     mh->_from_interpreted_entry = mh->get_i2c_entry();
 }

@@ -2215,10 +2257,12 @@
   if (intrinsic_id() != vmIntrinsics::_none)
     st->print_cr(" - intrinsic id:      %d %s", intrinsic_id(), vmIntrinsics::name_at(intrinsic_id()));
   if (highest_comp_level() != CompLevel_none)
     st->print_cr(" - highest level:     %d", highest_comp_level());
   st->print_cr(" - vtable index:      %d",   _vtable_index);
+  if (valid_itable_index())
+    st->print_cr(" - itable index:      %d",   itable_index());
   st->print_cr(" - i2i entry:         " INTPTR_FORMAT, p2i(interpreter_entry()));
   st->print(   " - adapters:          ");
   AdapterHandlerEntry* a = ((Method*)this)->adapter();
   if (a == NULL)
     st->print_cr(INTPTR_FORMAT, p2i(a));

@@ -2292,10 +2336,11 @@
 void Method::print_value_on(outputStream* st) const {
   assert(is_method(), "must be method");
   st->print("%s", internal_name());
   print_address_on(st);
   st->print(" ");
+  if (WizardMode) access_flags().print_on(st);
   name()->print_value_on(st);
   st->print(" ");
   signature()->print_value_on(st);
   st->print(" in ");
   method_holder()->print_value_on(st);
< prev index next >