changeset 46324:8764956ec928

8005165: Remove CPU-dependent code in self-patching vtables Reviewed-by: coleenp, stuefe, jiangli
author iklam
date Fri, 03 Mar 2017 23:08:35 -0800
parents d41bb2dcaeb8
children 0fa9327949f8
files hotspot/src/cpu/aarch64/vm/metaspaceShared_aarch64.cpp hotspot/src/cpu/arm/vm/metaspaceShared_arm.cpp hotspot/src/cpu/ppc/vm/metaspaceShared_ppc.cpp hotspot/src/cpu/s390/vm/metaspaceShared_s390.cpp hotspot/src/cpu/sparc/vm/metaspaceShared_sparc.cpp hotspot/src/cpu/x86/vm/metaspaceShared_x86_32.cpp hotspot/src/cpu/x86/vm/metaspaceShared_x86_64.cpp hotspot/src/cpu/zero/vm/metaspaceShared_zero.cpp hotspot/src/share/vm/classfile/systemDictionary.cpp hotspot/src/share/vm/memory/metaspace.cpp hotspot/src/share/vm/memory/metaspace.hpp hotspot/src/share/vm/memory/metaspaceShared.cpp hotspot/src/share/vm/memory/metaspaceShared.hpp hotspot/src/share/vm/memory/universe.cpp hotspot/src/share/vm/memory/universe.hpp hotspot/src/share/vm/oops/constantPool.cpp hotspot/src/share/vm/oops/constantPool.hpp hotspot/src/share/vm/oops/klass.cpp hotspot/src/share/vm/oops/method.cpp hotspot/src/share/vm/oops/method.hpp
diffstat 20 files changed, 268 insertions(+), 945 deletions(-) [+]
line wrap: on
line diff
--- a/hotspot/src/cpu/aarch64/vm/metaspaceShared_aarch64.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "asm/macroAssembler.hpp"
-#include "memory/metaspaceShared.hpp"
-
-// Generate the self-patching vtable method:
-//
-// This method will be called (as any other Klass virtual method) with
-// the Klass itself as the first argument.  Example:
-//
-//      oop obj;
-//      int size = obj->klass()->oop_size(this);
-//
-// for which the virtual method call is Klass::oop_size();
-//
-// The dummy method is called with the Klass object as the first
-// operand, and an object as the second argument.
-//
-
-//=====================================================================
-
-// All of the dummy methods in the vtable are essentially identical,
-// differing only by an ordinal constant, and they bear no relationship
-// to the original method which the caller intended. Also, there needs
-// to be 'vtbl_list_size' instances of the vtable in order to
-// differentiate between the 'vtable_list_size' original Klass objects.
-
-#define __ masm->
-
-extern "C" {
-  void aarch64_prolog(void);
-}
-
-void MetaspaceShared::generate_vtable_methods(void** vtbl_list,
-                                                   void** vtable,
-                                                   char** md_top,
-                                                   char* md_end,
-                                                   char** mc_top,
-                                                   char* mc_end) {
-
-#ifdef BUILTIN_SIM
-  // Write a dummy word to the writable shared metaspace.
-  // MetaspaceShared::initialize_shared_spaces will fill it with the
-  // address of aarch64_prolog().
-  address *prolog_ptr = (address*)*md_top;
-  *(intptr_t *)(*md_top) = (intptr_t)0;
-  (*md_top) += sizeof(intptr_t);
-#endif
-
-  intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*);
-  *(intptr_t *)(*md_top) = vtable_bytes;
-  *md_top += sizeof(intptr_t);
-  void** dummy_vtable = (void**)*md_top;
-  *vtable = dummy_vtable;
-  *md_top += vtable_bytes;
-
-  // Get ready to generate dummy methods.
-
-  CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
-  MacroAssembler* masm = new MacroAssembler(&cb);
-
-  Label common_code;
-  for (int i = 0; i < vtbl_list_size; ++i) {
-    for (int j = 0; j < num_virtuals; ++j) {
-      dummy_vtable[num_virtuals * i + j] = (void*)masm->pc();
-
-      // We're called directly from C code.
-#ifdef BUILTIN_SIM
-      __ c_stub_prolog(8, 0, MacroAssembler::ret_type_integral, prolog_ptr);
-#endif
-      // Load rscratch1 with a value indicating vtable/offset pair.
-      // -- bits[ 7..0]  (8 bits) which virtual method in table?
-      // -- bits[12..8]  (5 bits) which virtual method table?
-      __ mov(rscratch1, (i << 8) + j);
-      __ b(common_code);
-    }
-  }
-
-  __ bind(common_code);
-
-  Register tmp0 = r10, tmp1 = r11;       // AAPCS64 temporary registers
-  __ enter();
-  __ lsr(tmp0, rscratch1, 8);            // isolate vtable identifier.
-  __ mov(tmp1, (address)vtbl_list);      // address of list of vtable pointers.
-  __ ldr(tmp1, Address(tmp1, tmp0, Address::lsl(LogBytesPerWord))); // get correct vtable pointer.
-  __ str(tmp1, Address(c_rarg0));        // update vtable pointer in obj.
-  __ add(rscratch1, tmp1, rscratch1, ext::uxtb, LogBytesPerWord); // address of real method pointer.
-  __ ldr(rscratch1, Address(rscratch1)); // get real method pointer.
-  __ blrt(rscratch1, 8, 0, 1);           // jump to the real method.
-  __ leave();
-  __ ret(lr);
-
-  *mc_top = (char*)__ pc();
-}
-
-#ifdef BUILTIN_SIM
-void MetaspaceShared::relocate_vtbl_list(char **buffer) {
-  void **sim_entry = (void**)*buffer;
-  *sim_entry = (void*)aarch64_prolog;
-  *buffer += sizeof(intptr_t);
-}
-#endif
--- a/hotspot/src/cpu/arm/vm/metaspaceShared_arm.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "asm/macroAssembler.hpp"
-#include "assembler_arm.inline.hpp"
-#include "memory/metaspaceShared.hpp"
-
-// Generate the self-patching vtable method:
-//
-// This method will be called (as any other Klass virtual method) with
-// the Klass itself as the first argument.  Example:
-//
-//      oop obj;
-//      int size = obj->klass()->oop_size(this);
-//
-// for which the virtual method call is Klass::oop_size();
-//
-// The dummy method is called with the Klass object as the first
-// operand, and an object as the second argument.
-//
-
-//=====================================================================
-
-// All of the dummy methods in the vtable are essentially identical,
-// differing only by an ordinal constant, and they bear no relationship
-// to the original method which the caller intended. Also, there needs
-// to be 'vtbl_list_size' instances of the vtable in order to
-// differentiate between the 'vtable_list_size' original Klass objects.
-
-#define __ masm->
-
-void MetaspaceShared::generate_vtable_methods(void** vtbl_list,
-                                                   void** vtable,
-                                                   char** md_top,
-                                                   char* md_end,
-                                                   char** mc_top,
-                                                   char* mc_end) {
-  intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*);
-  *(intptr_t *)(*md_top) = vtable_bytes;
-  *md_top += sizeof(intptr_t);
-  void** dummy_vtable = (void**)*md_top;
-  *vtable = dummy_vtable;
-  *md_top += vtable_bytes;
-
-  CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
-  MacroAssembler* masm = new MacroAssembler(&cb);
-
-  for (int i = 0; i < vtbl_list_size; ++i) {
-    Label common_code;
-    for (int j = 0; j < num_virtuals; ++j) {
-      dummy_vtable[num_virtuals * i + j] = (void*) __ pc();
-      __ mov(Rtemp, j);  // Rtemp contains an index of a virtual method in the table
-      __ b(common_code);
-    }
-
-    InlinedAddress vtable_address((address)&vtbl_list[i]);
-    __ bind(common_code);
-    const Register tmp2 = AARCH64_ONLY(Rtemp2) NOT_AARCH64(R4);
-    assert_different_registers(Rtemp, tmp2);
-#ifndef AARCH64
-    __ push(tmp2);
-#endif // !AARCH64
-    // Do not use ldr_global since the code must be portable across all ARM architectures
-    __ ldr_literal(tmp2, vtable_address);
-    __ ldr(tmp2, Address(tmp2));                              // get correct vtable address
-    __ ldr(Rtemp, Address::indexed_ptr(tmp2, Rtemp));         // get real method pointer
-    __ str(tmp2, Address(R0));                                // update vtable. R0 = "this"
-#ifndef AARCH64
-    __ pop(tmp2);
-#endif // !AARCH64
-    __ jump(Rtemp);
-    __ bind_literal(vtable_address);
-  }
-
-  __ flush();
-  *mc_top = (char*) __ pc();
-}
--- a/hotspot/src/cpu/ppc/vm/metaspaceShared_ppc.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2013 SAP SE. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "asm/macroAssembler.inline.hpp"
-#include "asm/codeBuffer.hpp"
-#include "memory/metaspaceShared.hpp"
-
-// Generate the self-patching vtable method:
-//
-// This method will be called (as any other Klass virtual method) with
-// the Klass itself as the first argument.  Example:
-//
-//   oop obj;
-//   int size = obj->klass()->klass_part()->oop_size(this);
-//
-// for which the virtual method call is Klass::oop_size();
-//
-// The dummy method is called with the Klass object as the first
-// operand, and an object as the second argument.
-//
-
-//=====================================================================
-
-// All of the dummy methods in the vtable are essentially identical,
-// differing only by an ordinal constant, and they bear no releationship
-// to the original method which the caller intended. Also, there needs
-// to be 'vtbl_list_size' instances of the vtable in order to
-// differentiate between the 'vtable_list_size' original Klass objects.
-
-#define __ masm->
-
-void MetaspaceShared::generate_vtable_methods(void** vtbl_list,
-                                              void** vtable,
-                                              char** md_top,
-                                              char* md_end,
-                                              char** mc_top,
-                                              char* mc_end) {
-  intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*);
-  *(intptr_t *)(*md_top) = vtable_bytes;
-  *md_top += sizeof(intptr_t);
-  void** dummy_vtable = (void**)*md_top;
-  *vtable = dummy_vtable;
-  *md_top += vtable_bytes;
-
-  // Get ready to generate dummy methods.
-
-  CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
-  MacroAssembler* masm = new MacroAssembler(&cb);
-
-  // There are more general problems with CDS on ppc, so I can not
-  // really test this. But having this instead of Unimplementd() allows
-  // us to pass TestOptionsWithRanges.java.
-  __ unimplemented();
-}
-
--- a/hotspot/src/cpu/s390/vm/metaspaceShared_s390.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016 SAP SE. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "asm/codeBuffer.hpp"
-#include "asm/macroAssembler.inline.hpp"
-#include "memory/metaspaceShared.hpp"
-
-// Generate the self-patching vtable method:
-//
-// This method will be called (as any other Klass virtual method) with
-// the Klass itself as the first argument. Example:
-//
-//   oop obj;
-//   int size = obj->klass()->klass_part()->oop_size(this);
-//
-// for which the virtual method call is Klass::oop_size();.
-//
-// The dummy method is called with the Klass object as the first
-// operand, and an object as the second argument.
-//
-
-//=====================================================================
-
-// All of the dummy methods in the vtable are essentially identical,
-// differing only by an ordinal constant, and they bear no releationship
-// to the original method which the caller intended. Also, there needs
-// to be 'vtbl_list_size' instances of the vtable in order to
-// differentiate between the 'vtable_list_size' original Klass objects.
-
-#undef __
-#define __ masm->
-
-void MetaspaceShared::generate_vtable_methods(void** vtbl_list,
-                                              void** vtable,
-                                              char** md_top,
-                                              char* md_end,
-                                              char** mc_top,
-                                              char* mc_end) {
-
-  intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*);
-  *(intptr_t *)(*md_top) = vtable_bytes;
-  *md_top += sizeof(intptr_t);
-  void** dummy_vtable = (void**)*md_top;
-  *vtable = dummy_vtable;
-  *md_top += vtable_bytes;
-
-  // Get ready to generate dummy methods.
-
-  CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
-  MacroAssembler* masm = new MacroAssembler(&cb);
-
-  __ unimplemented();
-}
--- a/hotspot/src/cpu/sparc/vm/metaspaceShared_sparc.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "asm/macroAssembler.inline.hpp"
-#include "asm/codeBuffer.hpp"
-#include "memory/metaspaceShared.hpp"
-
-// Generate the self-patching vtable method:
-//
-// This method will be called (as any other Klass virtual method) with
-// the Klass itself as the first argument.  Example:
-//
-//      oop obj;
-//      int size = obj->klass()->oop_size(this);
-//
-// for which the virtual method call is Klass::oop_size();
-//
-// The dummy method is called with the Klass object as the first
-// operand, and an object as the second argument.
-//
-
-//=====================================================================
-
-// All of the dummy methods in the vtable are essentially identical,
-// differing only by an ordinal constant, and they bear no relationship
-// to the original method which the caller intended. Also, there needs
-// to be 'vtbl_list_size' instances of the vtable in order to
-// differentiate between the 'vtable_list_size' original Klass objects.
-
-#define __ masm->
-
-void MetaspaceShared::generate_vtable_methods(void** vtbl_list,
-                                                   void** vtable,
-                                                   char** md_top,
-                                                   char* md_end,
-                                                   char** mc_top,
-                                                   char* mc_end) {
-
-  intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*);
-  *(intptr_t *)(*md_top) = vtable_bytes;
-  *md_top += sizeof(intptr_t);
-  void** dummy_vtable = (void**)*md_top;
-  *vtable = dummy_vtable;
-  *md_top += vtable_bytes;
-
-  // Get ready to generate dummy methods.
-
-  CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
-  MacroAssembler* masm = new MacroAssembler(&cb);
-
-  Label common_code;
-  for (int i = 0; i < vtbl_list_size; ++i) {
-    for (int j = 0; j < num_virtuals; ++j) {
-      dummy_vtable[num_virtuals * i + j] = (void*)masm->pc();
-      __ save(SP, -256, SP);
-      int offset = (i << 8) + j;
-      Register src = G0;
-      if (!Assembler::is_simm13(offset)) {
-        __ sethi(offset, L0);
-        src = L0;
-        offset = offset & ((1 << 10) - 1);
-      }
-      __ brx(Assembler::always, false, Assembler::pt, common_code);
-
-      // Load L0 with a value indicating vtable/offset pair.
-      // -- bits[ 7..0]  (8 bits) which virtual method in table?
-      // -- bits[13..8]  (6 bits) which virtual method table?
-      __ delayed()->or3(src, offset, L0);
-    }
-  }
-
-  __ bind(common_code);
-
-  // Expecting to be called with the "this" pointer in O0/I0 (where
-  // "this" is a Klass object).  In addition, L0 was set (above) to
-  // identify the method and table.
-
-  // Look up the correct vtable pointer.
-
-  __ set((intptr_t)vtbl_list, L2);      // L2 = address of new vtable list.
-  __ srl(L0, 8, L3);                    // Isolate L3 = vtable identifier.
-  __ sll(L3, LogBytesPerWord, L3);
-  __ ld_ptr(L2, L3, L3);                // L3 = new (correct) vtable pointer.
-  __ st_ptr(L3, Address(I0, 0));        // Save correct vtable ptr in entry.
-
-  // Restore registers and jump to the correct method;
-
-  __ and3(L0, 255, L4);                 // Isolate L3 = method offset;.
-  __ sll(L4, LogBytesPerWord, L4);
-  __ ld_ptr(L3, L4, L4);                // Get address of correct virtual method
-  __ jmpl(L4, 0, G0);                   // Jump to correct method.
-  __ delayed()->restore();              // Restore registers.
-
-  __ flush();
-  *mc_top = (char*)__ pc();
-
-  guarantee(*mc_top <= mc_end, "Insufficient space for method wrappers.");
-}
--- a/hotspot/src/cpu/x86/vm/metaspaceShared_x86_32.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "asm/macroAssembler.hpp"
-#include "asm/codeBuffer.hpp"
-#include "memory/metaspaceShared.hpp"
-
-// Generate the self-patching vtable method:
-//
-// This method will be called (as any other Klass virtual method) with
-// the Klass itself as the first argument.  Example:
-//
-//      oop obj;
-//      int size = obj->klass()->oop_size(this);
-//
-// for which the virtual method call is Klass::oop_size();
-//
-// The dummy method is called with the Klass object as the first
-// operand, and an object as the second argument.
-//
-
-//=====================================================================
-
-// All of the dummy methods in the vtable are essentially identical,
-// differing only by an ordinal constant, and they bear no relationship
-// to the original method which the caller intended. Also, there needs
-// to be 'vtbl_list_size' instances of the vtable in order to
-// differentiate between the 'vtable_list_size' original Klass objects.
-
-#define __ masm->
-
-void MetaspaceShared::generate_vtable_methods(void** vtbl_list,
-                                                   void** vtable,
-                                                   char** md_top,
-                                                   char* md_end,
-                                                   char** mc_top,
-                                                   char* mc_end) {
-
-  intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*);
-  *(intptr_t *)(*md_top) = vtable_bytes;
-  *md_top += sizeof(intptr_t);
-  void** dummy_vtable = (void**)*md_top;
-  *vtable = dummy_vtable;
-  *md_top += vtable_bytes;
-
-  // Get ready to generate dummy methods.
-
-  CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
-  MacroAssembler* masm = new MacroAssembler(&cb);
-
-  Label common_code;
-  for (int i = 0; i < vtbl_list_size; ++i) {
-    for (int j = 0; j < num_virtuals; ++j) {
-      dummy_vtable[num_virtuals * i + j] = (void*)masm->pc();
-
-      // Load rax, with a value indicating vtable/offset pair.
-      // -- bits[ 7..0]  (8 bits) which virtual method in table?
-      // -- bits[12..8]  (5 bits) which virtual method table?
-      // -- must fit in 13-bit instruction immediate field.
-      __ movl(rax, (i << 8) + j);
-      __ jmp(common_code);
-    }
-  }
-
-  __ bind(common_code);
-
-#ifdef WIN32
-  // Expecting to be called with "thiscall" conventions -- the arguments
-  // are on the stack, except that the "this" pointer is in rcx.
-#else
-  // Expecting to be called with Unix conventions -- the arguments
-  // are on the stack, including the "this" pointer.
-#endif
-
-  // In addition, rax was set (above) to the offset of the method in the
-  // table.
-
-#ifdef WIN32
-  __ push(rcx);                         // save "this"
-#endif
-  __ mov(rcx, rax);
-  __ shrptr(rcx, 8);                    // isolate vtable identifier.
-  __ shlptr(rcx, LogBytesPerWord);
-  Address index(noreg, rcx,  Address::times_1);
-  ExternalAddress vtbl((address)vtbl_list);
-  __ movptr(rdx, ArrayAddress(vtbl, index)); // get correct vtable address.
-#ifdef WIN32
-  __ pop(rcx);                          // restore "this"
-#else
-  __ movptr(rcx, Address(rsp, BytesPerWord));   // fetch "this"
-#endif
-  __ movptr(Address(rcx, 0), rdx);      // update vtable pointer.
-
-  __ andptr(rax, 0x00ff);                       // isolate vtable method index
-  __ shlptr(rax, LogBytesPerWord);
-  __ addptr(rax, rdx);                  // address of real method pointer.
-  __ jmp(Address(rax, 0));              // get real method pointer.
-
-  __ flush();
-
-  *mc_top = (char*)__ pc();
-}
--- a/hotspot/src/cpu/x86/vm/metaspaceShared_x86_64.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "asm/macroAssembler.hpp"
-#include "asm/codeBuffer.hpp"
-#include "memory/metaspaceShared.hpp"
-
-// Generate the self-patching vtable method:
-//
-// This method will be called (as any other Klass virtual method) with
-// the Klass itself as the first argument.  Example:
-//
-//      oop obj;
-//      int size = obj->klass()->oop_size(this);
-//
-// for which the virtual method call is Klass::oop_size();
-//
-// The dummy method is called with the Klass object as the first
-// operand, and an object as the second argument.
-//
-
-//=====================================================================
-
-// All of the dummy methods in the vtable are essentially identical,
-// differing only by an ordinal constant, and they bear no relationship
-// to the original method which the caller intended. Also, there needs
-// to be 'vtbl_list_size' instances of the vtable in order to
-// differentiate between the 'vtable_list_size' original Klass objects.
-
-#define __ masm->
-
-void MetaspaceShared::generate_vtable_methods(void** vtbl_list,
-                                                   void** vtable,
-                                                   char** md_top,
-                                                   char* md_end,
-                                                   char** mc_top,
-                                                   char* mc_end) {
-
-  intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*);
-  *(intptr_t *)(*md_top) = vtable_bytes;
-  *md_top += sizeof(intptr_t);
-  void** dummy_vtable = (void**)*md_top;
-  *vtable = dummy_vtable;
-  *md_top += vtable_bytes;
-
-  // Get ready to generate dummy methods.
-
-  CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
-  MacroAssembler* masm = new MacroAssembler(&cb);
-
-  Label common_code;
-  for (int i = 0; i < vtbl_list_size; ++i) {
-    for (int j = 0; j < num_virtuals; ++j) {
-      dummy_vtable[num_virtuals * i + j] = (void*)masm->pc();
-
-      // Load eax with a value indicating vtable/offset pair.
-      // -- bits[ 7..0]  (8 bits) which virtual method in table?
-      // -- bits[12..8]  (5 bits) which virtual method table?
-      // -- must fit in 13-bit instruction immediate field.
-      __ movl(rax, (i << 8) + j);
-      __ jmp(common_code);
-    }
-  }
-
-  __ bind(common_code);
-
-  // Expecting to be called with "thiscall" convections -- the arguments
-  // are on the stack and the "this" pointer is in c_rarg0. In addition, rax
-  // was set (above) to the offset of the method in the table.
-
-  __ push(c_rarg1);                     // save & free register
-  __ push(c_rarg0);                     // save "this"
-  __ mov(c_rarg0, rax);
-  __ shrptr(c_rarg0, 8);                // isolate vtable identifier.
-  __ shlptr(c_rarg0, LogBytesPerWord);
-  __ lea(c_rarg1, ExternalAddress((address)vtbl_list)); // ptr to correct vtable list.
-  __ addptr(c_rarg1, c_rarg0);          // ptr to list entry.
-  __ movptr(c_rarg1, Address(c_rarg1, 0));      // get correct vtable address.
-  __ pop(c_rarg0);                      // restore "this"
-  __ movptr(Address(c_rarg0, 0), c_rarg1);      // update vtable pointer.
-
-  __ andptr(rax, 0x00ff);                       // isolate vtable method index
-  __ shlptr(rax, LogBytesPerWord);
-  __ addptr(rax, c_rarg1);              // address of real method pointer.
-  __ pop(c_rarg1);                      // restore register.
-  __ movptr(rax, Address(rax, 0));      // get real method pointer.
-  __ jmp(rax);                          // jump to the real method.
-
-  __ flush();
-
-  *mc_top = (char*)__ pc();
-}
--- a/hotspot/src/cpu/zero/vm/metaspaceShared_zero.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "assembler_zero.inline.hpp"
-#include "memory/metaspaceShared.hpp"
-
-void MetaspaceShared::generate_vtable_methods(void** vtbl_list,
-                                                   void** vtable,
-                                                   char** md_top,
-                                                   char*  md_end,
-                                                   char** mc_top,
-                                                   char*  mc_end) {
-  ShouldNotCallThis();
-}
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1348,11 +1348,6 @@
     int num_interfaces = interfaces->length();
     for (int index = 0; index < num_interfaces; index++) {
       Klass* k = interfaces->at(index);
-
-      // Note: can not use InstanceKlass::cast here because
-      // interfaces' InstanceKlass's C++ vtbls haven't been
-      // reinitialized yet (they will be once the interface classes
-      // are loaded)
       Symbol*  name  = k->name();
       Klass* i = resolve_super_or_fail(class_name, name, class_loader, protection_domain, false, CHECK_(nh));
       if (k != i) {
--- a/hotspot/src/share/vm/memory/metaspace.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ b/hotspot/src/share/vm/memory/metaspace.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -3781,7 +3781,10 @@
   if (UseSharedSpaces && MetaspaceShared::is_in_shared_space(ptr)) {
     return true;
   }
-
+  return contains_non_shared(ptr);
+}
+
+bool Metaspace::contains_non_shared(const void* ptr) {
   if (using_class_space() && get_space_list(ClassType)->contains(ptr)) {
      return true;
   }
--- a/hotspot/src/share/vm/memory/metaspace.hpp	Fri Mar 10 12:58:37 2017 -0500
+++ b/hotspot/src/share/vm/memory/metaspace.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -243,6 +243,7 @@
   void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
 
   static bool contains(const void* ptr);
+  static bool contains_non_shared(const void* ptr);
 
   void dump(outputStream* const out) const;
 
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,8 +40,13 @@
 #include "memory/metaspace.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
+#include "oops/instanceClassLoaderKlass.hpp"
+#include "oops/instanceMirrorKlass.hpp"
+#include "oops/instanceRefKlass.hpp"
+#include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayKlass.hpp"
 #include "runtime/timerTrace.hpp"
 #include "runtime/os.hpp"
 #include "runtime/signature.hpp"
@@ -229,85 +234,244 @@
   }
 }
 
