Tue, 10 Jun 2014 13:43:58 -0700
Merge
.hgtags | file | annotate | diff | comparison | revisions | |
make/hotspot_version | file | annotate | diff | comparison | revisions | |
test/gc/g1/TestStringDeduplicationMemoryUsage.java | file | annotate | diff | comparison | revisions |
1.1 --- a/.hgtags Thu Jun 05 15:08:46 2014 -0700 1.2 +++ b/.hgtags Tue Jun 10 13:43:58 2014 -0700 1.3 @@ -483,3 +483,4 @@ 1.4 c36ef639e6d3c2d238f4e4f8b2f5803a60de8be8 jdk8u20-b16 1.5 ee8b934668694dba5dc0ac039f8d56e52499c0f9 hs25.20-b17 1.6 8ea4732884ccd5586f0afe9478b80add90231455 jdk8u20-b17 1.7 +b685b4e870b159ea5731984199d275879d427038 hs25.20-b18
2.1 --- a/make/aix/makefiles/mapfile-vers-debug Thu Jun 05 15:08:46 2014 -0700 2.2 +++ b/make/aix/makefiles/mapfile-vers-debug Tue Jun 10 13:43:58 2014 -0700 2.3 @@ -122,7 +122,7 @@ 2.4 JVM_GetClassModifiers; 2.5 JVM_GetClassName; 2.6 JVM_GetClassNameUTF; 2.7 - JVM_GetClassSignature; 2.8 + JVM_GetClassSignature; 2.9 JVM_GetClassSigners; 2.10 JVM_GetClassTypeAnnotations; 2.11 JVM_GetComponentType; 2.12 @@ -163,6 +163,7 @@ 2.13 JVM_GetStackTraceElement; 2.14 JVM_GetSystemPackage; 2.15 JVM_GetSystemPackages; 2.16 + JVM_GetTemporaryDirectory; 2.17 JVM_GetThreadStateNames; 2.18 JVM_GetThreadStateValues; 2.19 JVM_GetVersionInfo;
3.1 --- a/make/aix/makefiles/mapfile-vers-product Thu Jun 05 15:08:46 2014 -0700 3.2 +++ b/make/aix/makefiles/mapfile-vers-product Tue Jun 10 13:43:58 2014 -0700 3.3 @@ -161,6 +161,7 @@ 3.4 JVM_GetStackTraceElement; 3.5 JVM_GetSystemPackage; 3.6 JVM_GetSystemPackages; 3.7 + JVM_GetTemporaryDirectory; 3.8 JVM_GetThreadStateNames; 3.9 JVM_GetThreadStateValues; 3.10 JVM_GetVersionInfo;
4.1 --- a/make/bsd/makefiles/mapfile-vers-debug Thu Jun 05 15:08:46 2014 -0700 4.2 +++ b/make/bsd/makefiles/mapfile-vers-debug Tue Jun 10 13:43:58 2014 -0700 4.3 @@ -161,6 +161,7 @@ 4.4 _JVM_GetStackTraceElement 4.5 _JVM_GetSystemPackage 4.6 _JVM_GetSystemPackages 4.7 + _JVM_GetTemporaryDirectory 4.8 _JVM_GetThreadStateNames 4.9 _JVM_GetThreadStateValues 4.10 _JVM_GetVersionInfo
5.1 --- a/make/bsd/makefiles/mapfile-vers-product Thu Jun 05 15:08:46 2014 -0700 5.2 +++ b/make/bsd/makefiles/mapfile-vers-product Tue Jun 10 13:43:58 2014 -0700 5.3 @@ -161,6 +161,7 @@ 5.4 _JVM_GetStackTraceElement 5.5 _JVM_GetSystemPackage 5.6 _JVM_GetSystemPackages 5.7 + _JVM_GetTemporaryDirectory 5.8 _JVM_GetThreadStateNames 5.9 _JVM_GetThreadStateValues 5.10 _JVM_GetVersionInfo
6.1 --- a/make/bsd/makefiles/universal.gmk Thu Jun 05 15:08:46 2014 -0700 6.2 +++ b/make/bsd/makefiles/universal.gmk Tue Jun 10 13:43:58 2014 -0700 6.3 @@ -1,5 +1,5 @@ 6.4 # 6.5 -# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. 6.6 +# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. 6.7 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 # 6.9 # This code is free software; you can redistribute it and/or modify it 6.10 @@ -74,19 +74,21 @@ 6.11 6.12 6.13 # Replace arch specific binaries with universal binaries 6.14 +# Do not touch jre/lib/{client,server}/libjsig.$(LIBRARY_SUFFIX) 6.15 +# That symbolic link belongs to the 'jdk' build. 6.16 export_universal: 6.17 $(RM) -r $(EXPORT_PATH)/jre/lib/{i386,amd64} 6.18 $(RM) -r $(JDK_IMAGE_DIR)/jre/lib/{i386,amd64} 6.19 - $(RM) $(JDK_IMAGE_DIR)/jre/lib/{client,server}/libjsig.$(LIBRARY_SUFFIX) 6.20 ($(CD) $(EXPORT_PATH) && \ 6.21 $(TAR) -cf - *) | \ 6.22 ($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xpf -) 6.23 6.24 6.25 # Overlay universal binaries 6.26 +# Do not touch jre/lib/{client,server}/libjsig.$(LIBRARY_SUFFIX) 6.27 +# That symbolic link belongs to the 'jdk' build. 6.28 copy_universal: 6.29 $(RM) -r $(JDK_IMAGE_DIR)$(COPY_SUBDIR)/jre/lib/{i386,amd64} 6.30 - $(RM) $(JDK_IMAGE_DIR)$(COPY_SUBDIR)/jre/lib/{client,server}/libjsig.$(LIBRARY_SUFFIX) 6.31 ($(CD) $(EXPORT_PATH)$(COPY_SUBDIR) && \ 6.32 $(TAR) -cf - *) | \ 6.33 ($(CD) $(JDK_IMAGE_DIR)$(COPY_SUBDIR) && $(TAR) -xpf -)
7.1 --- a/make/hotspot_version Thu Jun 05 15:08:46 2014 -0700 7.2 +++ b/make/hotspot_version Tue Jun 10 13:43:58 2014 -0700 7.3 @@ -35,7 +35,7 @@ 7.4 7.5 HS_MAJOR_VER=25 7.6 HS_MINOR_VER=20 7.7 -HS_BUILD_NUMBER=17 7.8 +HS_BUILD_NUMBER=18 7.9 7.10 JDK_MAJOR_VER=1 7.11 JDK_MINOR_VER=8
8.1 --- a/make/linux/makefiles/mapfile-vers-debug Thu Jun 05 15:08:46 2014 -0700 8.2 +++ b/make/linux/makefiles/mapfile-vers-debug Tue Jun 10 13:43:58 2014 -0700 8.3 @@ -122,7 +122,7 @@ 8.4 JVM_GetClassModifiers; 8.5 JVM_GetClassName; 8.6 JVM_GetClassNameUTF; 8.7 - JVM_GetClassSignature; 8.8 + JVM_GetClassSignature; 8.9 JVM_GetClassSigners; 8.10 JVM_GetClassTypeAnnotations; 8.11 JVM_GetComponentType; 8.12 @@ -163,6 +163,7 @@ 8.13 JVM_GetStackTraceElement; 8.14 JVM_GetSystemPackage; 8.15 JVM_GetSystemPackages; 8.16 + JVM_GetTemporaryDirectory; 8.17 JVM_GetThreadStateNames; 8.18 JVM_GetThreadStateValues; 8.19 JVM_GetVersionInfo;
9.1 --- a/make/linux/makefiles/mapfile-vers-product Thu Jun 05 15:08:46 2014 -0700 9.2 +++ b/make/linux/makefiles/mapfile-vers-product Tue Jun 10 13:43:58 2014 -0700 9.3 @@ -163,6 +163,7 @@ 9.4 JVM_GetStackTraceElement; 9.5 JVM_GetSystemPackage; 9.6 JVM_GetSystemPackages; 9.7 + JVM_GetTemporaryDirectory; 9.8 JVM_GetThreadStateNames; 9.9 JVM_GetThreadStateValues; 9.10 JVM_GetVersionInfo;
10.1 --- a/make/solaris/makefiles/mapfile-vers Thu Jun 05 15:08:46 2014 -0700 10.2 +++ b/make/solaris/makefiles/mapfile-vers Tue Jun 10 13:43:58 2014 -0700 10.3 @@ -163,6 +163,7 @@ 10.4 JVM_GetStackTraceElement; 10.5 JVM_GetSystemPackage; 10.6 JVM_GetSystemPackages; 10.7 + JVM_GetTemporaryDirectory; 10.8 JVM_GetThreadStateNames; 10.9 JVM_GetThreadStateValues; 10.10 JVM_GetVersionInfo;
11.1 --- a/src/cpu/sparc/vm/copy_sparc.hpp Thu Jun 05 15:08:46 2014 -0700 11.2 +++ b/src/cpu/sparc/vm/copy_sparc.hpp Tue Jun 10 13:43:58 2014 -0700 11.3 @@ -184,7 +184,7 @@ 11.4 assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation"); 11.5 11.6 if (value == 0 && UseBlockZeroing && 11.7 - (count > (BlockZeroingLowLimit >> LogHeapWordSize))) { 11.8 + (count > (size_t)(BlockZeroingLowLimit >> LogHeapWordSize))) { 11.9 // Call it only when block zeroing is used 11.10 ((_zero_Fn)StubRoutines::zero_aligned_words())(tohw, count); 11.11 } else {
12.1 --- a/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Jun 05 15:08:46 2014 -0700 12.2 +++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp Tue Jun 10 13:43:58 2014 -0700 12.3 @@ -158,6 +158,9 @@ 12.4 12.5 void BCEscapeAnalyzer::set_method_escape(ArgumentMap vars) { 12.6 clear_bits(vars, _arg_local); 12.7 + if (vars.contains_allocated()) { 12.8 + _allocated_escapes = true; 12.9 + } 12.10 } 12.11 12.12 void BCEscapeAnalyzer::set_global_escape(ArgumentMap vars, bool merge) {
13.1 --- a/src/share/vm/opto/bytecodeInfo.cpp Thu Jun 05 15:08:46 2014 -0700 13.2 +++ b/src/share/vm/opto/bytecodeInfo.cpp Tue Jun 10 13:43:58 2014 -0700 13.3 @@ -361,11 +361,14 @@ 13.4 set_msg("not an accessor"); 13.5 return false; 13.6 } 13.7 + 13.8 + // Limit inlining depth in case inlining is forced or 13.9 + // _max_inline_level was increased to compensate for lambda forms. 13.10 + if (inline_level() > MaxForceInlineLevel) { 13.11 + set_msg("MaxForceInlineLevel"); 13.12 + return false; 13.13 + } 13.14 if (inline_level() > _max_inline_level) { 13.15 - if (callee_method->force_inline() && inline_level() > MaxForceInlineLevel) { 13.16 - set_msg("MaxForceInlineLevel"); 13.17 - return false; 13.18 - } 13.19 if (!callee_method->force_inline() || !IncrementalInline) { 13.20 set_msg("inlining too deep"); 13.21 return false;
14.1 --- a/src/share/vm/opto/library_call.cpp Thu Jun 05 15:08:46 2014 -0700 14.2 +++ b/src/share/vm/opto/library_call.cpp Tue Jun 10 13:43:58 2014 -0700 14.3 @@ -3978,8 +3978,11 @@ 14.4 } 14.5 14.6 14.7 -//------------------------------inline_native_hashcode-------------------- 14.8 -// Build special case code for calls to hashCode on an object. 14.9 +/** 14.10 + * Build special case code for calls to hashCode on an object. This call may 14.11 + * be virtual (invokevirtual) or bound (invokespecial). For each case we generate 14.12 + * slightly different code. 14.13 + */ 14.14 bool LibraryCallKit::inline_native_hashcode(bool is_virtual, bool is_static) { 14.15 assert(is_static == callee()->is_static(), "correct intrinsic selection"); 14.16 assert(!(is_virtual && is_static), "either virtual, special, or static"); 14.17 @@ -3987,11 +3990,9 @@ 14.18 enum { _slow_path = 1, _fast_path, _null_path, PATH_LIMIT }; 14.19 14.20 RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT); 14.21 - PhiNode* result_val = new(C) PhiNode(result_reg, 14.22 - TypeInt::INT); 14.23 + PhiNode* result_val = new(C) PhiNode(result_reg, TypeInt::INT); 14.24 PhiNode* result_io = new(C) PhiNode(result_reg, Type::ABIO); 14.25 - PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY, 14.26 - TypePtr::BOTTOM); 14.27 + PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY, TypePtr::BOTTOM); 14.28 Node* obj = NULL; 14.29 if (!is_static) { 14.30 // Check for hashing null object 14.31 @@ -4017,12 +4018,6 @@ 14.32 return true; 14.33 } 14.34 14.35 - // After null check, get the object's klass. 14.36 - Node* obj_klass = load_object_klass(obj); 14.37 - 14.38 - // This call may be virtual (invokevirtual) or bound (invokespecial). 14.39 - // For each case we generate slightly different code. 14.40 - 14.41 // We only go to the fast case code if we pass a number of guards. The 14.42 // paths which do not pass are accumulated in the slow_region. 14.43 RegionNode* slow_region = new (C) RegionNode(1); 14.44 @@ -4035,19 +4030,24 @@ 14.45 // guard for non-virtual calls -- the caller is known to be the native 14.46 // Object hashCode(). 14.47 if (is_virtual) { 14.48 + // After null check, get the object's klass. 14.49 + Node* obj_klass = load_object_klass(obj); 14.50 generate_virtual_guard(obj_klass, slow_region); 14.51 } 14.52 14.53 // Get the header out of the object, use LoadMarkNode when available 14.54 Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes()); 14.55 - Node* header = make_load(control(), header_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered); 14.56 + // The control of the load must be NULL. Otherwise, the load can move before 14.57 + // the null check after castPP removal. 14.58 + Node* no_ctrl = NULL; 14.59 + Node* header = make_load(no_ctrl, header_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered); 14.60 14.61 // Test the header to see if it is unlocked. 14.62 - Node *lock_mask = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place); 14.63 - Node *lmasked_header = _gvn.transform(new (C) AndXNode(header, lock_mask)); 14.64 - Node *unlocked_val = _gvn.MakeConX(markOopDesc::unlocked_value); 14.65 - Node *chk_unlocked = _gvn.transform(new (C) CmpXNode( lmasked_header, unlocked_val)); 14.66 - Node *test_unlocked = _gvn.transform(new (C) BoolNode( chk_unlocked, BoolTest::ne)); 14.67 + Node* lock_mask = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place); 14.68 + Node* lmasked_header = _gvn.transform(new (C) AndXNode(header, lock_mask)); 14.69 + Node* unlocked_val = _gvn.MakeConX(markOopDesc::unlocked_value); 14.70 + Node* chk_unlocked = _gvn.transform(new (C) CmpXNode( lmasked_header, unlocked_val)); 14.71 + Node* test_unlocked = _gvn.transform(new (C) BoolNode( chk_unlocked, BoolTest::ne)); 14.72 14.73 generate_slow_guard(test_unlocked, slow_region); 14.74 14.75 @@ -4055,19 +4055,19 @@ 14.76 // We depend on hash_mask being at most 32 bits and avoid the use of 14.77 // hash_mask_in_place because it could be larger than 32 bits in a 64-bit 14.78 // vm: see markOop.hpp. 14.79 - Node *hash_mask = _gvn.intcon(markOopDesc::hash_mask); 14.80 - Node *hash_shift = _gvn.intcon(markOopDesc::hash_shift); 14.81 - Node *hshifted_header= _gvn.transform(new (C) URShiftXNode(header, hash_shift)); 14.82 + Node* hash_mask = _gvn.intcon(markOopDesc::hash_mask); 14.83 + Node* hash_shift = _gvn.intcon(markOopDesc::hash_shift); 14.84 + Node* hshifted_header= _gvn.transform(new (C) URShiftXNode(header, hash_shift)); 14.85 // This hack lets the hash bits live anywhere in the mark object now, as long 14.86 // as the shift drops the relevant bits into the low 32 bits. Note that 14.87 // Java spec says that HashCode is an int so there's no point in capturing 14.88 // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build). 14.89 hshifted_header = ConvX2I(hshifted_header); 14.90 - Node *hash_val = _gvn.transform(new (C) AndINode(hshifted_header, hash_mask)); 14.91 - 14.92 - Node *no_hash_val = _gvn.intcon(markOopDesc::no_hash); 14.93 - Node *chk_assigned = _gvn.transform(new (C) CmpINode( hash_val, no_hash_val)); 14.94 - Node *test_assigned = _gvn.transform(new (C) BoolNode( chk_assigned, BoolTest::eq)); 14.95 + Node* hash_val = _gvn.transform(new (C) AndINode(hshifted_header, hash_mask)); 14.96 + 14.97 + Node* no_hash_val = _gvn.intcon(markOopDesc::no_hash); 14.98 + Node* chk_assigned = _gvn.transform(new (C) CmpINode( hash_val, no_hash_val)); 14.99 + Node* test_assigned = _gvn.transform(new (C) BoolNode( chk_assigned, BoolTest::eq)); 14.100 14.101 generate_slow_guard(test_assigned, slow_region); 14.102
15.1 --- a/src/share/vm/prims/jvm.cpp Thu Jun 05 15:08:46 2014 -0700 15.2 +++ b/src/share/vm/prims/jvm.cpp Tue Jun 10 13:43:58 2014 -0700 15.3 @@ -392,6 +392,23 @@ 15.4 JVM_END 15.5 15.6 15.7 +/* 15.8 + * Return the temporary directory that the VM uses for the attach 15.9 + * and perf data files. 15.10 + * 15.11 + * It is important that this directory is well-known and the 15.12 + * same for all VM instances. It cannot be affected by configuration 15.13 + * variables such as java.io.tmpdir. 15.14 + */ 15.15 +JVM_ENTRY(jstring, JVM_GetTemporaryDirectory(JNIEnv *env)) 15.16 + JVMWrapper("JVM_GetTemporaryDirectory"); 15.17 + HandleMark hm(THREAD); 15.18 + const char* temp_dir = os::get_temp_directory(); 15.19 + Handle h = java_lang_String::create_from_platform_dependent_str(temp_dir, CHECK_NULL); 15.20 + return (jstring) JNIHandles::make_local(env, h()); 15.21 +JVM_END 15.22 + 15.23 + 15.24 // java.lang.Runtime ///////////////////////////////////////////////////////////////////////// 15.25 15.26 extern volatile jint vm_created;
16.1 --- a/src/share/vm/prims/jvm.h Thu Jun 05 15:08:46 2014 -0700 16.2 +++ b/src/share/vm/prims/jvm.h Tue Jun 10 13:43:58 2014 -0700 16.3 @@ -1485,6 +1485,9 @@ 16.4 JNIEXPORT jobject JNICALL 16.5 JVM_InitAgentProperties(JNIEnv *env, jobject agent_props); 16.6 16.7 +JNIEXPORT jstring JNICALL 16.8 +JVM_GetTemporaryDirectory(JNIEnv *env); 16.9 + 16.10 /* Generics reflection support. 16.11 * 16.12 * Returns information about the given class's EnclosingMethod
17.1 --- a/src/share/vm/runtime/objectMonitor.cpp Thu Jun 05 15:08:46 2014 -0700 17.2 +++ b/src/share/vm/runtime/objectMonitor.cpp Tue Jun 10 13:43:58 2014 -0700 17.3 @@ -418,6 +418,15 @@ 17.4 jt->java_suspend_self(); 17.5 } 17.6 Self->set_current_pending_monitor(NULL); 17.7 + 17.8 + // We cleared the pending monitor info since we've just gotten past 17.9 + // the enter-check-for-suspend dance and we now own the monitor free 17.10 + // and clear, i.e., it is no longer pending. The ThreadBlockInVM 17.11 + // destructor can go to a safepoint at the end of this block. If we 17.12 + // do a thread dump during that safepoint, then this thread will show 17.13 + // as having "-locked" the monitor, but the OS and java.lang.Thread 17.14 + // states will still report that the thread is blocked trying to 17.15 + // acquire it. 17.16 } 17.17 17.18 Atomic::dec_ptr(&_count);
18.1 --- a/src/share/vm/runtime/vframe.cpp Thu Jun 05 15:08:46 2014 -0700 18.2 +++ b/src/share/vm/runtime/vframe.cpp Tue Jun 10 13:43:58 2014 -0700 18.3 @@ -199,6 +199,7 @@ 18.4 continue; 18.5 } 18.6 if (monitor->owner() != NULL) { 18.7 + // the monitor is associated with an object, i.e., it is locked 18.8 18.9 // First, assume we have the monitor locked. If we haven't found an 18.10 // owned monitor before and this is the first frame, then we need to 18.11 @@ -209,7 +210,11 @@ 18.12 if (!found_first_monitor && frame_count == 0) { 18.13 markOop mark = monitor->owner()->mark(); 18.14 if (mark->has_monitor() && 18.15 - mark->monitor() == thread()->current_pending_monitor()) { 18.16 + ( // we have marked ourself as pending on this monitor 18.17 + mark->monitor() == thread()->current_pending_monitor() || 18.18 + // we are not the owner of this monitor 18.19 + !mark->monitor()->is_entered(thread()) 18.20 + )) { 18.21 lock_state = "waiting to lock"; 18.22 } 18.23 }
19.1 --- a/test/TEST.groups Thu Jun 05 15:08:46 2014 -0700 19.2 +++ b/test/TEST.groups Tue Jun 10 13:43:58 2014 -0700 19.3 @@ -1,5 +1,5 @@ 19.4 # 19.5 -# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 19.6 +# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 19.7 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 19.8 # 19.9 # This code is free software; you can redistribute it and/or modify it 19.10 @@ -84,6 +84,7 @@ 19.11 runtime/NMT/ThreadedVirtualAllocTestType.java \ 19.12 runtime/NMT/VirtualAllocTestType.java \ 19.13 runtime/RedefineObject/TestRedefineObject.java \ 19.14 + runtime/Thread/TestThreadDumpMonitorContention.java \ 19.15 runtime/XCheckJniJsig/XCheckJSig.java \ 19.16 serviceability/attach/AttachWithStalePidFile.java \ 19.17 serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java Tue Jun 10 13:43:58 2014 -0700 20.3 @@ -0,0 +1,107 @@ 20.4 +/* 20.5 + * Copyright 2014 Google, Inc. All Rights Reserved. 20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.7 + * 20.8 + * This code is free software; you can redistribute it and/or modify it 20.9 + * under the terms of the GNU General Public License version 2 only, as 20.10 + * published by the Free Software Foundation. 20.11 + * 20.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 20.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20.15 + * version 2 for more details (a copy is included in the LICENSE file that 20.16 + * accompanied this code). 20.17 + * 20.18 + * You should have received a copy of the GNU General Public License version 20.19 + * 2 along with this work; if not, write to the Free Software Foundation, 20.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20.21 + * 20.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20.23 + * or visit www.oracle.com if you need additional information or have any 20.24 + * questions. 20.25 + */ 20.26 + 20.27 +/* 20.28 + * @test 20.29 + * @bug 8043354 20.30 + * @summary bcEscapeAnalyzer allocated_escapes not conservative enough 20.31 + * @run main/othervm -XX:CompileOnly=.visitAndPop TestAllocatedEscapesPtrComparison 20.32 + * @author Chuck Rasbold rasbold@google.com 20.33 + */ 20.34 + 20.35 +/* 20.36 + * Test always passes with -XX:-OptmimizePtrCompare 20.37 + */ 20.38 + 20.39 +import java.util.ArrayList; 20.40 +import java.util.List; 20.41 + 20.42 +public class TestAllocatedEscapesPtrComparison { 20.43 + 20.44 + static TestAllocatedEscapesPtrComparison dummy; 20.45 + 20.46 + class Marker { 20.47 + } 20.48 + 20.49 + List<Marker> markerList = new ArrayList<>(); 20.50 + 20.51 + // Suppress compilation of this method, it must be processed 20.52 + // by the bytecode escape analyzer. 20.53 + 20.54 + // Make a new marker and put it on the List 20.55 + Marker getMarker() { 20.56 + // result escapes through markerList 20.57 + final Marker result = new Marker(); 20.58 + markerList.add(result); 20.59 + return result; 20.60 + } 20.61 + 20.62 + void visit(int depth) { 20.63 + // Make a new marker 20.64 + getMarker(); 20.65 + 20.66 + // Call visitAndPop every once in a while 20.67 + // Cap the depth of our recursive visits 20.68 + if (depth % 10 == 2) { 20.69 + visitAndPop(depth + 1); 20.70 + } else if (depth < 15) { 20.71 + visit(depth + 1); 20.72 + } 20.73 + } 20.74 + 20.75 + void visitAndPop(int depth) { 20.76 + // Random dummy allocation to force EscapeAnalysis to process this method 20.77 + dummy = new TestAllocatedEscapesPtrComparison(); 20.78 + 20.79 + // Make a new marker 20.80 + Marker marker = getMarker(); 20.81 + 20.82 + visit(depth + 1); 20.83 + 20.84 + // Walk and pop the marker list up to the current marker 20.85 + boolean found = false; 20.86 + for (int i = markerList.size() - 1; i >= 0; i--) { 20.87 + Marker removed = markerList.remove(i); 20.88 + 20.89 + // In the failure, EA mistakenly converts this comparison to false 20.90 + if (removed == marker) { 20.91 + found = true; 20.92 + break; 20.93 + } 20.94 + } 20.95 + 20.96 + if (!found) { 20.97 + throw new RuntimeException("test fails"); 20.98 + } 20.99 + } 20.100 + 20.101 + 20.102 + public static void main(String args[]) { 20.103 + TestAllocatedEscapesPtrComparison tc = new TestAllocatedEscapesPtrComparison(); 20.104 + 20.105 + // Warmup and run enough times 20.106 + for (int i = 0; i < 20000; i++) { 20.107 + tc.visit(0); 20.108 + } 20.109 + } 20.110 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/test/compiler/intrinsics/hashcode/TestHashCode.java Tue Jun 10 13:43:58 2014 -0700 21.3 @@ -0,0 +1,73 @@ 21.4 +/* 21.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.7 + * 21.8 + * This code is free software; you can redistribute it and/or modify it 21.9 + * under the terms of the GNU General Public License version 2 only, as 21.10 + * published by the Free Software Foundation. 21.11 + * 21.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 21.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 21.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21.15 + * version 2 for more details (a copy is included in the LICENSE file that 21.16 + * accompanied this code). 21.17 + * 21.18 + * You should have received a copy of the GNU General Public License version 21.19 + * 2 along with this work; if not, write to the Free Software Foundation, 21.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21.21 + * 21.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21.23 + * or visit www.oracle.com if you need additional information or have any 21.24 + * questions. 21.25 + */ 21.26 + 21.27 +/* 21.28 + * @test 21.29 + * @bug 8011646 21.30 + * @summary SEGV in compiled code with loop predication 21.31 + * @run main/othervm -XX:-TieredCompilation -XX:CompileOnly=TestHashCode.m1,Object.hashCode TestHashCode 21.32 + * 21.33 + */ 21.34 + 21.35 +public class TestHashCode { 21.36 + static class A { 21.37 + int i; 21.38 + } 21.39 + 21.40 + static class B extends A { 21.41 + } 21.42 + 21.43 + static boolean crash = false; 21.44 + 21.45 + static A m2() { 21.46 + if (crash) { 21.47 + return null; 21.48 + } 21.49 + return new A(); 21.50 + } 21.51 + 21.52 + static int m1(A aa) { 21.53 + int res = 0; 21.54 + for (int i = 0; i < 10; i++) { 21.55 + A a = m2(); 21.56 + int j = a.i; 21.57 + if (aa instanceof B) { 21.58 + } 21.59 + res += a.hashCode(); 21.60 + } 21.61 + return res; 21.62 + } 21.63 + 21.64 + public static void main(String[] args) { 21.65 + A a = new A(); 21.66 + for (int i = 0; i < 20000; i++) { 21.67 + m1(a); 21.68 + } 21.69 + crash = true; 21.70 + try { 21.71 + m1(a); 21.72 + } catch (NullPointerException e) { 21.73 + System.out.println("Test passed"); 21.74 + } 21.75 + } 21.76 +}
22.1 --- a/test/gc/g1/TestStringDeduplicationMemoryUsage.java Thu Jun 05 15:08:46 2014 -0700 22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 22.3 @@ -1,36 +0,0 @@ 22.4 -/* 22.5 - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 22.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 22.7 - * 22.8 - * This code is free software; you can redistribute it and/or modify it 22.9 - * under the terms of the GNU General Public License version 2 only, as 22.10 - * published by the Free Software Foundation. 22.11 - * 22.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 22.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 22.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 22.15 - * version 2 for more details (a copy is included in the LICENSE file that 22.16 - * accompanied this code). 22.17 - * 22.18 - * You should have received a copy of the GNU General Public License version 22.19 - * 2 along with this work; if not, write to the Free Software Foundation, 22.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22.21 - * 22.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22.23 - * or visit www.oracle.com if you need additional information or have any 22.24 - * questions. 22.25 - */ 22.26 - 22.27 -/* 22.28 - * @test TestStringDeduplicationMemoryUsage 22.29 - * @summary Test string deduplication memory usage 22.30 - * @bug 8029075 22.31 - * @key gc 22.32 - * @library /testlibrary 22.33 - */ 22.34 - 22.35 -public class TestStringDeduplicationMemoryUsage { 22.36 - public static void main(String[] args) throws Exception { 22.37 - TestStringDeduplicationTools.testMemoryUsage(); 22.38 - } 22.39 -}
23.1 --- a/test/gc/g1/TestStringDeduplicationTools.java Thu Jun 05 15:08:46 2014 -0700 23.2 +++ b/test/gc/g1/TestStringDeduplicationTools.java Tue Jun 10 13:43:58 2014 -0700 23.3 @@ -294,55 +294,6 @@ 23.4 } 23.5 } 23.6 23.7 - private static class MemoryUsageTest { 23.8 - public static void main(String[] args) { 23.9 - System.out.println("Begin: MemoryUsageTest"); 23.10 - 23.11 - final boolean useStringDeduplication = Boolean.parseBoolean(args[0]); 23.12 - final int numberOfStrings = LargeNumberOfStrings; 23.13 - final int numberOfUniqueStrings = 1; 23.14 - 23.15 - ArrayList<String> list = createStrings(numberOfStrings, numberOfUniqueStrings); 23.16 - forceDeduplication(DefaultAgeThreshold, FullGC); 23.17 - 23.18 - if (useStringDeduplication) { 23.19 - verifyStrings(list, numberOfUniqueStrings); 23.20 - } 23.21 - 23.22 - System.gc(); 23.23 - 23.24 - System.out.println("Heap Memory Usage: " + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed()); 23.25 - System.out.println("Array Header Size: " + unsafe.ARRAY_CHAR_BASE_OFFSET); 23.26 - 23.27 - System.out.println("End: MemoryUsageTest"); 23.28 - } 23.29 - 23.30 - public static OutputAnalyzer run(boolean useStringDeduplication) throws Exception { 23.31 - String[] extraArgs = new String[0]; 23.32 - 23.33 - if (useStringDeduplication) { 23.34 - extraArgs = new String[] { 23.35 - "-XX:+UseStringDeduplication", 23.36 - "-XX:+PrintStringDeduplicationStatistics", 23.37 - "-XX:StringDeduplicationAgeThreshold=" + DefaultAgeThreshold 23.38 - }; 23.39 - } 23.40 - 23.41 - String[] defaultArgs = new String[] { 23.42 - "-XX:+PrintGC", 23.43 - "-XX:+PrintGCDetails", 23.44 - MemoryUsageTest.class.getName(), 23.45 - "" + useStringDeduplication 23.46 - }; 23.47 - 23.48 - ArrayList<String> args = new ArrayList<String>(); 23.49 - args.addAll(Arrays.asList(extraArgs)); 23.50 - args.addAll(Arrays.asList(defaultArgs)); 23.51 - 23.52 - return runTest(args.toArray(new String[args.size()])); 23.53 - } 23.54 - } 23.55 - 23.56 /* 23.57 * Tests 23.58 */ 23.59 @@ -480,44 +431,4 @@ 23.60 OutputAnalyzer output = InternedTest.run(); 23.61 output.shouldHaveExitValue(0); 23.62 } 23.63 - 23.64 - public static void testMemoryUsage() throws Exception { 23.65 - // Test that memory usage is reduced after deduplication 23.66 - OutputAnalyzer output; 23.67 - final String heapMemoryUsagePattern = "Heap Memory Usage: (\\d+)"; 23.68 - final String arrayHeaderSizePattern = "Array Header Size: (\\d+)"; 23.69 - 23.70 - // Run without deduplication 23.71 - output = MemoryUsageTest.run(false); 23.72 - output.shouldHaveExitValue(0); 23.73 - final long heapMemoryUsageWithoutDedup = Long.parseLong(output.firstMatch(heapMemoryUsagePattern, 1)); 23.74 - final long arrayHeaderSizeWithoutDedup = Long.parseLong(output.firstMatch(arrayHeaderSizePattern, 1)); 23.75 - 23.76 - // Run with deduplication 23.77 - output = MemoryUsageTest.run(true); 23.78 - output.shouldHaveExitValue(0); 23.79 - final long heapMemoryUsageWithDedup = Long.parseLong(output.firstMatch(heapMemoryUsagePattern, 1)); 23.80 - final long arrayHeaderSizeWithDedup = Long.parseLong(output.firstMatch(arrayHeaderSizePattern, 1)); 23.81 - 23.82 - // Sanity check to make sure one instance isn't using compressed class pointers and the other not 23.83 - if (arrayHeaderSizeWithoutDedup != arrayHeaderSizeWithDedup) { 23.84 - throw new Exception("Unexpected difference between array header sizes"); 23.85 - } 23.86 - 23.87 - // Calculate expected memory usage with deduplication enabled. This calculation does 23.88 - // not take alignment and padding into account, so it's a conservative estimate. 23.89 - final long sizeOfChar = unsafe.ARRAY_CHAR_INDEX_SCALE; 23.90 - final long sizeOfCharArray = StringLength * sizeOfChar + arrayHeaderSizeWithoutDedup; 23.91 - final long bytesSaved = (LargeNumberOfStrings - 1) * sizeOfCharArray; 23.92 - final long heapMemoryUsageWithDedupExpected = heapMemoryUsageWithoutDedup - bytesSaved; 23.93 - 23.94 - System.out.println("Memory usage summary:"); 23.95 - System.out.println(" heapMemoryUsageWithoutDedup: " + heapMemoryUsageWithoutDedup); 23.96 - System.out.println(" heapMemoryUsageWithDedup: " + heapMemoryUsageWithDedup); 23.97 - System.out.println(" heapMemoryUsageWithDedupExpected: " + heapMemoryUsageWithDedupExpected); 23.98 - 23.99 - if (heapMemoryUsageWithDedup > heapMemoryUsageWithDedupExpected) { 23.100 - throw new Exception("Unexpected memory usage, heapMemoryUsageWithDedup should be less or equal to heapMemoryUsageWithDedupExpected"); 23.101 - } 23.102 - } 23.103 }
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/test/runtime/Thread/TestThreadDumpMonitorContention.java Tue Jun 10 13:43:58 2014 -0700 24.3 @@ -0,0 +1,405 @@ 24.4 +/* 24.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 24.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 24.7 + * 24.8 + * This code is free software; you can redistribute it and/or modify it 24.9 + * under the terms of the GNU General Public License version 2 only, as 24.10 + * published by the Free Software Foundation. 24.11 + * 24.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 24.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 24.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 24.15 + * version 2 for more details (a copy is included in the LICENSE file that 24.16 + * accompanied this code). 24.17 + * 24.18 + * You should have received a copy of the GNU General Public License version 24.19 + * 2 along with this work; if not, write to the Free Software Foundation, 24.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 24.21 + * 24.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 24.23 + * or visit www.oracle.com if you need additional information or have any 24.24 + * questions. 24.25 + */ 24.26 + 24.27 +/* 24.28 + * @test 24.29 + * @bug 8036823 24.30 + * @summary Creates two threads contending for the same lock and checks 24.31 + * whether jstack reports "locked" by more than one thread. 24.32 + * 24.33 + * @library /testlibrary 24.34 + * @run main/othervm TestThreadDumpMonitorContention 24.35 + */ 24.36 + 24.37 +import java.io.BufferedReader; 24.38 +import java.io.InputStreamReader; 24.39 +import java.lang.management.ManagementFactory; 24.40 +import java.lang.management.RuntimeMXBean; 24.41 +import java.util.ArrayList; 24.42 +import java.util.List; 24.43 +import java.util.regex.Matcher; 24.44 +import java.util.regex.Pattern; 24.45 + 24.46 +import com.oracle.java.testlibrary.*; 24.47 + 24.48 +public class TestThreadDumpMonitorContention { 24.49 + // jstack tends to be closely bound to the VM that we are running 24.50 + // so use getTestJDKTool() instead of getCompileJDKTool() or even 24.51 + // getJDKTool() which can fall back to "compile.jdk". 24.52 + final static String JSTACK = JDKToolFinder.getTestJDKTool("jstack"); 24.53 + final static String PID = getPid(); 24.54 + 24.55 + // looking for header lines with these patterns: 24.56 + // "ContendingThread-1" #19 prio=5 os_prio=64 tid=0x000000000079c000 nid=0x23 runnable [0xffff80ffb8b87000] 24.57 + // "ContendingThread-2" #21 prio=5 os_prio=64 tid=0x0000000000780000 nid=0x2f waiting for monitor entry [0xfffffd7fc1111000] 24.58 + final static Pattern HEADER_PREFIX_PATTERN = Pattern.compile( 24.59 + "^\"ContendingThread-.*"); 24.60 + final static Pattern HEADER_WAITING_PATTERN = Pattern.compile( 24.61 + "^\"ContendingThread-.* waiting for monitor entry .*"); 24.62 + final static Pattern HEADER_RUNNABLE_PATTERN = Pattern.compile( 24.63 + "^\"ContendingThread-.* runnable .*"); 24.64 + 24.65 + // looking for thread state lines with these patterns: 24.66 + // java.lang.Thread.State: RUNNABLE 24.67 + // java.lang.Thread.State: BLOCKED (on object monitor) 24.68 + final static Pattern THREAD_STATE_PREFIX_PATTERN = Pattern.compile( 24.69 + " *java\\.lang\\.Thread\\.State: .*"); 24.70 + final static Pattern THREAD_STATE_BLOCKED_PATTERN = Pattern.compile( 24.71 + " *java\\.lang\\.Thread\\.State: BLOCKED \\(on object monitor\\)"); 24.72 + final static Pattern THREAD_STATE_RUNNABLE_PATTERN = Pattern.compile( 24.73 + " *java\\.lang\\.Thread\\.State: RUNNABLE"); 24.74 + 24.75 + // looking for duplicates of this pattern: 24.76 + // - locked <0x000000076ac59e20> (a TestThreadDumpMonitorContention$1) 24.77 + final static Pattern LOCK_PATTERN = Pattern.compile( 24.78 + ".* locked \\<.*\\(a TestThreadDumpMonitorContention.*"); 24.79 + 24.80 + // sanity checking header and thread state lines associated 24.81 + // with this pattern: 24.82 + // - waiting to lock <0x000000076ac59e20> (a TestThreadDumpMonitorContention$1) 24.83 + final static Pattern WAITING_PATTERN = Pattern.compile( 24.84 + ".* waiting to lock \\<.*\\(a TestThreadDumpMonitorContention.*"); 24.85 + 24.86 + volatile static boolean done = false; 24.87 + 24.88 + static int error_cnt = 0; 24.89 + static String header_line = null; 24.90 + static boolean have_header_line = false; 24.91 + static boolean have_thread_state_line = false; 24.92 + static int match_cnt = 0; 24.93 + static String[] match_list = new String[2]; 24.94 + static int n_samples = 15; 24.95 + static String thread_state_line = null; 24.96 + static boolean verbose = false; 24.97 + 24.98 + public static void main(String[] args) throws Exception { 24.99 + if (args.length != 0) { 24.100 + int arg_i = 0; 24.101 + if (args[arg_i].equals("-v")) { 24.102 + verbose = true; 24.103 + arg_i++; 24.104 + } 24.105 + 24.106 + try { 24.107 + n_samples = Integer.parseInt(args[arg_i]); 24.108 + } catch (NumberFormatException nfe) { 24.109 + System.err.println(nfe); 24.110 + usage(); 24.111 + } 24.112 + } 24.113 + 24.114 + Runnable runnable = new Runnable() { 24.115 + public void run() { 24.116 + while (!done) { 24.117 + synchronized (this) { } 24.118 + } 24.119 + } 24.120 + }; 24.121 + Thread[] thread_list = new Thread[2]; 24.122 + thread_list[0] = new Thread(runnable, "ContendingThread-1"); 24.123 + thread_list[1] = new Thread(runnable, "ContendingThread-2"); 24.124 + thread_list[0].start(); 24.125 + thread_list[1].start(); 24.126 + 24.127 + doSamples(); 24.128 + 24.129 + done = true; 24.130 + 24.131 + thread_list[0].join(); 24.132 + thread_list[1].join(); 24.133 + 24.134 + if (error_cnt == 0) { 24.135 + System.out.println("Test PASSED."); 24.136 + } else { 24.137 + System.out.println("Test FAILED."); 24.138 + throw new AssertionError("error_cnt=" + error_cnt); 24.139 + } 24.140 + } 24.141 + 24.142 + // Reached a blank line which is the end of the 24.143 + // stack trace without matching either LOCK_PATTERN 24.144 + // or WAITING_PATTERN. Rare, but it's not an error. 24.145 + // 24.146 + // Example: 24.147 + // "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f runnable [0xfffffd7fc1111000] 24.148 + // java.lang.Thread.State: RUNNABLE 24.149 + // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67) 24.150 + // at java.lang.Thread.run(Thread.java:745) 24.151 + // 24.152 + static boolean checkBlankLine(String line) { 24.153 + if (line.length() == 0) { 24.154 + have_header_line = false; 24.155 + have_thread_state_line = false; 24.156 + return true; 24.157 + } 24.158 + 24.159 + return false; 24.160 + } 24.161 + 24.162 + // Process the locked line here if we found one. 24.163 + // 24.164 + // Example 1: 24.165 + // "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f runnable [0xfffffd7fc1111000] 24.166 + // java.lang.Thread.State: RUNNABLE 24.167 + // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67) 24.168 + // - locked <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1) 24.169 + // at java.lang.Thread.run(Thread.java:745) 24.170 + // 24.171 + // Example 2: 24.172 + // "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f waiting for monitor entry [0xfffffd7fc1111000] 24.173 + // java.lang.Thread.State: BLOCKED (on object monitor) 24.174 + // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67) 24.175 + // - locked <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1) 24.176 + // at java.lang.Thread.run(Thread.java:745) 24.177 + // 24.178 + static boolean checkLockedLine(String line) { 24.179 + Matcher matcher = LOCK_PATTERN.matcher(line); 24.180 + if (matcher.matches()) { 24.181 + if (verbose) { 24.182 + System.out.println("locked_line='" + line + "'"); 24.183 + } 24.184 + match_list[match_cnt] = new String(line); 24.185 + match_cnt++; 24.186 + 24.187 + matcher = HEADER_RUNNABLE_PATTERN.matcher(header_line); 24.188 + if (!matcher.matches()) { 24.189 + // It's strange, but a locked line can also 24.190 + // match the HEADER_WAITING_PATTERN. 24.191 + matcher = HEADER_WAITING_PATTERN.matcher(header_line); 24.192 + if (!matcher.matches()) { 24.193 + System.err.println(); 24.194 + System.err.println("ERROR: header line does " + 24.195 + "not match runnable or waiting patterns."); 24.196 + System.err.println("ERROR: header_line='" + 24.197 + header_line + "'"); 24.198 + System.err.println("ERROR: locked_line='" + line + "'"); 24.199 + error_cnt++; 24.200 + } 24.201 + } 24.202 + 24.203 + matcher = THREAD_STATE_RUNNABLE_PATTERN.matcher(thread_state_line); 24.204 + if (!matcher.matches()) { 24.205 + // It's strange, but a locked line can also 24.206 + // match the THREAD_STATE_BLOCKED_PATTERN. 24.207 + matcher = THREAD_STATE_BLOCKED_PATTERN.matcher( 24.208 + thread_state_line); 24.209 + if (!matcher.matches()) { 24.210 + System.err.println(); 24.211 + System.err.println("ERROR: thread state line does not " + 24.212 + "match runnable or waiting patterns."); 24.213 + System.err.println("ERROR: " + "thread_state_line='" + 24.214 + thread_state_line + "'"); 24.215 + System.err.println("ERROR: locked_line='" + line + "'"); 24.216 + error_cnt++; 24.217 + } 24.218 + } 24.219 + 24.220 + // Have everything we need from this thread stack 24.221 + // that matches the LOCK_PATTERN. 24.222 + have_header_line = false; 24.223 + have_thread_state_line = false; 24.224 + return true; 24.225 + } 24.226 + 24.227 + return false; 24.228 + } 24.229 + 24.230 + // Process the waiting line here if we found one. 24.231 + // 24.232 + // Example: 24.233 + // "ContendingThread-2" #22 prio=5 os_prio=64 tid=0x00000000007b9800 nid=0x30 waiting for monitor entry [0xfffffd7fc1010000] 24.234 + // java.lang.Thread.State: BLOCKED (on object monitor) 24.235 + // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67) 24.236 + // - waiting to lock <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1) 24.237 + // at java.lang.Thread.run(Thread.java:745) 24.238 + // 24.239 + static boolean checkWaitingLine(String line) { 24.240 + Matcher matcher = WAITING_PATTERN.matcher(line); 24.241 + if (matcher.matches()) { 24.242 + if (verbose) { 24.243 + System.out.println("waiting_line='" + line + "'"); 24.244 + } 24.245 + 24.246 + matcher = HEADER_WAITING_PATTERN.matcher(header_line); 24.247 + if (!matcher.matches()) { 24.248 + System.err.println(); 24.249 + System.err.println("ERROR: header line does " + 24.250 + "not match a waiting pattern."); 24.251 + System.err.println("ERROR: header_line='" + header_line + "'"); 24.252 + System.err.println("ERROR: waiting_line='" + line + "'"); 24.253 + error_cnt++; 24.254 + } 24.255 + 24.256 + matcher = THREAD_STATE_BLOCKED_PATTERN.matcher(thread_state_line); 24.257 + if (!matcher.matches()) { 24.258 + System.err.println(); 24.259 + System.err.println("ERROR: thread state line " + 24.260 + "does not match a waiting pattern."); 24.261 + System.err.println("ERROR: thread_state_line='" + 24.262 + thread_state_line + "'"); 24.263 + System.err.println("ERROR: waiting_line='" + line + "'"); 24.264 + error_cnt++; 24.265 + } 24.266 + 24.267 + // Have everything we need from this thread stack 24.268 + // that matches the WAITING_PATTERN. 24.269 + have_header_line = false; 24.270 + have_thread_state_line = false; 24.271 + return true; 24.272 + } 24.273 + 24.274 + return false; 24.275 + } 24.276 + 24.277 + static void doSamples() throws Exception { 24.278 + for (int count = 0; count < n_samples; count++) { 24.279 + match_cnt = 0; 24.280 + // verbose mode or an error has a lot of output so add more space 24.281 + if (verbose || error_cnt > 0) System.out.println(); 24.282 + System.out.println("Sample #" + count); 24.283 + 24.284 + // We don't use the ProcessTools, OutputBuffer or 24.285 + // OutputAnalyzer classes from the testlibrary because 24.286 + // we have a complicated multi-line parse to perform 24.287 + // on a narrow subset of the JSTACK output. 24.288 + // 24.289 + // - we only care about stack traces that match 24.290 + // HEADER_PREFIX_PATTERN; only two should match 24.291 + // - we care about at most three lines from each stack trace 24.292 + // - if both stack traces match LOCKED_PATTERN, then that's 24.293 + // a failure and we report it 24.294 + // - for a stack trace that matches LOCKED_PATTERN, we verify: 24.295 + // - the header line matches HEADER_RUNNABLE_PATTERN 24.296 + // or HEADER_WAITING_PATTERN 24.297 + // - the thread state line matches THREAD_STATE_BLOCKED_PATTERN 24.298 + // or THREAD_STATE_RUNNABLE_PATTERN 24.299 + // - we report any mismatches as failures 24.300 + // - for a stack trace that matches WAITING_PATTERN, we verify: 24.301 + // - the header line matches HEADER_WAITING_PATTERN 24.302 + // - the thread state line matches THREAD_STATE_BLOCKED_PATTERN 24.303 + // - we report any mismatches as failures 24.304 + // - the stack traces that match HEADER_PREFIX_PATTERN may 24.305 + // not match either LOCKED_PATTERN or WAITING_PATTERN 24.306 + // because we might observe the thread outside of 24.307 + // monitor operations; this is not considered a failure 24.308 + // 24.309 + // When we do observe LOCKED_PATTERN or WAITING_PATTERN, 24.310 + // then we are checking the header and thread state patterns 24.311 + // that occurred earlier in the current stack trace that 24.312 + // matched HEADER_PREFIX_PATTERN. We don't use data from 24.313 + // stack traces that don't match HEADER_PREFIX_PATTERN and 24.314 + // we don't mix data between the two stack traces that do 24.315 + // match HEADER_PREFIX_PATTERN. 24.316 + // 24.317 + Process process = new ProcessBuilder(JSTACK, PID) 24.318 + .redirectErrorStream(true).start(); 24.319 + 24.320 + BufferedReader reader = new BufferedReader(new InputStreamReader( 24.321 + process.getInputStream())); 24.322 + String line; 24.323 + while ((line = reader.readLine()) != null) { 24.324 + Matcher matcher = null; 24.325 + 24.326 + // process the header line here 24.327 + if (!have_header_line) { 24.328 + matcher = HEADER_PREFIX_PATTERN.matcher(line); 24.329 + if (matcher.matches()) { 24.330 + if (verbose) { 24.331 + System.out.println(); 24.332 + System.out.println("header='" + line + "'"); 24.333 + } 24.334 + header_line = new String(line); 24.335 + have_header_line = true; 24.336 + continue; 24.337 + } 24.338 + continue; // skip until have a header line 24.339 + } 24.340 + 24.341 + // process the thread state line here 24.342 + if (!have_thread_state_line) { 24.343 + matcher = THREAD_STATE_PREFIX_PATTERN.matcher(line); 24.344 + if (matcher.matches()) { 24.345 + if (verbose) { 24.346 + System.out.println("thread_state='" + line + "'"); 24.347 + } 24.348 + thread_state_line = new String(line); 24.349 + have_thread_state_line = true; 24.350 + continue; 24.351 + } 24.352 + continue; // skip until we have a thread state line 24.353 + } 24.354 + 24.355 + // process the locked line here if we find one 24.356 + if (checkLockedLine(line)) { 24.357 + continue; 24.358 + } 24.359 + 24.360 + // process the waiting line here if we find one 24.361 + if (checkWaitingLine(line)) { 24.362 + continue; 24.363 + } 24.364 + 24.365 + // process the blank line here if we find one 24.366 + if (checkBlankLine(line)) { 24.367 + continue; 24.368 + } 24.369 + } 24.370 + process.waitFor(); 24.371 + 24.372 + if (match_cnt == 2) { 24.373 + if (match_list[0].equals(match_list[1])) { 24.374 + System.err.println(); 24.375 + System.err.println("ERROR: matching lock lines:"); 24.376 + System.err.println("ERROR: line[0]'" + match_list[0] + "'"); 24.377 + System.err.println("ERROR: line[1]'" + match_list[1] + "'"); 24.378 + error_cnt++; 24.379 + } 24.380 + } 24.381 + 24.382 + // slight delay between jstack launches 24.383 + Thread.sleep(500); 24.384 + } 24.385 + } 24.386 + 24.387 + // This helper relies on RuntimeMXBean.getName() returning a string 24.388 + // that looks like this: 5436@mt-haku 24.389 + // 24.390 + // The testlibrary has tryFindJvmPid(), but that uses a separate 24.391 + // process which is much more expensive for finding out your own PID. 24.392 + // 24.393 + static String getPid() { 24.394 + RuntimeMXBean runtimebean = ManagementFactory.getRuntimeMXBean(); 24.395 + String vmname = runtimebean.getName(); 24.396 + int i = vmname.indexOf('@'); 24.397 + if (i != -1) { 24.398 + vmname = vmname.substring(0, i); 24.399 + } 24.400 + return vmname; 24.401 + } 24.402 + 24.403 + static void usage() { 24.404 + System.err.println("Usage: " + 24.405 + "java TestThreadDumpMonitorContention [-v] [n_samples]"); 24.406 + System.exit(1); 24.407 + } 24.408 +}