diff a/src/hotspot/share/oops/methodData.hpp b/src/hotspot/share/oops/methodData.hpp
--- a/src/hotspot/share/oops/methodData.hpp
+++ b/src/hotspot/share/oops/methodData.hpp
@@ -27,11 +27,10 @@
 
 #include "interpreter/bytecodes.hpp"
 #include "interpreter/invocationCounter.hpp"
 #include "oops/metadata.hpp"
 #include "oops/method.hpp"
-#include "oops/oop.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/deoptimization.hpp"
 #include "runtime/mutex.hpp"
 #include "utilities/align.hpp"
 #include "utilities/copy.hpp"
@@ -201,10 +200,13 @@
   }
   void release_set_cell_at(int index, intptr_t value);
   intptr_t cell_at(int index) const {
     return _cells[index];
   }
+  intptr_t* cell_at_adr(int index) const {
+    return const_cast<intptr_t*>(&_cells[index]);
+  }
 
   bool set_flag_at(u1 flag_number) {
     const u1 bit = 1 << flag_number;
     u1 compare_value;
     do {
@@ -344,10 +346,14 @@
   void release_set_intptr_at(int index, intptr_t value);
   intptr_t intptr_at(int index) const {
     assert(0 <= index && index < cell_count(), "oob");
     return data()->cell_at(index);
   }
+  intptr_t* intptr_at_adr(int index) const {
+    assert(0 <= index && index < cell_count(), "oob");
+    return data()->cell_at_adr(index);
+  }
   void set_uint_at(int index, uint value) {
     set_intptr_at(index, (intptr_t) value);
   }
   void release_set_uint_at(int index, uint value);
   uint uint_at(int index) const {
@@ -361,16 +367,10 @@
     return (int)intptr_at(index);
   }
   int int_at_unchecked(int index) const {
     return (int)data()->cell_at(index);
   }
-  void set_oop_at(int index, oop value) {
-    set_intptr_at(index, cast_from_oop<intptr_t>(value));
-  }
-  oop oop_at(int index) const {
-    return cast_to_oop(intptr_at(index));
-  }
 
   void set_flag_at(u1 flag_number) {
     data()->set_flag_at(flag_number);
   }
   bool flag_at(u1 flag_number) const {
@@ -487,11 +487,14 @@
   virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {}
 
   // GC support
   virtual void clean_weak_klass_links(bool always_clean) {}
 
-  // CI translation: ProfileData can represent both MethodDataOop data
+  // CDS support
+  virtual void metaspace_pointers_do(MetaspaceClosure* it) {}
+
+    // CI translation: ProfileData can represent both MethodDataOop data
   // as well as CIMethodData data. This function is provided for translating
   // an oop in a ProfileData to the ci equivalent. Generally speaking,
   // most ProfileData don't require any translation, so we provide the null
   // translation here, and the required translators are in the ci subclasses.
   virtual void translate_from(const ProfileData* data) {}
@@ -852,10 +855,15 @@
   intptr_t type(int i) const {
     assert(i >= 0 && i < _number_of_entries, "oob");
     return _pd->intptr_at(type_offset_in_cells(i));
   }
 
+  intptr_t* type_adr(int i) const {
+    assert(i >= 0 && i < _number_of_entries, "oob");
+    return _pd->intptr_at_adr(type_offset_in_cells(i));
+  }
+
   // set type for entry i
   void set_type(int i, intptr_t k) {
     assert(i >= 0 && i < _number_of_entries, "oob");
     _pd->set_intptr_at(type_offset_in_cells(i), k);
   }
@@ -873,10 +881,13 @@
   }
 
   // GC support
   void clean_weak_klass_links(bool always_clean);
 
+  // CDS support
+  virtual void metaspace_pointers_do(MetaspaceClosure* it);
+
   void print_data_on(outputStream* st) const;
 };
 
 // Type entry used for return from a call. A single cell to record the
 // type.
@@ -897,10 +908,14 @@
 
   intptr_t type() const {
     return _pd->intptr_at(_base_off);
   }
 
+  intptr_t* type_adr() const {
+    return _pd->intptr_at_adr(_base_off);
+  }
+
   void set_type(intptr_t k) {
     _pd->set_intptr_at(_base_off, k);
   }
 
   static int static_cell_count() {
@@ -916,10 +931,13 @@
   }
 
   // GC support
   void clean_weak_klass_links(bool always_clean);
 
+  // CDS support
+  virtual void metaspace_pointers_do(MetaspaceClosure* it);
+
   void print_data_on(outputStream* st) const;
 };
 
 // Entries to collect type information at a call: contains arguments
 // (TypeStackSlotEntries), a return type (ReturnTypeEntry) and a
@@ -1107,10 +1125,20 @@
     if (has_return()) {
       _ret.clean_weak_klass_links(always_clean);
     }
   }
 
+  // CDS support
+  virtual void metaspace_pointers_do(MetaspaceClosure* it) {
+    if (has_arguments()) {
+      _args.metaspace_pointers_do(it);
+    }
+    if (has_return()) {
+      _ret.metaspace_pointers_do(it);
+    }
+  }
+
   virtual void print_data_on(outputStream* st, const char* extra = nullptr) const;
 };
 
 // ReceiverTypeData
 //
