< prev index next >

src/hotspot/os/posix/signals_posix.cpp

Print this page
@@ -23,10 +23,13 @@
   */
  
  #include "precompiled.hpp"
  
  #include "jvm.h"
+ #include "code/codeCache.hpp"
+ #include "code/compiledMethod.hpp"
+ #include "code/nativeInst.hpp"
  #include "logging/log.hpp"
  #include "runtime/atomic.hpp"
  #include "runtime/globals.hpp"
  #include "runtime/interfaceSupport.inline.hpp"
  #include "runtime/java.hpp"

@@ -620,10 +623,34 @@
        (sig == SIGPIPE || sig == SIGXFSZ)) {
      PosixSignals::chained_handler(sig, info, ucVoid);
      signal_was_handled = true; // unconditionally.
    }
  
+   // Check for UD trap caused by NOP patching.
+   // If it is, patch return address to be deopt handler.
+   if (!signal_was_handled) {
+     address pc = os::Posix::ucontext_get_pc(uc);
+     assert (pc != NULL, "");
+     if (NativeDeoptInstruction::is_deopt_at(pc)) {
+       CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
+       if (cb != NULL && cb->is_compiled()) {
+         CompiledMethod* cm = cb->as_compiled_method();
+         assert(cm->insts_contains_inclusive(pc), "");
+         address deopt = cm->is_method_handle_return(pc) ?
+           cm->deopt_mh_handler_begin() :
+           cm->deopt_handler_begin();
+         assert (deopt != NULL, "");
+ 
+         frame fr = os::fetch_frame_from_context(uc);
+         cm->set_original_pc(&fr, pc);
+ 
+         os::Posix::ucontext_set_pc(uc, deopt);
+         signal_was_handled = true;
+       }
+     }
+   }
+ 
    // Call platform dependent signal handler.
    if (!signal_was_handled) {
      JavaThread* const jt = (t != NULL && t->is_Java_thread()) ? (JavaThread*) t : NULL;
      signal_was_handled = PosixSignals::pd_hotspot_signal_handler(sig, info, uc, jt);
    }
< prev index next >