src/hotspot/share/runtime/stubRoutines.cpp
changeset 55490 3f3dc00a69a5
parent 53546 63eb7e38ce84
child 55511 91b38bfb9079
--- a/src/hotspot/share/runtime/stubRoutines.cpp	Thu Jun 20 14:09:22 2019 +0100
+++ b/src/hotspot/share/runtime/stubRoutines.cpp	Mon Jun 24 11:37:56 2019 -0700
@@ -38,6 +38,10 @@
 #include "opto/runtime.hpp"
 #endif
 
+UnsafeCopyMemory* UnsafeCopyMemory::_table                      = NULL;
+int UnsafeCopyMemory::_table_length                             = 0;
+int UnsafeCopyMemory::_table_max_length                         = 0;
+address UnsafeCopyMemory::_common_exit_stub_pc                  = NULL;
 
 // Implementation of StubRoutines - for a description
 // of how to extend it, see the header file.
@@ -113,7 +117,6 @@
 address StubRoutines::_unsafe_arraycopy                  = NULL;
 address StubRoutines::_generic_arraycopy                 = NULL;
 
-
 address StubRoutines::_jbyte_fill;
 address StubRoutines::_jshort_fill;
 address StubRoutines::_jint_fill;
@@ -177,6 +180,31 @@
 
 extern void StubGenerator_generate(CodeBuffer* code, bool all); // only interface to generators
 
+void UnsafeCopyMemory::create_table(int max_size) {
+  UnsafeCopyMemory::_table = new UnsafeCopyMemory[max_size];
+  UnsafeCopyMemory::_table_max_length = max_size;
+}
+
+bool UnsafeCopyMemory::contains_pc(address pc) {
+  for (int i = 0; i < UnsafeCopyMemory::_table_length; i++) {
+    UnsafeCopyMemory* entry = &UnsafeCopyMemory::_table[i];
+    if (pc >= entry->start_pc() && pc < entry->end_pc()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+address UnsafeCopyMemory::page_error_continue_pc(address pc) {
+  for (int i = 0; i < UnsafeCopyMemory::_table_length; i++) {
+    UnsafeCopyMemory* entry = &UnsafeCopyMemory::_table[i];
+    if (pc >= entry->start_pc() && pc < entry->end_pc()) {
+      return entry->error_exit_pc();
+    }
+  }
+  return NULL;
+}
+
 void StubRoutines::initialize1() {
   if (_code1 == NULL) {
     ResourceMark rm;
@@ -569,3 +597,25 @@
 #undef RETURN_STUB
 #undef RETURN_STUB_PARM
 }
+
+UnsafeCopyMemoryMark::UnsafeCopyMemoryMark(StubCodeGenerator* cgen, bool add_entry, bool continue_at_scope_end, address error_exit_pc) {
+  _cgen = cgen;
+  _ucm_entry = NULL;
+  if (add_entry) {
+    address err_exit_pc = NULL;
+    if (!continue_at_scope_end) {
+      err_exit_pc = error_exit_pc != NULL ? error_exit_pc : UnsafeCopyMemory::common_exit_stub_pc();
+    }
+    assert(err_exit_pc != NULL || continue_at_scope_end, "error exit not set");
+    _ucm_entry = UnsafeCopyMemory::add_to_table(_cgen->assembler()->pc(), NULL, err_exit_pc);
+  }
+}
+
+UnsafeCopyMemoryMark::~UnsafeCopyMemoryMark() {
+  if (_ucm_entry != NULL) {
+    _ucm_entry->set_end_pc(_cgen->assembler()->pc());
+    if (_ucm_entry->error_exit_pc() == NULL) {
+      _ucm_entry->set_error_exit_pc(_cgen->assembler()->pc());
+    }
+  }
+}