diff a/src/hotspot/share/code/relocInfo.cpp b/src/hotspot/share/code/relocInfo.cpp
--- a/src/hotspot/share/code/relocInfo.cpp
+++ b/src/hotspot/share/code/relocInfo.cpp
@@ -21,14 +21,16 @@
  * questions.
  *
  */
 
 #include "precompiled.hpp"
+#include "ci/ciUtilities.hpp"
 #include "code/codeCache.hpp"
 #include "code/compiledIC.hpp"
 #include "code/nmethod.hpp"
 #include "code/relocInfo.hpp"
+#include "code/SCCache.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/flags/flagSetting.hpp"
@@ -171,10 +173,13 @@
   set_limits(begin, limit);
 }
 
 bool RelocIterator::addr_in_const() const {
   const int n = CodeBuffer::SECT_CONSTS;
+  if (_section_start[n] == nullptr) {
+    return false;
+  }
   return section_start(n) <= addr() && addr() < section_end(n);
 }
 
 
 void RelocIterator::set_limits(address begin, address limit) {
@@ -461,15 +466,16 @@
 }
 
 void external_word_Relocation::pack_data_to(CodeSection* dest) {
   short* p = (short*) dest->locs_end();
   int index = ExternalsRecorder::find_index(_target);
-  p = pack_1_int_to(p, index);
+  // Use 4 bytes to store index to be able patch it when
+  // updating relocations in SCCReader::read_relocations().
+  p = add_jint(p, index);
   dest->set_locs_end((relocInfo*) p);
 }
 
-
 void external_word_Relocation::unpack_data() {
   int index = unpack_1_int();
   _target = ExternalsRecorder::at(index);
 }
 
@@ -734,10 +740,18 @@
     set_value(_target);
   }
   // If target is nullptr, this is  an absolute embedded reference to an external
   // location, which means  there is nothing to fix here.  In either case, the
   // resulting target should be an "external" address.
+#ifdef ASSERT
+  if (SCCache::is_on()) {
+    // SCA needs relocation info for card table base which may point to CodeCache
+    if (is_card_table_address(target())) {
+      return;
+    }
+  }
+#endif
   postcond(src->section_index_of(target()) == CodeBuffer::SECT_NONE);
   postcond(dest->section_index_of(target()) == CodeBuffer::SECT_NONE);
 }
 
 
@@ -769,16 +783,11 @@
     }
   }
   return target;
 }
 
-//---------------------------------------------------------------------------------
-// Non-product code
-
-#ifndef PRODUCT
-
-static const char* reloc_type_string(relocInfo::relocType t) {
+const char* relocInfo::type_name(relocInfo::relocType t) {
   switch (t) {
   #define EACH_CASE(name) \
   case relocInfo::name##_type: \
     return #name;
 
@@ -793,29 +802,29 @@
     return "UNKNOWN RELOC TYPE";
   }
 }
 
 
-void RelocIterator::print_current() {
+void RelocIterator::print_current_on(outputStream* st) {
   if (!has_current()) {
-    tty->print_cr("(no relocs)");
+    st->print_cr("(no relocs)");
     return;
   }
-  tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT " offset=%d",
-             p2i(_current), type(), reloc_type_string((relocInfo::relocType) type()), p2i(_addr), _current->addr_offset());
+  st->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT " offset=%d",
+            p2i(_current), type(), relocInfo::type_name(type()), p2i(_addr), _current->addr_offset());
   if (current()->format() != 0)
-    tty->print(" format=%d", current()->format());
+    st->print(" format=%d", current()->format());
   if (datalen() == 1) {
-    tty->print(" data=%d", data()[0]);
+    st->print(" data=%d", data()[0]);
   } else if (datalen() > 0) {
-    tty->print(" data={");
+    st->print(" data={");
     for (int i = 0; i < datalen(); i++) {
-      tty->print("%04x", data()[i] & 0xFFFF);
+      st->print("%04x", data()[i] & 0xFFFF);
     }
-    tty->print("}");
+    st->print("}");
   }
-  tty->print("]");
+  st->print("]");
   switch (type()) {
   case relocInfo::oop_type:
     {
       oop_Relocation* r = oop_reloc();
       oop* oop_addr  = nullptr;
@@ -824,18 +833,18 @@
       if (code() != nullptr || r->oop_is_immediate()) {
         oop_addr  = r->oop_addr();
         raw_oop   = *oop_addr;
         oop_value = r->oop_value();
       }
-      tty->print(" | [oop_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT "]",
-                 p2i(oop_addr), p2i(raw_oop));
+      st->print(" | [oop_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " index=%d]",
+                 p2i(oop_addr), p2i(raw_oop), r->oop_index());
       // Do not print the oop by default--we want this routine to
       // work even during GC or other inconvenient times.
       if (WizardMode && oop_value != nullptr) {
-        tty->print("oop_value=" INTPTR_FORMAT ": ", p2i(oop_value));
+        st->print("oop_value=" INTPTR_FORMAT ": ", p2i(oop_value));
         if (oopDesc::is_oop(oop_value)) {
-          oop_value->print_value_on(tty);
+          oop_value->print_value_on(st);
         }
       }
       break;
     }
   case relocInfo::metadata_type:
