Mercurial > hg > openjdk > jdk9 > hotspot
changeset 11785:a4cdffa18e76
Merge
author | amurillo |
---|---|
date | Fri, 12 Aug 2016 13:58:14 -0700 |
parents | 713951c08aa2 (current diff) 14f97d7574bf (diff) |
children | 2bf98fb4ca55 46a21d1c5f1c |
files | |
diffstat | 25 files changed, 236 insertions(+), 101 deletions(-) [+] |
line wrap: on
line diff
--- a/make/test/JtregNative.gmk Fri Aug 12 08:59:20 2016 -0700 +++ b/make/test/JtregNative.gmk Fri Aug 12 13:58:14 2016 -0700 @@ -50,7 +50,6 @@ $(HOTSPOT_TOPDIR)/test/runtime/BoolReturn \ $(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \ $(HOTSPOT_TOPDIR)/test/compiler/calls \ - $(HOTSPOT_TOPDIR)/test/compiler/native \ $(HOTSPOT_TOPDIR)/test/serviceability/jvmti/GetNamedModule \ $(HOTSPOT_TOPDIR)/test/testlibrary/jvmti \ $(HOTSPOT_TOPDIR)/test/compiler/jvmci/jdk.vm.ci.code.test \
--- a/src/cpu/aarch64/vm/frame_aarch64.cpp Fri Aug 12 08:59:20 2016 -0700 +++ b/src/cpu/aarch64/vm/frame_aarch64.cpp Fri Aug 12 13:58:14 2016 -0700 @@ -110,17 +110,7 @@ // Entry frame checks if (is_entry_frame()) { // an entry frame must have a valid fp. - - if (!fp_safe) return false; - - // Validate the JavaCallWrapper an entry frame must have - - address jcw = (address)entry_frame_call_wrapper(); - - bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > fp); - - return jcw_safe; - + return fp_safe && is_entry_frame_valid(thread); } intptr_t* sender_sp = NULL; @@ -210,15 +200,8 @@ } // construct the potential sender - frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc); - - // Validate the JavaCallWrapper an entry frame must have - address jcw = (address)sender.entry_frame_call_wrapper(); - - bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp()); - - return jcw_safe; + return sender.is_entry_frame_valid(thread); } CompiledMethod* nm = sender_blob->as_compiled_method_or_null();
--- a/src/cpu/sparc/vm/frame_sparc.cpp Fri Aug 12 08:59:20 2016 -0700 +++ b/src/cpu/sparc/vm/frame_sparc.cpp Fri Aug 12 13:58:14 2016 -0700 @@ -225,19 +225,7 @@ // Entry frame checks if (is_entry_frame()) { // an entry frame must have a valid fp. - - if (!fp_safe) { - return false; - } - - // Validate the JavaCallWrapper an entry frame must have - - address jcw = (address)entry_frame_call_wrapper(); - - bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > _FP); - - return jcw_safe; - + return fp_safe && is_entry_frame_valid(thread); } intptr_t* younger_sp = sp(); @@ -290,14 +278,8 @@ return false; } - if( sender.is_entry_frame()) { - // Validate the JavaCallWrapper an entry frame must have - - address jcw = (address)sender.entry_frame_call_wrapper(); - - bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > sender_fp); - - return jcw_safe; + if (sender.is_entry_frame()) { + return sender.is_entry_frame_valid(thread); } // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size @@ -357,12 +339,6 @@ _cb = CodeCache::find_blob(_pc); } _deopt_state = unknown; -#ifdef ASSERT - if ( _cb != NULL && _cb->is_compiled()) { - // Without a valid unextended_sp() we can't convert the pc to "original" - assert(!((CompiledMethod*)_cb)->is_deopt_pc(_pc), "invariant broken"); - } -#endif // ASSERT } frame::frame(intptr_t* sp, unpatchable_t, address pc, CodeBlob* cb) { @@ -534,6 +510,7 @@ void frame::patch_pc(Thread* thread, address pc) { + vmassert(_deopt_state != unknown, "frame is unpatchable"); if(thread == Thread::current()) { StubRoutines::Sparc::flush_callers_register_windows_func()(); }
--- a/src/cpu/x86/vm/frame_x86.cpp Fri Aug 12 08:59:20 2016 -0700 +++ b/src/cpu/x86/vm/frame_x86.cpp Fri Aug 12 13:58:14 2016 -0700 @@ -108,17 +108,7 @@ // Entry frame checks if (is_entry_frame()) { // an entry frame must have a valid fp. - - if (!fp_safe) return false; - - // Validate the JavaCallWrapper an entry frame must have - - address jcw = (address)entry_frame_call_wrapper(); - - bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > fp); - - return jcw_safe; - + return fp_safe && is_entry_frame_valid(thread); } intptr_t* sender_sp = NULL; @@ -209,15 +199,8 @@ } // construct the potential sender - frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc); - - // Validate the JavaCallWrapper an entry frame must have - address jcw = (address)sender.entry_frame_call_wrapper(); - - bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp()); - - return jcw_safe; + return sender.is_entry_frame_valid(thread); } CompiledMethod* nm = sender_blob->as_compiled_method_or_null();
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/BreakpointInfo.java Fri Aug 12 08:59:20 2016 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/BreakpointInfo.java Fri Aug 12 13:58:14 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2016 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/MethodCounters.java Fri Aug 12 08:59:20 2016 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/MethodCounters.java Fri Aug 12 13:58:14 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java Fri Aug 12 08:59:20 2016 -0700 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java Fri Aug 12 13:58:14 2016 -0700 @@ -26,6 +26,7 @@ import java.lang.reflect.Modifier; import java.util.*; +import java.util.stream.*; import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.runtime.*; @@ -204,15 +205,29 @@ } } - protected Object getHashtable(Instance oop, boolean isProperties) { + private void setPropertiesEntry(java.util.Properties p, Oop oop) { + InstanceKlass ik = (InstanceKlass)oop.getKlass(); + OopField keyField = (OopField)ik.findField("key", "Ljava/lang/Object;"); + OopField valueField = (OopField)ik.findField("val", "Ljava/lang/Object;"); + + try { + p.setProperty((String)readObject(keyField.getValue(oop)), + (String)readObject(valueField.getValue(oop))); + } catch (ClassNotFoundException ce) { + if (DEBUG) { + debugPrintStackTrace(ce); + } + } + } + + protected Object getHashtable(Instance oop) { InstanceKlass k = (InstanceKlass)oop.getKlass(); OopField tableField = (OopField)k.findField("table", "[Ljava/util/Hashtable$Entry;"); if (tableField == null) { debugPrintln("Could not find field of [Ljava/util/Hashtable$Entry;"); return null; } - java.util.Hashtable table = (isProperties) ? new java.util.Properties() - : new java.util.Hashtable(); + java.util.Hashtable table = new java.util.Hashtable(); ObjArray kvs = (ObjArray)tableField.getValue(oop); long size = kvs.getLength(); debugPrintln("Hashtable$Entry Size = " + size); @@ -225,6 +240,39 @@ return table; } + private Properties getProperties(Instance oop) { + InstanceKlass k = (InstanceKlass)oop.getKlass(); + OopField mapField = (OopField)k.findField("map", "Ljava/util/concurrent/ConcurrentHashMap;"); + if (mapField == null) { + debugPrintln("Could not find field of Ljava/util/concurrent/ConcurrentHashMap"); + return null; + } + + Instance mapObj = (Instance)mapField.getValue(oop); + if (mapObj == null) { + debugPrintln("Could not get map field from java.util.Properties"); + return null; + } + + InstanceKlass mk = (InstanceKlass)mapObj.getKlass(); + OopField tableField = (OopField)mk.findField("table", "[Ljava/util/concurrent/ConcurrentHashMap$Node;"); + if (tableField == null) { + debugPrintln("Could not find field of [Ljava/util/concurrent/ConcurrentHashMap$Node"); + return null; + } + + java.util.Properties props = new java.util.Properties(); + ObjArray kvs = (ObjArray)tableField.getValue(mapObj); + long size = kvs.getLength(); + debugPrintln("ConcurrentHashMap$Node Size = " + size); + LongStream.range(0, size) + .mapToObj(kvs::getObjAt) + .filter(o -> o != null) + .forEach(o -> setPropertiesEntry(props, o)); + + return props; + } + public Object readInstance(Instance oop) throws ClassNotFoundException { Object result = getFromObjTable(oop); if (result == null) { @@ -240,11 +288,11 @@ } if (kls.getName().equals(javaUtilHashtable())) { - return getHashtable(oop, false); + return getHashtable(oop); } if (kls.getName().equals(javaUtilProperties())) { - return getHashtable(oop, true); + return getProperties(oop); } Class clz = readClass(kls);
--- a/src/share/vm/classfile/classLoaderData.cpp Fri Aug 12 08:59:20 2016 -0700 +++ b/src/share/vm/classfile/classLoaderData.cpp Fri Aug 12 13:58:14 2016 -0700 @@ -1173,7 +1173,7 @@ if (class_loader() == NULL) { out->print("NULL class_loader"); } else { - out->print("class loader " INTPTR_FORMAT, p2i(this)); + out->print("class loader " INTPTR_FORMAT " ", p2i(this)); class_loader()->print_value_on(out); } }
--- a/src/share/vm/gc/g1/g1Analytics.cpp Fri Aug 12 08:59:20 2016 -0700 +++ b/src/share/vm/gc/g1/g1Analytics.cpp Fri Aug 12 13:58:14 2016 -0700 @@ -316,8 +316,12 @@ return get_new_size_prediction(_pending_cards_seq); } +double G1Analytics::oldest_known_gc_end_time_sec() const { + return _recent_prev_end_times_for_all_gcs_sec->oldest(); +} + double G1Analytics::last_known_gc_end_time_sec() const { - return _recent_prev_end_times_for_all_gcs_sec->oldest(); + return _recent_prev_end_times_for_all_gcs_sec->last(); } void G1Analytics::update_recent_gc_times(double end_time_sec,
--- a/src/share/vm/gc/g1/g1Analytics.hpp Fri Aug 12 08:59:20 2016 -0700 +++ b/src/share/vm/gc/g1/g1Analytics.hpp Fri Aug 12 13:58:14 2016 -0700 @@ -155,6 +155,7 @@ void update_recent_gc_times(double end_time_sec, double elapsed_ms); void compute_pause_time_ratio(double interval_ms, double pause_time_ms); + double oldest_known_gc_end_time_sec() const; double last_known_gc_end_time_sec() const; };
--- a/src/share/vm/gc/g1/g1CollectedHeap.cpp Fri Aug 12 08:59:20 2016 -0700 +++ b/src/share/vm/gc/g1/g1CollectedHeap.cpp Fri Aug 12 13:58:14 2016 -0700 @@ -28,6 +28,7 @@ #include "classfile/symbolTable.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" +#include "gc/g1/g1Analytics.hpp" #include "gc/g1/bufferingOopClosure.hpp" #include "gc/g1/concurrentG1Refine.hpp" #include "gc/g1/concurrentG1RefineThread.hpp" @@ -2473,8 +2474,19 @@ } jlong G1CollectedHeap::millis_since_last_gc() { - // assert(false, "NYI"); - return 0; + jlong now = os::elapsed_counter() / NANOSECS_PER_MILLISEC; + const G1Analytics* analytics = _g1_policy->analytics(); + double last = analytics->last_known_gc_end_time_sec(); + jlong ret_val = now - (last * 1000); + if (ret_val < 0) { + // See the notes in GenCollectedHeap::millis_since_last_gc() + // for more information about the implementation. + log_warning(gc)("Detected clock going backwards. " + "Milliseconds since last GC would be " JLONG_FORMAT + ". returning zero instead.", ret_val); + return 0; + } + return ret_val; } void G1CollectedHeap::prepare_for_verify() {
--- a/src/share/vm/gc/g1/g1DefaultPolicy.cpp Fri Aug 12 08:59:20 2016 -0700 +++ b/src/share/vm/gc/g1/g1DefaultPolicy.cpp Fri Aug 12 13:58:14 2016 -0700 @@ -604,7 +604,7 @@ _analytics->report_alloc_rate_ms(alloc_rate_ms); double interval_ms = - (end_time_sec - _analytics->last_known_gc_end_time_sec()) * 1000.0; + (end_time_sec - _analytics->oldest_known_gc_end_time_sec()) * 1000.0; _analytics->update_recent_gc_times(end_time_sec, pause_time_ms); _analytics->compute_pause_time_ratio(interval_ms, pause_time_ms); }
--- a/src/share/vm/gc/shared/genCollectedHeap.cpp Fri Aug 12 08:59:20 2016 -0700 +++ b/src/share/vm/gc/shared/genCollectedHeap.cpp Fri Aug 12 13:58:14 2016 -0700 @@ -1256,21 +1256,21 @@ }; jlong GenCollectedHeap::millis_since_last_gc() { - // We need a monotonically non-decreasing time in ms but - // os::javaTimeMillis() does not guarantee monotonicity. + // javaTimeNanos() is guaranteed to be monotonically non-decreasing + // provided the underlying platform provides such a time source + // (and it is bug free). So we still have to guard against getting + // back a time later than 'now'. jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; GenTimeOfLastGCClosure tolgc_cl(now); // iterate over generations getting the oldest // time that a generation was collected generation_iterate(&tolgc_cl, false); - // javaTimeNanos() is guaranteed to be monotonically non-decreasing - // provided the underlying platform provides such a time source - // (and it is bug free). So we still have to guard against getting - // back a time later than 'now'. jlong retVal = now - tolgc_cl.time(); if (retVal < 0) { - NOT_PRODUCT(log_warning(gc)("time warp: " JLONG_FORMAT, retVal);) + log_warning(gc)("Detected clock going backwards. " + "Milliseconds since last GC would be " JLONG_FORMAT + ". returning zero instead.", retVal); return 0; } return retVal;
--- a/src/share/vm/oops/methodCounters.hpp Fri Aug 12 08:59:20 2016 -0700 +++ b/src/share/vm/oops/methodCounters.hpp Fri Aug 12 13:58:14 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it
--- a/src/share/vm/opto/cfgnode.cpp Fri Aug 12 08:59:20 2016 -0700 +++ b/src/share/vm/opto/cfgnode.cpp Fri Aug 12 13:58:14 2016 -0700 @@ -1703,29 +1703,51 @@ } if (uncasted) { - // Add a cast node between the phi to be removed and its unique input. + // Add cast nodes between the phi to be removed and its unique input. // Wait until after parsing for the type information to propagate from the casts. assert(can_reshape, "Invalid during parsing"); const Type* phi_type = bottom_type(); assert(phi_type->isa_int() || phi_type->isa_ptr(), "bad phi type"); - int opcode; - // Determine the type of cast to be added. + // Add casts to carry the control dependency of the Phi that is + // going away + Node* cast = NULL; if (phi_type->isa_int()) { - opcode = Op_CastII; + cast = ConstraintCastNode::make_cast(Op_CastII, r, uin, phi_type, true); } else { const Type* uin_type = phase->type(uin); - if ((phi_type->join(TypePtr::NOTNULL) == uin_type->join(TypePtr::NOTNULL)) || - (!phi_type->isa_oopptr() && !uin_type->isa_oopptr())) { - opcode = Op_CastPP; + if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) { + cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true); } else { - opcode = Op_CheckCastPP; + // Use a CastPP for a cast to not null and a CheckCastPP for + // a cast to a new klass (and both if both null-ness and + // klass change). + + // If the type of phi is not null but the type of uin may be + // null, uin's type must be casted to not null + if (phi_type->join(TypePtr::NOTNULL) == phi_type->remove_speculative() && + uin_type->join(TypePtr::NOTNULL) != uin_type->remove_speculative()) { + cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL, true); + } + + // If the type of phi and uin, both casted to not null, + // differ the klass of uin must be (check)cast'ed to match + // that of phi + if (phi_type->join_speculative(TypePtr::NOTNULL) != uin_type->join_speculative(TypePtr::NOTNULL)) { + Node* n = uin; + if (cast != NULL) { + cast = phase->transform(cast); + n = cast; + } + cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, true); + } + if (cast == NULL) { + cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true); + } } } - // Add a cast to carry the control dependency of the Phi that is - // going away - Node* cast = ConstraintCastNode::make_cast(opcode, r, uin, phi_type, true); + assert(cast != NULL, "cast should be set"); cast = phase->transform(cast); - // set all inputs to the new cast so the Phi is removed by Identity + // set all inputs to the new cast(s) so the Phi is removed by Identity PhaseIterGVN* igvn = phase->is_IterGVN(); for (uint i = 1; i < req(); i++) { set_req_X(i, cast, igvn);
--- a/src/share/vm/runtime/frame.cpp Fri Aug 12 08:59:20 2016 -0700 +++ b/src/share/vm/runtime/frame.cpp Fri Aug 12 13:58:14 2016 -0700 @@ -225,6 +225,19 @@ return NULL; } +bool frame::is_entry_frame_valid(JavaThread* thread) const { + // Validate the JavaCallWrapper an entry frame must have + address jcw = (address)entry_frame_call_wrapper(); + bool jcw_safe = (jcw < thread->stack_base()) && (jcw > (address)fp()); // less than stack base + if (!jcw_safe) { + return false; + } + + // Validate sp saved in the java frame anchor + JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor(); + return (jfa->last_Java_sp() > sp()); +} + bool frame::should_be_deoptimized() const { if (_deopt_state == is_deoptimized || !is_compiled_frame() ) return false;
--- a/src/share/vm/runtime/frame.hpp Fri Aug 12 08:59:20 2016 -0700 +++ b/src/share/vm/runtime/frame.hpp Fri Aug 12 13:58:14 2016 -0700 @@ -166,6 +166,8 @@ frame sender_for_interpreter_frame(RegisterMap* map) const; frame sender_for_native_frame(RegisterMap* map) const; + bool is_entry_frame_valid(JavaThread* thread) const; + // All frames: // A low-level interface for vframes:
--- a/test/Makefile Fri Aug 12 08:59:20 2016 -0700 +++ b/test/Makefile Fri Aug 12 13:58:14 2016 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -226,6 +226,9 @@ ( \ jtregExitCode=$$? && \ _summary="$(SUMMARY_TXT)"; \ + if [ $${jtregExitCode} = 1 ] ; then \ + jtregExitCode=0; \ + fi; \ $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \ $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \ if [ -r "$${_summary}" ] ; then \
--- a/test/compiler/codecache/stress/RandomAllocationTest.java Fri Aug 12 08:59:20 2016 -0700 +++ b/test/compiler/codecache/stress/RandomAllocationTest.java Fri Aug 12 13:58:14 2016 -0700 @@ -24,6 +24,7 @@ /* * @test RandomAllocationTest + * @key stress * @summary stressing code cache by allocating randomly sized "dummy" code blobs * @library /testlibrary /test/lib / * @modules java.base/jdk.internal.misc
--- a/test/compiler/codecache/stress/UnexpectedDeoptimizationTest.java Fri Aug 12 08:59:20 2016 -0700 +++ b/test/compiler/codecache/stress/UnexpectedDeoptimizationTest.java Fri Aug 12 13:58:14 2016 -0700 @@ -24,6 +24,7 @@ /* * @test UnexpectedDeoptimizationTest + * @key stress * @summary stressing code cache by forcing unexpected deoptimizations * @library /testlibrary /test/lib / * @modules java.base/jdk.internal.misc
--- a/test/compiler/codegen/aes/TestAESMain.java Fri Aug 12 08:59:20 2016 -0700 +++ b/test/compiler/codegen/aes/TestAESMain.java Fri Aug 12 13:58:14 2016 -0700 @@ -25,6 +25,7 @@ /** * @test * @bug 7184394 + * @key stress * @summary add intrinsics to use AES instructions * @library /testlibrary / * @modules java.base/jdk.internal.misc
--- a/test/compiler/floatingpoint/ModNaN.java Fri Aug 12 08:59:20 2016 -0700 +++ b/test/compiler/floatingpoint/ModNaN.java Fri Aug 12 13:58:14 2016 -0700 @@ -26,7 +26,6 @@ * @bug 8015396 * @summary double a%b returns NaN for some (a,b) (|a| < inf, |b|>0) (on Core i7 980X) * - * @ignore 8145543 * @run main compiler.floatingpoint.ModNaN */
--- a/test/gc/g1/ihop/TestIHOPErgo.java Fri Aug 12 08:59:20 2016 -0700 +++ b/test/gc/g1/ihop/TestIHOPErgo.java Fri Aug 12 13:58:14 2016 -0700 @@ -24,6 +24,7 @@ /* * @test TestIHOPErgo * @bug 8148397 + * @key stress * @summary Test checks that behavior of Adaptive and Static IHOP at concurrent cycle initiation * @requires vm.gc.G1 * @requires !vm.flightRecorder
--- a/test/runtime/StackGuardPages/exeinvoke.c Fri Aug 12 08:59:20 2016 -0700 +++ b/test/runtime/StackGuardPages/exeinvoke.c Fri Aug 12 13:58:14 2016 -0700 @@ -242,7 +242,7 @@ CLASS_PATH_OPT, javaclasspath); options[0].optionString = "-Xint"; - options[1].optionString = "-Xss328k"; + options[1].optionString = "-Xss1M"; options[2].optionString = javaclasspathopt; vm_args.version = JNI_VERSION_1_2;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/serviceability/sa/sadebugd/SADebugDTest.java Fri Aug 12 13:58:14 2016 -0700 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Checks that the jshdb debugd utility sucessfully starts + * and tries to attach to a running process + * @modules java.base/jdk.internal.misc + * @library /test/lib/share/classes + * + * @run main/othervm SADebugDTest + */ +import java.io.File; +import java.util.concurrent.CountDownLatch; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.Reader; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; +import static jdk.test.lib.Asserts.assertTrue; +import static jdk.test.lib.Platform.shouldSAAttach; +import static jdk.test.lib.process.ProcessTools.startProcess; + +public class SADebugDTest { + + private static final String GOLDEN = "Attaching to process ID %d and starting RMI services, please wait..."; + + private static final String JAVA_HOME = (System.getProperty("test.jdk") != null) + ? System.getProperty("test.jdk") : System.getProperty("java.home"); + + private static final String JAVA_BIN_DIR + = JAVA_HOME + File.separator + "bin" + File.separator; + + private static final String JHSDB = JAVA_BIN_DIR + "jhsdb"; + + public static void main(String[] args) throws Exception { + + if (!shouldSAAttach()) { + log("Not possible to attach the SA. Skipping the test"); + return; + } + + long ourPid = ProcessHandle.current().getPid(); + + // The string we are expecting in the debugd ouput + String golden = String.format(GOLDEN, ourPid); + + // We are going to run 'jhsdb debugd <our pid>' + // The startProcess will block untl the 'golden' string appears in either process' stdout or stderr + // In case of timeout startProcess kills the debugd process + ProcessBuilder pb = new ProcessBuilder(); + pb.command(JHSDB, "debugd", String.valueOf(ourPid)); + Process debugd = startProcess("debugd", pb, null, (line) -> line.trim().contains(golden), 0, TimeUnit.SECONDS); + + // If we are here, this means we have received the golden line and the test has passed + // The debugd remains running, we have to kill it + debugd.destroy(); + + } + + private static void log(String string) { + System.out.println(string); + } + +}