Mercurial > hg > graal-jvmci-8
changeset 24030:371fd9bb8202
Merge
author | asaha |
---|---|
date | Tue, 05 Jul 2016 15:18:38 -0700 |
parents | 0ce7a44c80a8 (current diff) e9fbef955b51 (diff) |
children | f2f59d888427 |
files | .hgtags src/cpu/x86/vm/macroAssembler_x86.cpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/oops/method.cpp src/share/vm/opto/compile.cpp |
diffstat | 18 files changed, 323 insertions(+), 67 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Mon Jul 04 14:29:23 2016 -0700 +++ b/.hgtags Tue Jul 05 15:18:38 2016 -0700 @@ -598,6 +598,7 @@ 6824e2475e0432e27f9cc51838bc34ea5fbf5113 jdk8u40-b27 8220f68a195f6eeed2f5fb6e8a303726b512e899 jdk8u40-b31 850a290eb1088a61178d1910c500e170ef4f4386 jdk8u40-b32 +e6aa4a8c1b46a05b6c493b4ffe5c2555013f5c99 jdk8u40-b33 1b3abbeee961dee49780c0e4af5337feb918c555 jdk8u40-b10 f10fe402dfb1543723b4b117a7cba3ea3d4159f1 hs25.40-b15 99372b2fee0eb8b3452f47230e84aa6e97003184 jdk8u40-b11 @@ -801,17 +802,28 @@ a8e4754b89aecc388623394a20f6d43d4c58f083 jdk8u72-b13 dc2fdd4e0b8105268b8231040f761f27ab4523f2 jdk8u72-b14 d6670c5d49ba381405ec9f69a78ccc5b8b0c8473 jdk8u72-b15 +da43260704c28b9f19cb652090ae65c258220fd6 jdk8u72-b31 26b99cd20661a1fa05939d1856a9389311e01c4f jdk8u73-b00 931c31db01ae873525a1b2c306b01129eb431960 jdk8u73-b01 67566d815a66d958c1f817d65f1621ba1d2e5f33 jdk8u73-b02 451dda77f6c29bd3260e87f847a9eadae122a759 jdk8u74-b00 c1031a924f2c910fad078838b88a2f0146f2de98 jdk8u74-b01 ca9cae9aa9e989bbe6713c91d55c913edeaecce4 jdk8u74-b02 +a5b78b56841e97ce00463874f1b7f63c54d84934 jdk8u74-b31 +94ec11846b18111e73929b6caa9fbe7262e142c1 jdk8u74-b32 +1b6d4fd2730e58f17820930f797938dc182117c4 jdk8u77-b00 +ddd297e340b1170d3cec011ee64e729f8b493c86 jdk8u77-b01 +1b4072e4bb3ad54c4e894998486a8b33f0689160 jdk8u77-b02 +223b64a19e94222dd97b92bb40abcfbc0bf6ef1f jdk8u77-b03 +dd8507f51d786572dae18af8ffdc5a1ea34c755e jdk8u77-b31 + +94ec11846b18111e73929b6caa9fbe7262e142c1 jdk8u74-b32 da43260704c28b9f19cb652090ae65c258220fd6 jdk8u72-b31 c0242ea4bde19d72be5149feda112a39e8c89b0a jdk8u75-b00 ca3b8c8e390ab0540b0cc2e5def869b38e460d86 jdk8u75-b01 9aef5b5e0a68f20059cfa9e2806b4ff0e11a3d31 jdk8u75-b02 2df9fe896819362b9075a670b78106b249e50d6d jdk8u75-b03 +b374548dcb4834eb8731a06b52faddd0f10bd45d jdk8u101-b00 32b682649973231b54740c09b10889660f6ebde5 jdk8u75-b04 1f43bd4fab06d2ca5d1964611df14d8506d6b36e jdk8u75-b05 916712f178c39d0acbc590f38802133fc86a7346 jdk8u75-b06 @@ -827,6 +839,7 @@ bbbb05e91c629f8d9eef2ba43933767f68a898b0 jdk8u91-b00 e36b6ade0499eadfd8673fe62ef0a613af2e6d67 jdk8u91-b13 fa8991ccf6e5b74890a0b5672440b3c09d8d8732 jdk8u91-b14 +e1ea97ad19af4d1e0bda449aa43be7e1b118ffe9 jdk8u91-b15 1b6d4fd2730e58f17820930f797938dc182117c4 jdk8u77-b00 ddd297e340b1170d3cec011ee64e729f8b493c86 jdk8u77-b01 1b4072e4bb3ad54c4e894998486a8b33f0689160 jdk8u77-b02 @@ -847,12 +860,37 @@ 481dcde745b6aec035781ed9f6797cfc93719f71 jdk8u92-b00 f3e1e734e2d29101a9537ddeb71ecad413fcd352 jdk8u92-b13 24a09407d71bb2cc4848bfa21660c890b4d722b1 jdk8u92-b14 +445941ba41c0e3829fe02140690b144281ac2141 jdk8u92-b31 +b374548dcb4834eb8731a06b52faddd0f10bd45d jdk8u81-b00 +ead07188d11107e877e8e4ad215ff6cb238a8a92 jdk8u101-b01 +34429bad9986677f4991c80aeb22665842881cba jdk8u101-b02 +b41d5faaf1d32ed1bf9592f65f2f94ddd4c60fc4 jdk8u101-b03 +ceecf88e5c2c09bfabf5926581e6d0b0f65f5148 jdk8u101-b04 +19e74265fc8def6a7fc96c836d8ebe38ad1cf199 jdk8u101-b05 +7c60503b0888ac16eac80a6cd074195973f8dedb jdk8u101-b06 +cb4af293fe70549b51039bb9197f373e6750fafb jdk8u101-b07 +8ed377d2cec94435d1617a37999960a24be73ad9 jdk8u101-b08 +9be452c4e7161e60d623d55bb72ad013386aefd1 jdk8u101-b09 +218a44a163fa8c2532fd5f2e8ea9bc3c9c2ca8cf jdk8u101-b10 +0095e54dcaa1acfe1614feff9600734c26af7ae8 jdk8u101-b11 +286fe17d81c3d153611a28e50926083ae934cc56 jdk8u101-b12 +77df35b662ed98236f67ab18e23691460f986981 jdk8u101-b13 d6c92b9e192ef97305a699e868387d55821c81ad jdk8u102-b00 d6c92b9e192ef97305a699e868387d55821c81ad jdk8u82-b00 516a64e6d7c2dc29fd932bf3b8313e560a01bcd0 jdk8u102-b01 83dc7e55f71596e6e76fabfa56b6008e070ff44c jdk8u102-b02 ef01a1634bb41dd5b36fc9824f8d35f745c6bd5a jdk8u102-b03 2094cac55c5955b4f19cd9e35e3be8b467e59b57 jdk8u102-b04 +a96cf90239c64f51679d106b852c9a5b343b9488 jdk8u102-b05 +12cd1f9b403eb5024e8642bfa59136cd275899a4 jdk8u102-b06 +9ff5455815c1864ef7ca2d5232decd2023d1d043 jdk8u102-b07 +69f5f6c2beeb3bb126494ed779ae1686f61602b9 jdk8u102-b08 +b5ecd8067e899c4bfb8d327ee7583a32129772d4 jdk8u102-b09 +2672cfc2d7b6ffa07b7714208f9d46a405211d94 jdk8u102-b10 +36a1a2875ed55fa17818f3eb203e27922a7b4589 jdk8u102-b11 +340e1a736ef7169786e70db7f31ffd32bc3be24d jdk8u102-b12 +f6daf04c0f48dab5420ad63d21da82a7fa4e3ad7 jdk8u102-b13 +ac29c9c1193aef5d480b200ed94c5d579243c17b jdk8u102-b14 b09a69142dd3bf78ca66bb0c99046ca7cccbdda9 jdk8u112-b00 cf1faa9100dd8c8df6e1a604aaf613d037f51ebf jdk8u112-b01 f22b5be95347c669a1463d9e05ec3bf11420208e jdk8u112-b02
--- a/src/share/vm/classfile/dictionary.cpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/classfile/dictionary.cpp Tue Jul 05 15:18:38 2016 -0700 @@ -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 @@ 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<Klass*, mtClass>(table_size, sizeof(DictionaryEntry)) { + : TwoOopHashtable<Klass*, mtClass>(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, HashtableBucket<mtClass>* t, int number_of_entries) - : TwoOopHashtable<Klass*, mtClass>(table_size, sizeof(DictionaryEntry), t, number_of_entries) { + : TwoOopHashtable<Klass*, mtClass>(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 @@ 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; }
--- a/src/share/vm/classfile/dictionary.hpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/classfile/dictionary.hpp Tue Jul 05 15:18:38 2016 -0700 @@ -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 @@ DictionaryEntry* get_entry(int index, unsigned int hash, Symbol* name, ClassLoaderData* loader_data); +protected: DictionaryEntry* bucket(int i) { return (DictionaryEntry*)Hashtable<Klass*, mtClass>::bucket(i); } @@ -66,6 +67,8 @@ Hashtable<Klass*, mtClass>::add_entry(index, (HashtableEntry<Klass*, mtClass>*)new_entry); } + static size_t entry_size(); + public: Dictionary(int table_size); Dictionary(int table_size, HashtableBucket<mtClass>* t, int number_of_entries);
--- a/src/share/vm/classfile/systemDictionary.cpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/classfile/systemDictionary.cpp Tue Jul 05 15:18:38 2016 -0700 @@ -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 @@ 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<Klass*>* interfaces = ik->local_interfaces(); @@ -1212,7 +1217,12 @@ // 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
--- a/src/share/vm/classfile/systemDictionaryShared.hpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/classfile/systemDictionaryShared.hpp Tue Jul 05 15:18:38 2016 -0700 @@ -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 @@ 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
--- a/src/share/vm/classfile/verificationType.cpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/classfile/verificationType.cpp Tue Jul 05 15:18:38 2016 -0700 @@ -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 @@ 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, <klass> will be + // loaded from the archived only if <from_class> and <this_class> 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);
--- a/src/share/vm/classfile/verifier.cpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/classfile/verifier.cpp Tue Jul 05 15:18:38 2016 -0700 @@ -2323,9 +2323,17 @@ case Bytecodes::_ifnonnull: target = bcs.dest(); if (visited_branches->contains(bci)) { - if (bci_stack->is_empty()) return true; - // Pop a bytecode starting offset and scan from there. - bcs.set_start(bci_stack->pop()); + if (bci_stack->is_empty()) { + if (handler_stack->is_empty()) { + return true; + } else { + // Parse the catch handlers for try blocks containing athrow. + bcs.set_start(handler_stack->pop()); + } + } else { + // Pop a bytecode starting offset and scan from there. + bcs.set_start(bci_stack->pop()); + } } else { if (target > bci) { // forward branch if (target >= code_length) return false; @@ -2348,9 +2356,17 @@ case Bytecodes::_goto_w: target = (opcode == Bytecodes::_goto ? bcs.dest() : bcs.dest_w()); if (visited_branches->contains(bci)) { - if (bci_stack->is_empty()) return true; - // Been here before, pop new starting offset from stack. - bcs.set_start(bci_stack->pop()); + if (bci_stack->is_empty()) { + if (handler_stack->is_empty()) { + return true; + } else { + // Parse the catch handlers for try blocks containing athrow. + bcs.set_start(handler_stack->pop()); + } + } else { + // Been here before, pop new starting offset from stack. + bcs.set_start(bci_stack->pop()); + } } else { if (target >= code_length) return false; // Continue scanning from the target onward.
--- a/src/share/vm/interpreter/bytecodeStream.cpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/interpreter/bytecodeStream.cpp Tue Jul 05 15:18:38 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -31,12 +31,12 @@ // set next bytecode position address bcp = RawBytecodeStream::bcp(); address end = method()->code_base() + end_bci(); - int l = Bytecodes::raw_special_length_at(bcp, end); - if (l <= 0 || (_bci + l) > _end_bci) { + int len = Bytecodes::raw_special_length_at(bcp, end); + // Very large tableswitch or lookupswitch size can cause _next_bci to overflow. + if (len <= 0 || (_bci > _end_bci - len) || (_bci - len >= _next_bci)) { code = Bytecodes::_illegal; } else { - _next_bci += l; - assert(_bci < _next_bci, "length must be > 0"); + _next_bci += len; // set attributes _is_wide = false; // check for special (uncommon) cases
--- a/src/share/vm/interpreter/bytecodeStream.hpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/interpreter/bytecodeStream.hpp Tue Jul 05 15:18:38 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, 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 @@ -149,12 +149,15 @@ code = Bytecodes::code_or_bp_at(bcp); // set next bytecode position - int l = Bytecodes::length_for(code); - if (l > 0 && (_bci + l) <= _end_bci) { + int len = Bytecodes::length_for(code); + if (len > 0 && (_bci <= _end_bci - len)) { assert(code != Bytecodes::_wide && code != Bytecodes::_tableswitch && code != Bytecodes::_lookupswitch, "can't be special bytecode"); _is_wide = false; - _next_bci += l; + _next_bci += len; + if (_next_bci <= _bci) { // Check for integer overflow + code = Bytecodes::_illegal; + } _raw_code = code; return code; } else { @@ -203,19 +206,23 @@ // note that we cannot advance before having the // tty bytecode otherwise the stepping is wrong! // (carefull: length_for(...) must be used first!) - int l = Bytecodes::length_for(code); - if (l == 0) l = Bytecodes::length_at(_method(), bcp); - _next_bci += l; - assert(_bci < _next_bci, "length must be > 0"); - // set attributes - _is_wide = false; - // check for special (uncommon) cases - if (code == Bytecodes::_wide) { - raw_code = (Bytecodes::Code)bcp[1]; - code = raw_code; // wide BCs are always Java-normal - _is_wide = true; + int len = Bytecodes::length_for(code); + if (len == 0) len = Bytecodes::length_at(_method(), bcp); + if (len <= 0 || (_bci > _end_bci - len) || (_bci - len >= _next_bci)) { + raw_code = code = Bytecodes::_illegal; + } else { + _next_bci += len; + assert(_bci < _next_bci, "length must be > 0"); + // set attributes + _is_wide = false; + // check for special (uncommon) cases + if (code == Bytecodes::_wide) { + raw_code = (Bytecodes::Code)bcp[1]; + code = raw_code; // wide BCs are always Java-normal + _is_wide = true; + } + assert(Bytecodes::is_java_code(code), "sanity check"); } - assert(Bytecodes::is_java_code(code), "sanity check"); } _raw_code = raw_code; _code = code;
--- a/src/share/vm/memory/metaspaceShared.cpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/memory/metaspaceShared.cpp Tue Jul 05 15:18:38 2016 -0700 @@ -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" @@ -53,6 +54,7 @@ bool MetaspaceShared::_check_classes_made_progress; bool MetaspaceShared::_has_error_classes; bool MetaspaceShared::_archive_loading_failed = false; +bool MetaspaceShared::_remapped_readwrite = false; // Read/write a data stream for restoring/preserving metadata pointers and // miscellaneous data from/to the shared archive file. @@ -684,6 +686,10 @@ exit(1); } } + + // Copy the dependencies from C_HEAP-alloced GrowableArrays to RO-alloced + // Arrays + SystemDictionaryShared::finalize_verification_dependencies(); } void MetaspaceShared::prepare_for_dumping() { @@ -1096,6 +1102,7 @@ if (!mapinfo->remap_shared_readonly_as_readwrite()) { return false; } + _remapped_readwrite = true; } return true; }
--- a/src/share/vm/memory/metaspaceShared.hpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/memory/metaspaceShared.hpp Tue Jul 05 15:18:38 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 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 @@ -55,6 +55,7 @@ static bool _check_classes_made_progress; static bool _has_error_classes; static bool _archive_loading_failed; + static bool _remapped_readwrite; public: enum { vtbl_list_size = 17, // number of entries in the shared space vtable list. @@ -123,6 +124,10 @@ // sharing is enabled. Simply returns true if sharing is not enabled // or if the remapping has already been done by a prior call. static bool remap_shared_readonly_as_readwrite() NOT_CDS_RETURN_(true); + static bool remapped_readwrite() { + CDS_ONLY(return _remapped_readwrite); + NOT_CDS(return false); + } static void print_shared_spaces();
--- a/src/share/vm/oops/instanceKlass.cpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/oops/instanceKlass.cpp Tue Jul 05 15:18:38 2016 -0700 @@ -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 @@ // 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 @@ -715,7 +726,12 @@ // methods have been rewritten since rewrite may // fabricate new Method*s. // also does loader constraint checking - if (!this_oop()->is_shared()) { + // + // Initialize_vtable and initialize_itable need to be rerun for + // a shared class if the class is not loaded by the NULL classloader. + ClassLoaderData * loader_data = this_oop->class_loader_data(); + if (!(this_oop()->is_shared() && + loader_data->is_the_null_class_loader_data())) { ResourceMark rm(THREAD); this_oop->vtable()->initialize_vtable(true, CHECK_false); this_oop->itable()->initialize_itable(true, CHECK_false);
--- a/src/share/vm/oops/klassVtable.cpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/oops/klassVtable.cpp Tue Jul 05 15:18:38 2016 -0700 @@ -27,6 +27,7 @@ #include "classfile/vmSymbols.hpp" #include "gc_implementation/shared/markSweep.inline.hpp" #include "memory/gcLocker.hpp" +#include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.inline.hpp" #include "oops/instanceKlass.hpp" @@ -47,6 +48,10 @@ return (InstanceKlass*)k; } +bool klassVtable::is_preinitialized_vtable() { + return _klass->is_shared() && !MetaspaceShared::remapped_readwrite(); +} + // this function computes the vtable size (including the size needed for miranda // methods) and the number of miranda methods in this class. @@ -128,6 +133,12 @@ int klassVtable::initialize_from_super(KlassHandle super) { if (super.is_null()) { return 0; + } else if (is_preinitialized_vtable()) { + // A shared class' vtable is preinitialized at dump time. No need to copy + // methods from super class for shared class, as that was already done + // during archiving time. However, if Jvmti has redefined a class, + // copy super class's vtable in case the super class has changed. + return super->vtable()->length(); } else { // copy methods from superKlass // can't inherit from array class, so must be InstanceKlass @@ -157,6 +168,8 @@ KlassHandle super (THREAD, klass()->java_super()); int nofNewEntries = 0; + bool is_shared = _klass->is_shared(); + if (PrintVtables && !klass()->oop_is_array()) { ResourceMark rm(THREAD); tty->print_cr("Initializing: %s", _klass->name()->as_C_string()); @@ -169,6 +182,7 @@ #endif if (Universe::is_bootstrapping()) { + assert(!is_shared, "sanity"); // just clear everything for (int i = 0; i < _length; i++) table()[i].clear(); return; @@ -208,6 +222,7 @@ if (len > 0) { Array<int>* def_vtable_indices = NULL; if ((def_vtable_indices = ik()->default_vtable_indices()) == NULL) { + assert(!is_shared, "shared class def_vtable_indices does not exist"); def_vtable_indices = ik()->create_new_default_vtable_indices(len, CHECK); } else { assert(def_vtable_indices->length() == len, "reinit vtable len?"); @@ -222,7 +237,15 @@ // needs new entry if (needs_new_entry) { put_method_at(mh(), initialized); - def_vtable_indices->at_put(i, initialized); //set vtable index + if (is_preinitialized_vtable()) { + // At runtime initialize_vtable is rerun for a shared class + // (loaded by the non-boot loader) as part of link_class_impl(). + // The dumptime vtable index should be the same as the runtime index. + assert(def_vtable_indices->at(i) == initialized, + "dump time vtable index is different from runtime index"); + } else { + def_vtable_indices->at_put(i, initialized); //set vtable index + } initialized++; } } @@ -365,7 +388,8 @@ } // we need a new entry if there is no superclass - if (klass->super() == NULL) { + Klass* super = klass->super(); + if (super == NULL) { return allocate_new; } @@ -394,7 +418,15 @@ Symbol* target_classname = target_klass->name(); for(int i = 0; i < super_vtable_len; i++) { - Method* super_method = method_at(i); + Method* super_method; + if (is_preinitialized_vtable()) { + // If this is a shared class, the vtable is already in the final state (fully + // initialized). Need to look at the super's vtable. + klassVtable* superVtable = super->vtable(); + super_method = superVtable->method_at(i); + } else { + super_method = method_at(i); + } // Check if method name matches if (super_method->name() == name && super_method->signature() == signature) { @@ -458,7 +490,15 @@ target_method()->set_vtable_index(i); } else { if (def_vtable_indices != NULL) { - def_vtable_indices->at_put(default_index, i); + if (is_preinitialized_vtable()) { + // At runtime initialize_vtable is rerun as part of link_class_impl() + // for a shared class loaded by the non-boot loader. + // The dumptime vtable index should be the same as the runtime index. + assert(def_vtable_indices->at(default_index) == i, + "dump time vtable index is different from runtime index"); + } else { + def_vtable_indices->at_put(default_index, i); + } } assert(super_method->is_default_method() || super_method->is_overpass() || super_method->is_abstract(), "default override error"); @@ -523,24 +563,33 @@ } void klassVtable::put_method_at(Method* m, int index) { + if (is_preinitialized_vtable()) { + // At runtime initialize_vtable is rerun as part of link_class_impl() + // for shared class loaded by the non-boot loader to obtain the loader + // constraints based on the runtime classloaders' context. The dumptime + // method at the vtable index should be the same as the runtime method. + assert(table()[index].method() == m, + "archived method is different from the runtime method"); + } else { #ifndef PRODUCT - if (PrintVtables && Verbose) { - ResourceMark rm; - const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>"; - tty->print("adding %s at index %d, flags: ", sig, index); - if (m != NULL) { - m->access_flags().print_on(tty); - if (m->is_default_method()) { - tty->print("default "); + if (PrintVtables && Verbose) { + ResourceMark rm; + const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>"; + tty->print("adding %s at index %d, flags: ", sig, index); + if (m != NULL) { + m->access_flags().print_on(tty); + if (m->is_default_method()) { + tty->print("default "); + } + if (m->is_overpass()) { + tty->print("overpass"); + } } - if (m->is_overpass()) { - tty->print("overpass"); - } + tty->cr(); } - tty->cr(); +#endif + table()[index].set(m); } -#endif - table()[index].set(m); } // Find out if a method "m" with superclass "super", loader "classloader" and @@ -971,7 +1020,15 @@ void itableMethodEntry::initialize(Method* m) { if (m == NULL) return; - _method = m; + if (MetaspaceShared::is_in_shared_space((void*)&_method) && + !MetaspaceShared::remapped_readwrite()) { + // At runtime initialize_itable is rerun as part of link_class_impl() + // for a shared class loaded by the non-boot loader. + // The dumptime itable method entry should be the same as the runtime entry. + assert(_method == m, "sanity"); + } else { + _method = m; + } } klassItable::klassItable(instanceKlassHandle klass) { @@ -1081,7 +1138,11 @@ tty->cr(); } if (!m->has_vtable_index()) { - assert(m->vtable_index() == Method::pending_itable_index, "set by initialize_vtable"); + // A shared method could have an initialized itable_index that + // is < 0. + assert(m->vtable_index() == Method::pending_itable_index || + m->is_shared(), + "set by initialize_vtable"); m->set_itable_index(ime_num); // Progress to next itable entry ime_num++; @@ -1277,7 +1338,6 @@ } #endif // INCLUDE_JVMTI - // Setup class InterfaceVisiterClosure : public StackObj { public:
--- a/src/share/vm/oops/klassVtable.hpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/oops/klassVtable.hpp Tue Jul 05 15:18:38 2016 -0700 @@ -142,6 +142,19 @@ Array<Klass*>* local_interfaces); void verify_against(outputStream* st, klassVtable* vt, int index); inline InstanceKlass* ik() const; + // When loading a class from CDS archive at run time, and no class redefintion + // has happened, it is expected that the class's itable/vtables are + // laid out exactly the same way as they had been during dump time. + // Therefore, in klassVtable::initialize_[iv]table, we do not layout the + // tables again. Instead, we only rerun the process to create/check + // the class loader constraints. In non-product builds, we add asserts to + // guarantee that the table's layout would be the same as at dump time. + // + // If JVMTI redefines any class, the read-only shared memory are remapped + // as read-write. A shared class' vtable/itable are re-initialized and + // might have different layout due to class redefinition of the shared class + // or its super types. + bool is_preinitialized_vtable(); };
--- a/src/share/vm/oops/method.cpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/oops/method.cpp Tue Jul 05 15:18:38 2016 -0700 @@ -36,6 +36,7 @@ #include "memory/generation.hpp" #include "memory/heapInspection.hpp" #include "memory/metadataFactory.hpp" +#include "memory/metaspaceShared.hpp" #include "memory/oopFactory.hpp" #include "oops/constMethod.hpp" #include "oops/methodData.hpp" @@ -305,6 +306,33 @@ unlink_method(); } +void Method::set_vtable_index(int index) { + if (is_shared() && !MetaspaceShared::remapped_readwrite()) { + // At runtime initialize_vtable is rerun as part of link_class_impl() + // for a shared class loaded by the non-boot loader to obtain the loader + // constraints based on the runtime classloaders' context. + return; // don't write into the shared class + } else { + _vtable_index = index; + } +} + +void Method::set_itable_index(int index) { + if (is_shared() && !MetaspaceShared::remapped_readwrite()) { + // At runtime initialize_itable is rerun as part of link_class_impl() + // for a shared class loaded by the non-boot loader to obtain the loader + // constraints based on the runtime classloaders' context. The dumptime + // itable index should be the same as the runtime index. + assert(_vtable_index == itable_index_max - index, + "archived itable index is different from runtime index"); + return; // don’t write into the shared class + } else { + _vtable_index = itable_index_max - index; + } + assert(valid_itable_index(), ""); +} + + bool Method::was_executed_more_than(int n) { // Invocation counter is reset when the Method* is compiled.
--- a/src/share/vm/oops/method.hpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/oops/method.hpp Tue Jul 05 15:18:38 2016 -0700 @@ -471,12 +471,12 @@ DEBUG_ONLY(bool valid_vtable_index() const { return _vtable_index >= nonvirtual_vtable_index; }) bool has_vtable_index() const { return _vtable_index >= 0; } int vtable_index() const { return _vtable_index; } - void set_vtable_index(int index) { _vtable_index = index; } + void set_vtable_index(int index); DEBUG_ONLY(bool valid_itable_index() const { return _vtable_index <= pending_itable_index; }) bool has_itable_index() const { return _vtable_index <= itable_index_max; } int itable_index() const { assert(valid_itable_index(), ""); return itable_index_max - _vtable_index; } - void set_itable_index(int index) { _vtable_index = itable_index_max - index; assert(valid_itable_index(), ""); } + void set_itable_index(int index); // interpreter entry address interpreter_entry() const { return _i2i_entry; }
--- a/src/share/vm/prims/whitebox.cpp Mon Jul 04 14:29:23 2016 -0700 +++ b/src/share/vm/prims/whitebox.cpp Tue Jul 05 15:18:38 2016 -0700 @@ -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 @@ 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 @@ {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 },
--- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Mon Jul 04 14:29:23 2016 -0700 +++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Tue Jul 05 15:18:38 2016 -0700 @@ -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 @@ return offset; } + // Class Data Sharing + public native boolean isSharedClass(Class<?> c); }