@@ -847,108 +856,151 @@
       if (code() != nullptr || r->metadata_is_immediate()) {
         metadata_addr  = r->metadata_addr();
         raw_metadata   = *metadata_addr;
         metadata_value = r->metadata_value();
       }
-      tty->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT "]",
-                 p2i(metadata_addr), p2i(raw_metadata));
+      st->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " index=%d]",
+                 p2i(metadata_addr), p2i(raw_metadata), r->metadata_index());
       if (metadata_value != nullptr) {
-        tty->print("metadata_value=" INTPTR_FORMAT ": ", p2i(metadata_value));
-        metadata_value->print_value_on(tty);
+        st->print("metadata_value=" INTPTR_FORMAT ": ", p2i(metadata_value));
+        metadata_value->print_value_on(st);
       }
       break;
     }
   case relocInfo::external_word_type:
   case relocInfo::internal_word_type:
   case relocInfo::section_word_type:
     {
       DataRelocation* r = (DataRelocation*) reloc();
-      tty->print(" | [target=" INTPTR_FORMAT "]", p2i(r->value())); //value==target
+      st->print(" | [target=" INTPTR_FORMAT "]", p2i(r->value())); //value==target
       break;
     }
   case relocInfo::static_call_type:
     {
       static_call_Relocation* r = (static_call_Relocation*) reloc();
-      tty->print(" | [destination=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
+      st->print(" | [destination=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
                  p2i(r->destination()), p2i(r->method_value()));
+      CodeBlob* cb = CodeCache::find_blob(r->destination());
+      if (cb != nullptr) {
+        st->print(" Blob::%s", cb->name());
+      }
       break;
     }
   case relocInfo::runtime_call_type:
   case relocInfo::runtime_call_w_cp_type:
     {
       CallRelocation* r = (CallRelocation*) reloc();
-      tty->print(" | [destination=" INTPTR_FORMAT "]", p2i(r->destination()));
+      address dest = r->destination();
+      st->print(" | [destination=" INTPTR_FORMAT "]", p2i(dest));
+      if (StubRoutines::contains(dest)) {
+        StubCodeDesc* desc = StubCodeDesc::desc_for(dest);
+        if (desc == nullptr) {
+          desc = StubCodeDesc::desc_for(dest + frame::pc_return_offset);
+        }
+        if (desc != nullptr) {
+          st->print(" Stub::%s", desc->name());
+        }
+      } else {
+        CodeBlob* cb = CodeCache::find_blob(dest);
+        if (cb != nullptr) {
+          st->print(" Blob::%s", cb->name());
+        } else {
+          ResourceMark rm;
+          const int buflen = 1024;
+          char* buf = NEW_RESOURCE_ARRAY(char, buflen);
+          int offset;
+          if (os::dll_address_to_function_name(dest, buf, buflen, &offset)) {
+            st->print(" %s", buf);
+            if (offset != 0) {
+              st->print("+%d", offset);
+            }
+          }
+        }
+      }
       break;
     }
   case relocInfo::virtual_call_type:
     {
       virtual_call_Relocation* r = (virtual_call_Relocation*) reloc();
-      tty->print(" | [destination=" INTPTR_FORMAT " cached_value=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
-                 p2i(r->destination()), p2i(r->cached_value()), p2i(r->method_value()));
+      st->print(" | [destination=" INTPTR_FORMAT " cached_value=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
+                p2i(r->destination()), p2i(r->cached_value()), p2i(r->method_value()));
+      CodeBlob* cb = CodeCache::find_blob(r->destination());
+      if (cb != nullptr) {
+        st->print(" Blob::%s", cb->name());
+      }
       break;
     }
   case relocInfo::static_stub_type:
     {
       static_stub_Relocation* r = (static_stub_Relocation*) reloc();
-      tty->print(" | [static_call=" INTPTR_FORMAT "]", p2i(r->static_call()));
+      st->print(" | [static_call=" INTPTR_FORMAT "]", p2i(r->static_call()));
       break;
     }
   case relocInfo::trampoline_stub_type:
     {
       trampoline_stub_Relocation* r = (trampoline_stub_Relocation*) reloc();
-      tty->print(" | [trampoline owner=" INTPTR_FORMAT "]", p2i(r->owner()));
+      st->print(" | [trampoline owner=" INTPTR_FORMAT "]", p2i(r->owner()));
       break;
     }
   case relocInfo::opt_virtual_call_type:
     {
       opt_virtual_call_Relocation* r = (opt_virtual_call_Relocation*) reloc();
-      tty->print(" | [destination=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
+      st->print(" | [destination=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
                  p2i(r->destination()), p2i(r->method_value()));
+      CodeBlob* cb = CodeCache::find_blob(r->destination());
+      if (cb != nullptr) {
+        st->print(" Blob::%s", cb->name());
+      }
       break;
     }
   default:
     break;
   }
-  tty->cr();
+  st->cr();
 }
 
 