-// Patch C++ vtable pointer in metadata.
+// Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables.
+// (In GCC this is the field <Type>::_vptr, i.e., first word in the object.)
+//
+// Addresses of the vtables and the methods may be different across JVM runs,
+// if libjvm.so is dynamically loaded at a different base address.
+//
+// To ensure that the Metadata objects in the CDS archive always have the correct vtable:
+//
+// + at dump time:  we redirect the _vptr to point to our own vtables inside
+//                  the CDS image
+// + at run time:   we clone the actual contents of the vtables from libjvm.so
+//                  into our own tables.
 
-// Klass and other metadata objects contain references to c++ vtables in the
-// JVM library.
-// Fix them to point to our constructed vtables.  However, don't iterate
-// across the space while doing this, as that causes the vtables to be
-// patched, undoing our useful work.  Instead, iterate to make a list,
-// then use the list to do the fixing.
+// Currently, the archive contain ONLY the following types of objects that have C++ vtables.
+#define CPP_VTABLE_PATCH_TYPES_DO(f) \
+  f(ConstantPool) \
+  f(InstanceKlass) \
+  f(InstanceClassLoaderKlass) \
+  f(InstanceMirrorKlass) \
+  f(InstanceRefKlass) \
+  f(Method) \
+  f(ObjArrayKlass) \
+  f(TypeArrayKlass)
+
+class CppVtableInfo {
+  intptr_t _vtable_size;
+  intptr_t _cloned_vtable[1];
+public:
+  static int num_slots(int vtable_size) {
+    return 1 + vtable_size; // Need to add the space occupied by _vtable_size;
+  }
+  int vtable_size()           { return int(uintx(_vtable_size)); }
+  void set_vtable_size(int n) { _vtable_size = intptr_t(n); }
+  intptr_t* cloned_vtable()   { return &_cloned_vtable[0]; }
+  void zero()                 { memset(_cloned_vtable, 0, sizeof(intptr_t) * vtable_size()); }
+  // Returns the address of the next CppVtableInfo that can be placed immediately after this CppVtableInfo
+  intptr_t* next(int vtable_size) {
+    return &_cloned_vtable[vtable_size];
+  }
+};
+
+template <class T> class CppVtableCloner : public T {
+  static intptr_t* vtable_of(Metadata& m) {
+    return *((intptr_t**)&m);
+  }
+  static CppVtableInfo* _info;
+
+  static int get_vtable_length(const char* name);
+
+public:
+  // Allocate and initialize the C++ vtable, starting from top, but do not go past end.
+  static intptr_t* allocate(const char* name, intptr_t* top, intptr_t* end);
+
+  // Clone the vtable to ...
+  static intptr_t* clone_vtable(const char* name, CppVtableInfo* info);
+
+  static void zero_vtable_clone() {
+    assert(DumpSharedSpaces, "dump-time only");
+    _info->zero();
+  }
+
+  // Switch the vtable pointer to point to the cloned vtable.
+  static void patch(Metadata* obj) {
+    assert(DumpSharedSpaces, "dump-time only");
+    *(void**)obj = (void*)(_info->cloned_vtable());
+  }
+
+  static bool is_valid_shared_object(const T* obj) {
+    intptr_t* vptr = *(intptr_t**)obj;
+    return vptr == _info->cloned_vtable();
+  }
+};
+
+template <class T> CppVtableInfo* CppVtableCloner<T>::_info = NULL;
+
+template <class T>
+intptr_t* CppVtableCloner<T>::allocate(const char* name, intptr_t* top, intptr_t* end) {
+  int n = get_vtable_length(name);
+  _info = (CppVtableInfo*)top;
+  intptr_t* next = _info->next(n);
+
+  if (next > end) {
+    report_out_of_shared_space(SharedMiscData);
+  }
+  _info->set_vtable_size(n);
+
+  intptr_t* p = clone_vtable(name, _info);
+  assert(p == next, "must be");
+
+  return p;
+}
+
+template <class T>
+intptr_t* CppVtableCloner<T>::clone_vtable(const char* name, CppVtableInfo* info) {
+  if (!DumpSharedSpaces) {
+    assert(_info == 0, "_info is initialized only at dump time");
+    _info = info; // Remember it -- it will be used by MetaspaceShared::is_valid_shared_method()
+  }
+  T tmp; // Allocate temporary dummy metadata object to get to the original vtable.
+  int n = info->vtable_size();
+  intptr_t* srcvtable = vtable_of(tmp);
+  intptr_t* dstvtable = info->cloned_vtable();
+
+  // We already checked (and, if necessary, adjusted n) when the vtables were allocated, so we are
+  // safe to do memcpy.
+  if (PrintSharedSpaces) {
+    tty->print_cr("Copying %3d vtable entries for %s", n, name);
+  }
+  memcpy(dstvtable, srcvtable, sizeof(intptr_t) * n);
+  return dstvtable + n;
+}
+
+// To determine the size of the vtable for each type, we use the following
+// trick by declaring 2 subclasses:
 //
