Fri, 05 May 2017 06:07:11 -0700
Merge
1.1 --- a/src/share/vm/classfile/classFileError.cpp Tue Apr 18 15:44:32 2017 -0700 1.2 +++ b/src/share/vm/classfile/classFileError.cpp Fri May 05 06:07:11 2017 -0700 1.3 @@ -56,6 +56,13 @@ 1.4 msg, index, name, _class_name->as_C_string()); 1.5 } 1.6 1.7 +void ClassFileParser::classfile_parse_error(const char* msg, const char* name, const char* signature, TRAPS) { 1.8 + assert(_class_name != NULL, "invariant"); 1.9 + ResourceMark rm(THREAD); 1.10 + Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), 1.11 + msg, name, signature, _class_name->as_C_string()); 1.12 +} 1.13 + 1.14 PRAGMA_DIAG_POP 1.15 1.16 void StackMapStream::stackmap_format_error(const char* msg, TRAPS) {
2.1 --- a/src/share/vm/classfile/classFileParser.cpp Tue Apr 18 15:44:32 2017 -0700 2.2 +++ b/src/share/vm/classfile/classFileParser.cpp Fri May 05 06:07:11 2017 -0700 2.3 @@ -821,11 +821,12 @@ 2.4 THREAD, NameSigHash*, HASH_ROW_SIZE); 2.5 initialize_hashtable(interface_names); 2.6 bool dup = false; 2.7 + Symbol* name = NULL; 2.8 { 2.9 debug_only(No_Safepoint_Verifier nsv;) 2.10 for (index = 0; index < length; index++) { 2.11 Klass* k = _local_interfaces->at(index); 2.12 - Symbol* name = InstanceKlass::cast(k)->name(); 2.13 + name = InstanceKlass::cast(k)->name(); 2.14 // If no duplicates, add (name, NULL) in hashtable interface_names. 2.15 if (!put_after_lookup(name, NULL, interface_names)) { 2.16 dup = true; 2.17 @@ -834,7 +835,8 @@ 2.18 } 2.19 } 2.20 if (dup) { 2.21 - classfile_parse_error("Duplicate interface name in class file %s", CHECK_NULL); 2.22 + classfile_parse_error("Duplicate interface name \"%s\" in class file %s", 2.23 + name->as_C_string(), CHECK_NULL); 2.24 } 2.25 } 2.26 return _local_interfaces; 2.27 @@ -1279,11 +1281,13 @@ 2.28 THREAD, NameSigHash*, HASH_ROW_SIZE); 2.29 initialize_hashtable(names_and_sigs); 2.30 bool dup = false; 2.31 + Symbol* name = NULL; 2.32 + Symbol* sig = NULL; 2.33 { 2.34 debug_only(No_Safepoint_Verifier nsv;) 2.35 for (AllFieldStream fs(fields, _cp); !fs.done(); fs.next()) { 2.36 - Symbol* name = fs.name(); 2.37 - Symbol* sig = fs.signature(); 2.38 + name = fs.name(); 2.39 + sig = fs.signature(); 2.40 // If no duplicates, add name/signature in hashtable names_and_sigs. 2.41 if (!put_after_lookup(name, sig, names_and_sigs)) { 2.42 dup = true; 2.43 @@ -1292,8 +1296,8 @@ 2.44 } 2.45 } 2.46 if (dup) { 2.47 - classfile_parse_error("Duplicate field name&signature in class file %s", 2.48 - CHECK_NULL); 2.49 + classfile_parse_error("Duplicate field name \"%s\" with signature \"%s\" in class file %s", 2.50 + name->as_C_string(), sig->as_klass_external_name(), CHECK_NULL); 2.51 } 2.52 } 2.53 2.54 @@ -2580,20 +2584,24 @@ 2.55 THREAD, NameSigHash*, HASH_ROW_SIZE); 2.56 initialize_hashtable(names_and_sigs); 2.57 bool dup = false; 2.58 + Symbol* name = NULL; 2.59 + Symbol* sig = NULL; 2.60 { 2.61 debug_only(No_Safepoint_Verifier nsv;) 2.62 for (int i = 0; i < length; i++) { 2.63 Method* m = _methods->at(i); 2.64 + name = m->name(); 2.65 + sig = m->signature(); 2.66 // If no duplicates, add name/signature in hashtable names_and_sigs. 2.67 - if (!put_after_lookup(m->name(), m->signature(), names_and_sigs)) { 2.68 + if (!put_after_lookup(name, sig, names_and_sigs)) { 2.69 dup = true; 2.70 break; 2.71 } 2.72 } 2.73 } 2.74 if (dup) { 2.75 - classfile_parse_error("Duplicate method name&signature in class file %s", 2.76 - CHECK_NULL); 2.77 + classfile_parse_error("Duplicate method name \"%s\" with signature \"%s\" in class file %s", 2.78 + name->as_C_string(), sig->as_klass_external_name(), CHECK_NULL); 2.79 } 2.80 } 2.81 }
3.1 --- a/src/share/vm/classfile/classFileParser.hpp Tue Apr 18 15:44:32 2017 -0700 3.2 +++ b/src/share/vm/classfile/classFileParser.hpp Fri May 05 06:07:11 2017 -0700 3.3 @@ -314,6 +314,7 @@ 3.4 void classfile_parse_error(const char* msg, int index, TRAPS); 3.5 void classfile_parse_error(const char* msg, const char *name, TRAPS); 3.6 void classfile_parse_error(const char* msg, int index, const char *name, TRAPS); 3.7 + void classfile_parse_error(const char* msg, const char* name, const char* signature, TRAPS); 3.8 inline void guarantee_property(bool b, const char* msg, TRAPS) { 3.9 if (!b) { classfile_parse_error(msg, CHECK); } 3.10 }
4.1 --- a/src/share/vm/classfile/classLoaderData.cpp Tue Apr 18 15:44:32 2017 -0700 4.2 +++ b/src/share/vm/classfile/classLoaderData.cpp Fri May 05 06:07:11 2017 -0700 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -78,7 +78,7 @@ 4.11 // The null-class-loader should always be kept alive. 4.12 _keep_alive(is_anonymous || h_class_loader.is_null()), 4.13 _metaspace(NULL), _unloading(false), _klasses(NULL), 4.14 - _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL), 4.15 + _claimed(0), _jmethod_ids(NULL), _handles(), _deallocate_list(NULL), 4.16 _next(NULL), _dependencies(dependencies), 4.17 _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) { 4.18 // empty 4.19 @@ -96,6 +96,45 @@ 4.20 _list_head = oopFactory::new_objectArray(2, CHECK); 4.21 } 4.22 4.23 +ClassLoaderData::ChunkedHandleList::~ChunkedHandleList() { 4.24 + Chunk* c = _head; 4.25 + while (c != NULL) { 4.26 + Chunk* next = c->_next; 4.27 + delete c; 4.28 + c = next; 4.29 + } 4.30 +} 4.31 + 4.32 +oop* ClassLoaderData::ChunkedHandleList::add(oop o) { 4.33 + if (_head == NULL || _head->_size == Chunk::CAPACITY) { 4.34 + Chunk* next = new Chunk(_head); 4.35 + OrderAccess::release_store_ptr(&_head, next); 4.36 + } 4.37 + oop* handle = &_head->_data[_head->_size]; 4.38 + *handle = o; 4.39 + OrderAccess::release_store(&_head->_size, _head->_size + 1); 4.40 + return handle; 4.41 +} 4.42 + 4.43 +inline void ClassLoaderData::ChunkedHandleList::oops_do_chunk(OopClosure* f, Chunk* c, const juint size) { 4.44 + for (juint i = 0; i < size; i++) { 4.45 + if (c->_data[i] != NULL) { 4.46 + f->do_oop(&c->_data[i]); 4.47 + } 4.48 + } 4.49 +} 4.50 + 4.51 +void ClassLoaderData::ChunkedHandleList::oops_do(OopClosure* f) { 4.52 + Chunk* head = (Chunk*) OrderAccess::load_ptr_acquire(&_head); 4.53 + if (head != NULL) { 4.54 + // Must be careful when reading size of head 4.55 + oops_do_chunk(f, head, OrderAccess::load_acquire(&head->_size)); 4.56 + for (Chunk* c = head->_next; c != NULL; c = c->_next) { 4.57 + oops_do_chunk(f, c, c->_size); 4.58 + } 4.59 + } 4.60 +} 4.61 + 4.62 bool ClassLoaderData::claim() { 4.63 if (_claimed == 1) { 4.64 return false; 4.65 @@ -111,7 +150,7 @@ 4.66 4.67 f->do_oop(&_class_loader); 4.68 _dependencies.oops_do(f); 4.69 - _handles->oops_do(f); 4.70 + _handles.oops_do(f); 4.71 if (klass_closure != NULL) { 4.72 classes_do(klass_closure); 4.73 } 4.74 @@ -342,11 +381,6 @@ 4.75 _metaspace = NULL; 4.76 // release the metaspace 4.77 delete m; 4.78 - // release the handles 4.79 - if (_handles != NULL) { 4.80 - JNIHandleBlock::release_block(_handles); 4.81 - _handles = NULL; 4.82 - } 4.83 } 4.84 4.85 // Clear all the JNI handles for methods 4.86 @@ -406,15 +440,9 @@ 4.87 return _metaspace; 4.88 } 4.89 4.90 -JNIHandleBlock* ClassLoaderData::handles() const { return _handles; } 4.91 -void ClassLoaderData::set_handles(JNIHandleBlock* handles) { _handles = handles; } 4.92 - 4.93 jobject ClassLoaderData::add_handle(Handle h) { 4.94 MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); 4.95 - if (handles() == NULL) { 4.96 - set_handles(JNIHandleBlock::allocate_block()); 4.97 - } 4.98 - return handles()->allocate_handle(h()); 4.99 + return (jobject) _handles.add(h()); 4.100 } 4.101 4.102 // Add this metadata pointer to be freed when it's safe. This is only during 4.103 @@ -479,7 +507,6 @@ 4.104 p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name()); 4.105 if (claimed()) out->print(" claimed "); 4.106 if (is_unloading()) out->print(" unloading "); 4.107 - out->print(" handles " INTPTR_FORMAT, p2i(handles())); 4.108 out->cr(); 4.109 if (metaspace_or_null() != NULL) { 4.110 out->print_cr("metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null()));
5.1 --- a/src/share/vm/classfile/classLoaderData.hpp Tue Apr 18 15:44:32 2017 -0700 5.2 +++ b/src/share/vm/classfile/classLoaderData.hpp Fri May 05 06:07:11 2017 -0700 5.3 @@ -1,5 +1,5 @@ 5.4 /* 5.5 - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 5.6 + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. 5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 * 5.9 * This code is free software; you can redistribute it and/or modify it 5.10 @@ -51,7 +51,6 @@ 5.11 5.12 class ClassLoaderData; 5.13 class JNIMethodBlock; 5.14 -class JNIHandleBlock; 5.15 class Metadebug; 5.16 5.17 // GC root for walking class loader data created 5.18 @@ -145,6 +144,31 @@ 5.19 void oops_do(OopClosure* f); 5.20 }; 5.21 5.22 + class ChunkedHandleList VALUE_OBJ_CLASS_SPEC { 5.23 + struct Chunk : public CHeapObj<mtClass> { 5.24 + static const size_t CAPACITY = 32; 5.25 + 5.26 + oop _data[CAPACITY]; 5.27 + volatile juint _size; 5.28 + Chunk* _next; 5.29 + 5.30 + Chunk(Chunk* c) : _next(c), _size(0) { } 5.31 + }; 5.32 + 5.33 + Chunk* _head; 5.34 + 5.35 + void oops_do_chunk(OopClosure* f, Chunk* c, const juint size); 5.36 + 5.37 + public: 5.38 + ChunkedHandleList() : _head(NULL) {} 5.39 + ~ChunkedHandleList(); 5.40 + 5.41 + // Only one thread at a time can add, guarded by ClassLoaderData::metaspace_lock(). 5.42 + // However, multiple threads can execute oops_do concurrently with add. 5.43 + oop* add(oop o); 5.44 + void oops_do(OopClosure* f); 5.45 + }; 5.46 + 5.47 friend class ClassLoaderDataGraph; 5.48 friend class ClassLoaderDataGraphKlassIteratorAtomic; 5.49 friend class ClassLoaderDataGraphMetaspaceIterator; 5.50 @@ -169,7 +193,8 @@ 5.51 // Has to be an int because we cas it. 5.52 Klass* _klasses; // The classes defined by the class loader. 5.53 5.54 - JNIHandleBlock* _handles; // Handles to constant pool arrays 5.55 + ChunkedHandleList _handles; // Handles to constant pool arrays, etc, which 5.56 + // have the same life cycle of the corresponding ClassLoader. 5.57 5.58 // These method IDs are created for the class loader and set to NULL when the 5.59 // class loader is unloaded. They are rarely freed, only for redefine classes 5.60 @@ -196,9 +221,6 @@ 5.61 5.62 void set_metaspace(Metaspace* m) { _metaspace = m; } 5.63 5.64 - JNIHandleBlock* handles() const; 5.65 - void set_handles(JNIHandleBlock* handles); 5.66 - 5.67 Mutex* metaspace_lock() const { return _metaspace_lock; } 5.68 5.69 // GC interface.
6.1 --- a/src/share/vm/runtime/arguments.cpp Tue Apr 18 15:44:32 2017 -0700 6.2 +++ b/src/share/vm/runtime/arguments.cpp Fri May 05 06:07:11 2017 -0700 6.3 @@ -3193,8 +3193,6 @@ 6.4 6.5 // Enable parallel GC and adaptive generation sizing 6.6 FLAG_SET_CMDLINE(bool, UseParallelGC, true); 6.7 - FLAG_SET_DEFAULT(ParallelGCThreads, 6.8 - Abstract_VM_Version::parallel_worker_threads()); 6.9 6.10 // Encourage steady state memory management 6.11 FLAG_SET_CMDLINE(uintx, ThresholdTolerance, 100);
7.1 --- a/test/TEST.groups Tue Apr 18 15:44:32 2017 -0700 7.2 +++ b/test/TEST.groups Fri May 05 06:07:11 2017 -0700 7.3 @@ -1,5 +1,5 @@ 7.4 # 7.5 -# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 7.6 +# Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. 7.7 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 # 7.9 # This code is free software; you can redistribute it and/or modify it 7.10 @@ -164,6 +164,7 @@ 7.11 gc/TestGCLogRotationViaJcmd.java \ 7.12 gc/g1/TestHumongousAllocInitialMark.java \ 7.13 gc/g1/TestHumongousShrinkHeap.java \ 7.14 + gc/arguments/TestAggressiveHeap.java \ 7.15 gc/arguments/TestG1HeapRegionSize.java \ 7.16 gc/metaspace/TestMetaspaceMemoryPool.java \ 7.17 gc/arguments/TestDynMinHeapFreeRatio.java \
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/test/gc/arguments/TestAggressiveHeap.java Fri May 05 06:07:11 2017 -0700 8.3 @@ -0,0 +1,91 @@ 8.4 +/* 8.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 + * 8.8 + * This code is free software; you can redistribute it and/or modify it 8.9 + * under the terms of the GNU General Public License version 2 only, as 8.10 + * published by the Free Software Foundation. 8.11 + * 8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.15 + * version 2 for more details (a copy is included in the LICENSE file that 8.16 + * accompanied this code). 8.17 + * 8.18 + * You should have received a copy of the GNU General Public License version 8.19 + * 2 along with this work; if not, write to the Free Software Foundation, 8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.21 + * 8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 8.23 + * or visit www.oracle.com if you need additional information or have any 8.24 + * questions. 8.25 + */ 8.26 + 8.27 +/* 8.28 + * @test TestAggressiveHeap 8.29 + * @key gc 8.30 + * @bug 8179084 8.31 + * @summary Test argument processing for -XX:+AggressiveHeap. 8.32 + * @library /testlibrary 8.33 + * @run driver TestAggressiveHeap 8.34 + */ 8.35 + 8.36 +import java.lang.management.ManagementFactory; 8.37 +import javax.management.MBeanServer; 8.38 +import javax.management.ObjectName; 8.39 + 8.40 +import com.oracle.java.testlibrary.OutputAnalyzer; 8.41 +import com.oracle.java.testlibrary.ProcessTools; 8.42 + 8.43 +public class TestAggressiveHeap { 8.44 + 8.45 + public static void main(String args[]) throws Exception { 8.46 + if (canUseAggressiveHeapOption()) { 8.47 + testFlag(); 8.48 + } 8.49 + } 8.50 + 8.51 + // Note: Not a normal boolean flag; -XX:-AggressiveHeap is invalid. 8.52 + private static final String option = "-XX:+AggressiveHeap"; 8.53 + 8.54 + // Option requires at least 256M, else error during option processing. 8.55 + private static final long minMemory = 256 * 1024 * 1024; 8.56 + 8.57 + // bool UseParallelGC := true {product} 8.58 + private static final String parallelGCPattern = 8.59 + " *bool +UseParallelGC *:= *true +\\{product\\}"; 8.60 + 8.61 + private static void testFlag() throws Exception { 8.62 + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 8.63 + option, "-XX:+PrintFlagsFinal", "-version"); 8.64 + 8.65 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 8.66 + 8.67 + output.shouldHaveExitValue(0); 8.68 + 8.69 + String value = output.firstMatch(parallelGCPattern); 8.70 + if (value == null) { 8.71 + throw new RuntimeException( 8.72 + option + " didn't set UseParallelGC"); 8.73 + } 8.74 + } 8.75 + 8.76 + private static boolean haveRequiredMemory() throws Exception { 8.77 + MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 8.78 + ObjectName os = new ObjectName("java.lang", "type", "OperatingSystem"); 8.79 + Object attr = server.getAttribute(os, "TotalPhysicalMemorySize"); 8.80 + String value = attr.toString(); 8.81 + long memory = Long.parseLong(value); 8.82 + return memory >= minMemory; 8.83 + } 8.84 + 8.85 + private static boolean canUseAggressiveHeapOption() throws Exception { 8.86 + if (!haveRequiredMemory()) { 8.87 + System.out.println( 8.88 + "Skipping test of " + option + " : insufficient memory"); 8.89 + return false; 8.90 + } 8.91 + return true; 8.92 + } 8.93 +} 8.94 +