@@ -1217,10 +1245,13 @@
   }
 
   // GC support
   virtual void clean_weak_klass_links(bool always_clean);
 
+  // CDS support
+  virtual void metaspace_pointers_do(MetaspaceClosure* it);
+
   void print_receiver_data_on(outputStream* st) const;
   void print_data_on(outputStream* st, const char* extra = nullptr) const;
 };
 
 // VirtualCallData
@@ -1382,10 +1413,21 @@
     if (has_return()) {
       _ret.clean_weak_klass_links(always_clean);
     }
   }
 
+  // CDS support
+  virtual void metaspace_pointers_do(MetaspaceClosure* it) {
+    ReceiverTypeData::metaspace_pointers_do(it);
+    if (has_arguments()) {
+      _args.metaspace_pointers_do(it);
+    }
+    if (has_return()) {
+      _ret.metaspace_pointers_do(it);
+    }
+  }
+
   virtual void print_data_on(outputStream* st, const char* extra = nullptr) const;
 };
 
 // RetData
 //
@@ -1565,14 +1607,10 @@
   }
   int array_int_at(int index) const {
     int aindex = index + array_start_off_set;
     return int_at(aindex);
   }
-  oop array_oop_at(int index) const {
-    int aindex = index + array_start_off_set;
-    return oop_at(aindex);
-  }
   void array_set_int_at(int index, int value) {
     int aindex = index + array_start_off_set;
     set_int_at(aindex, value);
   }
 
@@ -1781,10 +1819,15 @@
 
   virtual void clean_weak_klass_links(bool always_clean) {
     _parameters.clean_weak_klass_links(always_clean);
   }
 
+  // CDS support
+  virtual void metaspace_pointers_do(MetaspaceClosure* it) {
+    _parameters.metaspace_pointers_do(it);
+  }
+
   virtual void print_data_on(outputStream* st, const char* extra = nullptr) const;
 
   static ByteSize stack_slot_offset(int i) {
     return cell_offset(stack_slot_local_offset(i));
   }
@@ -1851,10 +1894,13 @@
 
   static ByteSize method_offset() {
     return cell_offset(speculative_trap_method);
   }
 
+  // CDS support
+  virtual void metaspace_pointers_do(MetaspaceClosure* it);
+
   virtual void print_data_on(outputStream* st, const char* extra = nullptr) const;
 };
 
 // MethodData*
 //
@@ -1960,14 +2006,16 @@
   int _size;
 
   // Cached hint for bci_to_dp and bci_to_data
   int _hint_di;
 
-  Mutex _extra_data_lock;
+  Mutex* volatile _extra_data_lock; // FIXME: CDS support
 
   MethodData(const methodHandle& method);
 public:
+  MethodData();
+
   static MethodData* allocate(ClassLoaderData* loader_data, const methodHandle& method, TRAPS);
 
   virtual bool is_methodData() const { return true; }
   void initialize();
 
@@ -1984,18 +2032,19 @@
     friend class JVMCIVMStructs;
 
     uint _nof_decompiles;             // count of all nmethod removals
     uint _nof_overflow_recompiles;    // recompile count, excluding recomp. bits
     uint _nof_overflow_traps;         // trap count, excluding _trap_hist
+    uint __gap;
     union {
       intptr_t _align;
       // JVMCI separates trap history for OSR compilations from normal compilations
       u1 _array[JVMCI_ONLY(2 *) MethodData::_trap_hist_limit];
     } _trap_hist;
 
   public:
-    CompilerCounters() : _nof_decompiles(0), _nof_overflow_recompiles(0), _nof_overflow_traps(0) {
+    CompilerCounters() : _nof_decompiles(0), _nof_overflow_recompiles(0), _nof_overflow_traps(0), __gap(0) {
 #ifndef ZERO
       // Some Zero platforms do not have expected alignment, and do not use
       // this code. static_assert would still fire and fail for them.
       static_assert(sizeof(_trap_hist) % HeapWordSize == 0, "align");
 #endif
@@ -2262,10 +2311,15 @@
   FailedSpeculation** get_failed_speculations_address() {
     return &_failed_speculations;
   }
 #endif
 
+#if INCLUDE_CDS
+  void remove_unshareable_info();
+  void restore_unshareable_info(TRAPS);
+#endif
+
   void set_would_profile(bool p)              { _would_profile = p ? profile : no_profile; }
   bool would_profile() const                  { return _would_profile != no_profile; }
 
   int num_loops() const                       { return _num_loops;  }
   void set_num_loops(short n)                 { _num_loops = n;     }
@@ -2501,10 +2555,10 @@
   static bool profile_parameters();
   static bool profile_return_jsr292_only();
 
   void clean_method_data(bool always_clean);
   void clean_weak_method_links();
-  Mutex* extra_data_lock() { return &_extra_data_lock; }
+  Mutex* extra_data_lock();
   void check_extra_data_locked() const NOT_DEBUG_RETURN;
 };
 
 #endif // SHARE_OOPS_METHODDATA_HPP