-// Our constructed vtables:
-// Dump time:
-//  1. init_self_patching_vtbl_list: table of pointers to current virtual method addrs
-//  2. generate_vtable_methods: create jump table, appended to above vtbl_list
-//  3. patch_klass_vtables: for Klass list, patch the vtable entry in klass and
-//     associated metadata to point to jump table rather than to current vtbl
-// Table layout: NOTE FIXED SIZE
-//   1. vtbl pointers
-//   2. #Klass X #virtual methods per Klass
-//   1 entry for each, in the order:
-//   Klass1:method1 entry, Klass1:method2 entry, ... Klass1:method<num_virtuals> entry
-//   Klass2:method1 entry, Klass2:method2 entry, ... Klass2:method<num_virtuals> entry
-//   ...
-//   Klass<vtbl_list_size>:method1 entry, Klass<vtbl_list_size>:method2 entry,
-//       ... Klass<vtbl_list_size>:method<num_virtuals> entry
-//  Sample entry: (Sparc):
-//   save(sp, -256, sp)
-//   ba,pt common_code
-//   mov XXX, %L0       %L0 gets: Klass index <<8 + method index (note: max method index 255)
+//   class CppVtableTesterA: public InstanceKlass {virtual int   last_virtual_method() {return 1;}    };
+//   class CppVtableTesterB: public InstanceKlass {virtual void* last_virtual_method() {return NULL}; };
 //
