< 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 >