# HG changeset patch # User andrew # Date 1376047296 -3600 # Node ID 38f1b987027f9fd3eadab1bdfd00a8cf5b82def1 # Parent a6502a8a6b3137ffc69316cb9a045d765c1835ae# Parent 40acb370626fbc439e4cfed8854960a83a376fba Merge jdk7u25-b16 diff -r a6502a8a6b31 -r 38f1b987027f .hgtags --- a/.hgtags Fri Jul 26 18:34:12 2013 +0100 +++ b/.hgtags Fri Aug 09 12:21:36 2013 +0100 @@ -336,6 +336,7 @@ ad27d7c42279783903b26cd42b09741f5640f6db icedtea-2.3.6 ad27d7c42279783903b26cd42b09741f5640f6db icedtea-2.3.6 0000000000000000000000000000000000000000 icedtea-2.3.6 +7566374c3c89b7d99be9bcdb9342283a3bea6930 jdk7u6-b31 f7933fecea9aa494e4032e17ff07e5fcec4b5961 jdk7u7-b10 eeef33dc4b40f9ba50c4c9b1ac61b30f0f2523bf jdk7u7-b30 f1551c70c7f598b7049bcc33e530fc738a81c7a4 jdk7u7-b11 @@ -349,6 +350,8 @@ ca6943c94e6075fc28353d52ac6ea52c80aef9bb jdk7u9-b02 ed42837374ac730ddaf2fd28814017c665634a8b jdk7u9-b04 da4aa289ac100017f850ed4d492e8054db6a1e28 jdk7u9-b05 +8eaa45ed5f804199c0823b409dc37f72e808926f jdk7u9-b31 +ea83168282c8c3a9f4a8ca723cc86972a3188d58 jdk7u9-b32 d2e25680db9d4209b3f0f51e5c848284cedea508 jdk7u10-b10 d37fd995683ab5bc2d941648ce7bf8bd194732f2 jdk7u10-b11 f26f3d92e6d9ef7842b2d785f92439dbb15e670e jdk7u10-b12 @@ -359,8 +362,11 @@ 5c154a591de987d515f5b102a988bcf96d439f53 jdk7u10-b17 78c7e1b4a006342230e04fbb73f637834207abef jdk7u10-b18 c6b78bbaf6976197ead9d5aa3f65e0224cd13541 jdk7u10-b30 +07f7daeb261073a4a2946d988979ee65ba8ed753 jdk7u10-b31 25a92b94ad538963d009bf8a53ce548e13f55c82 jdk7u11-b20 7a2cf85fc36e845db9ccb2a22af195c70af33bdf jdk7u11-b21 +06b5c3f663b81f11da2080a91d215a96ae431f84 jdk7u11-b32 +abb5b690122caabf09f93958c747358cc22f8a59 jdk7u11-b33 db7028c8a953f46225fceb6148f97de87c784dda jdk7u11-b03 4d418a1b8be04220f504cf414b47877821a22a26 jdk7u11-b04 f71032f398a3baea567710ba7161c64b94495cac jdk7u11-b05 @@ -382,6 +388,8 @@ 5fbe0cae3a2a78a73946cfd08c56a64860f1afd9 jdk7u15-b01 30d72c9abb560bc424d16d96bfd396ccd3c62cbc jdk7u15-b02 221c64550c5b4411d78b63820835de1a8cd0c118 jdk7u15-b30 +0b905a04f573565515aa8614085099abd73dcac4 jdk7u15-b31 +8b349f332a66ebe5982b5680c85f903efb03da8e jdk7u15-b33 5b55cef461b034766f05a46640caa123aa4247d4 jdk7u15-b03 34a7b6dda06e2ff6f7e9ad563e3fc3ecd8993579 jdk7u15-b32 a4dfda7a2655209abb170b2fa4914dbbba89bcd3 jdk7u17-b01 @@ -389,3 +397,34 @@ 4e374ade4066e340199c6f2371769e9aa2852282 icedtea-2.3.10 4413a836dcc7022fa64f60d7faa491aba1248edc icedtea-2.3.11 37b254871acbef27e5f29c73982ac324e7df2b9a icedtea-2.3.12 +0d82bf449a610602b6e9ddcc9e076839d5351449 jdk7u17-b02 +7b357c079370e2fd324c229f2e24c982915c80a0 jdk7u17-b30 +22b6fd616cfe61774525a944f162bf5e7c418f03 jdk7u17-b31 +8e04b403f5803f79db949b61b6c086758b611678 jdk7u17-b32 +be57a8d7a1a75971c3b1e7777dcacd20f3d33264 jdk7u21-b01 +5119d89c7cc844190c0799dca85710e7592d42e7 jdk7u21-b02 +ad14169fb640ca532193cca0fd6e14910f226075 jdk7u21-b03 +c954aab38a7f8f62e33ae5103494576f67fc36d9 jdk7u21-b04 +0e8e9d990d91dc0f8b8807bb82c090de3264c809 jdk7u21-b05 +beeb3d6b76f06d9f60c31d6c5b9e04d82f01ad79 jdk7u21-b06 +663b5c744e82d1c884048cd9b38f625e52004773 jdk7u21-b07 +87e9bb582938552180b024dd99bc5166816f3921 jdk7u21-b08 +1f195ee7856aecb6527bc5c957f66e1960e51a12 jdk7u21-b09 +d4a4c2bd389abcd80c25d20e0ffb7d5cee356715 jdk7u21-b10 +d07dafb51e1d75f110a3c506c250d995235acca6 jdk7u21-b11 +a977dedec81c346247631ead6f3364c76949d67a jdk7u21-b30 +c5e4585a045fe165d067ec0e98af42eace20c5f8 jdk7u21-b12 +bf2d84c5103d98db1697b50071a649ea23c4e33d jdk7u25-b01 +07119340f80f77dfcb03fa568641e80b43d4be74 jdk7u25-b02 +655bea6843fb7beabd8d9eeda59572c0c7055b85 jdk7u25-b03 +96a4e612195c0d753be24cf38fea0ee8ce30edcf jdk7u25-b04 +7151c26b838828a20cb28595ef1f70403d1868cf jdk7u25-b05 +fbb5f6083dd00ca7417e4a45311f33918bb2a5f0 jdk7u25-b06 +83abf4b2fc8a5bb7226177c5e4334bd0bfd7a8df jdk7u25-b07 +525252cd9fca4869c3fd81bc61299a85e73ff9c7 jdk7u25-b08 +706a255a8404b7e41579cea278df6bb87c314567 jdk7u25-b09 +402184622f60a2ba35479bdf124a8d4694835406 jdk7u25-b10 +cca49a35bf83664456af112482ffb3a7465d21fa jdk7u25-b11 +7ca68c0674df72fdd784de337c049404d2b5b0c3 jdk7u25-b12 +3e145a686fedd9eefdcb6b714241200ed236b41d jdk7u25-b13 +4fafaf293aa5666e8c9f5ca1d96c3f752305f586 jdk7u25-b14 diff -r a6502a8a6b31 -r 38f1b987027f make/hotspot_version --- a/make/hotspot_version Fri Jul 26 18:34:12 2013 +0100 +++ b/make/hotspot_version Fri Aug 09 12:21:36 2013 +0100 @@ -34,7 +34,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=23 -HS_MINOR_VER=7 +HS_MINOR_VER=25 HS_BUILD_NUMBER=01 JDK_MAJOR_VER=1 diff -r a6502a8a6b31 -r 38f1b987027f src/os/posix/vm/os_posix.cpp --- a/src/os/posix/vm/os_posix.cpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/os/posix/vm/os_posix.cpp Fri Aug 09 12:21:36 2013 +0100 @@ -75,6 +75,47 @@ return; } +// Multiple threads can race in this code, and can remap over each other with MAP_FIXED, +// so on posix, unmap the section at the start and at the end of the chunk that we mapped +// rather than unmapping and remapping the whole chunk to get requested alignment. +char* os::reserve_memory_aligned(size_t size, size_t alignment) { + assert((alignment & (os::vm_allocation_granularity() - 1)) == 0, + "Alignment must be a multiple of allocation granularity (page size)"); + assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned"); + + size_t extra_size = size + alignment; + assert(extra_size >= size, "overflow, size is too large to allow alignment"); + + char* extra_base = os::reserve_memory(extra_size, NULL, alignment); + + if (extra_base == NULL) { + return NULL; + } + + // Do manual alignment + char* aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment); + + // [ | | ] + // ^ extra_base + // ^ extra_base + begin_offset == aligned_base + // extra_base + begin_offset + size ^ + // extra_base + extra_size ^ + // |<>| == begin_offset + // end_offset == |<>| + size_t begin_offset = aligned_base - extra_base; + size_t end_offset = (extra_base + extra_size) - (aligned_base + size); + + if (begin_offset > 0) { + os::release_memory(extra_base, begin_offset); + } + + if (end_offset > 0) { + os::release_memory(extra_base + begin_offset + size, end_offset); + } + + return aligned_base; +} + void os::Posix::print_load_average(outputStream* st) { st->print("load average:"); double loadavg[3]; diff -r a6502a8a6b31 -r 38f1b987027f src/os/windows/vm/os_windows.cpp --- a/src/os/windows/vm/os_windows.cpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/os/windows/vm/os_windows.cpp Fri Aug 09 12:21:36 2013 +0100 @@ -2941,6 +2941,36 @@ } } +// Multiple threads can race in this code but it's not possible to unmap small sections of +// virtual space to get requested alignment, like posix-like os's. +// Windows prevents multiple thread from remapping over each other so this loop is thread-safe. +char* os::reserve_memory_aligned(size_t size, size_t alignment) { + assert((alignment & (os::vm_allocation_granularity() - 1)) == 0, + "Alignment must be a multiple of allocation granularity (page size)"); + assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned"); + + size_t extra_size = size + alignment; + assert(extra_size >= size, "overflow, size is too large to allow alignment"); + + char* aligned_base = NULL; + + do { + char* extra_base = os::reserve_memory(extra_size, NULL, alignment); + if (extra_base == NULL) { + return NULL; + } + // Do manual alignment + aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment); + + os::release_memory(extra_base, extra_size); + + aligned_base = os::reserve_memory(size, aligned_base); + + } while (aligned_base == NULL); + + return aligned_base; +} + char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) { assert((size_t)addr % os::vm_allocation_granularity() == 0, "reserve alignment"); diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/classfile/javaClasses.cpp --- a/src/share/vm/classfile/javaClasses.cpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/classfile/javaClasses.cpp Fri Aug 09 12:21:36 2013 +0100 @@ -2802,8 +2802,10 @@ result->obj_field_put(_context_offset, context()); result->obj_field_put(_privilegedContext_offset, privileged_context()); result->bool_field_put(_isPrivileged_offset, isPrivileged); - // whitelist AccessControlContexts created by the JVM. - result->bool_field_put(_isAuthorized_offset, true); + // whitelist AccessControlContexts created by the JVM if present + if (_isAuthorized_offset != -1) { + result->bool_field_put(_isAuthorized_offset, true); + } return result; } diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/classfile/javaClasses.hpp diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/classfile/vmSymbols.hpp diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/memory/allocation.cpp diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/memory/allocation.hpp diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/memory/universe.cpp diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/memory/universe.hpp diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/oops/cpCacheOop.cpp --- a/src/share/vm/oops/cpCacheOop.cpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/oops/cpCacheOop.cpp Fri Aug 09 12:21:36 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -470,6 +470,24 @@ return false; } +// a constant pool cache entry should never contain old or obsolete methods +bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() { + if (is_vfinal()) { + // virtual and final so _f2 contains method ptr instead of vtable index + methodOop m = (methodOop)_f2; + // Return false if _f2 refers to an old or an obsolete method. + // _f2 == NULL || !m->is_method() are just as unexpected here. + return (m != NULL && m->is_method() && !m->is_old() && !m->is_obsolete()); + } else if ((oop)_f1 == NULL || !((oop)_f1)->is_method()) { + // _f1 == NULL || !_f1->is_method() are OK here + return true; + } + + methodOop m = (methodOop)_f1; + // return false if _f1 refers to an old or an obsolete method + return (!m->is_old() && !m->is_obsolete()); +} + bool ConstantPoolCacheEntry::is_interesting_method_entry(klassOop k) { if (!is_method_entry()) { // not a method entry so not interesting by default @@ -492,7 +510,7 @@ } assert(m != NULL && m->is_method(), "sanity check"); - if (m == NULL || !m->is_method() || m->method_holder() != k) { + if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) { // robustness for above sanity checks or method is not in // the interesting class return false; @@ -577,3 +595,22 @@ } } } + +// the constant pool cache should never contain old or obsolete methods +bool constantPoolCacheOopDesc::check_no_old_or_obsolete_entries() { + for (int i = 1; i < length(); i++) { + if (entry_at(i)->is_interesting_method_entry(NULL) && + !entry_at(i)->check_no_old_or_obsolete_entries()) { + return false; + } + } + return true; +} + +void constantPoolCacheOopDesc::dump_cache() { + for (int i = 1; i < length(); i++) { + if (entry_at(i)->is_interesting_method_entry(NULL)) { + entry_at(i)->print(tty, i); + } + } +} diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/oops/cpCacheOop.hpp --- a/src/share/vm/oops/cpCacheOop.hpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/oops/cpCacheOop.hpp Fri Aug 09 12:21:36 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -298,6 +298,7 @@ // group don't print the klass name. bool adjust_method_entry(methodOop old_method, methodOop new_method, bool * trace_name_printed); + bool check_no_old_or_obsolete_entries(); bool is_interesting_method_entry(klassOop k); bool is_field_entry() const { return (_flags & (1 << hotSwapBit)) == 0; } bool is_method_entry() const { return (_flags & (1 << hotSwapBit)) != 0; } @@ -405,6 +406,8 @@ // group don't print the klass name. void adjust_method_entries(methodOop* old_methods, methodOop* new_methods, int methods_length, bool * trace_name_printed); + bool check_no_old_or_obsolete_entries(); + void dump_cache(); }; #endif // SHARE_VM_OOPS_CPCACHEOOP_HPP diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/oops/klassVtable.cpp --- a/src/share/vm/oops/klassVtable.cpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/oops/klassVtable.cpp Fri Aug 09 12:21:36 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -640,11 +640,37 @@ new_method->name()->as_C_string(), new_method->signature()->as_C_string())); } + // cannot 'break' here; see for-loop comment above. } } } } +// a vtable should never contain old or obsolete methods +bool klassVtable::check_no_old_or_obsolete_entries() { + for (int i = 0; i < length(); i++) { + methodOop m = unchecked_method_at(i); + if (m != NULL && (m->is_old() || m->is_obsolete())) { + return false; + } + } + return true; +} + +void klassVtable::dump_vtable() { + tty->print_cr("vtable dump --"); + for (int i = 0; i < length(); i++) { + methodOop m = unchecked_method_at(i); + if (m != NULL) { + tty->print(" (%5d) ", i); + m->access_flags().print_on(tty); + tty->print(" -- "); + m->print_name(tty); + tty->cr(); + } + } +} + // CDS/RedefineClasses support - clear vtables so they can be reinitialized void klassVtable::clear_vtable() { for (int i = 0; i < _length; i++) table()[i].clear(); @@ -994,13 +1020,42 @@ new_method->name()->as_C_string(), new_method->signature()->as_C_string())); } - break; + // cannot 'break' here; see for-loop comment above. } ime++; } } } +// an itable should never contain old or obsolete methods +bool klassItable::check_no_old_or_obsolete_entries() { + itableMethodEntry* ime = method_entry(0); + for (int i = 0; i < _size_method_table; i++) { + methodOop m = ime->method(); + if (m != NULL && (m->is_old() || m->is_obsolete())) { + return false; + } + ime++; + } + return true; +} + +void klassItable::dump_itable() { + itableMethodEntry* ime = method_entry(0); + tty->print_cr("itable dump --"); + for (int i = 0; i < _size_method_table; i++) { + methodOop m = ime->method(); + if (m != NULL) { + tty->print(" (%5d) ", i); + m->access_flags().print_on(tty); + tty->print(" -- "); + m->print_name(tty); + tty->cr(); + } + ime++; + } +} + // Setup class InterfaceVisiterClosure : public StackObj { @@ -1287,33 +1342,6 @@ tty->print_cr("%6d bytes total", total); } -bool klassVtable::check_no_old_entries() { - // Check that there really is no entry - for (int i = 0; i < length(); i++) { - methodOop m = unchecked_method_at(i); - if (m != NULL) { - if (m->is_old()) { - return false; - } - } - } - return true; -} - -void klassVtable::dump_vtable() { - tty->print_cr("vtable dump --"); - for (int i = 0; i < length(); i++) { - methodOop m = unchecked_method_at(i); - if (m != NULL) { - tty->print(" (%5d) ", i); - m->access_flags().print_on(tty); - tty->print(" -- "); - m->print_name(tty); - tty->cr(); - } - } -} - int klassItable::_total_classes; // Total no. of classes with itables long klassItable::_total_size; // Total no. of bytes used for itables diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/oops/klassVtable.hpp --- a/src/share/vm/oops/klassVtable.hpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/oops/klassVtable.hpp Fri Aug 09 12:21:36 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -98,6 +98,8 @@ // group don't print the klass name. void adjust_method_entries(methodOop* old_methods, methodOop* new_methods, int methods_length, bool * trace_name_printed); + bool check_no_old_or_obsolete_entries(); + void dump_vtable(); // Garbage collection void oop_follow_contents(); @@ -118,11 +120,6 @@ void verify(outputStream* st, bool force = false); static void print_statistics() PRODUCT_RETURN; -#ifndef PRODUCT - bool check_no_old_entries(); - void dump_vtable(); -#endif - protected: friend class vtableEntry; private: @@ -292,6 +289,8 @@ // group don't print the klass name. void adjust_method_entries(methodOop* old_methods, methodOop* new_methods, int methods_length, bool * trace_name_printed); + bool check_no_old_or_obsolete_entries(); + void dump_itable(); // Garbage collection void oop_follow_contents(); diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/oops/methodOop.cpp --- a/src/share/vm/oops/methodOop.cpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/oops/methodOop.cpp Fri Aug 09 12:21:36 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -1346,10 +1346,6 @@ } -//----------------------------------------------------------------------------------- -// Non-product code - -#ifndef PRODUCT class SignatureTypePrinter : public SignatureTypeNames { private: outputStream* _st; @@ -1386,6 +1382,10 @@ } +//----------------------------------------------------------------------------------- +// Non-product code + +#ifndef PRODUCT void methodOopDesc::print_codes_on(outputStream* st) const { print_codes_on(0, code_size(), st); } diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/oops/methodOop.hpp --- a/src/share/vm/oops/methodOop.hpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/oops/methodOop.hpp Fri Aug 09 12:21:36 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -703,8 +703,8 @@ static bool has_unloaded_classes_in_signature(methodHandle m, TRAPS); // Printing - void print_short_name(outputStream* st) /*PRODUCT_RETURN*/; // prints as klassname::methodname; Exposed so field engineers can debug VM - void print_name(outputStream* st) PRODUCT_RETURN; // prints as "virtual void foo(int)" + void print_short_name(outputStream* st); // prints as klassname::methodname; Exposed so field engineers can debug VM + void print_name(outputStream* st); // prints as "virtual void foo(int)"; exposed for TraceRedefineClasses // Helper routine used for method sorting static void sort_methods(objArrayOop methods, diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/opto/library_call.cpp diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/prims/jvm.cpp diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Aug 09 12:21:36 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -129,8 +129,15 @@ // See jvmtiExport.hpp for detailed explanation. JvmtiExport::set_has_redefined_a_class(); -#ifdef ASSERT - SystemDictionary::classes_do(check_class, thread); +// check_class() is optionally called for product bits, but is +// always called for non-product bits. +#ifdef PRODUCT + if (RC_TRACE_ENABLED(0x00004000)) { +#endif + RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class")); + SystemDictionary::classes_do(check_class, thread); +#ifdef PRODUCT + } #endif } @@ -3366,76 +3373,116 @@ } } -#ifndef PRODUCT void VM_RedefineClasses::check_class(klassOop k_oop, oop initiating_loader, TRAPS) { Klass *k = k_oop->klass_part(); if (k->oop_is_instance()) { HandleMark hm(THREAD); instanceKlass *ik = (instanceKlass *) k; - - if (ik->vtable_length() > 0) { - ResourceMark rm(THREAD); - if (!ik->vtable()->check_no_old_entries()) { - tty->print_cr("klassVtable::check_no_old_entries failure -- OLD method found -- class: %s", ik->signature_name()); + bool no_old_methods = true; // be optimistic + ResourceMark rm(THREAD); + + // a vtable should never contain old or obsolete methods + if (ik->vtable_length() > 0 && + !ik->vtable()->check_no_old_or_obsolete_entries()) { + if (RC_TRACE_ENABLED(0x00004000)) { + RC_TRACE_WITH_THREAD(0x00004000, THREAD, + ("klassVtable::check_no_old_or_obsolete_entries failure" + " -- OLD or OBSOLETE method found -- class: %s", + ik->signature_name())); ik->vtable()->dump_vtable(); + } + no_old_methods = false; + } + + // an itable should never contain old or obsolete methods + if (ik->itable_length() > 0 && + !ik->itable()->check_no_old_or_obsolete_entries()) { + if (RC_TRACE_ENABLED(0x00004000)) { + RC_TRACE_WITH_THREAD(0x00004000, THREAD, + ("klassItable::check_no_old_or_obsolete_entries failure" + " -- OLD or OBSOLETE method found -- class: %s", + ik->signature_name())); + ik->itable()->dump_itable(); + } + no_old_methods = false; + } + + // the constant pool cache should never contain old or obsolete methods + if (ik->constants() != NULL && + ik->constants()->cache() != NULL && + !ik->constants()->cache()->check_no_old_or_obsolete_entries()) { + if (RC_TRACE_ENABLED(0x00004000)) { + RC_TRACE_WITH_THREAD(0x00004000, THREAD, + ("cp-cache::check_no_old_or_obsolete_entries failure" + " -- OLD or OBSOLETE method found -- class: %s", + ik->signature_name())); + ik->constants()->cache()->dump_cache(); + } + no_old_methods = false; + } + + if (!no_old_methods) { + if (RC_TRACE_ENABLED(0x00004000)) { dump_methods(); - assert(false, "OLD method found"); + } else { + tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option " + "to see more info about the following guarantee() failure."); } + guarantee(false, "OLD and/or OBSOLETE method(s) found"); } } } void VM_RedefineClasses::dump_methods() { - int j; - tty->print_cr("_old_methods --"); - for (j = 0; j < _old_methods->length(); ++j) { - methodOop m = (methodOop) _old_methods->obj_at(j); - tty->print("%4d (%5d) ", j, m->vtable_index()); - m->access_flags().print_on(tty); - tty->print(" -- "); - m->print_name(tty); - tty->cr(); - } - tty->print_cr("_new_methods --"); - for (j = 0; j < _new_methods->length(); ++j) { - methodOop m = (methodOop) _new_methods->obj_at(j); - tty->print("%4d (%5d) ", j, m->vtable_index()); - m->access_flags().print_on(tty); - tty->print(" -- "); - m->print_name(tty); - tty->cr(); - } - tty->print_cr("_matching_(old/new)_methods --"); - for (j = 0; j < _matching_methods_length; ++j) { - methodOop m = _matching_old_methods[j]; - tty->print("%4d (%5d) ", j, m->vtable_index()); - m->access_flags().print_on(tty); - tty->print(" -- "); - m->print_name(tty); - tty->cr(); - m = _matching_new_methods[j]; - tty->print(" (%5d) ", m->vtable_index()); - m->access_flags().print_on(tty); - tty->cr(); - } - tty->print_cr("_deleted_methods --"); - for (j = 0; j < _deleted_methods_length; ++j) { - methodOop m = _deleted_methods[j]; - tty->print("%4d (%5d) ", j, m->vtable_index()); - m->access_flags().print_on(tty); - tty->print(" -- "); - m->print_name(tty); - tty->cr(); - } - tty->print_cr("_added_methods --"); - for (j = 0; j < _added_methods_length; ++j) { - methodOop m = _added_methods[j]; - tty->print("%4d (%5d) ", j, m->vtable_index()); - m->access_flags().print_on(tty); - tty->print(" -- "); - m->print_name(tty); - tty->cr(); - } + int j; + RC_TRACE(0x00004000, ("_old_methods --")); + for (j = 0; j < _old_methods->length(); ++j) { + methodOop m = (methodOop) _old_methods->obj_at(j); + RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); + m->access_flags().print_on(tty); + tty->print(" -- "); + m->print_name(tty); + tty->cr(); + } + RC_TRACE(0x00004000, ("_new_methods --")); + for (j = 0; j < _new_methods->length(); ++j) { + methodOop m = (methodOop) _new_methods->obj_at(j); + RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); + m->access_flags().print_on(tty); + tty->print(" -- "); + m->print_name(tty); + tty->cr(); + } + RC_TRACE(0x00004000, ("_matching_(old/new)_methods --")); + for (j = 0; j < _matching_methods_length; ++j) { + methodOop m = _matching_old_methods[j]; + RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); + m->access_flags().print_on(tty); + tty->print(" -- "); + m->print_name(tty); + tty->cr(); + m = _matching_new_methods[j]; + RC_TRACE_NO_CR(0x00004000, (" (%5d) ", m->vtable_index())); + m->access_flags().print_on(tty); + tty->cr(); + } + RC_TRACE(0x00004000, ("_deleted_methods --")); + for (j = 0; j < _deleted_methods_length; ++j) { + methodOop m = _deleted_methods[j]; + RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); + m->access_flags().print_on(tty); + tty->print(" -- "); + m->print_name(tty); + tty->cr(); + } + RC_TRACE(0x00004000, ("_added_methods --")); + for (j = 0; j < _added_methods_length; ++j) { + methodOop m = _added_methods[j]; + RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); + m->access_flags().print_on(tty); + tty->print(" -- "); + m->print_name(tty); + tty->cr(); + } } -#endif diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/prims/jvmtiRedefineClasses.hpp --- a/src/share/vm/prims/jvmtiRedefineClasses.hpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/prims/jvmtiRedefineClasses.hpp Fri Aug 09 12:21:36 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -478,9 +478,8 @@ void flush_dependent_code(instanceKlassHandle k_h, TRAPS); - static void check_class(klassOop k_oop, oop initiating_loader, TRAPS) PRODUCT_RETURN; - - static void dump_methods() PRODUCT_RETURN; + static void check_class(klassOop k_oop, oop initiating_loader, TRAPS); + static void dump_methods(); public: VM_RedefineClasses(jint class_count, diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/prims/jvmtiRedefineClassesTrace.hpp --- a/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp Fri Aug 09 12:21:36 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -54,7 +54,7 @@ // 0x00000800 | 2048 - previous class breakpoint mgmt // 0x00001000 | 4096 - detect calls to obsolete methods // 0x00002000 | 8192 - fail a guarantee() in addition to detection -// 0x00004000 | 16384 - unused +// 0x00004000 | 16384 - detect old/obsolete methods in metadata // 0x00008000 | 32768 - old/new method matching/add/delete // 0x00010000 | 65536 - impl details: CP size info // 0x00020000 | 131072 - impl details: CP merge pass info @@ -82,6 +82,13 @@ tty->print_cr args; \ } while (0) +#define RC_TRACE_NO_CR(level, args) \ + if ((TraceRedefineClasses & level) != 0) { \ + ResourceMark rm; \ + tty->print("RedefineClasses-0x%x: ", level); \ + tty->print args; \ + } while (0) + #define RC_TRACE_WITH_THREAD(level, thread, args) \ if ((TraceRedefineClasses & level) != 0) { \ ResourceMark rm(thread); \ diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/runtime/os.hpp --- a/src/share/vm/runtime/os.hpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/runtime/os.hpp Fri Aug 09 12:21:36 2013 +0100 @@ -233,6 +233,7 @@ static int vm_allocation_granularity(); static char* reserve_memory(size_t bytes, char* addr = 0, size_t alignment_hint = 0); + static char* reserve_memory_aligned(size_t size, size_t alignment); static char* attempt_reserve_memory_at(size_t bytes, char* addr); static void split_reserved_memory(char *base, size_t size, size_t split, bool realloc); diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/runtime/virtualspace.cpp --- a/src/share/vm/runtime/virtualspace.cpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/runtime/virtualspace.cpp Fri Aug 09 12:21:36 2013 +0100 @@ -340,20 +340,9 @@ if ((((size_t)base + noaccess_prefix) & (alignment - 1)) != 0) { // Base not aligned, retry if (!os::release_memory(base, size)) fatal("os::release_memory failed"); - // Reserve size large enough to do manual alignment and - // increase size to a multiple of the desired alignment + // Make sure that size is aligned size = align_size_up(size, alignment); - size_t extra_size = size + alignment; - do { - char* extra_base = os::reserve_memory(extra_size, NULL, alignment); - if (extra_base == NULL) return; - // Do manual alignement - base = (char*) align_size_up((uintptr_t) extra_base, alignment); - assert(base >= extra_base, "just checking"); - // Re-reserve the region at the aligned base address. - os::release_memory(extra_base, extra_size); - base = os::reserve_memory(size, base); - } while (base == NULL); + base = os::reserve_memory_aligned(size, alignment); if (requested_address != 0 && failed_to_reserve_as_requested(base, requested_address, size, false)) { diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/utilities/accessFlags.cpp --- a/src/share/vm/utilities/accessFlags.cpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/utilities/accessFlags.cpp Fri Aug 09 12:21:36 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -59,8 +59,6 @@ } while(f != old_flags); } -#ifndef PRODUCT - void AccessFlags::print_on(outputStream* st) const { if (is_public ()) st->print("public " ); if (is_private ()) st->print("private " ); @@ -79,8 +77,6 @@ if (is_obsolete ()) st->print("{obsolete} " ); } -#endif - void accessFlags_init() { assert(sizeof(AccessFlags) == sizeof(jint), "just checking size of flags"); } diff -r a6502a8a6b31 -r 38f1b987027f src/share/vm/utilities/accessFlags.hpp --- a/src/share/vm/utilities/accessFlags.hpp Fri Jul 26 18:34:12 2013 +0100 +++ b/src/share/vm/utilities/accessFlags.hpp Fri Aug 09 12:21:36 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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,7 +233,7 @@ inline friend AccessFlags accessFlags_from(jint flags); // Printing/debugging - void print_on(outputStream* st) const PRODUCT_RETURN; + void print_on(outputStream* st) const; }; inline AccessFlags accessFlags_from(jint flags) {