-// Restore time:
-//   1. initialize_shared_space: reserve space for table
-//   2. init_self_patching_vtbl_list: update pointers to NEW virtual method addrs in text
+// CppVtableTesterA and CppVtableTesterB's vtables have the following properties:
+// - Their size (N+1) is exactly one more than the size of InstanceKlass's vtable (N)
+// - The first N entries have are exactly the same as in InstanceKlass's vtable.
+// - Their last entry is different.
 //
-// Execution time:
-//   First virtual method call for any object of these metadata types:
-//   1. object->klass
-//   2. vtable entry for that klass points to the jump table entries
-//   3. branches to common_code with %O0/klass, %L0: Klass index <<8 + method index
-//   4. common_code:
-//      Get address of new vtbl pointer for this Klass from updated table
-//      Update new vtbl pointer in the Klass: future virtual calls go direct
-//      Jump to method, using new vtbl pointer and method index
+// So to determine the value of N, we just walk CppVtableTesterA and CppVtableTesterB's tables
+// and find the first entry that's different.
+//
+// This works on all C++ compilers supported by Oracle, but you may need to tweak it for more
+// esoteric compilers.
 
+template <class T> class CppVtableTesterB: public T {
+public:
+  virtual int last_virtual_method() {return 1;}
+};
 
-static void* find_matching_vtbl_ptr(void** vtbl_list, void* new_vtable_start, void* obj) {
-  void* old_vtbl_ptr = *(void**)obj;
-  for (int i = 0; i < MetaspaceShared::vtbl_list_size; i++) {
-    if (vtbl_list[i] == old_vtbl_ptr) {
-      return (void**)new_vtable_start + i * MetaspaceShared::num_virtuals;
+template <class T> class CppVtableTesterA : public T {
+public:
+  virtual void* last_virtual_method() {
+    // Make this different than CppVtableTesterB::last_virtual_method so the C++
+    // compiler/linker won't alias the two functions.
+    return NULL;
+  }
+};
+
+template <class T>
+int CppVtableCloner<T>::get_vtable_length(const char* name) {
+  CppVtableTesterA<T> a;
+  CppVtableTesterB<T> b;
+
+  intptr_t* avtable = vtable_of(a);
+  intptr_t* bvtable = vtable_of(b);
+
+  // Start at slot 1, because slot 0 may be RTTI (on Solaris/Sparc)
+  int vtable_len = 1;
+  for (; ; vtable_len++) {
+    if (avtable[vtable_len] != bvtable[vtable_len]) {
+      break;
     }
   }
-  ShouldNotReachHere();
-  return NULL;
+  if (PrintSharedSpaces) {
+    tty->print_cr("Found   %3d vtable entries for %s", vtable_len, name);
+  }
+
+  return vtable_len;
 }
 
-// Assumes the vtable is in first slot in object.
-static void patch_klass_vtables(void** vtbl_list, void* new_vtable_start) {
+#define ALLOC_CPP_VTABLE_CLONE(c) \
+  top = CppVtableCloner<c>::allocate(#c, top, end);
+
+#define CLONE_CPP_VTABLE(c) \
+  p = CppVtableCloner<c>::clone_vtable(#c, (CppVtableInfo*)p);
+
+#define ZERO_CPP_VTABLE(c) \
+ CppVtableCloner<c>::zero_vtable_clone();
+
+// This can be called at both dump time and run time.
+intptr_t* MetaspaceShared::clone_cpp_vtables(intptr_t* p) {
+  assert(DumpSharedSpaces || UseSharedSpaces, "sanity");
+  CPP_VTABLE_PATCH_TYPES_DO(CLONE_CPP_VTABLE);
+  return p;
+}
+
+void MetaspaceShared::zero_cpp_vtable_clones_for_writing() {
+  assert(DumpSharedSpaces, "dump-time only");
+  CPP_VTABLE_PATCH_TYPES_DO(ZERO_CPP_VTABLE);
+}
+
+// Allocate and initialize the C++ vtables, starting from top, but do not go past end.
+intptr_t* MetaspaceShared::allocate_cpp_vtable_clones(intptr_t* top, intptr_t* end) {
+  assert(DumpSharedSpaces, "dump-time only");
+  // Layout (each slot is a intptr_t):
+  //   [number of slots in the first vtable = n1]
+  //   [ <n1> slots for the first vtable]
+  //   [number of slots in the first second = n2]
+  //   [ <n2> slots for the second vtable]
+  //   ...
+  // The order of the vtables is the same as the CPP_VTAB_PATCH_TYPES_DO macro.
+  CPP_VTABLE_PATCH_TYPES_DO(ALLOC_CPP_VTABLE_CLONE);
+  return top;
+}
+
+// Switch the vtable pointer to point to the cloned vtable. We assume the
+// vtable pointer is in first slot in object.
+void MetaspaceShared::patch_cpp_vtable_pointers() {
   int n = _global_klass_objects->length();
   for (int i = 0; i < n; i++) {
     Klass* obj = _global_klass_objects->at(i);
-    // Note is_instance_klass() is a virtual call in debug.  After patching vtables
-    // all virtual calls on the dummy vtables will restore the original!
     if (obj->is_instance_klass()) {
       InstanceKlass* ik = InstanceKlass::cast(obj);
-      *(void**)ik = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, ik);
+      if (ik->is_class_loader_instance_klass()) {
+        CppVtableCloner<InstanceClassLoaderKlass>::patch(ik);
+      } else if (ik->is_reference_instance_klass()) {
+        CppVtableCloner<InstanceRefKlass>::patch(ik);
+      } else if (ik->is_mirror_instance_klass()) {
+        CppVtableCloner<InstanceMirrorKlass>::patch(ik);
+      } else {
+        CppVtableCloner<InstanceKlass>::patch(ik);
+      }
       ConstantPool* cp = ik->constants();
-      *(void**)cp = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, cp);
+      CppVtableCloner<ConstantPool>::patch(cp);
       for (int j = 0; j < ik->methods()->length(); j++) {
         Method* m = ik->methods()->at(j);
-        *(void**)m = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, m);
+        CppVtableCloner<Method>::patch(m);
+        assert(CppVtableCloner<Method>::is_valid_shared_object(m), "must be");
       }
+    } else if (obj->is_objArray_klass()) {
+      CppVtableCloner<ObjArrayKlass>::patch(obj);
     } else {
-      // Array klasses
-      Klass* k = obj;
-      *(void**)k = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, k);
+      assert(obj->is_typeArray_klass(), "sanity");
+      CppVtableCloner<TypeArrayKlass>::patch(obj);
     }
   }
 }
 
+bool MetaspaceShared::is_valid_shared_method(const Method* m) {
+  assert(is_in_shared_space(m), "must be");
+  return CppVtableCloner<Method>::is_valid_shared_object(m);
+}
+
 // Closure for serializing initialization data out to a data area to be
 // written to the shared file.
 
@@ -618,24 +782,12 @@
   char* od_top = MetaspaceShared::optional_data_region()->alloc_top();
   char* od_end = _od_vs.high();
 
-  // Reserve space for the list of Klass*s whose vtables are used
-  // for patching others as needed.
+  char* vtbl_list = md_top;
+  md_top = (char*)MetaspaceShared::allocate_cpp_vtable_clones((intptr_t*)md_top, (intptr_t*)md_end);
 
-  void** vtbl_list = (void**)md_top;
-  int vtbl_list_size = MetaspaceShared::vtbl_list_size;
-  Universe::init_self_patching_vtbl_list(vtbl_list, vtbl_list_size);
-
-  md_top += vtbl_list_size * sizeof(void*);
-  void* vtable = md_top;
-
-  // Reserve space for a new dummy vtable for klass objects in the
-  // heap.  Generate self-patching vtable entries.
-
-  MetaspaceShared::generate_vtable_methods(vtbl_list, &vtable,
-                                     &md_top, md_end,
-                                     &mc_top, mc_end);
-
-  guarantee(md_top <= md_end, "Insufficient space for vtables.");
+  // We don't use MC section anymore. We will remove it in a future RFE. For now, put one
+  // byte inside so the region writing/mapping code works.
+  mc_top ++;
 
   // Reorder the system dictionary.  (Moving the symbols affects
   // how the hash table indices are calculated.)
@@ -709,20 +861,19 @@
   tty->print_cr("total   : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]",
                  total_bytes, total_alloced, total_u_perc);
 
-  // Update the vtable pointers in all of the Klass objects in the
-  // heap. They should point to newly generated vtable.
-  patch_klass_vtables(vtbl_list, vtable);
+  // During patching, some virtual methods may be called, so at this point
+  // the vtables must contain valid methods (as filled in by CppVtableCloner::allocate).
+  MetaspaceShared::patch_cpp_vtable_pointers();
 
-  // dunno what this is for.
-  char* saved_vtbl = (char*)os::malloc(vtbl_list_size * sizeof(void*), mtClass);
-  memmove(saved_vtbl, vtbl_list, vtbl_list_size * sizeof(void*));
-  memset(vtbl_list, 0, vtbl_list_size * sizeof(void*));
+  // The vtable clones contain addresses of the current process.
+  // We don't want to write these addresses into the archive.
+  MetaspaceShared::zero_cpp_vtable_clones_for_writing();
 
   // Create and write the archive file that maps the shared spaces.
 
   FileMapInfo* mapinfo = new FileMapInfo();
   mapinfo->populate_header(MetaspaceShared::max_alignment());
-  mapinfo->set_misc_data_patching_start((char*)vtbl_list);
+  mapinfo->set_misc_data_patching_start(vtbl_list);
   mapinfo->set_cds_i2i_entry_code_buffers(MetaspaceShared::cds_i2i_entry_code_buffers());
   mapinfo->set_cds_i2i_entry_code_buffers_size(MetaspaceShared::cds_i2i_entry_code_buffers_size());
 
@@ -757,8 +908,8 @@
 
   mapinfo->close();
 
-  memmove(vtbl_list, saved_vtbl, vtbl_list_size * sizeof(void*));
-  os::free(saved_vtbl);
+  // Restore the vtable in case we invoke any virtual methods.
+  MetaspaceShared::clone_cpp_vtables((intptr_t*)vtbl_list);
 
   if (PrintSharedSpaces) {
     DumpAllocClosure dac;
@@ -1134,19 +1285,7 @@
   _cds_i2i_entry_code_buffers_size = mapinfo->cds_i2i_entry_code_buffers_size();
   char* buffer = mapinfo->misc_data_patching_start();
 
-  // Skip over (reserve space for) a list of addresses of C++ vtables
-  // for Klass objects.  They get filled in later.
-
-  void** vtbl_list = (void**)buffer;
-  buffer += MetaspaceShared::vtbl_list_size * sizeof(void*);
-  Universe::init_self_patching_vtbl_list(vtbl_list, vtbl_list_size);
-
-  // Skip over (reserve space for) dummy C++ vtables Klass objects.
-  // They are used as is.
-
-  intptr_t vtable_size = *(intptr_t*)buffer;
-  buffer += sizeof(intptr_t);
-  buffer += vtable_size;
+  buffer = (char*)clone_cpp_vtables((intptr_t*)buffer);
 
   int sharedDictionaryLen = *(intptr_t*)buffer;
   buffer += sizeof(intptr_t);
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp	Fri Mar 10 12:58:37 2017 -0500
+++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,17 +32,6 @@
 #include "utilities/exceptions.hpp"
 #include "utilities/macros.hpp"
 
-#define DEFAULT_VTBL_LIST_SIZE          (17)  // number of entries in the shared space vtable list.
-#define DEFAULT_VTBL_VIRTUALS_COUNT     (200) // maximum number of virtual functions
-// If virtual functions are added to Metadata,
-// this number needs to be increased.  Also,
-// SharedMiscCodeSize will need to be increased.
-// The following 2 sizes were based on
-// MetaspaceShared::generate_vtable_methods()
-#define DEFAULT_VTBL_METHOD_SIZE        (16)  // conservative size of the mov1 and jmp instructions
-// for the x64 platform
-#define DEFAULT_VTBL_COMMON_CODE_SIZE   (1*K) // conservative size of the "common_code" for the x64 platform
-
 #define DEFAULT_SHARED_READ_WRITE_SIZE  (NOT_LP64(6*M) LP64_ONLY(10*M))
 #define MIN_SHARED_READ_WRITE_SIZE      (NOT_LP64(6*M) LP64_ONLY(10*M))
 
@@ -135,13 +124,6 @@
   static SharedMiscRegion _od;
  public:
   enum {
-    vtbl_list_size         = DEFAULT_VTBL_LIST_SIZE,
-    num_virtuals           = DEFAULT_VTBL_VIRTUALS_COUNT,
-    vtbl_method_size       = DEFAULT_VTBL_METHOD_SIZE,
-    vtbl_common_code_size  = DEFAULT_VTBL_COMMON_CODE_SIZE
-  };
-
-  enum {
     ro = 0,  // read-only shared space in the heap
     rw = 1,  // read-write shared space in the heap
     md = 2,  // miscellaneous data for initializing tables, etc.
@@ -194,10 +176,12 @@
 
   static bool is_string_region(int idx) NOT_CDS_RETURN_(false);
 
-  static void generate_vtable_methods(void** vtbl_list,
-                                      void** vtable,
-                                      char** md_top, char* md_end,
-                                      char** mc_top, char* mc_end);
+  static intptr_t* allocate_cpp_vtable_clones(intptr_t* top, intptr_t* end);
+  static intptr_t* clone_cpp_vtables(intptr_t* p);
+  static void zero_cpp_vtable_clones_for_writing();
+  static void patch_cpp_vtable_pointers();
+  static bool is_valid_shared_method(const Method* m);
+
   static void serialize(SerializeClosure* sc, GrowableArray<MemRegion> *string_space,
                         size_t* space_size);
 
--- a/hotspot/src/share/vm/memory/universe.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ b/hotspot/src/share/vm/memory/universe.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -410,30 +410,6 @@
 
 }
 
-// CDS support for patching vtables in metadata in the shared archive.
-// All types inherited from Metadata have vtables, but not types inherited
-// from MetaspaceObj, because the latter does not have virtual functions.
-// If the metadata type has a vtable, it cannot be shared in the read-only
-// section of the CDS archive, because the vtable pointer is patched.
-static inline void add_vtable(void** list, int* n, void* o, int count) {
-  guarantee((*n) < count, "vtable list too small");
-  void* vtable = dereference_vptr(o);
-  assert(*(void**)(vtable) != NULL, "invalid vtable");
-  list[(*n)++] = vtable;
-}
-
-void Universe::init_self_patching_vtbl_list(void** list, int count) {
-  int n = 0;
-  { InstanceKlass o;          add_vtable(list, &n, &o, count); }
-  { InstanceClassLoaderKlass o; add_vtable(list, &n, &o, count); }
-  { InstanceMirrorKlass o;    add_vtable(list, &n, &o, count); }
-  { InstanceRefKlass o;       add_vtable(list, &n, &o, count); }
-  { TypeArrayKlass o;         add_vtable(list, &n, &o, count); }
-  { ObjArrayKlass o;          add_vtable(list, &n, &o, count); }
-  { Method o;                 add_vtable(list, &n, &o, count); }
-  { ConstantPool o;           add_vtable(list, &n, &o, count); }
-}
-
 void Universe::initialize_basic_type_mirrors(TRAPS) {
     assert(_int_mirror==NULL, "basic type mirrors already initialized");
     _int_mirror     =
--- a/hotspot/src/share/vm/memory/universe.hpp	Fri Mar 10 12:58:37 2017 -0500
+++ b/hotspot/src/share/vm/memory/universe.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -480,9 +480,6 @@
   // SystemDictionary).
   static void basic_type_classes_do(void f(Klass*));
 
-  // For sharing -- fill in a list of known vtable pointers.
-  static void init_self_patching_vtbl_list(void** list, int count);
-
   // Debugging
   enum VERIFY_FLAGS {
     Verify_Threads = 1,
--- a/hotspot/src/share/vm/oops/constantPool.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ b/hotspot/src/share/vm/oops/constantPool.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -152,6 +152,7 @@
 
 // CDS support. Create a new resolved_references array.
 void ConstantPool::restore_unshareable_info(TRAPS) {
+  assert(is_constantPool(), "ensure C++ vtable is restored");
 
   // Only create the new resolved references array if it hasn't been attempted before
   if (resolved_references() != NULL) return;
--- a/hotspot/src/share/vm/oops/constantPool.hpp	Fri Mar 10 12:58:37 2017 -0500
+++ b/hotspot/src/share/vm/oops/constantPool.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -715,6 +715,11 @@
   friend class ClassFileParser;
   friend class SystemDictionary;
 
+  // Used by CDS. These classes need to access the private ConstantPool() constructor.
+  template <class T> friend class CppVtableTesterA;
+  template <class T> friend class CppVtableTesterB;
+  template <class T> friend class CppVtableCloner;
+
   // Used by compiler to prevent classloading.
   static Method*          method_at_if_loaded      (const constantPoolHandle& this_cp, int which);
   static bool       has_appendix_at_if_loaded      (const constantPoolHandle& this_cp, int which);
--- a/hotspot/src/share/vm/oops/klass.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ b/hotspot/src/share/vm/oops/klass.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -168,7 +168,7 @@
 
 // "Normal" instantiation is preceeded by a MetaspaceObj allocation
 // which zeros out memory - calloc equivalent.
-// The constructor is also used from init_self_patching_vtbl_list,
+// The constructor is also used from CppVtableCloner,
 // which doesn't zero out the memory before calling the constructor.
 // Need to set the _java_mirror field explicitly to not hit an assert that the field
 // should be NULL before setting it.
@@ -501,6 +501,7 @@
 }
 
 void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
+  assert(is_klass(), "ensure C++ vtable is restored");
   TRACE_RESTORE_ID(this);
 
   // If an exception happened during CDS restore, some of these fields may already be
--- a/hotspot/src/share/vm/oops/method.cpp	Fri Mar 10 12:58:37 2017 -0500
+++ b/hotspot/src/share/vm/oops/method.cpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1101,12 +1101,11 @@
 }
 
 void Method::restore_unshareable_info(TRAPS) {
+  assert(is_method() && is_valid_method(), "ensure C++ vtable is restored");
+
   // Since restore_unshareable_info can be called more than once for a method, don't
   // redo any work.
   if (adapter() == NULL) {
-    // Restore Method's C++ vtable by calling a virtual function
-    restore_vtable();
-
     methodHandle mh(THREAD, this);
     link_method(mh, CHECK);
   }
@@ -2166,7 +2165,6 @@
 bool Method::has_method_vptr(const void* ptr) {
   Method m;
   // This assumes that the vtbl pointer is the first word of a C++ object.
-  // This assumption is also in universe.cpp patch_klass_vtble
   return dereference_vptr(&m) == dereference_vptr(ptr);
 }
 
@@ -2177,10 +2175,12 @@
   } else if ((intptr_t(this) & (wordSize-1)) != 0) {
     // Quick sanity check on pointer.
     return false;
-  } else if (!is_metaspace_object()) {
+  } else if (MetaspaceShared::is_in_shared_space(this)) {
+    return MetaspaceShared::is_valid_shared_method(this);
+  } else if (Metaspace::contains_non_shared(this)) {
+    return has_method_vptr((const void*)this);
+  } else {
     return false;
-  } else {
-    return has_method_vptr((const void*)this);
   }
 }
 
--- a/hotspot/src/share/vm/oops/method.hpp	Fri Mar 10 12:58:37 2017 -0500
+++ b/hotspot/src/share/vm/oops/method.hpp	Fri Mar 03 23:08:35 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -122,11 +122,6 @@
   // CDS and vtbl checking can create an empty Method to get vtbl pointer.
   Method(){}
 
-  // The Method vtable is restored by this call when the Method is in the
-  // shared archive.  See patch_klass_vtables() in metaspaceShared.cpp for
-  // all the gory details.  SA, dtrace and pstack helpers distinguish metadata
-  // by their vtable.
-  void restore_vtable() { guarantee(is_method(), "vtable restored by this call"); }
   bool is_method() const volatile { return true; }
 
   void restore_unshareable_info(TRAPS);