780 if (_nmethod_mirror_index == -1) {
781 return nullptr;
782 }
783 return nm->oop_at(_nmethod_mirror_index);
784 }
785
786 void JVMCINMethodData::set_nmethod_mirror(nmethod* nm, oop new_mirror) {
787 guarantee(_nmethod_mirror_index != -1, "cannot set JVMCI mirror for nmethod");
788 oop* addr = nm->oop_addr_at(_nmethod_mirror_index);
789 guarantee(new_mirror != nullptr, "use clear_nmethod_mirror to clear the mirror");
790 guarantee(*addr == nullptr, "cannot overwrite non-null mirror");
791
792 *addr = new_mirror;
793
794 // Since we've patched some oops in the nmethod,
795 // (re)register it with the heap.
796 MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag);
797 Universe::heap()->register_nmethod(nm);
798 }
799
800 void JVMCINMethodData::invalidate_nmethod_mirror(nmethod* nm) {
801 oop nmethod_mirror = get_nmethod_mirror(nm);
802 if (nmethod_mirror == nullptr) {
803 return;
804 }
805
806 // Update the values in the mirror if it still refers to nm.
807 // We cannot use JVMCIObject to wrap the mirror as this is called
808 // during GC, forbidding the creation of JNIHandles.
809 JVMCIEnv* jvmciEnv = nullptr;
810 nmethod* current = (nmethod*) HotSpotJVMCI::InstalledCode::address(jvmciEnv, nmethod_mirror);
811 if (nm == current) {
812 if (nm->is_unloading()) {
813 // Break the link from the mirror to nm such that
814 // future invocations via the mirror will result in
815 // an InvalidInstalledCodeException.
816 HotSpotJVMCI::InstalledCode::set_address(jvmciEnv, nmethod_mirror, 0);
817 HotSpotJVMCI::InstalledCode::set_entryPoint(jvmciEnv, nmethod_mirror, 0);
818 HotSpotJVMCI::HotSpotInstalledCode::set_codeStart(jvmciEnv, nmethod_mirror, 0);
819 } else if (nm->is_not_entrant()) {
820 // Zero the entry point so any new invocation will fail but keep
821 // the address link around that so that existing activations can
822 // be deoptimized via the mirror (i.e. JVMCIEnv::invalidate_installed_code).
823 HotSpotJVMCI::InstalledCode::set_entryPoint(jvmciEnv, nmethod_mirror, 0);
824 HotSpotJVMCI::HotSpotInstalledCode::set_codeStart(jvmciEnv, nmethod_mirror, 0);
825 }
826 }
827
828 if (_nmethod_mirror_index != -1 && nm->is_unloading()) {
829 // Drop the reference to the nmethod mirror object but don't clear the actual oop reference. Otherwise
830 // it would appear that the nmethod didn't need to be unloaded in the first place.
831 _nmethod_mirror_index = -1;
832 }
833 }
834
835 // Handles to objects in the Hotspot heap.
836 static OopStorage* object_handles() {
837 return Universe::vm_global();
838 }
839
840 jlong JVMCIRuntime::make_oop_handle(const Handle& obj) {
841 assert(!Universe::heap()->is_stw_gc_active(), "can't extend the root set during GC pause");
842 assert(oopDesc::is_oop(obj()), "not an oop");
843
844 oop* ptr = OopHandle(object_handles(), obj()).ptr_raw();
2167 result = JVMCI::cache_full;
2168 } else {
2169 nm->set_has_unsafe_access(has_unsafe_access);
2170 nm->set_has_wide_vectors(has_wide_vector);
2171 nm->set_has_monitors(has_monitors);
2172 nm->set_has_scoped_access(has_scoped_access);
2173
2174 JVMCINMethodData* data = nm->jvmci_nmethod_data();
2175 assert(data != nullptr, "must be");
2176 if (install_default) {
2177 assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm) == nullptr, "must be");
2178 if (entry_bci == InvocationEntryBci) {
2179 // If there is an old version we're done with it
2180 nmethod* old = method->code();
2181 if (TraceMethodReplacement && old != nullptr) {
2182 ResourceMark rm;
2183 char *method_name = method->name_and_sig_as_C_string();
2184 tty->print_cr("Replacing method %s", method_name);
2185 }
2186 if (old != nullptr) {
2187 old->make_not_entrant("JVMCI register method");
2188 }
2189
2190 LogTarget(Info, nmethod, install) lt;
2191 if (lt.is_enabled()) {
2192 ResourceMark rm;
2193 char *method_name = method->name_and_sig_as_C_string();
2194 lt.print("Installing method (%d) %s [entry point: %p]",
2195 comp_level, method_name, nm->entry_point());
2196 }
2197 // Allow the code to be executed
2198 MutexLocker ml(NMethodState_lock, Mutex::_no_safepoint_check_flag);
2199 if (nm->make_in_use()) {
2200 method->set_code(method, nm);
2201 } else {
2202 result = JVMCI::nmethod_reclaimed;
2203 }
2204 } else {
2205 LogTarget(Info, nmethod, install) lt;
2206 if (lt.is_enabled()) {
2207 ResourceMark rm;
|
780 if (_nmethod_mirror_index == -1) {
781 return nullptr;
782 }
783 return nm->oop_at(_nmethod_mirror_index);
784 }
785
786 void JVMCINMethodData::set_nmethod_mirror(nmethod* nm, oop new_mirror) {
787 guarantee(_nmethod_mirror_index != -1, "cannot set JVMCI mirror for nmethod");
788 oop* addr = nm->oop_addr_at(_nmethod_mirror_index);
789 guarantee(new_mirror != nullptr, "use clear_nmethod_mirror to clear the mirror");
790 guarantee(*addr == nullptr, "cannot overwrite non-null mirror");
791
792 *addr = new_mirror;
793
794 // Since we've patched some oops in the nmethod,
795 // (re)register it with the heap.
796 MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag);
797 Universe::heap()->register_nmethod(nm);
798 }
799
800 void JVMCINMethodData::invalidate_nmethod_mirror(nmethod* nm, nmethod::InvalidationReason invalidation_reason) {
801 oop nmethod_mirror = get_nmethod_mirror(nm);
802 if (nmethod_mirror == nullptr) {
803 return;
804 }
805
806 // Update the values in the mirror if it still refers to nm.
807 // We cannot use JVMCIObject to wrap the mirror as this is called
808 // during GC, forbidding the creation of JNIHandles.
809 JVMCIEnv* jvmciEnv = nullptr;
810 nmethod* current = (nmethod*) HotSpotJVMCI::InstalledCode::address(jvmciEnv, nmethod_mirror);
811 if (nm == current) {
812 if (nm->is_unloading()) {
813 // Break the link from the mirror to nm such that
814 // future invocations via the mirror will result in
815 // an InvalidInstalledCodeException.
816 HotSpotJVMCI::InstalledCode::set_address(jvmciEnv, nmethod_mirror, 0);
817 HotSpotJVMCI::InstalledCode::set_entryPoint(jvmciEnv, nmethod_mirror, 0);
818 HotSpotJVMCI::HotSpotInstalledCode::set_codeStart(jvmciEnv, nmethod_mirror, 0);
819 if (HotSpotJVMCI::HotSpotNmethod::invalidationReason(jvmciEnv, nmethod_mirror) ==
820 static_cast<int>(nmethod::InvalidationReason::NOT_INVALIDATED)) {
821 HotSpotJVMCI::HotSpotNmethod::set_invalidationReason(jvmciEnv, nmethod_mirror, static_cast<int>(invalidation_reason));
822 }
823 } else if (nm->is_not_entrant()) {
824 // Zero the entry point so any new invocation will fail but keep
825 // the address link around that so that existing activations can
826 // be deoptimized via the mirror (i.e. JVMCIEnv::invalidate_installed_code).
827 HotSpotJVMCI::InstalledCode::set_entryPoint(jvmciEnv, nmethod_mirror, 0);
828 HotSpotJVMCI::HotSpotInstalledCode::set_codeStart(jvmciEnv, nmethod_mirror, 0);
829 if (HotSpotJVMCI::HotSpotNmethod::invalidationReason(jvmciEnv, nmethod_mirror) ==
830 static_cast<int>(nmethod::InvalidationReason::NOT_INVALIDATED)) {
831 HotSpotJVMCI::HotSpotNmethod::set_invalidationReason(jvmciEnv, nmethod_mirror, static_cast<int>(invalidation_reason));
832 }
833 }
834 }
835
836 if (_nmethod_mirror_index != -1 && nm->is_unloading()) {
837 // Drop the reference to the nmethod mirror object but don't clear the actual oop reference. Otherwise
838 // it would appear that the nmethod didn't need to be unloaded in the first place.
839 _nmethod_mirror_index = -1;
840 }
841 }
842
843 // Handles to objects in the Hotspot heap.
844 static OopStorage* object_handles() {
845 return Universe::vm_global();
846 }
847
848 jlong JVMCIRuntime::make_oop_handle(const Handle& obj) {
849 assert(!Universe::heap()->is_stw_gc_active(), "can't extend the root set during GC pause");
850 assert(oopDesc::is_oop(obj()), "not an oop");
851
852 oop* ptr = OopHandle(object_handles(), obj()).ptr_raw();
2175 result = JVMCI::cache_full;
2176 } else {
2177 nm->set_has_unsafe_access(has_unsafe_access);
2178 nm->set_has_wide_vectors(has_wide_vector);
2179 nm->set_has_monitors(has_monitors);
2180 nm->set_has_scoped_access(has_scoped_access);
2181
2182 JVMCINMethodData* data = nm->jvmci_nmethod_data();
2183 assert(data != nullptr, "must be");
2184 if (install_default) {
2185 assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm) == nullptr, "must be");
2186 if (entry_bci == InvocationEntryBci) {
2187 // If there is an old version we're done with it
2188 nmethod* old = method->code();
2189 if (TraceMethodReplacement && old != nullptr) {
2190 ResourceMark rm;
2191 char *method_name = method->name_and_sig_as_C_string();
2192 tty->print_cr("Replacing method %s", method_name);
2193 }
2194 if (old != nullptr) {
2195 old->make_not_entrant(nmethod::InvalidationReason::JVMCI_REPLACED_WITH_NEW_CODE);
2196 }
2197
2198 LogTarget(Info, nmethod, install) lt;
2199 if (lt.is_enabled()) {
2200 ResourceMark rm;
2201 char *method_name = method->name_and_sig_as_C_string();
2202 lt.print("Installing method (%d) %s [entry point: %p]",
2203 comp_level, method_name, nm->entry_point());
2204 }
2205 // Allow the code to be executed
2206 MutexLocker ml(NMethodState_lock, Mutex::_no_safepoint_check_flag);
2207 if (nm->make_in_use()) {
2208 method->set_code(method, nm);
2209 } else {
2210 result = JVMCI::nmethod_reclaimed;
2211 }
2212 } else {
2213 LogTarget(Info, nmethod, install) lt;
2214 if (lt.is_enabled()) {
2215 ResourceMark rm;
|