Tue, 10 Jun 2014 14:52:20 -0700
Merge
1.1 --- a/.hgtags Mon Jun 09 22:21:12 2014 -0700 1.2 +++ b/.hgtags Tue Jun 10 14:52:20 2014 -0700 1.3 @@ -483,5 +483,6 @@ 1.4 c36ef639e6d3c2d238f4e4f8b2f5803a60de8be8 jdk8u20-b16 1.5 ee8b934668694dba5dc0ac039f8d56e52499c0f9 hs25.20-b17 1.6 8ea4732884ccd5586f0afe9478b80add90231455 jdk8u20-b17 1.7 +b685b4e870b159ea5731984199d275879d427038 hs25.20-b18 1.8 a4d44dfb7d30eea54bc172e4429a655454ae0bbf jdk8u25-b00 1.9 9a2152fbd929b0d8b2f5c326a5526214ae71731a jdk8u25-b01
2.1 --- a/make/aix/makefiles/mapfile-vers-debug Mon Jun 09 22:21:12 2014 -0700 2.2 +++ b/make/aix/makefiles/mapfile-vers-debug Tue Jun 10 14:52:20 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 Mon Jun 09 22:21:12 2014 -0700 3.2 +++ b/make/aix/makefiles/mapfile-vers-product Tue Jun 10 14:52:20 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 Mon Jun 09 22:21:12 2014 -0700 4.2 +++ b/make/bsd/makefiles/mapfile-vers-debug Tue Jun 10 14:52:20 2014 -0700 4.3 @@ -162,6 +162,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 Mon Jun 09 22:21:12 2014 -0700 5.2 +++ b/make/bsd/makefiles/mapfile-vers-product Tue Jun 10 14:52:20 2014 -0700 5.3 @@ -162,6 +162,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 Mon Jun 09 22:21:12 2014 -0700 6.2 +++ b/make/bsd/makefiles/universal.gmk Tue Jun 10 14:52:20 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/linux/makefiles/mapfile-vers-debug Mon Jun 09 22:21:12 2014 -0700 7.2 +++ b/make/linux/makefiles/mapfile-vers-debug Tue Jun 10 14:52:20 2014 -0700 7.3 @@ -123,7 +123,7 @@ 7.4 JVM_GetClassModifiers; 7.5 JVM_GetClassName; 7.6 JVM_GetClassNameUTF; 7.7 - JVM_GetClassSignature; 7.8 + JVM_GetClassSignature; 7.9 JVM_GetClassSigners; 7.10 JVM_GetClassTypeAnnotations; 7.11 JVM_GetComponentType; 7.12 @@ -164,6 +164,7 @@ 7.13 JVM_GetStackTraceElement; 7.14 JVM_GetSystemPackage; 7.15 JVM_GetSystemPackages; 7.16 + JVM_GetTemporaryDirectory; 7.17 JVM_GetThreadStateNames; 7.18 JVM_GetThreadStateValues; 7.19 JVM_GetVersionInfo;
8.1 --- a/make/linux/makefiles/mapfile-vers-product Mon Jun 09 22:21:12 2014 -0700 8.2 +++ b/make/linux/makefiles/mapfile-vers-product Tue Jun 10 14:52:20 2014 -0700 8.3 @@ -164,6 +164,7 @@ 8.4 JVM_GetStackTraceElement; 8.5 JVM_GetSystemPackage; 8.6 JVM_GetSystemPackages; 8.7 + JVM_GetTemporaryDirectory; 8.8 JVM_GetThreadStateNames; 8.9 JVM_GetThreadStateValues; 8.10 JVM_GetVersionInfo;
9.1 --- a/make/solaris/makefiles/mapfile-vers Mon Jun 09 22:21:12 2014 -0700 9.2 +++ b/make/solaris/makefiles/mapfile-vers Tue Jun 10 14:52:20 2014 -0700 9.3 @@ -164,6 +164,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/src/cpu/sparc/vm/copy_sparc.hpp Mon Jun 09 22:21:12 2014 -0700 10.2 +++ b/src/cpu/sparc/vm/copy_sparc.hpp Tue Jun 10 14:52:20 2014 -0700 10.3 @@ -184,7 +184,7 @@ 10.4 assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation"); 10.5 10.6 if (value == 0 && UseBlockZeroing && 10.7 - (count > (BlockZeroingLowLimit >> LogHeapWordSize))) { 10.8 + (count > (size_t)(BlockZeroingLowLimit >> LogHeapWordSize))) { 10.9 // Call it only when block zeroing is used 10.10 ((_zero_Fn)StubRoutines::zero_aligned_words())(tohw, count); 10.11 } else {
11.1 --- a/src/share/vm/ci/bcEscapeAnalyzer.cpp Mon Jun 09 22:21:12 2014 -0700 11.2 +++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp Tue Jun 10 14:52:20 2014 -0700 11.3 @@ -158,6 +158,9 @@ 11.4 11.5 void BCEscapeAnalyzer::set_method_escape(ArgumentMap vars) { 11.6 clear_bits(vars, _arg_local); 11.7 + if (vars.contains_allocated()) { 11.8 + _allocated_escapes = true; 11.9 + } 11.10 } 11.11 11.12 void BCEscapeAnalyzer::set_global_escape(ArgumentMap vars, bool merge) {
12.1 --- a/src/share/vm/opto/bytecodeInfo.cpp Mon Jun 09 22:21:12 2014 -0700 12.2 +++ b/src/share/vm/opto/bytecodeInfo.cpp Tue Jun 10 14:52:20 2014 -0700 12.3 @@ -361,11 +361,14 @@ 12.4 set_msg("not an accessor"); 12.5 return false; 12.6 } 12.7 + 12.8 + // Limit inlining depth in case inlining is forced or 12.9 + // _max_inline_level was increased to compensate for lambda forms. 12.10 + if (inline_level() > MaxForceInlineLevel) { 12.11 + set_msg("MaxForceInlineLevel"); 12.12 + return false; 12.13 + } 12.14 if (inline_level() > _max_inline_level) { 12.15 - if (callee_method->force_inline() && inline_level() > MaxForceInlineLevel) { 12.16 - set_msg("MaxForceInlineLevel"); 12.17 - return false; 12.18 - } 12.19 if (!callee_method->force_inline() || !IncrementalInline) { 12.20 set_msg("inlining too deep"); 12.21 return false;
13.1 --- a/src/share/vm/opto/library_call.cpp Mon Jun 09 22:21:12 2014 -0700 13.2 +++ b/src/share/vm/opto/library_call.cpp Tue Jun 10 14:52:20 2014 -0700 13.3 @@ -3978,8 +3978,11 @@ 13.4 } 13.5 13.6 13.7 -//------------------------------inline_native_hashcode-------------------- 13.8 -// Build special case code for calls to hashCode on an object. 13.9 +/** 13.10 + * Build special case code for calls to hashCode on an object. This call may 13.11 + * be virtual (invokevirtual) or bound (invokespecial). For each case we generate 13.12 + * slightly different code. 13.13 + */ 13.14 bool LibraryCallKit::inline_native_hashcode(bool is_virtual, bool is_static) { 13.15 assert(is_static == callee()->is_static(), "correct intrinsic selection"); 13.16 assert(!(is_virtual && is_static), "either virtual, special, or static"); 13.17 @@ -3987,11 +3990,9 @@ 13.18 enum { _slow_path = 1, _fast_path, _null_path, PATH_LIMIT }; 13.19 13.20 RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT); 13.21 - PhiNode* result_val = new(C) PhiNode(result_reg, 13.22 - TypeInt::INT); 13.23 + PhiNode* result_val = new(C) PhiNode(result_reg, TypeInt::INT); 13.24 PhiNode* result_io = new(C) PhiNode(result_reg, Type::ABIO); 13.25 - PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY, 13.26 - TypePtr::BOTTOM); 13.27 + PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY, TypePtr::BOTTOM); 13.28 Node* obj = NULL; 13.29 if (!is_static) { 13.30 // Check for hashing null object 13.31 @@ -4017,12 +4018,6 @@ 13.32 return true; 13.33 } 13.34 13.35 - // After null check, get the object's klass. 13.36 - Node* obj_klass = load_object_klass(obj); 13.37 - 13.38 - // This call may be virtual (invokevirtual) or bound (invokespecial). 13.39 - // For each case we generate slightly different code. 13.40 - 13.41 // We only go to the fast case code if we pass a number of guards. The 13.42 // paths which do not pass are accumulated in the slow_region. 13.43 RegionNode* slow_region = new (C) RegionNode(1); 13.44 @@ -4035,19 +4030,24 @@ 13.45 // guard for non-virtual calls -- the caller is known to be the native 13.46 // Object hashCode(). 13.47 if (is_virtual) { 13.48 + // After null check, get the object's klass. 13.49 + Node* obj_klass = load_object_klass(obj); 13.50 generate_virtual_guard(obj_klass, slow_region); 13.51 } 13.52 13.53 // Get the header out of the object, use LoadMarkNode when available 13.54 Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes()); 13.55 - Node* header = make_load(control(), header_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered); 13.56 + // The control of the load must be NULL. Otherwise, the load can move before 13.57 + // the null check after castPP removal. 13.58 + Node* no_ctrl = NULL; 13.59 + Node* header = make_load(no_ctrl, header_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered); 13.60 13.61 // Test the header to see if it is unlocked. 13.62 - Node *lock_mask = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place); 13.63 - Node *lmasked_header = _gvn.transform(new (C) AndXNode(header, lock_mask)); 13.64 - Node *unlocked_val = _gvn.MakeConX(markOopDesc::unlocked_value); 13.65 - Node *chk_unlocked = _gvn.transform(new (C) CmpXNode( lmasked_header, unlocked_val)); 13.66 - Node *test_unlocked = _gvn.transform(new (C) BoolNode( chk_unlocked, BoolTest::ne)); 13.67 + Node* lock_mask = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place); 13.68 + Node* lmasked_header = _gvn.transform(new (C) AndXNode(header, lock_mask)); 13.69 + Node* unlocked_val = _gvn.MakeConX(markOopDesc::unlocked_value); 13.70 + Node* chk_unlocked = _gvn.transform(new (C) CmpXNode( lmasked_header, unlocked_val)); 13.71 + Node* test_unlocked = _gvn.transform(new (C) BoolNode( chk_unlocked, BoolTest::ne)); 13.72 13.73 generate_slow_guard(test_unlocked, slow_region); 13.74 13.75 @@ -4055,19 +4055,19 @@ 13.76 // We depend on hash_mask being at most 32 bits and avoid the use of 13.77 // hash_mask_in_place because it could be larger than 32 bits in a 64-bit 13.78 // vm: see markOop.hpp. 13.79 - Node *hash_mask = _gvn.intcon(markOopDesc::hash_mask); 13.80 - Node *hash_shift = _gvn.intcon(markOopDesc::hash_shift); 13.81 - Node *hshifted_header= _gvn.transform(new (C) URShiftXNode(header, hash_shift)); 13.82 + Node* hash_mask = _gvn.intcon(markOopDesc::hash_mask); 13.83 + Node* hash_shift = _gvn.intcon(markOopDesc::hash_shift); 13.84 + Node* hshifted_header= _gvn.transform(new (C) URShiftXNode(header, hash_shift)); 13.85 // This hack lets the hash bits live anywhere in the mark object now, as long 13.86 // as the shift drops the relevant bits into the low 32 bits. Note that 13.87 // Java spec says that HashCode is an int so there's no point in capturing 13.88 // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build). 13.89 hshifted_header = ConvX2I(hshifted_header); 13.90 - Node *hash_val = _gvn.transform(new (C) AndINode(hshifted_header, hash_mask)); 13.91 - 13.92 - Node *no_hash_val = _gvn.intcon(markOopDesc::no_hash); 13.93 - Node *chk_assigned = _gvn.transform(new (C) CmpINode( hash_val, no_hash_val)); 13.94 - Node *test_assigned = _gvn.transform(new (C) BoolNode( chk_assigned, BoolTest::eq)); 13.95 + Node* hash_val = _gvn.transform(new (C) AndINode(hshifted_header, hash_mask)); 13.96 + 13.97 + Node* no_hash_val = _gvn.intcon(markOopDesc::no_hash); 13.98 + Node* chk_assigned = _gvn.transform(new (C) CmpINode( hash_val, no_hash_val)); 13.99 + Node* test_assigned = _gvn.transform(new (C) BoolNode( chk_assigned, BoolTest::eq)); 13.100 13.101 generate_slow_guard(test_assigned, slow_region); 13.102
14.1 --- a/src/share/vm/prims/jvm.cpp Mon Jun 09 22:21:12 2014 -0700 14.2 +++ b/src/share/vm/prims/jvm.cpp Tue Jun 10 14:52:20 2014 -0700 14.3 @@ -392,6 +392,23 @@ 14.4 JVM_END 14.5 14.6 14.7 +/* 14.8 + * Return the temporary directory that the VM uses for the attach 14.9 + * and perf data files. 14.10 + * 14.11 + * It is important that this directory is well-known and the 14.12 + * same for all VM instances. It cannot be affected by configuration 14.13 + * variables such as java.io.tmpdir. 14.14 + */ 14.15 +JVM_ENTRY(jstring, JVM_GetTemporaryDirectory(JNIEnv *env)) 14.16 + JVMWrapper("JVM_GetTemporaryDirectory"); 14.17 + HandleMark hm(THREAD); 14.18 + const char* temp_dir = os::get_temp_directory(); 14.19 + Handle h = java_lang_String::create_from_platform_dependent_str(temp_dir, CHECK_NULL); 14.20 + return (jstring) JNIHandles::make_local(env, h()); 14.21 +JVM_END 14.22 + 14.23 + 14.24 // java.lang.Runtime ///////////////////////////////////////////////////////////////////////// 14.25 14.26 extern volatile jint vm_created;
15.1 --- a/src/share/vm/prims/jvm.h Mon Jun 09 22:21:12 2014 -0700 15.2 +++ b/src/share/vm/prims/jvm.h Tue Jun 10 14:52:20 2014 -0700 15.3 @@ -1498,6 +1498,9 @@ 15.4 JNIEXPORT jobject JNICALL 15.5 JVM_InitAgentProperties(JNIEnv *env, jobject agent_props); 15.6 15.7 +JNIEXPORT jstring JNICALL 15.8 +JVM_GetTemporaryDirectory(JNIEnv *env); 15.9 + 15.10 /* Generics reflection support. 15.11 * 15.12 * Returns information about the given class's EnclosingMethod
16.1 --- a/src/share/vm/runtime/objectMonitor.cpp Mon Jun 09 22:21:12 2014 -0700 16.2 +++ b/src/share/vm/runtime/objectMonitor.cpp Tue Jun 10 14:52:20 2014 -0700 16.3 @@ -418,6 +418,15 @@ 16.4 jt->java_suspend_self(); 16.5 } 16.6 Self->set_current_pending_monitor(NULL); 16.7 + 16.8 + // We cleared the pending monitor info since we've just gotten past 16.9 + // the enter-check-for-suspend dance and we now own the monitor free 16.10 + // and clear, i.e., it is no longer pending. The ThreadBlockInVM 16.11 + // destructor can go to a safepoint at the end of this block. If we 16.12 + // do a thread dump during that safepoint, then this thread will show 16.13 + // as having "-locked" the monitor, but the OS and java.lang.Thread 16.14 + // states will still report that the thread is blocked trying to 16.15 + // acquire it. 16.16 } 16.17 16.18 Atomic::dec_ptr(&_count);
17.1 --- a/src/share/vm/runtime/vframe.cpp Mon Jun 09 22:21:12 2014 -0700 17.2 +++ b/src/share/vm/runtime/vframe.cpp Tue Jun 10 14:52:20 2014 -0700 17.3 @@ -199,6 +199,7 @@ 17.4 continue; 17.5 } 17.6 if (monitor->owner() != NULL) { 17.7 + // the monitor is associated with an object, i.e., it is locked 17.8 17.9 // First, assume we have the monitor locked. If we haven't found an 17.10 // owned monitor before and this is the first frame, then we need to 17.11 @@ -209,7 +210,11 @@ 17.12 if (!found_first_monitor && frame_count == 0) { 17.13 markOop mark = monitor->owner()->mark(); 17.14 if (mark->has_monitor() && 17.15 - mark->monitor() == thread()->current_pending_monitor()) { 17.16 + ( // we have marked ourself as pending on this monitor 17.17 + mark->monitor() == thread()->current_pending_monitor() || 17.18 + // we are not the owner of this monitor 17.19 + !mark->monitor()->is_entered(thread()) 17.20 + )) { 17.21 lock_state = "waiting to lock"; 17.22 } 17.23 }
18.1 --- a/test/TEST.groups Mon Jun 09 22:21:12 2014 -0700 18.2 +++ b/test/TEST.groups Tue Jun 10 14:52:20 2014 -0700 18.3 @@ -1,5 +1,5 @@ 18.4 # 18.5 -# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 18.6 +# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 18.7 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.8 # 18.9 # This code is free software; you can redistribute it and/or modify it 18.10 @@ -84,6 +84,7 @@ 18.11 runtime/NMT/ThreadedVirtualAllocTestType.java \ 18.12 runtime/NMT/VirtualAllocTestType.java \ 18.13 runtime/RedefineObject/TestRedefineObject.java \ 18.14 + runtime/Thread/TestThreadDumpMonitorContention.java \ 18.15 runtime/XCheckJniJsig/XCheckJSig.java \ 18.16 serviceability/attach/AttachWithStalePidFile.java \ 18.17 serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java Tue Jun 10 14:52:20 2014 -0700 19.3 @@ -0,0 +1,107 @@ 19.4 +/* 19.5 + * Copyright 2014 Google, Inc. All Rights Reserved. 19.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 19.7 + * 19.8 + * This code is free software; you can redistribute it and/or modify it 19.9 + * under the terms of the GNU General Public License version 2 only, as 19.10 + * published by the Free Software Foundation. 19.11 + * 19.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 19.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 19.15 + * version 2 for more details (a copy is included in the LICENSE file that 19.16 + * accompanied this code). 19.17 + * 19.18 + * You should have received a copy of the GNU General Public License version 19.19 + * 2 along with this work; if not, write to the Free Software Foundation, 19.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19.21 + * 19.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19.23 + * or visit www.oracle.com if you need additional information or have any 19.24 + * questions. 19.25 + */ 19.26 + 19.27 +/* 19.28 + * @test 19.29 + * @bug 8043354 19.30 + * @summary bcEscapeAnalyzer allocated_escapes not conservative enough 19.31 + * @run main/othervm -XX:CompileOnly=.visitAndPop TestAllocatedEscapesPtrComparison 19.32 + * @author Chuck Rasbold rasbold@google.com 19.33 + */ 19.34 + 19.35 +/* 19.36 + * Test always passes with -XX:-OptmimizePtrCompare 19.37 + */ 19.38 + 19.39 +import java.util.ArrayList; 19.40 +import java.util.List; 19.41 + 19.42 +public class TestAllocatedEscapesPtrComparison { 19.43 + 19.44 + static TestAllocatedEscapesPtrComparison dummy; 19.45 + 19.46 + class Marker { 19.47 + } 19.48 + 19.49 + List<Marker> markerList = new ArrayList<>(); 19.50 + 19.51 + // Suppress compilation of this method, it must be processed 19.52 + // by the bytecode escape analyzer. 19.53 + 19.54 + // Make a new marker and put it on the List 19.55 + Marker getMarker() { 19.56 + // result escapes through markerList 19.57 + final Marker result = new Marker(); 19.58 + markerList.add(result); 19.59 + return result; 19.60 + } 19.61 + 19.62 + void visit(int depth) { 19.63 + // Make a new marker 19.64 + getMarker(); 19.65 + 19.66 + // Call visitAndPop every once in a while 19.67 + // Cap the depth of our recursive visits 19.68 + if (depth % 10 == 2) { 19.69 + visitAndPop(depth + 1); 19.70 + } else if (depth < 15) { 19.71 + visit(depth + 1); 19.72 + } 19.73 + } 19.74 + 19.75 + void visitAndPop(int depth) { 19.76 + // Random dummy allocation to force EscapeAnalysis to process this method 19.77 + dummy = new TestAllocatedEscapesPtrComparison(); 19.78 + 19.79 + // Make a new marker 19.80 + Marker marker = getMarker(); 19.81 + 19.82 + visit(depth + 1); 19.83 + 19.84 + // Walk and pop the marker list up to the current marker 19.85 + boolean found = false; 19.86 + for (int i = markerList.size() - 1; i >= 0; i--) { 19.87 + Marker removed = markerList.remove(i); 19.88 + 19.89 + // In the failure, EA mistakenly converts this comparison to false 19.90 + if (removed == marker) { 19.91 + found = true; 19.92 + break; 19.93 + } 19.94 + } 19.95 + 19.96 + if (!found) { 19.97 + throw new RuntimeException("test fails"); 19.98 + } 19.99 + } 19.100 + 19.101 + 19.102 + public static void main(String args[]) { 19.103 + TestAllocatedEscapesPtrComparison tc = new TestAllocatedEscapesPtrComparison(); 19.104 + 19.105 + // Warmup and run enough times 19.106 + for (int i = 0; i < 20000; i++) { 19.107 + tc.visit(0); 19.108 + } 19.109 + } 19.110 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/test/compiler/intrinsics/hashcode/TestHashCode.java Tue Jun 10 14:52:20 2014 -0700 20.3 @@ -0,0 +1,73 @@ 20.4 +/* 20.5 + * Copyright (c) 2014, Oracle and/or its affiliates. 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 8011646 20.30 + * @summary SEGV in compiled code with loop predication 20.31 + * @run main/othervm -XX:-TieredCompilation -XX:CompileOnly=TestHashCode.m1,Object.hashCode TestHashCode 20.32 + * 20.33 + */ 20.34 + 20.35 +public class TestHashCode { 20.36 + static class A { 20.37 + int i; 20.38 + } 20.39 + 20.40 + static class B extends A { 20.41 + } 20.42 + 20.43 + static boolean crash = false; 20.44 + 20.45 + static A m2() { 20.46 + if (crash) { 20.47 + return null; 20.48 + } 20.49 + return new A(); 20.50 + } 20.51 + 20.52 + static int m1(A aa) { 20.53 + int res = 0; 20.54 + for (int i = 0; i < 10; i++) { 20.55 + A a = m2(); 20.56 + int j = a.i; 20.57 + if (aa instanceof B) { 20.58 + } 20.59 + res += a.hashCode(); 20.60 + } 20.61 + return res; 20.62 + } 20.63 + 20.64 + public static void main(String[] args) { 20.65 + A a = new A(); 20.66 + for (int i = 0; i < 20000; i++) { 20.67 + m1(a); 20.68 + } 20.69 + crash = true; 20.70 + try { 20.71 + m1(a); 20.72 + } catch (NullPointerException e) { 20.73 + System.out.println("Test passed"); 20.74 + } 20.75 + } 20.76 +}
21.1 --- a/test/gc/g1/TestStringDeduplicationMemoryUsage.java Mon Jun 09 22:21:12 2014 -0700 21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 21.3 @@ -1,36 +0,0 @@ 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 TestStringDeduplicationMemoryUsage 21.29 - * @summary Test string deduplication memory usage 21.30 - * @bug 8029075 21.31 - * @key gc 21.32 - * @library /testlibrary 21.33 - */ 21.34 - 21.35 -public class TestStringDeduplicationMemoryUsage { 21.36 - public static void main(String[] args) throws Exception { 21.37 - TestStringDeduplicationTools.testMemoryUsage(); 21.38 - } 21.39 -}
22.1 --- a/test/gc/g1/TestStringDeduplicationTools.java Mon Jun 09 22:21:12 2014 -0700 22.2 +++ b/test/gc/g1/TestStringDeduplicationTools.java Tue Jun 10 14:52:20 2014 -0700 22.3 @@ -294,55 +294,6 @@ 22.4 } 22.5 } 22.6 22.7 - private static class MemoryUsageTest { 22.8 - public static void main(String[] args) { 22.9 - System.out.println("Begin: MemoryUsageTest"); 22.10 - 22.11 - final boolean useStringDeduplication = Boolean.parseBoolean(args[0]); 22.12 - final int numberOfStrings = LargeNumberOfStrings; 22.13 - final int numberOfUniqueStrings = 1; 22.14 - 22.15 - ArrayList<String> list = createStrings(numberOfStrings, numberOfUniqueStrings); 22.16 - forceDeduplication(DefaultAgeThreshold, FullGC); 22.17 - 22.18 - if (useStringDeduplication) { 22.19 - verifyStrings(list, numberOfUniqueStrings); 22.20 - } 22.21 - 22.22 - System.gc(); 22.23 - 22.24 - System.out.println("Heap Memory Usage: " + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed()); 22.25 - System.out.println("Array Header Size: " + unsafe.ARRAY_CHAR_BASE_OFFSET); 22.26 - 22.27 - System.out.println("End: MemoryUsageTest"); 22.28 - } 22.29 - 22.30 - public static OutputAnalyzer run(boolean useStringDeduplication) throws Exception { 22.31 - String[] extraArgs = new String[0]; 22.32 - 22.33 - if (useStringDeduplication) { 22.34 - extraArgs = new String[] { 22.35 - "-XX:+UseStringDeduplication", 22.36 - "-XX:+PrintStringDeduplicationStatistics", 22.37 - "-XX:StringDeduplicationAgeThreshold=" + DefaultAgeThreshold 22.38 - }; 22.39 - } 22.40 - 22.41 - String[] defaultArgs = new String[] { 22.42 - "-XX:+PrintGC", 22.43 - "-XX:+PrintGCDetails", 22.44 - MemoryUsageTest.class.getName(), 22.45 - "" + useStringDeduplication 22.46 - }; 22.47 - 22.48 - ArrayList<String> args = new ArrayList<String>(); 22.49 - args.addAll(Arrays.asList(extraArgs)); 22.50 - args.addAll(Arrays.asList(defaultArgs)); 22.51 - 22.52 - return runTest(args.toArray(new String[args.size()])); 22.53 - } 22.54 - } 22.55 - 22.56 /* 22.57 * Tests 22.58 */ 22.59 @@ -480,44 +431,4 @@ 22.60 OutputAnalyzer output = InternedTest.run(); 22.61 output.shouldHaveExitValue(0); 22.62 } 22.63 - 22.64 - public static void testMemoryUsage() throws Exception { 22.65 - // Test that memory usage is reduced after deduplication 22.66 - OutputAnalyzer output; 22.67 - final String heapMemoryUsagePattern = "Heap Memory Usage: (\\d+)"; 22.68 - final String arrayHeaderSizePattern = "Array Header Size: (\\d+)"; 22.69 - 22.70 - // Run without deduplication 22.71 - output = MemoryUsageTest.run(false); 22.72 - output.shouldHaveExitValue(0); 22.73 - final long heapMemoryUsageWithoutDedup = Long.parseLong(output.firstMatch(heapMemoryUsagePattern, 1)); 22.74 - final long arrayHeaderSizeWithoutDedup = Long.parseLong(output.firstMatch(arrayHeaderSizePattern, 1)); 22.75 - 22.76 - // Run with deduplication 22.77 - output = MemoryUsageTest.run(true); 22.78 - output.shouldHaveExitValue(0); 22.79 - final long heapMemoryUsageWithDedup = Long.parseLong(output.firstMatch(heapMemoryUsagePattern, 1)); 22.80 - final long arrayHeaderSizeWithDedup = Long.parseLong(output.firstMatch(arrayHeaderSizePattern, 1)); 22.81 - 22.82 - // Sanity check to make sure one instance isn't using compressed class pointers and the other not 22.83 - if (arrayHeaderSizeWithoutDedup != arrayHeaderSizeWithDedup) { 22.84 - throw new Exception("Unexpected difference between array header sizes"); 22.85 - } 22.86 - 22.87 - // Calculate expected memory usage with deduplication enabled. This calculation does 22.88 - // not take alignment and padding into account, so it's a conservative estimate. 22.89 - final long sizeOfChar = unsafe.ARRAY_CHAR_INDEX_SCALE; 22.90 - final long sizeOfCharArray = StringLength * sizeOfChar + arrayHeaderSizeWithoutDedup; 22.91 - final long bytesSaved = (LargeNumberOfStrings - 1) * sizeOfCharArray; 22.92 - final long heapMemoryUsageWithDedupExpected = heapMemoryUsageWithoutDedup - bytesSaved; 22.93 - 22.94 - System.out.println("Memory usage summary:"); 22.95 - System.out.println(" heapMemoryUsageWithoutDedup: " + heapMemoryUsageWithoutDedup); 22.96 - System.out.println(" heapMemoryUsageWithDedup: " + heapMemoryUsageWithDedup); 22.97 - System.out.println(" heapMemoryUsageWithDedupExpected: " + heapMemoryUsageWithDedupExpected); 22.98 - 22.99 - if (heapMemoryUsageWithDedup > heapMemoryUsageWithDedupExpected) { 22.100 - throw new Exception("Unexpected memory usage, heapMemoryUsageWithDedup should be less or equal to heapMemoryUsageWithDedupExpected"); 22.101 - } 22.102 - } 22.103 }
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/test/runtime/Thread/TestThreadDumpMonitorContention.java Tue Jun 10 14:52:20 2014 -0700 23.3 @@ -0,0 +1,405 @@ 23.4 +/* 23.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 23.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 23.7 + * 23.8 + * This code is free software; you can redistribute it and/or modify it 23.9 + * under the terms of the GNU General Public License version 2 only, as 23.10 + * published by the Free Software Foundation. 23.11 + * 23.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 23.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 23.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 23.15 + * version 2 for more details (a copy is included in the LICENSE file that 23.16 + * accompanied this code). 23.17 + * 23.18 + * You should have received a copy of the GNU General Public License version 23.19 + * 2 along with this work; if not, write to the Free Software Foundation, 23.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23.21 + * 23.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23.23 + * or visit www.oracle.com if you need additional information or have any 23.24 + * questions. 23.25 + */ 23.26 + 23.27 +/* 23.28 + * @test 23.29 + * @bug 8036823 23.30 + * @summary Creates two threads contending for the same lock and checks 23.31 + * whether jstack reports "locked" by more than one thread. 23.32 + * 23.33 + * @library /testlibrary 23.34 + * @run main/othervm TestThreadDumpMonitorContention 23.35 + */ 23.36 + 23.37 +import java.io.BufferedReader; 23.38 +import java.io.InputStreamReader; 23.39 +import java.lang.management.ManagementFactory; 23.40 +import java.lang.management.RuntimeMXBean; 23.41 +import java.util.ArrayList; 23.42 +import java.util.List; 23.43 +import java.util.regex.Matcher; 23.44 +import java.util.regex.Pattern; 23.45 + 23.46 +import com.oracle.java.testlibrary.*; 23.47 + 23.48 +public class TestThreadDumpMonitorContention { 23.49 + // jstack tends to be closely bound to the VM that we are running 23.50 + // so use getTestJDKTool() instead of getCompileJDKTool() or even 23.51 + // getJDKTool() which can fall back to "compile.jdk". 23.52 + final static String JSTACK = JDKToolFinder.getTestJDKTool("jstack"); 23.53 + final static String PID = getPid(); 23.54 + 23.55 + // looking for header lines with these patterns: 23.56 + // "ContendingThread-1" #19 prio=5 os_prio=64 tid=0x000000000079c000 nid=0x23 runnable [0xffff80ffb8b87000] 23.57 + // "ContendingThread-2" #21 prio=5 os_prio=64 tid=0x0000000000780000 nid=0x2f waiting for monitor entry [0xfffffd7fc1111000] 23.58 + final static Pattern HEADER_PREFIX_PATTERN = Pattern.compile( 23.59 + "^\"ContendingThread-.*"); 23.60 + final static Pattern HEADER_WAITING_PATTERN = Pattern.compile( 23.61 + "^\"ContendingThread-.* waiting for monitor entry .*"); 23.62 + final static Pattern HEADER_RUNNABLE_PATTERN = Pattern.compile( 23.63 + "^\"ContendingThread-.* runnable .*"); 23.64 + 23.65 + // looking for thread state lines with these patterns: 23.66 + // java.lang.Thread.State: RUNNABLE 23.67 + // java.lang.Thread.State: BLOCKED (on object monitor) 23.68 + final static Pattern THREAD_STATE_PREFIX_PATTERN = Pattern.compile( 23.69 + " *java\\.lang\\.Thread\\.State: .*"); 23.70 + final static Pattern THREAD_STATE_BLOCKED_PATTERN = Pattern.compile( 23.71 + " *java\\.lang\\.Thread\\.State: BLOCKED \\(on object monitor\\)"); 23.72 + final static Pattern THREAD_STATE_RUNNABLE_PATTERN = Pattern.compile( 23.73 + " *java\\.lang\\.Thread\\.State: RUNNABLE"); 23.74 + 23.75 + // looking for duplicates of this pattern: 23.76 + // - locked <0x000000076ac59e20> (a TestThreadDumpMonitorContention$1) 23.77 + final static Pattern LOCK_PATTERN = Pattern.compile( 23.78 + ".* locked \\<.*\\(a TestThreadDumpMonitorContention.*"); 23.79 + 23.80 + // sanity checking header and thread state lines associated 23.81 + // with this pattern: 23.82 + // - waiting to lock <0x000000076ac59e20> (a TestThreadDumpMonitorContention$1) 23.83 + final static Pattern WAITING_PATTERN = Pattern.compile( 23.84 + ".* waiting to lock \\<.*\\(a TestThreadDumpMonitorContention.*"); 23.85 + 23.86 + volatile static boolean done = false; 23.87 + 23.88 + static int error_cnt = 0; 23.89 + static String header_line = null; 23.90 + static boolean have_header_line = false; 23.91 + static boolean have_thread_state_line = false; 23.92 + static int match_cnt = 0; 23.93 + static String[] match_list = new String[2]; 23.94 + static int n_samples = 15; 23.95 + static String thread_state_line = null; 23.96 + static boolean verbose = false; 23.97 + 23.98 + public static void main(String[] args) throws Exception { 23.99 + if (args.length != 0) { 23.100 + int arg_i = 0; 23.101 + if (args[arg_i].equals("-v")) { 23.102 + verbose = true; 23.103 + arg_i++; 23.104 + } 23.105 + 23.106 + try { 23.107 + n_samples = Integer.parseInt(args[arg_i]); 23.108 + } catch (NumberFormatException nfe) { 23.109 + System.err.println(nfe); 23.110 + usage(); 23.111 + } 23.112 + } 23.113 + 23.114 + Runnable runnable = new Runnable() { 23.115 + public void run() { 23.116 + while (!done) { 23.117 + synchronized (this) { } 23.118 + } 23.119 + } 23.120 + }; 23.121 + Thread[] thread_list = new Thread[2]; 23.122 + thread_list[0] = new Thread(runnable, "ContendingThread-1"); 23.123 + thread_list[1] = new Thread(runnable, "ContendingThread-2"); 23.124 + thread_list[0].start(); 23.125 + thread_list[1].start(); 23.126 + 23.127 + doSamples(); 23.128 + 23.129 + done = true; 23.130 + 23.131 + thread_list[0].join(); 23.132 + thread_list[1].join(); 23.133 + 23.134 + if (error_cnt == 0) { 23.135 + System.out.println("Test PASSED."); 23.136 + } else { 23.137 + System.out.println("Test FAILED."); 23.138 + throw new AssertionError("error_cnt=" + error_cnt); 23.139 + } 23.140 + } 23.141 + 23.142 + // Reached a blank line which is the end of the 23.143 + // stack trace without matching either LOCK_PATTERN 23.144 + // or WAITING_PATTERN. Rare, but it's not an error. 23.145 + // 23.146 + // Example: 23.147 + // "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f runnable [0xfffffd7fc1111000] 23.148 + // java.lang.Thread.State: RUNNABLE 23.149 + // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67) 23.150 + // at java.lang.Thread.run(Thread.java:745) 23.151 + // 23.152 + static boolean checkBlankLine(String line) { 23.153 + if (line.length() == 0) { 23.154 + have_header_line = false; 23.155 + have_thread_state_line = false; 23.156 + return true; 23.157 + } 23.158 + 23.159 + return false; 23.160 + } 23.161 + 23.162 + // Process the locked line here if we found one. 23.163 + // 23.164 + // Example 1: 23.165 + // "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f runnable [0xfffffd7fc1111000] 23.166 + // java.lang.Thread.State: RUNNABLE 23.167 + // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67) 23.168 + // - locked <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1) 23.169 + // at java.lang.Thread.run(Thread.java:745) 23.170 + // 23.171 + // Example 2: 23.172 + // "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f waiting for monitor entry [0xfffffd7fc1111000] 23.173 + // java.lang.Thread.State: BLOCKED (on object monitor) 23.174 + // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67) 23.175 + // - locked <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1) 23.176 + // at java.lang.Thread.run(Thread.java:745) 23.177 + // 23.178 + static boolean checkLockedLine(String line) { 23.179 + Matcher matcher = LOCK_PATTERN.matcher(line); 23.180 + if (matcher.matches()) { 23.181 + if (verbose) { 23.182 + System.out.println("locked_line='" + line + "'"); 23.183 + } 23.184 + match_list[match_cnt] = new String(line); 23.185 + match_cnt++; 23.186 + 23.187 + matcher = HEADER_RUNNABLE_PATTERN.matcher(header_line); 23.188 + if (!matcher.matches()) { 23.189 + // It's strange, but a locked line can also 23.190 + // match the HEADER_WAITING_PATTERN. 23.191 + matcher = HEADER_WAITING_PATTERN.matcher(header_line); 23.192 + if (!matcher.matches()) { 23.193 + System.err.println(); 23.194 + System.err.println("ERROR: header line does " + 23.195 + "not match runnable or waiting patterns."); 23.196 + System.err.println("ERROR: header_line='" + 23.197 + header_line + "'"); 23.198 + System.err.println("ERROR: locked_line='" + line + "'"); 23.199 + error_cnt++; 23.200 + } 23.201 + } 23.202 + 23.203 + matcher = THREAD_STATE_RUNNABLE_PATTERN.matcher(thread_state_line); 23.204 + if (!matcher.matches()) { 23.205 + // It's strange, but a locked line can also 23.206 + // match the THREAD_STATE_BLOCKED_PATTERN. 23.207 + matcher = THREAD_STATE_BLOCKED_PATTERN.matcher( 23.208 + thread_state_line); 23.209 + if (!matcher.matches()) { 23.210 + System.err.println(); 23.211 + System.err.println("ERROR: thread state line does not " + 23.212 + "match runnable or waiting patterns."); 23.213 + System.err.println("ERROR: " + "thread_state_line='" + 23.214 + thread_state_line + "'"); 23.215 + System.err.println("ERROR: locked_line='" + line + "'"); 23.216 + error_cnt++; 23.217 + } 23.218 + } 23.219 + 23.220 + // Have everything we need from this thread stack 23.221 + // that matches the LOCK_PATTERN. 23.222 + have_header_line = false; 23.223 + have_thread_state_line = false; 23.224 + return true; 23.225 + } 23.226 + 23.227 + return false; 23.228 + } 23.229 + 23.230 + // Process the waiting line here if we found one. 23.231 + // 23.232 + // Example: 23.233 + // "ContendingThread-2" #22 prio=5 os_prio=64 tid=0x00000000007b9800 nid=0x30 waiting for monitor entry [0xfffffd7fc1010000] 23.234 + // java.lang.Thread.State: BLOCKED (on object monitor) 23.235 + // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67) 23.236 + // - waiting to lock <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1) 23.237 + // at java.lang.Thread.run(Thread.java:745) 23.238 + // 23.239 + static boolean checkWaitingLine(String line) { 23.240 + Matcher matcher = WAITING_PATTERN.matcher(line); 23.241 + if (matcher.matches()) { 23.242 + if (verbose) { 23.243 + System.out.println("waiting_line='" + line + "'"); 23.244 + } 23.245 + 23.246 + matcher = HEADER_WAITING_PATTERN.matcher(header_line); 23.247 + if (!matcher.matches()) { 23.248 + System.err.println(); 23.249 + System.err.println("ERROR: header line does " + 23.250 + "not match a waiting pattern."); 23.251 + System.err.println("ERROR: header_line='" + header_line + "'"); 23.252 + System.err.println("ERROR: waiting_line='" + line + "'"); 23.253 + error_cnt++; 23.254 + } 23.255 + 23.256 + matcher = THREAD_STATE_BLOCKED_PATTERN.matcher(thread_state_line); 23.257 + if (!matcher.matches()) { 23.258 + System.err.println(); 23.259 + System.err.println("ERROR: thread state line " + 23.260 + "does not match a waiting pattern."); 23.261 + System.err.println("ERROR: thread_state_line='" + 23.262 + thread_state_line + "'"); 23.263 + System.err.println("ERROR: waiting_line='" + line + "'"); 23.264 + error_cnt++; 23.265 + } 23.266 + 23.267 + // Have everything we need from this thread stack 23.268 + // that matches the WAITING_PATTERN. 23.269 + have_header_line = false; 23.270 + have_thread_state_line = false; 23.271 + return true; 23.272 + } 23.273 + 23.274 + return false; 23.275 + } 23.276 + 23.277 + static void doSamples() throws Exception { 23.278 + for (int count = 0; count < n_samples; count++) { 23.279 + match_cnt = 0; 23.280 + // verbose mode or an error has a lot of output so add more space 23.281 + if (verbose || error_cnt > 0) System.out.println(); 23.282 + System.out.println("Sample #" + count); 23.283 + 23.284 + // We don't use the ProcessTools, OutputBuffer or 23.285 + // OutputAnalyzer classes from the testlibrary because 23.286 + // we have a complicated multi-line parse to perform 23.287 + // on a narrow subset of the JSTACK output. 23.288 + // 23.289 + // - we only care about stack traces that match 23.290 + // HEADER_PREFIX_PATTERN; only two should match 23.291 + // - we care about at most three lines from each stack trace 23.292 + // - if both stack traces match LOCKED_PATTERN, then that's 23.293 + // a failure and we report it 23.294 + // - for a stack trace that matches LOCKED_PATTERN, we verify: 23.295 + // - the header line matches HEADER_RUNNABLE_PATTERN 23.296 + // or HEADER_WAITING_PATTERN 23.297 + // - the thread state line matches THREAD_STATE_BLOCKED_PATTERN 23.298 + // or THREAD_STATE_RUNNABLE_PATTERN 23.299 + // - we report any mismatches as failures 23.300 + // - for a stack trace that matches WAITING_PATTERN, we verify: 23.301 + // - the header line matches HEADER_WAITING_PATTERN 23.302 + // - the thread state line matches THREAD_STATE_BLOCKED_PATTERN 23.303 + // - we report any mismatches as failures 23.304 + // - the stack traces that match HEADER_PREFIX_PATTERN may 23.305 + // not match either LOCKED_PATTERN or WAITING_PATTERN 23.306 + // because we might observe the thread outside of 23.307 + // monitor operations; this is not considered a failure 23.308 + // 23.309 + // When we do observe LOCKED_PATTERN or WAITING_PATTERN, 23.310 + // then we are checking the header and thread state patterns 23.311 + // that occurred earlier in the current stack trace that 23.312 + // matched HEADER_PREFIX_PATTERN. We don't use data from 23.313 + // stack traces that don't match HEADER_PREFIX_PATTERN and 23.314 + // we don't mix data between the two stack traces that do 23.315 + // match HEADER_PREFIX_PATTERN. 23.316 + // 23.317 + Process process = new ProcessBuilder(JSTACK, PID) 23.318 + .redirectErrorStream(true).start(); 23.319 + 23.320 + BufferedReader reader = new BufferedReader(new InputStreamReader( 23.321 + process.getInputStream())); 23.322 + String line; 23.323 + while ((line = reader.readLine()) != null) { 23.324 + Matcher matcher = null; 23.325 + 23.326 + // process the header line here 23.327 + if (!have_header_line) { 23.328 + matcher = HEADER_PREFIX_PATTERN.matcher(line); 23.329 + if (matcher.matches()) { 23.330 + if (verbose) { 23.331 + System.out.println(); 23.332 + System.out.println("header='" + line + "'"); 23.333 + } 23.334 + header_line = new String(line); 23.335 + have_header_line = true; 23.336 + continue; 23.337 + } 23.338 + continue; // skip until have a header line 23.339 + } 23.340 + 23.341 + // process the thread state line here 23.342 + if (!have_thread_state_line) { 23.343 + matcher = THREAD_STATE_PREFIX_PATTERN.matcher(line); 23.344 + if (matcher.matches()) { 23.345 + if (verbose) { 23.346 + System.out.println("thread_state='" + line + "'"); 23.347 + } 23.348 + thread_state_line = new String(line); 23.349 + have_thread_state_line = true; 23.350 + continue; 23.351 + } 23.352 + continue; // skip until we have a thread state line 23.353 + } 23.354 + 23.355 + // process the locked line here if we find one 23.356 + if (checkLockedLine(line)) { 23.357 + continue; 23.358 + } 23.359 + 23.360 + // process the waiting line here if we find one 23.361 + if (checkWaitingLine(line)) { 23.362 + continue; 23.363 + } 23.364 + 23.365 + // process the blank line here if we find one 23.366 + if (checkBlankLine(line)) { 23.367 + continue; 23.368 + } 23.369 + } 23.370 + process.waitFor(); 23.371 + 23.372 + if (match_cnt == 2) { 23.373 + if (match_list[0].equals(match_list[1])) { 23.374 + System.err.println(); 23.375 + System.err.println("ERROR: matching lock lines:"); 23.376 + System.err.println("ERROR: line[0]'" + match_list[0] + "'"); 23.377 + System.err.println("ERROR: line[1]'" + match_list[1] + "'"); 23.378 + error_cnt++; 23.379 + } 23.380 + } 23.381 + 23.382 + // slight delay between jstack launches 23.383 + Thread.sleep(500); 23.384 + } 23.385 + } 23.386 + 23.387 + // This helper relies on RuntimeMXBean.getName() returning a string 23.388 + // that looks like this: 5436@mt-haku 23.389 + // 23.390 + // The testlibrary has tryFindJvmPid(), but that uses a separate 23.391 + // process which is much more expensive for finding out your own PID. 23.392 + // 23.393 + static String getPid() { 23.394 + RuntimeMXBean runtimebean = ManagementFactory.getRuntimeMXBean(); 23.395 + String vmname = runtimebean.getName(); 23.396 + int i = vmname.indexOf('@'); 23.397 + if (i != -1) { 23.398 + vmname = vmname.substring(0, i); 23.399 + } 23.400 + return vmname; 23.401 + } 23.402 + 23.403 + static void usage() { 23.404 + System.err.println("Usage: " + 23.405 + "java TestThreadDumpMonitorContention [-v] [n_samples]"); 23.406 + System.exit(1); 23.407 + } 23.408 +}