--- old/src/share/vm/memory/metaspaceShared.cpp 2017-02-28 17:55:11.184031347 -0800 +++ new/src/share/vm/memory/metaspaceShared.cpp 2017-02-28 17:55:11.024025349 -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" @@ -233,63 +238,229 @@ } } -// Patch C++ vtable pointer in metadata. - -// 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. +// Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables. +// (In GCC this is the field ::_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. // -// 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 entry -// Klass2:method1 entry, Klass2:method2 entry, ... Klass2:method entry -// ... -// Klass:method1 entry, Klass:method2 entry, -// ... Klass:method 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) +// To ensure that the Metadata objects in the CDS archive always have the correct vtable: // -// 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 +// + 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. // -// 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 - - -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; +// We conservatively estimate that each class's vtable has less than 150 entries. See +// CppVtabCloner::MAX_VTABLE_SIZE + +// Currently, the archive contain ONLY the following types of objects that have C++ vtables. +#define CPP_VTAB_PATCH_TYPES_DO(f) \ + f(ConstantPool) \ + f(InstanceKlass) \ + f(InstanceClassLoaderKlass) \ + f(InstanceMirrorKlass) \ + f(InstanceRefKlass) \ + f(Method) \ + f(ObjArrayKlass) \ + f(TypeArrayKlass) + +#ifndef PRODUCT +template class CppVtabTesterB: public T { +public: + virtual int last_virtual_method() {return 1;} +}; + +template class CppVtabTesterA : public T { +public: + virtual void* last_virtual_method() { + // Make this different than CppVtabTesterB::last_virtual_method so the C++ + // compiler/linker won't alias the two functions. + return NULL; + } +}; +#endif + +class CppVtabInfo { + intptr_t _vtab_size; + intptr_t _vtab[1]; +public: + static int num_slots(int vtab_size) { + return 1 + vtab_size; // Need to add the space occupied by _vtab_size; + } + int vtab_size() { return int(uintx(_vtab_size)); } + void set_vtab_size(int n) { _vtab_size = intptr_t(n); } + intptr_t* vtab() { return &_vtab[0]; } + void zero() { memset(_vtab, 0, sizeof(intptr_t) * vtab_size()); } +}; + +template class CppVtabCloner : public T { + static intptr_t* vtab_of(Metadata& m) { + return *((intptr_t**)&m); + } + // Currently we have no more than 120 virtual methods for all + // Metadata subclasses for all platforms. If you add more virtual + // method you will trigger the assert in verify_sufficient_size(). + const static int MAX_VTABLE_SIZE = 150; + static CppVtabInfo* _info; + +#ifndef PRODUCT + // To determine the size of the vtable for each type, we use the following + // trick by declaring 2 subclasses: + // + // class CppVtabTesterA: public InstanceKlass {virtual int last_virtual_method() {return 1;} }; + // class CppVtabTesterB: public InstanceKlass {virtual void* last_virtual_method() {return NULL}; }; + // + // CppVtabTesterA and CppVtabTesterB'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. + // + // So to determine the value of N, we just walk CppVtabTesterA and CppVtabTesterB'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. + + static void verify_sufficient_size(const char* name) { + CppVtabTesterA a; + CppVtabTesterB b; + + intptr_t* avtab = vtab_of(a); + intptr_t* bvtab = vtab_of(b); + + // Start at slot 1, because slot 0 may be RTTI (on Solaris/Sparc) + int i; + for (i=1; ; i++) { + if (avtab[i] != bvtab[i]) { + break; + } + } + if (PrintSharedSpaces) { + tty->print_cr("%s has %d virtual methods", name, i); + } + if (i > MAX_VTABLE_SIZE) { + tty->print_cr("The C++ vtable size of %s (%d) is larger than the hard-coded default %d", + name, i, MAX_VTABLE_SIZE); + assert(0, "Please increase CppVtabCloner::MAX_VTABLE_SIZE"); + } + } +#endif + +public: + static intptr_t* allocate(const char* name, intptr_t* md_top, intptr_t* md_end) { + DEBUG_ONLY(verify_sufficient_size(name)); + int n = MAX_VTABLE_SIZE; + intptr_t* next = md_top + CppVtabInfo::num_slots(n); + + if (next > md_end) { + report_out_of_shared_space(SharedMiscData); + } + + _info = (CppVtabInfo*)md_top; + _info->set_vtab_size(n); + + T tmp; + intptr_t* srcvtab = vtab_of(tmp); + intptr_t* dstvtab = _info->vtab(); + + // It is not safe to call memcpy(), because srcvtab may be shorter than MAX_VTABLE_SIZE, and + // may be at the last page of an addressable space. Crossing over to the next page would + // cause a page fault. + if (!CanUseSafeFetchN()) { + vm_exit_during_initialization("CanUseSafeFetchN() must be true to enable CDS"); + } + + for (int i=0; i 120 /* uncomment this line to test */ + ) { + _info->set_vtab_size(i-1); + break; + } + dstvtab[i] = num; + } + + return md_top + CppVtabInfo::num_slots(_info->vtab_size()); + } + + static intptr_t* clone_vtable(const char* name, intptr_t* p) { + T tmp; + CppVtabInfo* info = (CppVtabInfo*)p; + int n = info->vtab_size(); + intptr_t* srcvtab = vtab_of(tmp); + intptr_t* dstvtab = info->vtab(); + + // 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("%s copying %d vtable entries", name, n); } + memcpy(dstvtab, srcvtab, sizeof(intptr_t) * n); + return dstvtab + n; + } + + static void zero_vtable_clone() { + assert(DumpSharedSpaces, "dump-time only"); + _info->zero(); + } + + static void patch(Metadata* obj) { + assert(DumpSharedSpaces, "dump-time only"); + *(void**)obj = (void*)(_info->vtab()); } - ShouldNotReachHere(); - return NULL; +}; + +template CppVtabInfo* CppVtabCloner::_info = NULL; + + +#define ALLOC_CPP_VTAB_CLONE(c) \ + md_top = CppVtabCloner::allocate(#c, md_top, md_end); + +#define CLONE_CPP_VTABLE(c) \ + p = CppVtabCloner::clone_vtable(#c, p); + +#define ZERO_CPP_VTABLE(c) \ + CppVtabCloner::zero_vtable_clone(); + + +intptr_t* MetaspaceShared::allocate_cpp_vtable_clones(intptr_t* md_top, intptr_t* md_end) { + assert(DumpSharedSpaces, "dump-time only"); + CPP_VTAB_PATCH_TYPES_DO(ALLOC_CPP_VTAB_CLONE); + return md_top; } -// Assumes the vtable is in first slot in object. -static void patch_klass_vtables(void** vtbl_list, void* new_vtable_start) { +// 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_VTAB_PATCH_TYPES_DO(CLONE_CPP_VTABLE); + return p; +} + +void MetaspaceShared::zero_cpp_vtable_clones_for_writing() { + assert(DumpSharedSpaces, "dump-time only"); + CPP_VTAB_PATCH_TYPES_DO(ZERO_CPP_VTABLE); +} + +intptr_t* MetaspaceShared::init_cpp_vtable_clones(intptr_t* md_top, intptr_t* md_end) { + assert(DumpSharedSpaces, "dump-time only"); + // Layout (each slot is a intptr_t): + // [number of slots in the first vtable = n1] + // [ slots for the first vtable] + // [number of slots in the first second = n2] + // [ slots for the second vtable] + // ... + // The order of the vtables is the same as the CPP_VTAB_PATCH_TYPES_DO macro. + + intptr_t* start = md_top; + md_top = allocate_cpp_vtable_clones(md_top, md_end); + return md_top; +} + +// Assumes 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); @@ -297,17 +468,26 @@ // 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()) { + CppVtabCloner::patch(ik); + } else if (ik->is_reference_instance_klass()) { + CppVtabCloner::patch(ik); + } else if (ik->is_mirror_instance_klass()) { + CppVtabCloner::patch(ik); + } else { + CppVtabCloner::patch(ik); + } ConstantPool* cp = ik->constants(); - *(void**)cp = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, cp); + CppVtabCloner::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); + CppVtabCloner::patch(m); } + } else if (obj->is_objArray_klass()) { + CppVtabCloner::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"); + CppVtabCloner::patch(obj); } } } @@ -341,7 +521,7 @@ } void do_u4(u4* p) { - void* ptr = (void*)(uintx(*p)); + void* ptr = (void*)(intptr_t(*p)); do_ptr(&ptr); } @@ -622,24 +802,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. - - 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); + char* vtbl_list = md_top; + md_top = (char*)MetaspaceShared::init_cpp_vtable_clones((intptr_t*)md_top, (intptr_t*)md_end); - 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.) @@ -713,20 +881,17 @@ 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); - - // 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*)); + MetaspaceShared::patch_cpp_vtable_pointers(); + + // The vtable clones contain addresses of the current process. + // We don't want to write addresses these 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()); @@ -761,8 +926,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; @@ -1138,19 +1303,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); --- old/src/share/vm/memory/metaspaceShared.hpp 2017-02-28 17:55:11.732051893 -0800 +++ new/src/share/vm/memory/metaspaceShared.hpp 2017-02-28 17:55:11.572045894 -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,14 @@ 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); +private: + static intptr_t* allocate_cpp_vtable_clones(intptr_t* md_top, intptr_t* md_end); +public: + static intptr_t* clone_cpp_vtables(intptr_t* p); + static intptr_t* init_cpp_vtable_clones(intptr_t* md_top, intptr_t* md_end); + static void zero_cpp_vtable_clones_for_writing(); + static void patch_cpp_vtable_pointers(); + static void serialize(SerializeClosure* sc, GrowableArray *string_space, size_t* space_size); --- old/src/share/vm/oops/constantPool.cpp 2017-02-28 17:55:12.392076637 -0800 +++ new/src/share/vm/oops/constantPool.cpp 2017-02-28 17:55:12.232070639 -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; --- old/src/share/vm/oops/constantPool.hpp 2017-02-28 17:55:13.272109631 -0800 +++ new/src/share/vm/oops/constantPool.hpp 2017-02-28 17:55:13.104103332 -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 @@ -714,6 +714,9 @@ friend class ClassFileParser; friend class SystemDictionary; + template friend class CppVtabTesterA; // See metaspaceShared.cpp + template friend class CppVtabTesterB; + template friend class CppVtabCloner; // Used by compiler to prevent classloading. static Method* method_at_if_loaded (const constantPoolHandle& this_cp, int which); --- old/src/share/vm/oops/klass.cpp 2017-02-28 17:55:14.132141874 -0800 +++ new/src/share/vm/oops/klass.cpp 2017-02-28 17:55:13.972135875 -0800 @@ -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 --- old/src/share/vm/oops/method.cpp 2017-02-28 17:55:14.988173967 -0800 +++ new/src/share/vm/oops/method.cpp 2017-02-28 17:55:14.824167818 -0800 @@ -1102,12 +1102,11 @@ } void Method::restore_unshareable_info(TRAPS) { + assert(is_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); } --- old/src/share/vm/oops/method.hpp 2017-02-28 17:55:15.892207860 -0800 +++ new/src/share/vm/oops/method.hpp 2017-02-28 17:55:15.728201711 -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 @@ -121,11 +121,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); --- old/src/cpu/aarch64/vm/metaspaceShared_aarch64.cpp 2017-02-28 17:55:16.764240554 -0800 +++ /dev/null 2016-10-11 18:49:32.781206965 -0700 @@ -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 --- old/src/cpu/arm/vm/metaspaceShared_arm.cpp 2017-02-28 17:55:17.236258250 -0800 +++ /dev/null 2016-10-11 18:49:32.781206965 -0700 @@ -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(); -} --- old/src/cpu/ppc/vm/metaspaceShared_ppc.cpp 2017-02-28 17:55:17.752277596 -0800 +++ /dev/null 2016-10-11 18:49:32.781206965 -0700 @@ -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(); -} - --- old/src/cpu/s390/vm/metaspaceShared_s390.cpp 2017-02-28 17:55:18.272297092 -0800 +++ /dev/null 2016-10-11 18:49:32.781206965 -0700 @@ -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(); -} --- old/src/cpu/sparc/vm/metaspaceShared_sparc.cpp 2017-02-28 17:55:18.768315688 -0800 +++ /dev/null 2016-10-11 18:49:32.781206965 -0700 @@ -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."); -} --- old/src/cpu/x86/vm/metaspaceShared_x86_32.cpp 2017-02-28 17:55:19.260334135 -0800 +++ /dev/null 2016-10-11 18:49:32.781206965 -0700 @@ -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(); -} --- old/src/cpu/x86/vm/metaspaceShared_x86_64.cpp 2017-02-28 17:55:19.756352731 -0800 +++ /dev/null 2016-10-11 18:49:32.781206965 -0700 @@ -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(); -} --- old/src/cpu/zero/vm/metaspaceShared_zero.cpp 2017-02-28 17:55:20.272372077 -0800 +++ /dev/null 2016-10-11 18:49:32.781206965 -0700 @@ -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(); -}