src/share/vm/runtime/stubRoutines.hpp

Print this page
rev 4810 : 8016697: PPC64 (part 5): Use stubs to implement safefetch
Summary: Implement Safefetch as stub routines. This reduces compiler and os dependencies.
Reviewed-by: twisti, kvn

@@ -219,10 +219,18 @@
   static double (*_intrinsic_pow)(double, double);
   static double (*_intrinsic_sin)(double);
   static double (*_intrinsic_cos)(double);
   static double (*_intrinsic_tan)(double);
 
+  // Safefetch stubs.
+  static address _safefetch32_entry;
+  static address _safefetch32_fault_pc;
+  static address _safefetch32_continuation_pc;
+  static address _safefetchN_entry;
+  static address _safefetchN_fault_pc;
+  static address _safefetchN_continuation_pc;
+
  public:
   // Initialization/Testing
   static void    initialize1();                            // must happen before universe::genesis
   static void    initialize2();                            // must happen after  universe::genesis
 

@@ -377,10 +385,38 @@
     assert(_intrinsic_tan != NULL, "must be defined");
     return _intrinsic_tan(d);
   }
 
   //
+  // Safefetch stub support
+  //
+
+  typedef int      (*SafeFetch32Stub)(int*      adr, int      errValue);
+  typedef intptr_t (*SafeFetchNStub) (intptr_t* adr, intptr_t errValue);
+
+  static SafeFetch32Stub SafeFetch32_stub() { return CAST_TO_FN_PTR(SafeFetch32Stub, _safefetch32_entry); }
+  static SafeFetchNStub  SafeFetchN_stub()  { return CAST_TO_FN_PTR(SafeFetchNStub,  _safefetchN_entry); }
+
+  static bool is_safefetch_fault(address pc) {
+    return pc != NULL &&
+          (pc == _safefetch32_fault_pc ||
+           pc == _safefetchN_fault_pc);
+  }
+
+  static address continuation_for_safefetch_fault(address pc) {
+    assert(_safefetch32_continuation_pc != NULL &&
+           _safefetchN_continuation_pc  != NULL,
+           "not initialized");
+
+    if (pc == _safefetch32_fault_pc) return _safefetch32_continuation_pc;
+    if (pc == _safefetchN_fault_pc)  return _safefetchN_continuation_pc;
+
+    ShouldNotReachHere();
+    return NULL;
+  }
+
+  //
   // Default versions of the above arraycopy functions for platforms which do
   // not have specialized versions
   //
   static void jbyte_copy     (jbyte*  src, jbyte*  dest, size_t count);
   static void jshort_copy    (jshort* src, jshort* dest, size_t count);

@@ -395,6 +431,17 @@
   static void arrayof_jlong_copy     (HeapWord* src, HeapWord* dest, size_t count);
   static void arrayof_oop_copy       (HeapWord* src, HeapWord* dest, size_t count);
   static void arrayof_oop_copy_uninit(HeapWord* src, HeapWord* dest, size_t count);
 };
 
+// Safefetch allows to load a value from a location that's not known
+// to be valid. If the load causes a fault, the error value is returned.
+inline int SafeFetch32(int* adr, int errValue) {
+  assert(StubRoutines::SafeFetch32_stub(), "stub not yet generated");
+  return StubRoutines::SafeFetch32_stub()(adr, errValue);
+}
+inline intptr_t SafeFetchN(intptr_t* adr, intptr_t errValue) {
+  assert(StubRoutines::SafeFetchN_stub(), "stub not yet generated");
+  return StubRoutines::SafeFetchN_stub()(adr, errValue);
+}
+
 #endif // SHARE_VM_RUNTIME_STUBROUTINES_HPP