diff --git a/src/share/vm/classfile/dictionary.cpp b/src/share/vm/classfile/dictionary.cpp index 5e8f5a5ec16f2534eea39074a8ce3ad42c9f52a0..c9a43de1d3af2cdb549372f8c49b079372214329 100644 --- a/src/share/vm/classfile/dictionary.cpp +++ b/src/share/vm/classfile/dictionary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "classfile/dictionary.hpp" #include "classfile/systemDictionary.hpp" +#include "classfile/systemDictionaryShared.hpp" #include "memory/iterator.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiRedefineClassesTrace.hpp" @@ -36,9 +37,16 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC DictionaryEntry* Dictionary::_current_class_entry = NULL; int Dictionary::_current_class_index = 0; +size_t Dictionary::entry_size() { + if (DumpSharedSpaces) { + return SystemDictionaryShared::dictionary_entry_size(); + } else { + return sizeof(DictionaryEntry); + } +} Dictionary::Dictionary(int table_size) - : TwoOopHashtable(table_size, sizeof(DictionaryEntry)) { + : TwoOopHashtable(table_size, (int)entry_size()) { _current_class_index = 0; _current_class_entry = NULL; _pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize); @@ -47,7 +55,7 @@ Dictionary::Dictionary(int table_size) Dictionary::Dictionary(int table_size, HashtableBucket* t, int number_of_entries) - : TwoOopHashtable(table_size, sizeof(DictionaryEntry), t, number_of_entries) { + : TwoOopHashtable(table_size, (int)entry_size(), t, number_of_entries) { _current_class_index = 0; _current_class_entry = NULL; _pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize); @@ -63,6 +71,9 @@ DictionaryEntry* Dictionary::new_entry(unsigned int hash, Klass* klass, entry->set_loader_data(loader_data); entry->set_pd_set(NULL); assert(klass->oop_is_instance(), "Must be"); + if (DumpSharedSpaces) { + SystemDictionaryShared::init_shared_dictionary_entry(klass, entry); + } return entry; } diff --git a/src/share/vm/classfile/dictionary.hpp b/src/share/vm/classfile/dictionary.hpp index 180f07e9e010590fd20ce2d50701d213b1c8e7c9..504e7350519ceb098dc49ee7b7acced6b93d4f19 100644 --- a/src/share/vm/classfile/dictionary.hpp +++ b/src/share/vm/classfile/dictionary.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -53,6 +53,7 @@ private: DictionaryEntry* get_entry(int index, unsigned int hash, Symbol* name, ClassLoaderData* loader_data); +protected: DictionaryEntry* bucket(int i) { return (DictionaryEntry*)Hashtable::bucket(i); } @@ -66,6 +67,8 @@ private: Hashtable::add_entry(index, (HashtableEntry*)new_entry); } + static size_t entry_size(); + public: Dictionary(int table_size); Dictionary(int table_size, HashtableBucket* t, int number_of_entries); diff --git a/src/share/vm/classfile/systemDictionary.cpp b/src/share/vm/classfile/systemDictionary.cpp index 46b88470bd7592754e06e4f5ebd2608412e64583..31be14bd4bdf70d6b7e0df0f6eaa13f7fc693795 100644 --- a/src/share/vm/classfile/systemDictionary.cpp +++ b/src/share/vm/classfile/systemDictionary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -1198,8 +1198,13 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik, if (ik->super() != NULL) { Symbol* cn = ik->super()->name(); - resolve_super_or_fail(class_name, cn, - class_loader, protection_domain, true, CHECK_(nh)); + Klass *s = resolve_super_or_fail(class_name, cn, + class_loader, protection_domain, true, CHECK_(nh)); + if (s != ik->super()) { + // The dynamically resolved super class is not the same as the one we used during dump time, + // so we cannot use ik. + return nh; + } } Array* interfaces = ik->local_interfaces(); @@ -1212,7 +1217,12 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik, // reinitialized yet (they will be once the interface classes // are loaded) Symbol* name = k->name(); - resolve_super_or_fail(class_name, name, class_loader, protection_domain, false, CHECK_(nh)); + Klass* i = resolve_super_or_fail(class_name, name, class_loader, protection_domain, false, CHECK_(nh)); + if (k != i) { + // The dynamically resolved interface class is not the same as the one we used during dump time, + // so we cannot use ik. + return nh; + } } // Adjust methods to recover missing data. They need addresses for diff --git a/src/share/vm/classfile/systemDictionaryShared.hpp b/src/share/vm/classfile/systemDictionaryShared.hpp index bc688798ce89e298a208d85650e68b503a5b62b8..e1adf8b553b1539ab4df42df0bda0ba90125728c 100644 --- a/src/share/vm/classfile/systemDictionaryShared.hpp +++ b/src/share/vm/classfile/systemDictionaryShared.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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 @@ -26,6 +26,7 @@ #ifndef SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP #define SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP +#include "classfile/dictionary.hpp" #include "classfile/systemDictionary.hpp" class SystemDictionaryShared: public SystemDictionary { @@ -42,6 +43,22 @@ public: oop class_loader = loader_data->class_loader(); return (class_loader == NULL); } + + static size_t dictionary_entry_size() { + return sizeof(DictionaryEntry); + } + static void init_shared_dictionary_entry(Klass* k, DictionaryEntry* entry) {} + + // The (non-application) CDS implementation supports only classes in the boot + // class loader, which ensures that the verification dependencies are the same + // during archive creation time and runtime. Thus we can do the dependency checks + // entirely during archive creation time. + static void add_verification_dependency(Klass* k, Symbol* accessor_clsname, + Symbol* target_clsname) {} + static void finalize_verification_dependencies() {} + static bool check_verification_dependencies(Klass* k, Handle class_loader, + Handle protection_domain, + char** message_buffer, TRAPS) {return true;} }; #endif // SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP diff --git a/src/share/vm/classfile/verificationType.cpp b/src/share/vm/classfile/verificationType.cpp index 120d9a37d623eb556f5babd644d623a5d126268a..716a72d0d2aef2e76441ab6fce7226bc227e90e1 100644 --- a/src/share/vm/classfile/verificationType.cpp +++ b/src/share/vm/classfile/verificationType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/symbolTable.hpp" +#include "classfile/systemDictionaryShared.hpp" #include "classfile/verificationType.hpp" #include "classfile/verifier.hpp" @@ -73,7 +74,23 @@ bool VerificationType::is_reference_assignable_from( Klass* from_class = SystemDictionary::resolve_or_fail( from.name(), Handle(THREAD, klass->class_loader()), Handle(THREAD, klass->protection_domain()), true, CHECK_false); - return InstanceKlass::cast(from_class)->is_subclass_of(this_class()); + bool result = InstanceKlass::cast(from_class)->is_subclass_of(this_class()); + if (result && DumpSharedSpaces) { + if (klass()->is_subclass_of(from_class) && klass()->is_subclass_of(this_class())) { + // No need to save verification dependency. At run time, will be + // loaded from the archived only if and are + // also loaded from the archive. I.e., all 3 classes are exactly the same + // as we saw at archive creation time. + } else { + // Save the dependency. At run time, we need to check that the condition + // from_class->is_subclass_of(this_class() is still true. + Symbol* accessor_clsname = from.name(); + Symbol* target_clsname = this_class()->name(); + SystemDictionaryShared::add_verification_dependency(klass(), + accessor_clsname, target_clsname); + } + } + return result; } } else if (is_array() && from.is_array()) { VerificationType comp_this = get_component(context, CHECK_false); diff --git a/src/share/vm/memory/metaspaceShared.cpp b/src/share/vm/memory/metaspaceShared.cpp index 71fbcb9d1f8a63ac1cd4f6c68545a431161ec452..d1102c4662fb9e8b563528472e9b38bf1c3cd535 100644 --- a/src/share/vm/memory/metaspaceShared.cpp +++ b/src/share/vm/memory/metaspaceShared.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, 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 @@ -30,6 +30,7 @@ #include "classfile/sharedClassUtil.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" +#include "classfile/systemDictionaryShared.hpp" #include "code/codeCache.hpp" #include "memory/filemap.hpp" #include "memory/gcLocker.hpp" @@ -684,6 +685,10 @@ void MetaspaceShared::link_and_cleanup_shared_classes(TRAPS) { exit(1); } } + + // Copy the dependencies from C_HEAP-alloced GrowableArrays to RO-alloced + // Arrays + SystemDictionaryShared::finalize_verification_dependencies(); } void MetaspaceShared::prepare_for_dumping() { diff --git a/src/share/vm/oops/instanceKlass.cpp b/src/share/vm/oops/instanceKlass.cpp index c6a5bddb03c51966471cb1f55d47e49d3b1ecc1f..571bd5a608beb49ebf704b0a70de60eb77061b94 100644 --- a/src/share/vm/oops/instanceKlass.cpp +++ b/src/share/vm/oops/instanceKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "classfile/javaClasses.hpp" #include "classfile/systemDictionary.hpp" +#include "classfile/systemDictionaryShared.hpp" #include "classfile/verifier.hpp" #include "classfile/vmSymbols.hpp" #include "compiler/compileBroker.hpp" @@ -706,6 +707,16 @@ bool InstanceKlass::link_class_impl( // also sets rewritten this_oop->rewrite_class(CHECK_false); + } else if (this_oop()->is_shared()) { + ResourceMark rm(THREAD); + char* message_buffer; // res-allocated by check_verification_dependencies + Handle loader = this_oop()->class_loader(); + Handle pd = this_oop()->protection_domain(); + bool verified = SystemDictionaryShared::check_verification_dependencies(this_oop(), + loader, pd, &message_buffer, THREAD); + if (!verified) { + THROW_MSG_(vmSymbols::java_lang_VerifyError(), message_buffer, false); + } } // relocate jsrs and link methods after they are all rewritten diff --git a/src/share/vm/prims/whitebox.cpp b/src/share/vm/prims/whitebox.cpp index ef1da19d2db48c935ef58278b8616ea30fea9472..c3e0688ab30124c8af043691f56bd22746092e35 100644 --- a/src/share/vm/prims/whitebox.cpp +++ b/src/share/vm/prims/whitebox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, 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 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "memory/metadataFactory.hpp" +#include "memory/metaspaceShared.hpp" #include "memory/universe.hpp" #include "oops/oop.inline.hpp" @@ -914,6 +915,10 @@ WB_ENTRY(jlong, WB_MetaspaceCapacityUntilGC(JNIEnv* env, jobject wb)) return (jlong) MetaspaceGC::capacity_until_GC(); WB_END +WB_ENTRY(jboolean, WB_IsSharedClass(JNIEnv* env, jobject wb, jclass clazz)) + return (jboolean)MetaspaceShared::is_in_shared_space(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); +WB_END + WB_ENTRY(jboolean, WB_IsMonitorInflated(JNIEnv* env, jobject wb, jobject obj)) oop obj_oop = JNIHandles::resolve(obj); return (jboolean) obj_oop->mark()->has_monitor(); @@ -1034,6 +1039,7 @@ static JNINativeMethod methods[] = { {CC"runMemoryUnitTests", CC"()V", (void*)&WB_RunMemoryUnitTests}, {CC"readFromNoaccessArea",CC"()V", (void*)&WB_ReadFromNoaccessArea}, {CC"stressVirtualSpaceResize",CC"(JJJ)I", (void*)&WB_StressVirtualSpaceResize}, + {CC"isSharedClass", CC"(Ljava/lang/Class;)Z", (void*)&WB_IsSharedClass }, #if INCLUDE_ALL_GCS {CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark}, {CC"g1IsHumongous", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous }, diff --git a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java index 99bb670007a63e6e5d27118b5c6782570b414649..6b3d3e34854e2842cf07d9788b149ef492e0c622 100644 --- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java +++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, 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 @@ -233,4 +233,6 @@ public class WhiteBox { return offset; } + // Class Data Sharing + public native boolean isSharedClass(Class c); }