-void RelocIterator::print() {
+void RelocIterator::print_on(outputStream* st) {
   RelocIterator save_this = (*this);
   relocInfo* scan = _current;
   if (!has_current())  scan += 1;  // nothing to scan here!
 
   bool skip_next = has_current();
   bool got_next;
   while (true) {
     got_next = (skip_next || next());
     skip_next = false;
 
-    tty->print("         @" INTPTR_FORMAT ": ", p2i(scan));
+    st->print("         @" INTPTR_FORMAT ": ", p2i(scan));
     relocInfo* newscan = _current+1;
     if (!has_current())  newscan -= 1;  // nothing to scan here!
     while (scan < newscan) {
-      tty->print("%04x", *(short*)scan & 0xFFFF);
+      st->print("%04x", *(short*)scan & 0xFFFF);
       scan++;
     }
-    tty->cr();
+    st->cr();
 
     if (!got_next)  break;
-    print_current();
+    print_current_on(st);
   }
 
   (*this) = save_this;
 }
 
+//---------------------------------------------------------------------------------
+// Non-product code
+
+#ifndef PRODUCT
+
 // For the debugger:
 extern "C"
 void print_blob_locs(nmethod* nm) {
   nm->print();
   RelocIterator iter(nm);
-  iter.print();
+  iter.print_on(tty);
 }
 extern "C"
 void print_buf_locs(CodeBuffer* cb) {
   FlagSetting fs(PrintRelocations, true);
-  cb->print();
+  cb->print_on(tty);
 }
 #endif // !PRODUCT
