Mercurial > hg > icedtea8-forest > hotspot
changeset 9662:0bd600d6d77b jdk8u152-b04
Merge
author | robm |
---|---|
date | Fri, 05 May 2017 06:07:11 -0700 |
parents | cf85f331361b (current diff) afff7bd98f7d (diff) |
children | 4d9931ebf861 ce9a710b0f63 |
files | |
diffstat | 8 files changed, 189 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/classfile/classFileError.cpp Tue Apr 18 15:44:32 2017 -0700 +++ b/src/share/vm/classfile/classFileError.cpp Fri May 05 06:07:11 2017 -0700 @@ -56,6 +56,13 @@ msg, index, name, _class_name->as_C_string()); } +void ClassFileParser::classfile_parse_error(const char* msg, const char* name, const char* signature, TRAPS) { + assert(_class_name != NULL, "invariant"); + ResourceMark rm(THREAD); + Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), + msg, name, signature, _class_name->as_C_string()); +} + PRAGMA_DIAG_POP void StackMapStream::stackmap_format_error(const char* msg, TRAPS) {
--- a/src/share/vm/classfile/classFileParser.cpp Tue Apr 18 15:44:32 2017 -0700 +++ b/src/share/vm/classfile/classFileParser.cpp Fri May 05 06:07:11 2017 -0700 @@ -821,11 +821,12 @@ THREAD, NameSigHash*, HASH_ROW_SIZE); initialize_hashtable(interface_names); bool dup = false; + Symbol* name = NULL; { debug_only(No_Safepoint_Verifier nsv;) for (index = 0; index < length; index++) { Klass* k = _local_interfaces->at(index); - Symbol* name = InstanceKlass::cast(k)->name(); + name = InstanceKlass::cast(k)->name(); // If no duplicates, add (name, NULL) in hashtable interface_names. if (!put_after_lookup(name, NULL, interface_names)) { dup = true; @@ -834,7 +835,8 @@ } } if (dup) { - classfile_parse_error("Duplicate interface name in class file %s", CHECK_NULL); + classfile_parse_error("Duplicate interface name \"%s\" in class file %s", + name->as_C_string(), CHECK_NULL); } } return _local_interfaces; @@ -1279,11 +1281,13 @@ THREAD, NameSigHash*, HASH_ROW_SIZE); initialize_hashtable(names_and_sigs); bool dup = false; + Symbol* name = NULL; + Symbol* sig = NULL; { debug_only(No_Safepoint_Verifier nsv;) for (AllFieldStream fs(fields, _cp); !fs.done(); fs.next()) { - Symbol* name = fs.name(); - Symbol* sig = fs.signature(); + name = fs.name(); + sig = fs.signature(); // If no duplicates, add name/signature in hashtable names_and_sigs. if (!put_after_lookup(name, sig, names_and_sigs)) { dup = true; @@ -1292,8 +1296,8 @@ } } if (dup) { - classfile_parse_error("Duplicate field name&signature in class file %s", - CHECK_NULL); + classfile_parse_error("Duplicate field name \"%s\" with signature \"%s\" in class file %s", + name->as_C_string(), sig->as_klass_external_name(), CHECK_NULL); } } @@ -2580,20 +2584,24 @@ THREAD, NameSigHash*, HASH_ROW_SIZE); initialize_hashtable(names_and_sigs); bool dup = false; + Symbol* name = NULL; + Symbol* sig = NULL; { debug_only(No_Safepoint_Verifier nsv;) for (int i = 0; i < length; i++) { Method* m = _methods->at(i); + name = m->name(); + sig = m->signature(); // If no duplicates, add name/signature in hashtable names_and_sigs. - if (!put_after_lookup(m->name(), m->signature(), names_and_sigs)) { + if (!put_after_lookup(name, sig, names_and_sigs)) { dup = true; break; } } } if (dup) { - classfile_parse_error("Duplicate method name&signature in class file %s", - CHECK_NULL); + classfile_parse_error("Duplicate method name \"%s\" with signature \"%s\" in class file %s", + name->as_C_string(), sig->as_klass_external_name(), CHECK_NULL); } } }
--- a/src/share/vm/classfile/classFileParser.hpp Tue Apr 18 15:44:32 2017 -0700 +++ b/src/share/vm/classfile/classFileParser.hpp Fri May 05 06:07:11 2017 -0700 @@ -314,6 +314,7 @@ void classfile_parse_error(const char* msg, int index, TRAPS); void classfile_parse_error(const char* msg, const char *name, TRAPS); void classfile_parse_error(const char* msg, int index, const char *name, TRAPS); + void classfile_parse_error(const char* msg, const char* name, const char* signature, TRAPS); inline void guarantee_property(bool b, const char* msg, TRAPS) { if (!b) { classfile_parse_error(msg, CHECK); } }
--- a/src/share/vm/classfile/classLoaderData.cpp Tue Apr 18 15:44:32 2017 -0700 +++ b/src/share/vm/classfile/classLoaderData.cpp Fri May 05 06:07:11 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, 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 @@ -78,7 +78,7 @@ // The null-class-loader should always be kept alive. _keep_alive(is_anonymous || h_class_loader.is_null()), _metaspace(NULL), _unloading(false), _klasses(NULL), - _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL), + _claimed(0), _jmethod_ids(NULL), _handles(), _deallocate_list(NULL), _next(NULL), _dependencies(dependencies), _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) { // empty @@ -96,6 +96,45 @@ _list_head = oopFactory::new_objectArray(2, CHECK); } +ClassLoaderData::ChunkedHandleList::~ChunkedHandleList() { + Chunk* c = _head; + while (c != NULL) { + Chunk* next = c->_next; + delete c; + c = next; + } +} + +oop* ClassLoaderData::ChunkedHandleList::add(oop o) { + if (_head == NULL || _head->_size == Chunk::CAPACITY) { + Chunk* next = new Chunk(_head); + OrderAccess::release_store_ptr(&_head, next); + } + oop* handle = &_head->_data[_head->_size]; + *handle = o; + OrderAccess::release_store(&_head->_size, _head->_size + 1); + return handle; +} + +inline void ClassLoaderData::ChunkedHandleList::oops_do_chunk(OopClosure* f, Chunk* c, const juint size) { + for (juint i = 0; i < size; i++) { + if (c->_data[i] != NULL) { + f->do_oop(&c->_data[i]); + } + } +} + +void ClassLoaderData::ChunkedHandleList::oops_do(OopClosure* f) { + Chunk* head = (Chunk*) OrderAccess::load_ptr_acquire(&_head); + if (head != NULL) { + // Must be careful when reading size of head + oops_do_chunk(f, head, OrderAccess::load_acquire(&head->_size)); + for (Chunk* c = head->_next; c != NULL; c = c->_next) { + oops_do_chunk(f, c, c->_size); + } + } +} + bool ClassLoaderData::claim() { if (_claimed == 1) { return false; @@ -111,7 +150,7 @@ f->do_oop(&_class_loader); _dependencies.oops_do(f); - _handles->oops_do(f); + _handles.oops_do(f); if (klass_closure != NULL) { classes_do(klass_closure); } @@ -342,11 +381,6 @@ _metaspace = NULL; // release the metaspace delete m; - // release the handles - if (_handles != NULL) { - JNIHandleBlock::release_block(_handles); - _handles = NULL; - } } // Clear all the JNI handles for methods @@ -406,15 +440,9 @@ return _metaspace; } -JNIHandleBlock* ClassLoaderData::handles() const { return _handles; } -void ClassLoaderData::set_handles(JNIHandleBlock* handles) { _handles = handles; } - jobject ClassLoaderData::add_handle(Handle h) { MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); - if (handles() == NULL) { - set_handles(JNIHandleBlock::allocate_block()); - } - return handles()->allocate_handle(h()); + return (jobject) _handles.add(h()); } // Add this metadata pointer to be freed when it's safe. This is only during @@ -479,7 +507,6 @@ p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name()); if (claimed()) out->print(" claimed "); if (is_unloading()) out->print(" unloading "); - out->print(" handles " INTPTR_FORMAT, p2i(handles())); out->cr(); if (metaspace_or_null() != NULL) { out->print_cr("metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null()));
--- a/src/share/vm/classfile/classLoaderData.hpp Tue Apr 18 15:44:32 2017 -0700 +++ b/src/share/vm/classfile/classLoaderData.hpp Fri May 05 06:07:11 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, 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 @@ -51,7 +51,6 @@ class ClassLoaderData; class JNIMethodBlock; -class JNIHandleBlock; class Metadebug; // GC root for walking class loader data created @@ -145,6 +144,31 @@ void oops_do(OopClosure* f); }; + class ChunkedHandleList VALUE_OBJ_CLASS_SPEC { + struct Chunk : public CHeapObj<mtClass> { + static const size_t CAPACITY = 32; + + oop _data[CAPACITY]; + volatile juint _size; + Chunk* _next; + + Chunk(Chunk* c) : _next(c), _size(0) { } + }; + + Chunk* _head; + + void oops_do_chunk(OopClosure* f, Chunk* c, const juint size); + + public: + ChunkedHandleList() : _head(NULL) {} + ~ChunkedHandleList(); + + // Only one thread at a time can add, guarded by ClassLoaderData::metaspace_lock(). + // However, multiple threads can execute oops_do concurrently with add. + oop* add(oop o); + void oops_do(OopClosure* f); + }; + friend class ClassLoaderDataGraph; friend class ClassLoaderDataGraphKlassIteratorAtomic; friend class ClassLoaderDataGraphMetaspaceIterator; @@ -169,7 +193,8 @@ // Has to be an int because we cas it. Klass* _klasses; // The classes defined by the class loader. - JNIHandleBlock* _handles; // Handles to constant pool arrays + ChunkedHandleList _handles; // Handles to constant pool arrays, etc, which + // have the same life cycle of the corresponding ClassLoader. // These method IDs are created for the class loader and set to NULL when the // class loader is unloaded. They are rarely freed, only for redefine classes @@ -196,9 +221,6 @@ void set_metaspace(Metaspace* m) { _metaspace = m; } - JNIHandleBlock* handles() const; - void set_handles(JNIHandleBlock* handles); - Mutex* metaspace_lock() const { return _metaspace_lock; } // GC interface.
--- a/src/share/vm/runtime/arguments.cpp Tue Apr 18 15:44:32 2017 -0700 +++ b/src/share/vm/runtime/arguments.cpp Fri May 05 06:07:11 2017 -0700 @@ -3193,8 +3193,6 @@ // Enable parallel GC and adaptive generation sizing FLAG_SET_CMDLINE(bool, UseParallelGC, true); - FLAG_SET_DEFAULT(ParallelGCThreads, - Abstract_VM_Version::parallel_worker_threads()); // Encourage steady state memory management FLAG_SET_CMDLINE(uintx, ThresholdTolerance, 100);
--- a/test/TEST.groups Tue Apr 18 15:44:32 2017 -0700 +++ b/test/TEST.groups Fri May 05 06:07:11 2017 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 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 @@ -164,6 +164,7 @@ gc/TestGCLogRotationViaJcmd.java \ gc/g1/TestHumongousAllocInitialMark.java \ gc/g1/TestHumongousShrinkHeap.java \ + gc/arguments/TestAggressiveHeap.java \ gc/arguments/TestG1HeapRegionSize.java \ gc/metaspace/TestMetaspaceMemoryPool.java \ gc/arguments/TestDynMinHeapFreeRatio.java \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/arguments/TestAggressiveHeap.java Fri May 05 06:07:11 2017 -0700 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 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 + * 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. + */ + +/* + * @test TestAggressiveHeap + * @key gc + * @bug 8179084 + * @summary Test argument processing for -XX:+AggressiveHeap. + * @library /testlibrary + * @run driver TestAggressiveHeap + */ + +import java.lang.management.ManagementFactory; +import javax.management.MBeanServer; +import javax.management.ObjectName; + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +public class TestAggressiveHeap { + + public static void main(String args[]) throws Exception { + if (canUseAggressiveHeapOption()) { + testFlag(); + } + } + + // Note: Not a normal boolean flag; -XX:-AggressiveHeap is invalid. + private static final String option = "-XX:+AggressiveHeap"; + + // Option requires at least 256M, else error during option processing. + private static final long minMemory = 256 * 1024 * 1024; + + // bool UseParallelGC := true {product} + private static final String parallelGCPattern = + " *bool +UseParallelGC *:= *true +\\{product\\}"; + + private static void testFlag() throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + option, "-XX:+PrintFlagsFinal", "-version"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + output.shouldHaveExitValue(0); + + String value = output.firstMatch(parallelGCPattern); + if (value == null) { + throw new RuntimeException( + option + " didn't set UseParallelGC"); + } + } + + private static boolean haveRequiredMemory() throws Exception { + MBeanServer server = ManagementFactory.getPlatformMBeanServer(); + ObjectName os = new ObjectName("java.lang", "type", "OperatingSystem"); + Object attr = server.getAttribute(os, "TotalPhysicalMemorySize"); + String value = attr.toString(); + long memory = Long.parseLong(value); + return memory >= minMemory; + } + + private static boolean canUseAggressiveHeapOption() throws Exception { + if (!haveRequiredMemory()) { + System.out.println( + "Skipping test of " + option + " : insufficient memory"); + return false; + } + return true; + } +} +